C++/C:pass-by-value(值传递)与pass-by-reference(引用传递)

一、C++的引用(reference)

1.1、引用的概念

c++中新增了引用(reference)的概念,引用可以作为一个已定义变量的别名。

Declares a named variable as a reference, that is, an alias to an already-existing object or function.

1.2、引用的定义与初始化

基本语法:Type& ref = val;

运用定义完成后,相当于目标变量有两个名称,变量名ref实际上是一段连续内存空间的别名

注意事项:

1、&在此不是求地址运算,而是起标识作用。

2、必须在声明引用变量时进行初始化。比如:int a = 10; int& b = a;

3、引用初始化后不能改变,即不能在作为别的变量的引用

int a = 10;
int& b = a;
int c = 20;
b = c; \\错误!reference初始化之后不能再次赋值

4、数组不能定义引用

1.3、引用和指针的区别

C++中指针与引用的区别 - 知乎

1.4、C++为什么要引入引用?

1.4.1、优势:

  • 可读性更好

  • 更容易实现链式调用

1.4.2、必要性:

引用就是顶层const指针
为什么需要引用:是一个访谈里面的一段话,里面说设计c++语法的时候之所以增加引用,是因为重载赋值运算符的时候,指针不好使。

二、c语言的值传递和引用传递

先看一段简单的passing by value代码:

void passByValue(int num){num++;printf("function number: %d\n",num); //num=>11
}
int main(){int num = 10;passByValue(num);printf("original number: %d\n",num); //num=>10return 0;
}

运行此代码就会发现,num被复制到了函数中,并没有改变其本身值。

下面是一段passing by reference的代码,值得注意的是C语言不像C++一样有真正的引用(reference),所以传递reference的时候要用到pointer来实现。

void passByReference(int* num){(*num)++;  //"dereference"printf("function number: %d\n",*num); //num=>11
}
int main(){int num = 10;passByReference(&num);printf("original number: %d\n",num); //num=>11return 0;
}

运行此代码可以看到,两次print出来的都是11。因此可知传递的是变量的地址,在函数内对变量做出改变会影响到原变量的值。

 三、c++语言的值传递、指针传递和引用传递

例如:c++中常用的vector容器作为参数时,有三种传参方式,分别如下:

function1(vector<int> vec),传值
function2(vector<int> &vec),传引用
function3(vector<int> *vec),传指针

三种方式对应的调用形式分别为:

function1(vec),传入值
function2(vec),传入引用
function3(&vec),传入地址

三种方式的效果分别为:

会发生拷贝构造
不会发生拷贝构造
不会发生拷贝构造
 

pass-by-reference与pass-by-value相比,后者多调用了一次拷贝构造函数与析构函数,且当形参为非基本类型时,也将在栈区开辟更多的空间。因此,参数传递尽可能使用pass-by-reference方式,如果不希望函数内部对实参进行更改,可以在形参前加canst修饰。

但是,并不是pass-by-reference方式一定优于pass-by-value,由于引用的实质是指针实现,引用真正传递的是指针,进行间接寻址,在传递内置类型时(如 int),指针所占空间甚至高于变量所占内存空间(char类型占用一个字节,而32bit系统指针占用4个字节),且间接寻址的效率要低些,因此,此时应选用pass-by-value更有效。同理,大多数STL容器内含的东西仅仅比指针类型多一点。因此,pass-by-reference节省空间有限,且间接寻址降低了程序效率,选用pass-by-value效率更高。
 

REF:

C++ reference - cppreference.com

Standard C++

[C++引用] 关于return by reference 和 pass by reference_c++returnbyreference_llnllm的博客-CSDN博客

C++ Functions - Pass By Reference - GeeksforGeeks

引用传递(passing by references) 在C语言和C++中的区别_J_039的博客-CSDN博客

C++ 高效编程:pass-by-value(值传递)与pass-by-reference(引用传递)_c99 pass by reference_hik_老鬼的博客-CSDN博客

为什么C++既有指针又有引用 | 指针和引用的区别 |_哔哩哔哩_bilibili

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

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

相关文章

2分钟搭建FastGPT训练企业知识库AI助理(Docker部署)

我们使用宝塔面板来进行搭建&#xff0c;更方便快捷灵活&#xff0c;争取操作时间只需两分钟 宝塔面板下安装Docker 在【软件商店中】安装【docker管理器】【docker模块】即可 通过Docker安装FastGPT 通过【Docker】【添加容器】【容器编排】创建里新增docker-compose.yaml以下…

