【C++ 学习】C++ 传值 传指针 传引用

C++ 传值 传指针 传引用

文章目录

  • C++ 传值 传指针 传引用
    • 引用
      • const 引用
      • 指针的引用和引用的指针
      • 引用作为函数参数
      • 例子

C++ 函数传参主要是三种方法:传值、传指针、传引用。

说在前面:

  1. 传引用相对来说是简单一点的,也更加优雅。

明确几点:

  1. 指针也是一个变量,指针中存的值是一个地址,
  2. 非main函数的其他调用函数传递的形参只在其函数范围内起作用。即单纯的形式参数,只在其调用函数范围内其作用,
  3. 由于2的原因,当我们在调用函数中改变了某些数据,并且希望这种改动能够被携带出来。我们需要使用引用& 或 指针*。
  4. 使用传值的方法,当变量在调用函数中改变时,在返回的函数中是不会改变的。(原因在于,传值方法,调用函数生成了变量的副本,改变的是变量的副本)默认的参数传递语义是值传递(pass-by-value):函数接收其参数的副本。修改这些参数后,原始实参将保持不变。

请注意本文中的很多内容来自《C++20高级编程 第5版》,感谢本书的作者和翻译人员。

引用

C++中的引用(reference)是另一个变量的别名。对引用的所有修改都会更改其引用的变量的值。可以将引用视为隐式指针,它省去了获取变量地址和解引用指针的麻烦。

引用变量必须总是在创建时初始化。

具体来说,就是

int x = 3, y = 4;
int &xRef = x;		// 其中xRef是引用变量, 该语句不能写为int &xRef; xRef = x; 这是不合法的
xRef = y; 			// 此时,x 中的值被修改,此时x = 4;xRef = 5;		   // 这是被允许的,这相当于将 x值改为5;xRef = &y;			// 这是不合法的,编译器报错。

该程序也表明,引用与指针非常相似。

int main() {std::cout << "Hello, World!" << std::endl;int x = 5;int &xrf = x;std::cout << x << std::endl;std::cout << xrf << std::endl;xrf = 6;std::cout << x << std::endl;std::cout<< xrf << std::endl;std::cout << &xrf << std::endl;std::cout << &x << std::endl;return 0;
}

const 引用

  1. 引用默认是 const(因为我们不能改变引用的指向)。
  2. 无法创建引用的引用(即不能对别名本身在起一个别名, 引用必须针对一个实体)。
int main(){std::cout << "Hello, World!" << std::endl;int x = 5, y = 4;int &xrf = x;xrf = &y;		// 针对1的解释,即不能改变引用的指向int &xxrf = xrf;		//针对2的解释,即不能创建引用的引用。return 0;
}

针对引用使用 const,其含义为:

int z;
const int& zRef {z};
zRef = 4;		// 编译器报错

对于引用使用const,使得我们无法通过该引用来改变变量的值。然而,我们可以使用变量自身进行值的更改。

指针的引用和引用的指针

// 指向int的指针的引用
int* intP{ nullptr };
int*& ptrRef {intP};
ptrRef = new int;
*ptrRef = 5;

ptrRef是对intP的引用,intP是对int的指针,修改ptrRef会更改intP。也就是说ptrRef是一个指针的引用。

int x = 3; // int x {3};
int& xRef {x};
int* xPtr {&xRef};
*xPtr = 100;

这是一个引用的指针。也就是说,该代码通过取x的引用的地址来将xPtr设置为指向x。将100赋值给*xPtr会将x的值更改为100。

xPtr是指针,xPtr存放的是一个地址,*对该地址中的内容进行访问。xPtr==&xRef,也就是xRef不是一个地址

引用作为函数参数

C++程序员通常不使用独立的引用变量或引用数据成员,引用的最常见用途是用于函数的参数。默认的参数传递语义是值传递(pass-by-value):函数接收其参数的副本。修改这些参数后,原始实参将保持不变。

传指针:栈中变量的指针经常在C语言中使用,以允许函数修改其他栈帧中的变量。通过对指针解引用,函数可以修改表示该变量的内存,即使该变量不在当前的栈帧中。然而,指针是比较麻烦的。

传引用:C++中提供了一种更好的机制,称为引用传递(pass-by-reference),参数是引用而不是指针。

从函数返回对象的推荐方法是通过值返回,而不是使用一个输出参数。

引用传递(pass-by-reference)的好处:

  1. 效率: 复制大型的对象可能花费很长时间,引用传递知识将该对象的一个引用传给函数。
  2. 支持:不是所有的类都允许值传递。

