C++入门——引用
C++入门——引用
一、引用的概念
- 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。这就好比《水浒传》中,一百零八位好汉都有自己的绰号。
- 通过
&符号,我们可以实现对一个变量的引用。
1.使用规则
如图所示:

- 在这里,我们先定义了一个变量a,
int& b的意思就是给a取别名为b,因为a定义的是一个整型,因此是int&,如果a是浮点型,则取别名为double&,如果a为整型指针,那么取别名就应该写为int*&。 - 我们可以给同一个变量取多个别名,比如这里就是把a取别名为b,把b又取别名为c,其实,b和c都是a的别名,就像《水浒传》中一个好汉可能有好多个称呼,比如鲁智深,他在做和尚之前名为鲁达,作为提辖,人称鲁提辖;后来人们又叫他“花和尚”,一个道理。
- 我们将a以及它的别名b,c的地址打印出来,不难发现都是指向同一块空间。
2.注意事项
- 引用在定义时必须
初始化,指针没有要求。如图所示:


- 同理,我们也不能引用空指针。
- 我们来看下面两段代码:


在两段代码中,均初始化了两个变量int a=1,int b=10;在第一段代码中,我们给变量a取别名为x,然后,我们让x=b。怎么理解这个x=b呢?我们先来运行一下,发现此时a和b都是10,说明a发生了变化。如果x=b意思是x刚才是a的别名,现在变成b的别名,那么a的值就不会发生变化;而事实恰恰相反,说明这里的=并不是改变引用的对象,而是一个赋值,将b的值拷贝给a的别名x,既然a的别名发生了变化,自然而然a也就发生了变化,因为a和x本来就是一个变量,就好比“豹子头”喝了酒就是林冲喝了酒,同样的意思。第二段代码就有所不同了,p作为一个指针,它指向的对象是可以改变的。因此我们可以总结出引用和指针的一个不同点:引用一旦引用一个实体,再不能引用其他实体,而指针可以任意改变指向的对象。 - 引用是编译器自己处理,指针需要显式解引用,
让我们来感受一下:


这是一个经典的交换两个数的函数,我们以前都是用的第一种方法,使用指针,但是在函数中需要写解引用;有了引用(取别名)操作后,我们在传参的时候也不需要传地址,直接传值即可,因为函数形参都是int&,是实参的别名,因此在函数里直接修改别名即可,更加方便。
二、引用作参数、返回值
1.引用作参数

