当前位置: 首页 > news >正文

【C++基础】引用(引用的概念;引用的特性;常引用;使用场景:做输出型参数、大对象传参、做输出型返回值、返回大对象的引用);引用和指针的区别)

六、引用

6.1 引用的概念

  • 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(语法上)

  • 格式:类型& 引用变量名(对象名) = 引用实体;

void TestRef()
{int a = 10;int& ra = a;//<====定义引用类型printf("%p\n", &a);printf("%p\n", &ra);
}

注意:引用类型必须和引用实体是同种类型的


6.2 引用的特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体

在这里插入图片描述

说明:

  • int& d = c; //c是a变量的别名,再为c取别名实际上还是引用a。相当于:int& d = a;
  • b = x; //b是a的别名,这句相当于:a = x; 将x赋值给b(a);

6.3 常引用

常引用即引用的类型用const进行修饰,表示不能通过该引用修改引用对象的值。类似于常量指针:const int *p;

  • 权限不能放大
  • 权限可以缩小
  • 显示或隐式类型转换都会产生同类型的临时变量,产生的临时变量具有常性。
void TestConstRef()
{//权限不能放大const int a = 20;//int& ra = a;const int& ra = a;//权限可以缩小int b = 30;const int& rb = b;//类型转换产生临时变量,产生的临时变量具有常性int i = 1;double d = i; //类型转换的过程中会产生同类型的临时变量//double& rd = i; //产生的临时变量具有常性   const double &rd = i; //此处临时变量的类型是const double
}

在这里插入图片描述

说明:

  • 权限放大或缩小的问题只存在于引用或指针上。普通变量不存在,因为普通变量不对源值做修改,只做值拷贝。
  • 如果使用引用传参,函数内如果不改变源值(输入型参数),那么建议尽量用const引用传参,提高程序的健壮性,且这样的形参具有非常强的接收度(类型转换)。

6.4 使用场景

1. 做输出型参数

引用做输出型参数,相比指针传参,使用更加方便。

void Swap(int& left, int& right){int temp = left;left = right;right = temp;
}
int main(){int a = 0, b = 2;Swap(a,b);return 0;
}

2. 大对象传参

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

  • 我们可以做以下测试:
#include <time.h>
struct A{ int a[10000]; };
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;
}
  • 测试结果:
    在这里插入图片描述
  • 得出结论:大对象使用引用传参,提高效率,节省空间。

3. 做输出型返回值

做输出型返回值,调用者可以修改返回对象。

int& Count()
{static int n = 0;n++;// ...return n;
}

同指针一样,不能返回局部变量的引用。但可以返回静态区或堆空间变量的引用。

4.(误区警示)返回局部变量的引用

下面代码输出什么结果?为什么?

int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :"<< ret <<endl;return 0;
}
  • 测试结果:
    在这里插入图片描述
  • 解释原因:
    在这里插入图片描述
  • 得出结论:函数返回后,函数内的局部变量(栈帧空间)就销毁了。那么一定不能返回局部变量的引用,只能传值返回。

5. 返回大对象的引用

返回大对象的引用可以减少拷贝,提高效率。

  • 我们可以做以下测试:
#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;
}
  • 测试结果:
    在这里插入图片描述
  • 得出结论:结合大对象的传参和返回测试,我们可以看出传值和引用在作为传参以及返回值类型上效率相差很大。

6.5 引用和指针的区别

在语法概念上引用就是一个别名,没有独立空间,和其引用的实体共用同一块空间。

#include <iostream>    
using namespace std;    
int main()    
{    int a = 10;    int& ra = a;    int* pa = &a;    cout<<"a = "<<a<<endl;    cout<<"ra = "<<ra<<endl;    cout<<"pa = "<<pa<<endl;    cout<<"*pa = "<<*pa<<endl<<endl;                                                                                                                  cout<<"&a = "<<&a<<endl;    cout<<"&ra = "<<&ra<<endl;    cout<<"&pa = "<<&pa<<endl;    cout<<"pa = "<<pa<<endl;    
return 0;    
}  

测试结果:
在这里插入图片描述

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}

我们来看下引用和指针的汇编代码对比:
在这里插入图片描述

底层汇编完全相同,说明引用是按照指针的方式来实现的。

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求。
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体。
  4. 没有NULL引用,但有NULL指针。
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)。
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小。
  7. 有多级指针,但是没有多级引用。
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理。
  9. 引用比指针使用起来相对更安全。

