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

news2024/12/29 3:49:08

一、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=>10
	return 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=>11
	return 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.coloradmin.cn/o/963973.html

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

相关文章

vulnhub靶机EvilBox---One

靶机地址&#xff1a;EvilBox: One ~ VulnHub 主机发现 arp-scan -l 端口扫描 nmap --min-rate 10000 -p- 192.168.21.153 扫描端口信息 nmap -sV -sT -O -p22,80 192.168.21.153 漏洞扫描 nmap --scriptvuln -p22,80 192.168.21.153 访问网站 再去看看robots.txt 之前扫描…

GoT:用大语言模型解决复杂的问题

GoT&#xff1a;用大语言模型解决复杂的问题 摘要介绍背景和符号表示语言模型和上下文学习Input-Output&#xff08;IO&#xff09;Chain of thought&#xff08;CoT&#xff09;Multiple CoTTree of thoughts&#xff08;ToT&#xff09; GoT框架推理过程思维变换聚合变换&…

数据结构-第一期——数组(Python)

目录 00、前言&#xff1a; 01、一维数组 一维数组的定义和初始化 一维变长数组 一维正向遍历 一维反向遍历 一维数组的区间操作 竞赛小技巧&#xff1a;不用从a[0]开始&#xff0c;从a[1]开始 蓝桥杯真题练习1 读入一维数组 例题一 例题二​ 例题三 实战训…

清理docker镜像方法

首先stop ps -a里的容器&#xff0c;然后rm容器&#xff0c;最后再rmi镜像 先停止容器 rm容器 docker rmi 镜像 删除后可以发现已经不存在

(数字图像处理MATLAB+Python)第十一章图像描述与分析-第五、六节:边界描述和矩描述

文章目录 一&#xff1a;边界描述&#xff08;1&#xff09;边界链码A&#xff1a;概述B&#xff1a;边界链码改进C&#xff1a;程序 &#xff08;2&#xff09;傅里叶描绘子A&#xff1a;概述B&#xff1a;程序 二&#xff1a;矩描述&#xff08;1&#xff09;矩A&#xff1a;…

软件测试Day5|软件测试理论03

白盒测试方法 针对程序的代码进行测试&#xff0c;代码覆盖率高&#xff1b;缺点&#xff1a;覆盖所有代码路径大、业务功能可能覆盖不全、测试开销大 静态方法&#xff1a;1&#xff09;桌面检查&#xff08;一个人检查&#xff09;&#xff1b;2&#xff09;代码审查&#…

音频——硬件拓扑

文章目录 硬件拓扑I2S 数据通路五线模式四线模式两线 TX两线 RX 典型应用硬件连接数据流 硬件拓扑 控制路径&#xff1a;UART/I2C/SPI数据路径&#xff1a;I2S 简略图如下 I2S 数据通路 五线模式 四线模式 两线 TX 两线 RX 典型应用 硬件连接 控制信号&#xff1a;SPI 用…

网络通讯接收组播异常问题技术分析报告

1、问题概述 2023年8月24日&#xff0c;深夜约22:10分&#xff0c;内部网络E5刀片上运行的组播接收软件未收到目的地址是230.1.6.4的航迹组播报文&#xff0c;利用交换机Web页面查看交换机组播表项&#xff0c;发现E5刀片连接的交换机29端口没有任何组播表项。重新运行组播接收…

每日一题 2511. 最多可以摧毁的敌人城堡数目

难度&#xff1a;简单 翻译&#xff1a;寻找距离最远的 1 和 -1 的组合&#xff0c;要求它们之间只有0 class Solution:def captureForts(self, forts: List[int]) -> int:res, t 0, -1for i, fort in enumerate(forts):if fort -1 or fort 1:if t > 0 and fort ! f…

687. 最长同值路径

687. 最长同值路径 C代码&#xff1a;DFS int res; // int res 0; 这种初始化有问题int dfs(struct TreeNode* root, int val) {if (root NULL) {return 0;}int left dfs(root->left, root->val);int right dfs(root->right, root->val);res fmax(res, lef…

【STM32】学习笔记(TIM定时器)

TIM&#xff08;Timer&#xff09;定时器 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断功能&#xff0c;而且…

nvidia-smi nvcc -V 及 CUDA、cuDNN 安装

nvidia-smi nvcc -V 及 CUDA、cuDNN 安装 1. 问题缘由2. 分析3. CUDA Driver API 安装3.1 Software & Updates3.2 官网下载 4. CUDA Runtime API 安装5. 安装 cuDNN5.1 cuDNN下载 6. 一点点小注意事项 1. 问题缘由 之前查找 CUDA 版本时都是直接使用的 nvidia-smi 指令&am…

软考A计划-网络工程师-复习背熟-数据通信基础和局域网技术

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

Power View

界面 切换可视化效果 对于已经上传到透视表的数据&#xff0c;选择power view&#xff0c;形成表格后。

Windows开发调试纯Linux代码(WSL+Qt+MobaXterm)环境搭建(超详细教程)

为何要调试Linux代码 1 学习Linux环境开发 想必很多同学都想学习Linux环境下的开发&#xff0c;一个是很多纯服务端程序不需要Windows这样的窗口界面。另一个纯服务端开发Linux的命令行以及脚本优势也比较明显。相反&#xff0c;Windows在纯服务端编程方面并没有Linux有优势。…

拓扑排序算法 -- dfs、bfs

210. 课程表 II 该题用到「拓扑排序」的算法思想&#xff0c;关于拓扑排序&#xff0c;直观地说就是&#xff0c;让你把⼀幅图「拉平」&#xff0c;⽽且这个「拉平」的图⾥⾯&#xff0c;所有箭头⽅向都是⼀致的&#xff0c;⽐如上图所有箭头都是朝右的。 很显然&#xff0c;如…

CVE-2023-32315:Openfire管理控制台身份验证绕过到RCE的复现

CVE-2023-32315&#xff1a;Openfire管理控制台身份验证绕过到RCE复现 前言 本次测试仅供学习使用&#xff0c;如若非法他用&#xff0c;与本文作者无关&#xff0c;需自行负责&#xff01;&#xff01;&#xff01; 一.Openfire简介 Openfire是根据开源Apache许可证授权的…

C语言——指针基本语法

概述 内存地址 在计算机内存中&#xff0c;每个存储单元都有一个唯一的地址(内存编号)。 通俗理解&#xff0c;内存就是房间&#xff0c;地址就是门牌号 指针和指针变量 指针&#xff08;Pointer&#xff09;是一种特殊的变量类型&#xff0c;它用于存储内存地址。 指针的实…

46、SpringBoot输入校验--JSR 303

★ Spring Boot的输入校验 springboot支持两种校验方式&#xff1a;1. Spring原生提供的 Validation&#xff0c;这种验证方式需要开发者手写验证代码&#xff0c;比较繁琐。就是普通的if判断2. 使用JSR 303的校验&#xff0c;这种验证方式只需使用注解、即可以声明式的方式进…

封装(个人学习笔记黑马学习)

1、格式 #include <iostream> using namespace std;const double PI 3.14;//设计一个圆类&#xff0c;求圆的周长 class Circle {//访问权限//公共权限 public://属性//半径int m_r;//行为//获取圆的周长double calculateZC() {return 2 * PI * m_r;} };int main() {//通…