C++ 参数的三种传递方式和应用场景

news2024/11/18 11:50:37

C++ 参数的三种传递方式分别是值传递指针传递引用传递

值传递

值传递的实质

  • 将实参的值(a、b)复制到形参(m、n)相应的存储单元中,即形参和实参分别占用不同的存储单元。

值传递的特点

  • 值传递的特点是单向传递,即主调函数被调用时给形参分配存储单元,把实参的值传递给形参,在调用结束后,形参的存储单元被释放,而形参值的任何变化都不会影响到实参的值,实参的存储单元仍保留并维持数值不变。

值传递的应用场景

  • 适用于传递简单的数据类型,如int、float、double等。传值是将参数的值传递给函数,函数内部会创建一个新的变量来存储该值,对该变量的修改不会影响原变量的值。

例子1:我们首先讲值传递,并且把它的特性列出来。下面我们先看代码:
void test(int a) {
a += 3;
cout << “a的值:” << a << “\n”
<< “a的地址:” << &a << “\n”;
}
void main()
{
int b = 10;
test(b);
cout << “b的值:” << b << “\n”
<< “b的地址:” << &b << “\n”;
}
这是一个简单的值传递,而地址就是内存位置,学过C++的人都清楚,下面是运行的结果

在这里插入图片描述

 根据代码和结果我们可以知道的是值传传递的参数是有自己的内存的,并且当b把自己的值传递进去之后,对b是没有影响的,那么值传递则是等于把b的值赋给了a等于进行了一个赋值操作这就是值传递。

指针传递

指针传递的实质

  • 所谓的地址传递,指的就是函数的参数是数组名或者指针。传递的是数组的首地址或指针的值,而形参接收到的是实参的地址,即指向实参的存储单元,形参和实参占用相同的存储单元,所以形参和实参是相同的。

特点

  • 形参并不存在存储空间,编译系统不为形参数组分配内存。因此在数组名或指针作函数参数时所进行的传送只是地址传送,形参在取得该地址之后,与实参共同拥有一段内存空间,形参的变化也就是实参的变化。

运用场景

  • 适用于传递数组、结构体等复杂的数据类型。指针传递是将参数的地址传递给函数,函数内部通过指针来访问该变量,对该变量的修改会影响原变量的值。

例子2:接下下来我讲指针传递,下面是指针传递的代码:
void test(int *a) {
*a += 3;
cout << “a所指向地址:” << a << “\n”
<< “a的地址:” << &a << “\n”
<< “a所指向地址的值:” << *a << “\n”;
}
void main()
{
int b = 10;
test(&b);
cout << “b的值:” << b << “\n”
<< “b的地址:” << &b << “\n”;
}
这是一个指针传递,可以明显的发现和值传递的差别,指针是存储地址的,当我们想要把b的值传进test()函数时,我们传的是b的地址,然后通过b的地址,来获得b的值,下面是结果
在这里插入图片描述

 我们输出的跟值传递不同的是什么呢,很明显的是这次输出的地址比值传递多一个地址,那这个多的地址和b的地址一模一样,可以说明的是指针传递的是地址,然后还有不同的是b的值也被改变了,这就指针传递和值传递的不同。

引用传递

引用传递的实质

  • 形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。
  • 形参的地址是实参地址的映射,即拥有不同的储存空间但是里面存放的地址相同。

特点

  • 被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

运用场景

  • 适用于传递对象、类等复杂的数据类型。引用传递是将参数的引用传递给函数,函数内部通过引用来访问该变量,对该变量的修改也会影响原变量的值。引用传递与指针传递相似,但使用起来更加简洁明了。

例子3:最后一个是引用传递,引用传递,传递的是什么呢?它和值传递、指针传递不同的地方是什么呢,下面是代码:
void test(int &a) {
a += 3;
cout << “a的值:” << a << “\n”
<< “a的地址:” << &a << “\n”;
}
void main()
{
int b = 10;
test(b);
cout << “b的值:” << b << “\n”
<< “b的地址:” << &b << “\n”;
}
在代码上是不是发现和值传递差不多,只是参数声明哪里比值传递的多了一个&符号其他的和值传递一样,但是就是在参数声明哪里多一个&符号,它就不是值传递,它的传递方式和值传递的是完全不一样的,所以在写参数声明时,要注意不要在你需要的引用传递时漏了一个&符号,它们的不同之处在哪里呢,我们看输出结果就知道了,下面是结果:
在这里插入图片描述

 可以发现的是a的值和b的值是一样的,上面我们说指针传递时,是输出了一个a所指向地址的值,它的值和b的值是一样,那么引用是不是和指针一样传的地址呢,其实不是的因为引用传递其实是等于把b作为test()函数的全局变量,为什么这样说呢,是因为a的地址和b相同,然后a所做的所有操作都等于b做的,这a像是b的什么呢,这是名字不同,其他一样,a其实就是b的一个别名,所以test()函数对a的所有操作,都等于对b进行,而a只是b的另外一个标识。