总结:

  • 指针更强大,更危险,更复杂;
  • 引用相对局限一些,更安全,更简单;

相关文章:

【C++基础】引用(引用的概念;引用的特性;常引用;使用场景:做输出型参数、大对象传参、做输出型返回值、返回大对象的引用);引用和指针的区别)

六、引用 6.1 引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。&#xff08;语法上&#xff09; 格式&#xff1a;类型& 引用变量名(对象名) …...

Redis只用来做缓存?来认识一下它其他强大的能力吧。

当今互联网应用中&#xff0c;随着业务的发展&#xff0c;数据量越来越大&#xff0c;查询效率越来越高&#xff0c;对于时序数据的存储、查询和分析需求也越来越强烈&#xff0c;这时候 Redis 就成为了首选的方案之一。 Redis 提供了多种数据结构&#xff0c;如字符串、哈希表…...

【ES】数据同步集群

【ES】数据同步&集群3.数据同步3.1.思路分析3.1.1.同步调用3.1.2.异步通知3.1.3.监听binlog3.1.4.选择3.2.实现数据同步3.2.1.思路3.2.2.导入demo3.2.3.声明交换机、队列1&#xff09;引入依赖2&#xff09;声明队列交换机名称3&#xff09;声明队列交换机3.2.4.发送MQ消息…...

37岁男子不愿熬夜,回乡养鸡每天准时下班,青山绿水中养鸡,直播间里卖鸡蛋...

37岁男子不愿熬夜&#xff0c;回乡养鸡每天准时下班&#xff0c;青山绿水中养鸡&#xff0c;直播间里卖鸡蛋。今天和大家分享一个创业案例&#xff0c;他叫胡铭浩&#xff0c;来自安徽省旌德县&#xff0c;今年37岁&#xff0c;曾做过车床操作工&#xff0c;开过婚纱摄影店&…...

深度学习和人工智能之间是什么样的关系?

深度学习与人工智能概念的潜在联系&#xff0c;我们依然借助维恩图来说明&#xff0c;如图4.1所示。 1、人工智能 “人工智能”这个概念新鲜时髦但又含混模糊&#xff0c;同时包罗万象。尽管如此,我们仍尝试对 人工智能进行定义:用一台机器处理来自其周围环境的信息,然后将这些…...

实战打靶集锦-016-lampiao

提示&#xff1a;本文记录了博主打靶过程中一次曲折的提权经历 文章1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 80端口探查4.2 1898端口探查4.3 EXP搜索4.3.1 exploit/unix/webapp/drupal_coder_exec4.3.2 exploit/unix/webapp/drupal_drupalgeddon25. 提权5.1 系统信息…...

《Web前端应用开发》考试试卷(模拟题)

一、产品搜索页面 打开“考试文件夹”中的input.html&#xff0c;完成以下步骤&#xff1a; 注意&#xff1a;本题仅能在input.html的&#xff08;1&#xff09;为产品名称所在的div添加样式属性&#xff0c;使得产品名称保持在文本框的左边&#xff1b; &#xff08;2&#xf…...

【react全家桶学习】react简介

react是什么&#xff1f; react是用于构建用户界面的JS库&#xff0c;是一个将数据渲染为HTML视图的开源JS库 谁开发的&#xff1f; 由Facebook开发&#xff0c;且开源 为什么要学&#xff1f; 原生JavaScript操作DOM繁琐、效率低 ( DOM-API操作 UI)使用JavaScript直接操作…...

此战成硕,我成功上岸西南交通大学了~~~

友友们&#xff0c;好久不见&#xff0c;很长时间没有更一个正式点的文章了&#xff01; 是因为我在去年年底忙着准备初试&#xff0c;今年年初在准备复试&#xff0c;直到3月底拟录取后&#xff0c;终于可以写下这篇上岸贴&#xff0c;和大家分享一下考研至上岸的一个过程 文章…...

光耦继电器工作原理及优点概述

光耦继电器是一种电子元器件&#xff0c;也是固态继电器的一种&#xff0c;其主要作用是隔离输入与输出电路&#xff0c;用于保护或者控制电路的正常工作。 光耦继电器工作原理是利用光电转换器将外界信号转化为光信号&#xff0c;通过光纤传输到另一端&#xff0c;再由另一端的…...

