C++中按引用传递参数

2023-10-29

C++中按引用传递参数

实参通常是通过值传递给函数的,这意味着形参接收的只是发送给它们的值的副本,它们存储在函数的本地内存中。对形参值进行的任何更改都不会影响原始实参的值。

然而,有时候可能会希望一个函数能够改变正在调用中的函数(即调用它的函数)中的一个值,这可以通过引用传递的方式来完成。

我们知道,变量是可以保存数据的内存位置的名称。当使用变量时,实际上就是访问存储在分配给它的内存位置的数据。引用变量是变量的另一个别名,它没有自己的存储数据的内存位置,它访问的是另一个变量的内存位置。对引用变量作出的任何更改,实际上都是对它所引用的变量内存位置中存储数据的更改。

当使用引用变量作为形参时,它将变为实参列表中相应变量的别名,对形参进行的任何更改都将真正更改正在调用它的函数中的变量。当以这种方式将数据传递给形参时,该实参被称为按引用传递。

引用变量的定义方法和常规变量类似,但是其数据类型和名称之间有一个 & 符号。例如,以下函数定义使形参 refVar 成为引用变量:

void doubleNum(int& refVar){    refVar *= 2;}

注意,变量 refVar 被称为“对 int 的引用”。

该函数将 refVar 乘以 2,因为 refVar 是引用变量,所以该操作实际上将对作为实参传递给函数的变量执行。

来看一下根据半径计算圆面积的函数:

// Function definitions (implementations)
double Area(double radius)
{
    return Pi * radius * radius;
}

其中,参数 InputRadius 包含的值是在 main( )中调用函数时复制给它的:

// Call function "Area"
cout << "Area is: " << Area(radius) << endl;

这意味着函数调用不会影响 main( )中的变量 radius,因为 Area( )使用的是 radius 包含的值的拷贝。有时候,您可能希望函数修改的变量在其外部(如调用函数)中也可用,为此,可将形参的类型声明为引用。下面的 Area( )函数计算面积,并以参数的方式按引用返回它:

// output parameter result by reference
void Area(double radius, double& result)
{
    result = Pi * radius * radius;
}

注意到该 Area() 函数接受两个参数。别遗漏了第二个形参 result 旁边的 &,它告诉编译器,不要将第二个实参复制给函数,而将指向该实参的引用传递给函数。返回类型变成了 void,因为该函数不再通过返回值提供计算得到的面积,而按引用以输出参数的方式提供它。如下的示例程序演示了如何按引用返回值,该程序计算圆的面积:

#include <iostream>
using namespace std;

const double Pi = 3.1416;

// output parameter result by reference 
void Area(double radius, double& result)
{
    result = Pi * radius * radius;
}

int main() 
{
    cout << "Enter radius: ";
    double radius = 0;
    cin >> radius;

    double areaFetched = 0;
    Area(radius, areaFetched);

    cout << "The area is: " << areaFetched << endl;
    return 0;
}

输出:

Enter radius: 2
The area is: 12.5664

分析:

注意到第 18 行调用函数 Area() 时提供了两个参数,其中第二个参数将包含结果。由于 Area() 的第二个参数是按引用传递的,因此 Area() 中第 8 行使用的变量 result,与 main() 中第 17 行声明的 double areaFetched 指向同一个内存单元。因此,在 main() 中,可以使用 Area() 中第 8 行计算得到的结果—第 20 行将其显示到屏幕上。

注意:

使用 return 语句时,函数只能返回一个值。因此,如果函数需要执行影响众多值的操作,且需要在调用者中使用这些值,则按引用传递参数是让函数将修改结果提供给调用模块的方式之一。

该文章会更新,欢迎大家批评指正。

推荐一个零声学院的C++服务器开发课程,个人觉得老师讲得不错,
分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容
点击立即学习:C/C++后台高级服务器课程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++中按引用传递参数 的相关文章