那么有人对引用传递还有疑惑对吧,&在参数处是引用在所有非参数声明处都是获取某个变量的地址。还有就是引用可不可以解地址对吧,其实是不可以的,我们可以看一下它如果对引用解地址的话会报什么错误。下面错误提示
在这里插入图片描述

它提示的*(解址符)的操作数必须是指针,意思只能对指针进行解址,对其他的类型是不能解址的。

总结:

然后我们总结一下值传递、指针传递和引用传递不同的地方,首先它们都是可以把值传递给函数的只不过是传递的方式不同,有一点是可以很明显的,指针传递和引用传递都会改变b的值,值传递不会,这就是值传递和另外的区别,而指针传递和引用传递的不同的地方则是指针传递的是b的地址,而引用传递则等于给b起了一个别名,然后通过别名来操作b的值,和它所在的内存地址。

总而言之

值传递:形参开辟内存空间,与形参不同的地址,不能改变值。(变量名的访问)

地址传递:形参不开辟内存空间,与形参相同的地址,能改变值。(地址的访问)

引用传递:形参开辟内存空间,与形参相同的地址,能改变值。


 

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

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

相关文章

Java Web开发实战经典学习过程笔记

Java Web开发实战经典学习简单笔记 第一章 Java Web 开发简介 1.胖客户端程序指的是&#xff0c;当一个程序运行时需要一个单独的客户端程序支持(如&#xff1a;QQ)。瘦客户端程序在操作时不需要任何其他程序的安装(如&#xff1a;登录网上论坛&#xff0c;只需浏览器即可)。 2…

I.MX6ull UART

一 简介 UART 全称叫做串行接口&#xff0c;通常也叫做 COM 接口&#xff0c;串行接口指的是数据一个一个的顺序传输&#xff0c;通信线路简单。使用两条线即可实现双向通信&#xff0c;一条用于发送&#xff0c;一条用于接收。串口通信距离远&#xff0c;但是速度相对会低&…

Self-Attention 自注意力机制

输出形式 李宏毅讲到&#xff1a; 模型的输入是只有一种形式——词向量但是输出的形式却是不唯一的&#xff0c;主要有以下三种&#xff1a; 每一个向量对应一个输出(多对多&#xff0c;且一一对应) 每个序列只有一个输出(多对一) 一个序列对应一个序列(多对多&#xff0c;长…

MySQL 索引的10 个核心要点

文章目录 &#x1f349;1. 索引底层采用什么数据结构&#xff1f;为什么不用hash&#x1f349;2. B树与B树区别&#xff1f;为何用B树&#xff1f;&#x1f349;3. 自增主键理解&#xff1f;&#x1f349;4. 为什么自增主键不连续&#x1f349;5. Innodb为什么推荐用自增ID&…

代码随想录第59天

1.下一个更大元素II 有两种方法&#xff1a; 1.把两个一样的数组拼起来&#xff1a; // 版本一 class Solution { public:vector<int> nextGreaterElements(vector<int>& nums) {// 拼接一个新的numsvector<int> nums1(nums.begin(), nums.end());nu…

Chapter7: SpringBoot与数据访问

尚硅谷SpringBoot顶尖教程 1. JDBC 1.1 依赖及配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency><groupId>mysql</groupId…

《Reinforcement Learning: An Introduction》第4章笔记

Chapter 4 Dynamic Programming 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;是一类在给定完备环境模型的MDP后用来计算最优策略的算法。动态规划算法在强化学习中因为&#xff1a;1. 假设有一个完美的环境模型&#xff1b;2. 极大的计算代价 实际用处…

树莓派4B连接不了产品开的热点

目的 关于树莓派连接不了产品开的5G热点&#xff0c; 当时还是一头雾水。 参考这篇博客 把思路方向转向了频率&#xff0c; 信道&#xff0c; 通过给的产品A相关规格说明wifi 5.18GHz, 信道36。 于是乎我两款产品A、产品B为例。 树莓派是能连接产品B开的热点&#xff08;5.74…

【Unity SRP】实现基础的Temporal AA(未完)

写在前面 【技术美术图形部分】简述主流及新的抗锯齿技术&#xff0c;花了点时间盘点了一些主流AA技术&#xff0c;再在SRP下的URP管线中实现一下目前游戏用得比较多的TAA。参考Unity的TAA&#xff08;比较容易懂&#xff09;以及sienaiwun的实现思路&#xff0c;也参考了很多…