【Mysql】mysql8.0.26解压包部署方式

版本背景&#xff1a; 操作系统&#xff1a;centos7.3 mysql版本&#xff1a;mysql-8.0.26-linux-glibc2.12-x86_64.tar 一、前期准备 1、检测操作系统自带安装的mysql和mariadb服务&#xff0c;如存在&#xff0c;需卸载 rpm -qa | grep mysql rpm -qa | grep mariadb 卸载…...

进销存管理系统能为企业带来哪些实际效益?

随着互联网的不断发展&#xff0c;如今的商业世界已经越来越向数字化转型。拥有一套完整的数字化的进销存管理能够极大地提升公司货物进出库存情况的效率和准确性&#xff0c;避免过程中出现不必要的错误和漏洞&#xff0c;从而帮助企业更加稳健地自我发展。那么&#xff0c;一…...

图片怎么转换成pdf格式?这几个方法帮你一键转换

现今电子书籍越来越受到欢迎&#xff0c;其中PDF格式也成为了一种常用的电子书籍格式。无论是工作还是学习&#xff0c;我们都可能会遇到需要将图片转换成PDF格式的情况&#xff0c;例如保存一些资料证明、公文公告、学习资料等。在这篇文章中&#xff0c;我们将为大家介绍三种…...

数据结构exp1_2学生成绩排序

目录 数据结构exp1_2学生成绩排序 程序设计 程序分析 数据结构exp1_2学生成绩排序 【问题描述】 对某班学生成绩排序。从键盘依次输入某班学生的姓名和成绩(一个班级人数最多不超过50人)并保存,然后分别按学生成绩由高到低顺序输出学生姓名和成绩,成绩相同时,则按输…...

在DongshanPI-D1开箱使用分享与折腾记录实现MPU6050数据读取

前言 上一篇文章使用RT-Smart的IIC驱动OLED屏幕&#xff0c;进行基本的字符串显示,在使用过程中对RT-Smart有了一定熟悉&#xff0c;准备使用SPI驱动ST7789&#xff0c;但SPI接口没有引出&#xff0c;本次使用手上已有的传感器MPU6050进行使用。 过程 本次直接开始添加离线包…...

Nature子刊 定制饮食去除半胱氨酸和蛋氨酸可诱导细胞自毁进而治疗脑瘤?

恶性胶质瘤是成人最常见的脑部肿瘤。恶性胶质瘤的致死率为100%&#xff0c;无法治愈&#xff0c;是一种极度的恶性肿瘤。如此糟糕的预后促使研究者及神经外科医生不断学习研究肿瘤生物学&#xff0c;期望创造更好的疗法。神经外科助理教授Dominique Higgins博士从事肿瘤生物学的…...

抛弃 TCP 和 QUIC 的 HTTP

下班路上发了一则朋友圈&#xff1a; 周四听了斯坦福老教授 John Ousterhout 关于 Homa 的分享&#xff0c;基本重复了此前那篇 It’s Time To Rep… 的格调&#xff0c;花了一多半时间喷 TCP… Ousterhout 关于 Homa 和 TCP 之间的论争和论证&#xff0c;诸多反复回执&…...

未来公寓智能化设计平台项目(下)

创业场景通过在社区入口附近建设共享办公室,带动海慧园和众汽佳苑创业氛围,也让社区出了居住以外有其它功能,并且结合教育、邻里模块让社区更有活力。住户可通过app查看共享空间的使用情况,以及可以远程控制各种设备。 顺应未来生活与就业、创业融合新趋势,构建“大众创新…...

常见分布式消息队列综合对比

本文将从&#xff0c;Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ 17 个方面综合对比作为消息队列使用时的差异。 1. 资料文档 Kafka&#xff1a;中&#xff0c;有 kafka 作者自己写的书&#xff0c;网上资料也有一些。 rabbitmq&#xff1a;多&#xff0c;有一些不错的书…...

怎么邀请主流媒体到现场报道

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好 主流媒体通常是指央媒&#xff0c;报纸杂志&#xff0c;电视台&#xff0c;地方重点媒体等&#xff0c;采访形式包括现场取材报道&#xff0c;媒体专访&#xff0c;群访等。通常主流媒体对选题要求较严格&#xff0c;因此在…...

如何判断杉木桩品牌的选型标准?