随机推荐

  • MyBatis---缓存-提高检索效率的利器

    目录 让我们来看看官方文档 缓存 一 一级缓存 1 基本介绍 2 一级缓存 3 一级缓存失效分析 二 二级缓存 1 基本介绍 2 二级缓存快速入门 2 1快速入门 3 注意事项和使用陷阱 三 Mybatis 的一级缓存和二级缓存执行顺序 四
  • C++对象模型之内存区的使用

    对象模型是面向对象程序设计语言的一个重要方面 它会直接影响面向对象语言编写程序的运行机制及对内在的使用机制 因此了解对象模型是进行程序优化 的基础 分析一般意义上程序中的数据在内存中的分布 以及程序使用的不同种类的内存等基本的概念 了解对象
  • 第八章(3) 聚类:DBSCAN和簇评估

    基于密度的聚类寻找被低密度区域分离的高密度区域 传统的密度 基于中心的方法 数据集中特定点的密度通过对该点半径之内的点计数 包括本身 来估计 关键是确定半径 根据基于中心的密度进行点分类 稠密区域内的点 核心点 点的邻域由距离函数和指定半径
  • 微信小程序(十)之消息推送配置(token验证失败的解决方案)

    背景 微信小程序开发 准备使用模板消息做些事情 但是发现需要先在微信公众平台的开发 开发设置 消息推送做配置 然后我们后台人员就开始各种配置 但是一到验证token就报错 很是郁闷 然后各种排查 发现了最终原因 过程和代码如下 很多网站给出
  • datx 开启debug

    1 datax源码编译 编译 mvn U clean package assembly assembly Dmaven test skip true 2 创建mysql测试表 SET FOREIGN KEY CHECKS 0 Table s
  • mysql中 SET autocommit=0 与 START TRANSACTION 的区别

    在MySQL中 SET autocommit 0 指事务非自动提交 自此句命令执行以后 每个SQL语句或者语句块所在的事务都需要显式调用commit才能提交事务 不管autocommit 是1还是0 START TRANSACTION co
  • ssh 配置文件中 maxsessions 与 MaxStartups

    MaxStartups 同时允许几个尚未登入的联机画面 所谓联机画面就是在你ssh登录的时候 没有输入密码的阶段 如下图 maxsessions 同一地址的最大连接数 也就是同一个IP地址最大可以保持多少个链接 转载于 https blog
  • CentOS基础命令大全

    1 关机 立即关机 shutdown h now 立即关机 init 0 立即关机 telinit 0 预约时间关机 shutdown h hours minutes 取消预约关机 shutdown c 重启 shutdown r now
  • 一些关于远程仓库操作的git指令

    1 更换项目所关联的仓库 要先删除目前的远程仓库 然后再添加新的远程仓库 1 git remote rm origin 2 git remote add origin 新的仓库地址 3 git remote v 查看现在的远程仓库 4 gi
  • Hausdorff 距离

    Hausdorff 距离是描述两组点集之间相似程度的一种量度 假设有两组集合 则这两个点集之间的单向 Hausdorff 距离 其中 a b 表示 a 与 b 之间的欧氏距离 h A B 也叫前向 Hausdorff 距离 h B A 也叫
  • Android9.0 mm编译失败:ninja: error: 'xxx', needed by 'xxx', missing and no known rule to make it

    Android系统源码环境下使用mm命令单独编译某一个模块 如果该模块依赖其它模块 可能会报如下错误 解决此问题的方法就是改成mma命令编译 mma命令会构建所需要的关联模块 编译命令简单总结 mm 编译当前目录下的模块 当前目录下要有An
  • 获取成员函数地址及获取函数地址

    首先我们定义一个类Ctest 类里面包含三个不同形式的成员函数 静态成员函数statFunc 动态成员函数dynFunc 和虚拟函数virtFunc 在main函数中我们利用cout标准输出流分别输出这三个函数的地址 程序如下所示 incl
  • WebSocket协议深度解析

    WebSocket协议深度解析 1 WebSocket简介 WebSocket相比于Http协议 它有如下几个优点 支持双向通信 更灵活 更高效 可扩展性更好 支持双向通信 实时性更强 更好的二进制支持 较少的控制开销 连接创建后 ws客户
  • NER相关技术

    实体词典匹配 优点 缺点 模型原理 优点 缺点 模型输入 模型输出 实体词典匹配 模型预测两路结果是怎么合并输出的 目前我们采用训练好的CRF权重网络作为打分器 来对实体词典匹配 模型预测两路输出的NER路径进行打分 在词典匹配无结果或是其
  • 随机生成六位不重复数值

    在 Core JAVA 中有个随机生成六位不重复数值的算法 大二用过一次 今天在写 Algorithms 的练习题遇到类似的问题 特贴出 1 随机生成六位不重复的数字 2 private static int generate6BitInt
  • Mybatis的四种分页方式详解

    LIMIT关键字 mapper代码 select from tb user limit pageNo pageSize 业务层直接调用 public List findByPageInfo PageInfo info return user
  • 关于微信小程序在部分PC设备无法打开的问题

    目前为止微信小程序PC端仍处于灰度测试阶段 部分设备无法打开微信小程序 这个问题在启用分包能力后尤为明显 由于我们不能去控制用户通过PC端访问小程序的行为 仍需对PC端兼容性进行测试 下面我们来介绍测试方式 一 安装微信客户端大于3 4 5
  • 【LeetCode75】第五十四题 咒语和药水的成功对数

    目录 题目 示例 分析 代码 题目 示例 分析 题目给我们两个数组 要我们找出第一个数组中每个元素能和另一个数组的元素匹配的数量 匹配的条件是乘积大于特定的值 那么要乘积大于某个值 就需要乘数越大越好 我们可以把表示药水的数组升序排序 接着
  • aircrack-ng 介绍、功能测试及部分源码分析

    aircrack ng 介绍 功能测试及部分源码分析 实验目的 1 理清aircrack ng的总体设计框架 包括各模块的功能与联系 2 核心模块的实现原理 aircrack ng aireplay ng airodump ng 实验要求
  • C++中按引用传递参数

    C 中按引用传递参数 实参通常是通过值传递给函数的 这意味着形参接收的只是发送给它们的值的副本 它们存储在函数的本地内存中 对形参值进行的任何更改都不会影响原始实参的值 然而 有时候可能会希望一个函数能够改变正在调用中的函数 即调用它的函数