【德哥说库系列】-ASM管理Oracle 19C单实例部署

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

opencv鼠标事件函数setMouseCallback()详解

文章目录 opencv鼠标事件函数setMouseCallback()详解1、鼠标事件函数&#xff1a;&#xff08;1&#xff09;鼠标事件函数原型&#xff1a;setMouseCallback()&#xff0c;此函数会在调用之后不断查询回调函数onMouse()&#xff0c;直到窗口销毁&#xff08;2&#xff09;回调函…

视频云存储/安防监控/AI视频智能分析网关V3:工服检测功能详解

在一些工地、后厨、化工、电力等特定的场景中&#xff0c;工服的穿戴是必不可少的。这不仅是安全制度的要求&#xff0c;更能降低工作风险、提高工作效率。TSINGSEE青犀AI 边缘计算网关硬件 —— 智能分析网关可以通过实时监测和识别工人的工装穿戴情况&#xff0c;确保他们符合…

openGauss学习笔记-55 openGauss 高级特性-全密态数据库

文章目录 openGauss学习笔记-55 openGauss 高级特性-全密态数据库55.1 连接全密态数据库55.2 创建用户密钥55.3 创建加密表55.4 向加密表插入数据并进行查询 openGauss学习笔记-55 openGauss 高级特性-全密态数据库 全密态数据库意在解决数据全生命周期的隐私保护问题&#xf…

vim练级攻略(精简版)

vim推荐配置: curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh 0. 规定 Ctrl-λ 等价于 <C-λ> :command 等价于 :command <回车> n 等价于 数字 blank字符 等价于 空格&#xff0c;tab&am…

windows主机和Ubuntu虚拟机共享设置

参考文章 Ubuntu Linux 与主机共享文件夹 vim 修改文件出现错误 “ E45: ‘readonly’ option is set (add to override)“ vim退出时报错“E212: Cant open file for writing”的解决办法 VMware 安装后&#xff0c;安装Ubuntu 20.04一路顺利。 1&#xff0c;在VMware设置…

设计模式-原则篇-01.开闭原则

简介 ​ 可以把设计模式理解为一套比较成熟并且成体系的建筑图纸&#xff0c;经过多次编码检验目前看来使用效果还不错的软件设计方案。适用的场景也比较广泛&#xff0c;在使用具体的设计模式之前先要学习软件设计的基础 “软件设计原则”&#xff0c;后面的23个设计模式都是…

《爵士乐史》乔德.泰亚 笔记

第一章 【美国音乐的非洲化】 【乡村布鲁斯和经典布鲁斯】 布鲁斯&#xff1a;不止包括忧愁、哀痛 十二小节布鲁斯特征&#xff1a; 1.乐型&#xff08;A:主、B:属、C/D:下属&#xff09;&#xff1a;A→A→B→A→C→D→A→A 2.旋律&#xff1a;大三、小三、降七、降五 盲人…

SpringBoot入门篇3 - 整合junit、整合mybatis、基于SpringBoot实现ssm整合

目录 1.整合JUnit Spring整合JUnit SpringBoot整合JUnit 测试类注解&#xff1a;SpringBootTest 作用&#xff1a;设置JUnit加载的SpringBoot启动类 2.整合mybatis ①使用spring initializr初始化项目的时候&#xff0c;添加依赖。 ②设置数据源application.yml spring:d…

(Deep Learning)准确率和召回率的基础概念

算法模型极大的提升了对各类结果的预测效率。 【算法模型的本质】 算法模型的本质&#xff0c;是基于输入的各类变量因子&#xff0c;通过计算规则&#xff08;模型or公式&#xff09;&#xff0c;得出预测结果。 典型的预测结果比如&#xff1a; 1.&#xff08;通过历史行为…

【个人博客系统网站】注册与登录 · 加盐加密验密算法 · 上传头像

【JavaEE】进阶 个人博客系统&#xff08;3&#xff09; 文章目录 【JavaEE】进阶 个人博客系统&#xff08;3&#xff09;1. 加盐加密验密算法原理1.1 md5加密1.2 md5验密1.3 md5缺漏1.4 加盐加密1.5 后端的盐值拼接约定1.6 代码实现1.6.1 加密1.6.2 验密1.6.3 测试 2. 博客…