上文提到的就是一个典型的例子,引用做参数,能够减少拷贝提高效率,尤其是大对象,深拷贝对象(以后会逐渐讲解),使用引用效率更高,我们举个例子:
#include <time.h>struct A
{int a[100000];
};void TestFunc1(A a)
{;
}void TestFunc2(A& a)
{;
}void TestRefAndValue()
{A a;// 以值作为函数参数size_t begin1 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc1(a);size_t end1 = clock();// 以引用作为函数参数size_t begin2 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc2(a);size_t end2 = clock();// 分别计算两个函数运行结束后的时间cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}int main()
{TestRefAndValue();return 0;
}
运行结果如图:

很明显,传引用效率更高。
2.引用作返回值
- 传值返回:

- 传引用返回:

这里返回的是n的引用 - 引用作返回值,能够减少拷贝提高效率,尤其是大对象,深拷贝对象(以后会逐渐讲解),使用引用效率更高,我们举个例子:
#include <time.h>struct A
{ int a[10000];
};A a;
// 值返回
A TestFunc1()
{return a;
}
// 引用返回
A& TestFunc2()
{ return a;
}void TestReturnByRefOrValue()
{// 以值作为函数的返回值类型size_t begin1 = clock();for (size_t i = 0; i < 100000; ++i)TestFunc1();size_t end1 = clock();// 以引用作为函数的返回值类型size_t begin2 = clock();for (size_t i = 0; i < 100000; ++i)TestFunc2();size_t end2 = clock();// 计算两个函数运算完成之后的时间cout << "TestFunc1 time:" << end1 - begin1 << endl;cout << "TestFunc2 time:" << end2 - begin2 << endl;
}int main()
{TestReturnByRefOrValue();return 0;
}
很明显,引用作返回值效率更高。
- 基本所有的场合都可以用引用进行传参。
- 需要注意的是,我们应当谨慎使用引用作为函数的返回值,如果出了函数的作用域,引用的对象不在了,就不能使用引用作返回,还在(比如static int a)就可以用引用返回。
三、引用的权限问题——常引用
1.引用过程中,权限不能放大
如图所示:

这里的a加了const,是不能被修改的,但是a的别名b没有加const,是可以被修改的,在引用(取别名)的过程中,a的权限被放大,因此产生报错,作如下修改即可:

这样一来,a和b都是不能被修改的,它们的权限相等。
2.引用的过程中,权限可以平移或缩小
- 权限平移

上文的示例就是一个权限的平移,a和它的引用b都加上了const,都是不能被修改的。 - 权限缩小
如图所示:

如图所示,这里的a是可以被修改的,它的别名b是不可以被修改的,这就是权限的缩小,那么既然b不可以被修改,为什么a+1后b也+1了呢?我们打个比方,宋江让李逵下山办事,城里的人们都知道“黑旋风”的存在,因此宋江告诉李逵,下山后,人人都知道你是“黑旋风”,你不能喝酒,喝酒会误事,等你回来后,我们再慢慢喝。也就是说,李逵作为“黑旋风”时,不能喝酒,在这里就相当于a的别名b不能被修改;李逵上山后,宋江又允许他喝酒了,这里就相当于a+1,那么,既然李逵上山后喝了酒,“黑旋风”不就喝酒了吗,a+1就是b+1,只不过在只能以b的形式出面时,权限被约束罢了。
本期总结+下期预告
本期内容我们讨论了引用的相关知识,下期内容将为大家带来内联函数,auto关键字,基于范围的for循环等内容!
感谢大家的关注,我们下期再见!

相关文章:
C++入门——引用
C入门——引用 一、引用的概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。这就好比《水浒传》中,一百零八位好汉都有自己的绰号。通过&…...
深度学习模型组件之优化器—Lookahead:通过“快慢”两组优化器协同工作,提升训练稳定性
深度学习模型组件之优化器—Lookahead:通过“快/慢”两组优化器协同工作,提升训练稳定性 文章目录 深度学习模型组件之优化器—Lookahead:通过“快/慢”两组优化器协同工作,提升训练稳定性1. Lookahead优化器的背景2. Lookahead优…...
K8s 1.27.1 实战系列(五)Namespace
Kubernetes 1.27.1 中的 Namespace(命名空间)是集群中实现多租户资源隔离的核心机制。以下从功能、操作、配置及实践角度进行详细解析: 一、核心功能与特性 1、资源隔离 Namespace 将集群资源划分为逻辑组,实现 Pod、Service、Deployment 等资源的虚拟隔离。例如,…...
Spring Boot整合ArangoDB教程
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、环境准备 JDK 17Maven 3.8Spring Boot 3.2ArangoDB 3.11(本地安装或Docker运行) Docker启动ArangoDB docker run -d --name ar…...
虚幻基础:动画层接口
文章目录 动画层:动画图表中的函数接口:名字,没有实现。动画层接口:由动画蓝图实现1.动画层可直接调用实现功能2.动画层接口必须安装3.动画层默认使用本身实现4.动画层也可使用其他动画蓝图实现,但必须在角色蓝图中关联…...
从 GitHub 批量下载项目各版本的方法
一、脚本功能概述 这个 Python 脚本的主要功能是从 GitHub 上下载指定项目的各个发布版本的压缩包(.zip 和 .tar.gz 格式)。用户需要提供两个参数:一个是包含项目信息的 CSV 文件,另一个是用于保存下载版本信息的 CSV 文件。脚本…...
一、对lora_sx1278v1.2模块通信记录梳理
一、通信测试: 注意: 1、检查供电是否满足。 2、检测引脚是否松动或虚焊。 3、检测触发是否能触发。 引脚作用: SPI:通信(仅作一次初始化,初始化后会进行模块通信返回测试,返回值和预定值相否即…...
Java在word中动态增加表格行并写入数据
SpringBoot项目中在word中动态增加表格行并写入数据,不废话,直接上配置和代码: 模板内容如下图所示: 模板是一个空word表格即可,模板放在resources下的自定义目录下,如下图示例。 实体类定义如下: @Data @AllArgsConstructor @NoArgsConstructor public class Person …...
[通讯协议]232通信
RS-232 简介 RS-232是一种广泛应用的串行通信接口标准,使用的协议就是串口协议。 通信能力 单端信号传输:信号以地线为参考,逻辑“1”为-3V至-15V,逻辑“0”为3V至15V。点对点通信:仅支持两个设备之间的通信&#x…...
Refreshtoken 前端 安全 前端安全方面
网络安全 前端不需要过硬的网络安全方面的知识,但是能够了解大多数的网络安全,并且可以进行简单的防御前两三个是需要的 介绍一下常见的安全问题,解决方式,和小的Demo,希望大家喜欢 网络安全汇总 XSSCSRF点击劫持SQL注入OS注入请求劫持DDOS 在我看来,前端可以了解并且防御前…...
EasyRTC嵌入式音视频通话SDK:基于ICE与STUN/TURN的实时音视频通信解决方案
在当今数字化时代,实时音视频通信技术已成为人们生活和工作中不可或缺的一部分。无论是家庭中的远程看护、办公场景中的远程协作,还是工业领域的远程巡检和智能设备的互联互通,高效、稳定的通信技术都是实现这些功能的核心。 EasyRTC嵌入式音…...
AI终章.展望未来2026-2030年预测与DeepSeek的角色
人工智能(AI)近年来发展迅速,正在改变行业、商业模式以及我们与技术互动的方式。展望2026-2030年,预计在多模态AI、自主代理和自动化驱动的新职业创造方面将出现革命性发展。本章将探讨这些趋势,以及DeepSeek将如何在这…...
PyTorch系列教程:编写高效模型训练流程
当使用PyTorch开发机器学习模型时,建立一个有效的训练循环是至关重要的。这个过程包括组织和执行对数据、参数和计算资源的操作序列。让我们深入了解关键组件,并演示如何构建一个精细的训练循环流程,有效地处理数据处理,向前和向后…...
【面试】Zookeeper
Zookeeper 1、ZooKeeper 介绍2、znode 节点里面的存储3、znode 节点上监听机制4、ZooKeeper 集群部署5、ZooKeeper 选举机制6、何为集群脑裂7、如何保证数据一致性8、讲一下 zk 分布式锁实现原理吧9、Eureka 与 Zk 有什么区别 1、ZooKeeper 介绍 ZooKeeper 的核心特性 高可用…...
电力系统中各参数的详细解释【智能电表】
一、核心电力参数 电压 (Voltage) 单位:伏特(V) 含义:电势差,推动电流流动的动力 类型:线电压(三相系统)、相电压,如220V(家用)或380Vÿ…...
前端系统测试(单元、集成、数据|性能|回归)
有关前端测试的面试题 系统测试 首先,功能测试部分。根据资料,单元测试是验证最小可测试单元的正确性,比如函数或组件。都提到了单元测试的重要性,强调其在开发早期发现问题,并通过自动化提高效率。需要整合我搜索到的资料中的观点,比如单元测试的方法(接口测试、路径覆…...
软件开发过程总揽
开发模型 传统开发模型 瀑布模型 #mermaid-svg-yDNBSwh3gDYETWou {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-yDNBSwh3gDYETWou .error-icon{fill:#552222;}#mermaid-svg-yDNBSwh3gDYETWou .error-text{fill:#…...
VBA第二十期 VBA最简单复制整张表格Cells的用法
前面讲过复制整张表格的方法,使用语句Workbooks("实例.xlsm").Sheets("表格1").Copy Workbooks(wjm).Sheets(1)实现,这里用我们熟悉的Cells属性也可以实现整表复制。实例如下: Sheets("全部").Activate Cells…...
Redis为什么要自定义序列化?如何实现自定义序列化器?
在 Redis中,通常会使用自定义序列化器,那么,Redis为什么需要自定义序列化器,该如何实现它? 1、为什么需要自定义序列化器? 整体来说,Redis需要自定义序列化器,主要有以下几个原因&…...
Matlab:矩阵运算篇——矩阵数学运算
目录 1.矩阵的加法运算 实例——验证加法法则 实例——矩阵求和 实例——矩阵求差 2.矩阵的乘法运算 1.数乘运算 2.乘运算 3.点乘运算 实例——矩阵乘法运算 3.矩阵的除法运算 1.左除运算 实例——验证矩阵的除法 2.右除运算 实例——矩阵的除法 ヾ( ̄…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