建议多使用:const &

例子

使用引用可以比使用指针干净得多。本书中使用了一个很好的例子,该例子中使用了标准库容器vector。

void seperateOddsAndEvens(const vector<int>& arr, vector<int>& odds, vector<int>& evens){for (int i : arr){if (i % 2 == 1){odds.push_back(i);}else{evens.push_back(i);}}
}

使用引用能够让代码非常简洁,而且效率也非常高,这是可以明确的。使用引用,可以把值传递出来。

vector<int> vecUnSplit {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int> odds, evens;
separateOddsAndEvens(vecUnSplit, odds, evens)

其对应的指针版本为:

void separateOddsAndEvens(const int arr[], size_t size, int** odds, size_t* numOdds, int** evens, size_t* numEvens){//count the number of odds and evens*numOdds = *numEvens = 0;for(size_t i = 0; i < size; ++i){if (arr[i] % 2 == 1){++(*numOdds);}else{++(*numEvens);}}// 指针需要先统计一下// Allocate two new arrays of the approriate size*odds = new int [*numOdds];*evens = new int [*numEvens];// Copy the odds and evens to the new arrayssize_t oddsPos = 0, evenPos = 0;for (size_t i = 0; i < size; ++i){if (arr[i] % 2 == 1){(*odds)[oddsPos++] = arr[i];}else{(*evens)[evensPos++] = arr[i];}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/722316.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js形参传递特殊字符

在前端我们给其他页面传值或者传数据到后台的时候&#xff0c;字符串经常将一些特殊符号识别成字符集。这种情况下会将数据打断或者打乱&#xff0c;比如字符串里面包含*/&这些符号的时候就会错误。 我们可以通过将字符中的特殊字符替换成十六进制的字符&#xff0c;一些特…

【Linux从青铜到王者】进程信号

——————————————————————————————————————————— 信号入门 在了解信号之前有许多要理解的相关概念 我们可以先通过一个生活例子来初步认识一下信号 1.生活角度的信号 你在网上买了很多件商品&#xff0c;再等待不同商品快递的到来…

LeetCode hot100-4

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。我的解法可以通过&#xff0c;而且时间能打败99.98%的Java 思路就是找出有几个0。然后遍历数…

从事测绘地信,你需要这些插件、软件、小工具、图源...

特别声明&#xff0c;本篇是来自公众号GIS前沿的资源&#xff0c;看着比较好&#xff0c;特别给大家推荐。加粗样式 今天&#xff0c;我们又来汇总了一些工作中实用的插件、小工具、数据等等&#xff0c;小助手又来帮你提高工作效率了****。 因为小助手每年都会总结一次&…

15.Django总结

文章目录 1.Django创建项目的命令2.MVC,MVT的理解3.Django中间件的使用4.WSGI,uWSGI服务器 和 uwsgi协议5.nginx和uWISG 服务器之间如何配合工作的6.django开发中数据库做过什么优化7.Python中三大框架各自的应用场景8.django如何提升性能(高并发)9. 什么是restful api谈谈你的…

Verilog宏、`include<要包含的路径/文件>

Verilog宏 Verilog对宏的定义如下&#xff1a; define TESTEQ1 4b1101 定义的宏稍后将被引用&#xff0c;如下所示&#xff1a; 如果&#xff08;请求TESTEQ1&#xff09; “ifdef”和“endif”构造执行以下操作&#xff1a; •确定是否定义了宏。 •定义条件编译。 如果定义了…

MySQL性能优化-数据库调优有哪些维度可以选择

数据库调优的目标 简单来说&#xff0c;数据库调优的目的就是要让数据库运行得更快&#xff0c;也就是说响应的时间更快&#xff0c;吞吐量更大。 不过随着用户量的不断增加&#xff0c;以及应用程序复杂度的提升&#xff0c;我们很难用“更快”去定义数据库调优的目标&#…

windows常用命令总结

Windows常用命令总结如下&#xff1a; 系统管理与维护&#xff1a; shutdown&#xff1a;用于关闭或重新启动计算机。例如&#xff0c;shutdown -s -t 60 表示60秒后关机&#xff0c;shutdown -r -t 60 表示60秒后重启。systeminfo&#xff1a;显示关于计算机及其操作系统的详细…

掘根宝典之C语言if,switch,break,continue,逻辑运算符(||,,!),?:运算符

if语句 C语言中的if语句用于执行给定条件下的一部分代码。 if语句的语法如下&#xff1a; if (condition) {// code to be executed if condition is true }在这里&#xff0c;condition是一个表达式&#xff0c;如果为真&#xff0c;则执行if语句块中的代码。如果条件为假&…

蓝桥集训之重新排序

蓝桥集训之重新排序 核心思想&#xff1a;差分 利用差分 在一段区间内 最终求和得到每个位置数计算的次数然后分别从大到小排序w[i]和s[i]数组 #include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int N 100010;int w[N],s…

Python并发编程:协程-gevent模块

一 gevent模块 Gevent是一个第三方库&#xff0c;可以轻松通过gevent实现并发同步或异步编程。在gevent中用到的主要模式是Greenlet&#xff0c;它是以C扩展模块形式接入Python的轻量级协程。Greenlet 全部运行在主程序操作系统进程的内部&#xff0c;但它们被协作式地调度。 …

Stable Diffusion ———LDM、SD 1.0, 1.5, 2.0、SDXL、SDXL-Turbo等版本之间关系现原理详解

前言 2021年5月&#xff0c;OpenAI发表了《扩散模型超越GANs》的文章&#xff0c;标志着扩散模型&#xff08;Diffusion Models&#xff0c;DM&#xff09;在图像生成领域开始超越传统的GAN模型&#xff0c;进一步推动了DM的应用。 然而&#xff0c;早期的DM直接作用于像素空…

cmd模式下启动mysql

1.打开cmd输入services.msc&#xff0c;找到MYSQL&#xff0c;右击属性&#xff0c;找到可执行文件路径&#xff0c;加载到环境变量。 2.打开cmd&#xff0c;启动MYSQL&#xff1a;输入net start mysql; 3.登陆MYSQL&#xff0c;需要管理权限&#xff1b; 输入&#xff1a;my…

HALCON 快速入门手册

HALCON 快速入门手册 1 什么是 HALCON HALCON 是德国 MVtec 公司开发的一套完善的标准的机器视觉算法包&#xff0c;拥有应用广泛 的机器视觉集成开发环境。它节约了产品成本&#xff0c;缩短了软件开发周期——HALCON 灵活的 架构便于机器视觉&#xff0c;医学图像和图像分析应…

Docker容器化解决方案

什么是Docker&#xff1f; Docker是一个构建在LXC之上&#xff0c;基于进程容器的轻量级VM解决方案&#xff0c;实现了一种应用程序级别的资源隔离及配额。Docker起源于PaaS提供商dotCloud 基于go语言开发&#xff0c;遵从Apache2.0开源协议。 Docker 自开源后受到广泛的关注和…

数据链路层----滑动窗口协议的相关计算

目录 1.窗口大小的相关计算 •停等协议&#xff1a; •后退N帧协议&#xff1a; •选择重传协议&#xff1a; 2.信道利用率相关计算 •停等协议的信道利用率&#xff1a; •连续ARQ&#xff08;后退N帧协议&#xff0c;选择重传协议&#xff09;的信道利用率&#xff1a;…

工具函数模板题(蓝桥杯 C++ 代码 注解)

目录 一、Vector容器&#xff1a; 二、Queue队列 三、Map映射 四、题目&#xff08;快递分拣 vector&#xff09;&#xff1a; 代码&#xff1a; 五、题目&#xff08;CLZ银行问题 queue&#xff09;&#xff1a; 代码&#xff1a; 六、题目&#xff08;费里的语言 map&…

每日学习总结20240301

20240301 1. strchr VS strrchr strchr和strrchr是C语言标准库中的字符串处理函数&#xff0c;用于在字符串中查找特定字符的位置。 1.1 strchr函数 strchr函数用于在字符串中查找第一次出现指定字符的位置&#xff0c;并返回该位置的指针。函数原型如下&#xff1a; char…

你都了解2024程序员拿捏高薪的新方式吗?

2024年&#xff0c;程序员该如何拿高薪呢&#xff1f; 道理是这么讲&#xff0c;那我们到底应该如何去践行呢&#xff1f;以我自身的经验来看&#xff0c;网络接单无疑是我们程序员来钱最快的方式&#xff0c;既可以做到兼顾本职工作和快点搞钱&#xff0c;又可以充分利用好每一…

云解析的高防DNS技术有哪些优势和作用?(国科云)

云解析作为一种更加智能安全的解析技术&#xff0c;开始替代传统解析技术&#xff0c;受到越来越多政府机关和企业的关注和信赖。相比传统解析技术&#xff0c;云解析具备智能解析、健康监测、全局流量管理等技术优点&#xff0c;有效提升DNS解析的效率和精度&#xff0c;而其所…