OpenCV转换HDR图像与源码分析

我们常见的图像位深一般是8bit&#xff0c;颜色范围[0, 255]&#xff0c;称为标准动态范围SDR(Standard Dynamic Range)。SDR的颜色值有限&#xff0c;如果要图像色彩更鲜艳&#xff0c;那么就需要10bit&#xff0c;甚至12bit&#xff0c;称为高动态范围HDR(High Dynamic Range…

Docker部署ES集群、kibana、RabbitMq和chrome安装elasticsearch-head插件

文章目录 [toc] 1.安装ES集群和kibana1.1安装ES集群1.1.1 准备挂载目录1.1.2 准备配置文件1.1.3 启动命令1.1.3.0 启动前设置系统环境变量1.1.3.1 Windows10环境启动命令1.1.3.2 Linux环境启动命令 1.2安装kibana1.2.1 准备挂载目录1.2.2 准备配置文件1.2.3 启动命令1.2.3.1 Wi…

Spring IOC基于XML和注解管理Bean(一)

Spring IOC基于XML和注解管理Bean&#xff08;二&#xff09; 文章目录 1、IoC容器1.1、控制反转&#xff08;IoC&#xff09;1.2、依赖注入1.3、IoC容器在Spring的实现 2、基于XML管理Bean2.1、搭建模块spring-first2.2、实验一&#xff1a;获取bean①方式一&#xff1a;根据i…

过滤器和拦截器实现

说明&#xff1a;当用户未经登录&#xff0c;直接访问后台网址时&#xff0c;为了避免可以直接访问后台内容&#xff0c;就需要使用过滤器或拦截器将此类请求在服务器响应数据之前做核对&#xff0c;如果未登录&#xff0c;则驳回请求&#xff0c;返回登录页面&#xff0c;如果…

PyQt5桌面应用开发(20):界面设计结果自动测试(一)

本文目录 PyQt5桌面应用系列PyQt5的测试驱动开发&#xff08;Test-Driven Development&#xff0c;TDD&#xff09;QTestUI动作函数信号测试 最平凡的例子unittest框架总结 PyQt5桌面应用系列 PyQt5桌面应用开发&#xff08;1&#xff09;&#xff1a;需求分析 PyQt5桌面应用开…

【Apache Pinot】简单聊聊前面没讲的 Deep Store 和 Cluster

背景 前面3篇文章讲解了 Pinot 用的最多的几个组件&#xff0c;现在就聊最后剩下的两个&#xff0c;一个是 Cluster&#xff0c;另外一个就是 Deep Store。 Cluster 其实 Cluster 比较简单&#xff0c;就是一个概念的集合&#xff0c;他说有 Server&#xff0c;Broker 和 Co…

代码随想录算法训练营第五十六天 | 力扣 583. 两个字符串的删除操作, 72. 编辑距离

583. 两个字符串的删除操作 题目 583. 两个字符串的删除操作 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 解析 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 …

学会这个Python库,做接口测试不是手拿把掐吗?

我们在做接口测试时&#xff0c;大多数返回的都是json属性&#xff0c;我们需要通过接口返回的json提取出来对应的值&#xff0c;然后进行做断言或者提取想要的值供下一个接口进行使用。 但是如果返回的json数据嵌套了很多层&#xff0c;通过查找需要的词&#xff0c;就很不方便…

三、Typora软件的介绍及安装

1、Typora软件的介绍 (1)Typora时一款Markdown编辑器和阅读器。 (2)Typora使用起来十分简洁&#xff0c;十分方便&#xff0c;可用于记录日常的笔记等。 (3)Markdown 是一种轻量级标记语言&#xff0c;它允许人们使用易读易写的纯文本格式编写文档。 2、Typora软件的安装 …

都说未来AI测试辅助自动化测试,难道手工测试真的要被淘汰了吗?

目录 前言 AI测试的迷思 第一个问题&#xff1a;AI辅助测试真的能用吗&#xff1f; 第二个问题&#xff1a;AI辅助测试已经发展到什么程度了&#xff1f; 第三个问题&#xff1a;哪些软件系统能用AI辅助测试&#xff1f; 总结 总结&#xff1a; 前言 近年来&#xff0c;…

FPGA实现简易的自动售货机模型

文章目录 前言一、系统设计1、模块框图2、状态机框图3、RTL视图 二、源码1.蜂鸣器驱动模块2.按键消抖模块3、PWM模块4、sale_goods模块(状态机部分)5、数码管驱动模块6、Sales(顶层模块) 三、效果四、总结五、参考资料 前言 环境&#xff1a; 1、Quartus18.1 2、vscode 3、板子…