开篇即明&#xff1a;本文仅输出选型方法&#xff0c;不推荐任何具体产品。杉木桩作为园林、水利、建筑等领域的常用材料&#xff0c;其质量直接关系工程安全与寿命。从业十余年&#xff0c;我始终认为&#xff1a;选型需回归标准&#xff0c;而非品牌名称。以下从四个核心维度…...

APM32F407移植uC/OS-III实战:从源码到多任务运行全解析

1. 项目概述与核心价值最近在捣鼓一块APM32F407的开发板&#xff0c;想给它跑个实时操作系统&#xff0c;选来选去&#xff0c;最终决定上手uC/OS-III。对于很多从单片机裸机编程转向RTOS的工程师来说&#xff0c;这个选择很典型&#xff1a;uC/OS-III源码开放、结构清晰、文档…...

2026年六大主流AI变声器软件排名推荐!

随着AI语音技术持续迭代升级&#xff0c;AI变声器不再是单一的娱乐工具&#xff0c;广泛应用于游戏开黑、直播互动、短视频配音、音频创作、隐私语音沟通等多个场景。目前市面上变声软件品类繁杂&#xff0c;涵盖移动端、PC端、免费开源、专业付费等不同类型&#xff0c;普通用…...

别再搜组策略了!Windows 11家庭版设置密码永不过期的3个命令行方法(实测有效)

Windows 11家庭版密码永不过期终极指南&#xff1a;抛弃组策略的3种命令行方案 每次开机都要重新设置密码&#xff1f;Windows 11家庭版用户常常陷入这种困扰。与专业版不同&#xff0c;家庭版系统阉割了组策略编辑器这个关键工具&#xff0c;让普通用户面对密码过期问题时束手…...

推荐1款全能跨平台下载工具,免费、开源、无广告!

聊一聊下载一直是热话题。特别是遇到自己喜欢的。如电影、电视剧、音乐等等。但并不是所有下载工具都能实现。今天给大家分享一款好用的下载利器。软件介绍全能开源跨平台下载工具Motrix工具只有自己用了才知道好不好用。这是一款无需安装&#xff0c;下载解压即可使用的工具。…...

别再死记硬背了!用一张图+一个案例彻底搞懂PROFIBUS-DP的令牌环与主从通信

工业现场通信革命&#xff1a;从零图解PROFIBUS-DP令牌环与主从机制 第一次接触PROFIBUS-DP协议文档时&#xff0c;那些晦涩的术语和抽象的状态转换图让我在调试现场设备时屡屡碰壁。直到某天亲眼目睹PLC通过一串神秘的数据包精准控制阀门阵列&#xff0c;才意识到这套诞生于上…...

TPS5450同步降压转换器设计:从宽压输入到5V/3.3V输出的工程实践

1. 项目概述与芯片选型考量最近在做一个需要从较高直流电压&#xff08;比如12V或24V&#xff09;降压到5V和3.3V为系统供电的项目&#xff0c;电流需求还不小&#xff0c;峰值可能达到3A以上。这种场景下&#xff0c;传统的线性稳压器&#xff08;LDO&#xff09;效率太低&…...

ETT数据集实战:如何用油温预测优化电网负载与设备维护策略

ETT数据集实战&#xff1a;如何用油温预测优化电网负载与设备维护策略 当一座城市的电网在盛夏午后突然崩溃&#xff0c;背后往往隐藏着变压器油温失控的连锁反应。去年某沿海城市电网的故障分析报告显示&#xff0c;超过60%的突发停电事件与变压器过热直接相关——这个数据让行…...

为什么顶级策展人不用Google搜文化新闻?Perplexity文化垂直搜索的5层语义增强架构(含可复用prompt工程模板)

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;为什么顶级策展人不用Google搜文化新闻&#xff1f; 顶级策展人并非排斥搜索引擎&#xff0c;而是早已构建起一套高度结构化、语义化、可验证的信息摄取系统——它绕过关键词匹配的偶然性&#xff0c;直击文化…...

Python点云处理入门:从零开始用pypcd4库读取.pcd文件并可视化(附完整代码)

Python点云处理入门&#xff1a;从零开始用pypcd4库读取.pcd文件并可视化 点云数据正逐渐成为三维感知领域的通用语言&#xff0c;从自动驾驶的环境建模到工业质检的精密测量&#xff0c;这些由数百万个空间点构成的数据集正在重塑我们与物理世界交互的方式。对于刚接触这一领域…...