C++中引用的基本内容

news/2024/4/27 19:52:15/文章来源:https://blog.csdn.net/m0_74352571/article/details/130324021

个人主页:平行线也会相交
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创
收录于专栏【C++之路】
在这里插入图片描述

引用,其实没啥特别的,就是起外号,或者说起小名。就比如说孙悟空就有很多外号,如齐天大圣、孙行者、斗战胜佛等等。虽然说可能有多种外号,但是这些外号都是指的是一个对象。下面来具体看一看到底什么是C++中的引用。

目录

  • 一、什么是引用
    • 1.1引用概念
      • 引用在Swap函数应用场景
      • 为指针定义别名
    • 1.2引用特性
  • 二、引用使用场景
    • 2.1引用做参数
    • 2.2引用做返回值
    • 2.3引用的几大作用
  • 三、常引用
  • 四、指针和引用的区别:

一、什么是引用

1.1引用概念

引用不是定义一个新的变量,而是给已存在的变量取一个别名,编译器并不会为引用变量开辟内存空间,而是它和它引用的变量共同占用同一块内存空间

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

我们直接来举一个样例:
在这里插入图片描述
上图中ba的引用,而c又是b的引用,同时a、b、c其实指向的都是同一块内存空间
在这里插入图片描述
注意:我们不可以这样使用引用,int& b,这是一种错误写法。即:

在这里插入图片描述

引用在Swap函数应用场景

下面把引用应用到Swap函数上,请看:

void Swap(int& m, int& n)
{int tmp = m;m = n;n = tmp;
}
int main()
{int a = 10;int b = 20;cout << "a=" << a << endl;cout << "b=" << b << endl;Swap(a, b);cout << "a=" << a << endl;cout << "b=" << b << endl;return 0;
}

在这里插入图片描述
上面代码函数中的形参就是实参的一个引用,即m是a的引用,n是b的引用,改变m就是改变a,改变n就是改变b

为指针定义别名

引用还可以为指针定义别名,请看:
在这里插入图片描述
上图就是我们通过引用交换了两个变量的地址。

1.2引用特性

1.引用必须要进行初始化(即int& a;这种写法是错误的)。
2.一个变量可以有多个引用
3.引用一旦引用一个实体,则不能在继续引用其它实体。

同时,引用类型必须要与引用实体同一种类型

二、引用使用场景

2.1引用做参数

比如,我们刚刚的交换函数Swap就是利用的引用来做参数:

void Swap(int& m, int& n)
{int tmp = m;m = n;n = tmp;
}

2.2引用做返回值

下面是引用作传值返回。

int fun()
{static int n = 0;n++;return n;
}int main()
{int ret = fun();return 0;
}

函数fun中的变量n存放在静态区中,出了局部域后栈帧不会销毁。但是在进行返回n的时候依然会生成临时变量。所以,引用作返回值的时候,不管变量n是局部变量还是静态区的变量又或者是全局变量。编译器都会生成一个临时变量。
倘若我们不想生成临时变量的话应该怎么半呢?这就是引用的另一大作用:即引用作返回值的时候不会生成临时变量
不生成临时变量的好处减少了拷贝,提高了效率。请看:
在这里插入图片描述
这里就是返回的n的别名(即返回的n的引用)
当我们的变量n是局部变量而非静态区变量的时候。请看:
在这里插入图片描述
我们已经知道这里返回的是局部变量n的别名,当把局部变量n的值给ret的时候,局部变量n所在的函数栈帧已经销毁了(即归还局部变量n所占空间的使用权),所以返回变量n的值理论上应该是不确定的。所以这里程序的运行结果应该有两种情况:

情况一:如果函数fun结束后,栈帧销毁,但是没有销毁栈帧,此时ret的结果侥幸是正确的。
情况二:如果函数fun结束后,栈帧销毁,清理栈帧了,那么此时ret的结果是随机的。
总之具体栈帧是否销毁还是要看编译器是如何处理的。

还有一种情况,请看:
在这里插入图片描述
首先,ret依然是n的别名(因为返回的是n的别名,而ret又是n的别名的别名,所以最后ret就是n的别名)。
其次我们发现程序运行结果就成了随机值了,这里的话就是刚刚上面提到的第二种情况了,即函数栈帧销毁后,清理了函数栈帧,所以打印出来的就是随机值。这里的话依然是和编译器的处理方式有关。

我们再来看一种情况:
在这里插入图片描述
这里打印出来依然是随机值,但是其具体原因与刚刚那种情况有些不同,这里rand()函数调用栈帧正好把fun()函数的栈帧覆盖了(说白了就是后面的函数栈帧覆盖了前面的函数栈帧),打印出来时随机值其实归根揭底还时栈帧被清理的问题。

在这里插入图片描述

2.3引用的几大作用

(1)引用作参数形参的改变可以改变实参),即引用作输入型参数;引用也可以作输出型参数提高效率。
(2)引用作返回值(当对象比较大的时候,与传值返回相比会极大的提高效率)。

三、常引用

常引用这里我们通过几段代码来引出来:

请看:
在这里插入图片描述
上述变量a经过const修饰后不可更改,既然a本身已经不可以进行更改了,所以就不要妄想通过引用b来更改a了这里强调的就是在引用的过程中,权限不可以放大。
再来看一段代码:
在这里插入图片描述
上述代码中强调的就是引用过程中权限可以平移但是权限不可以缩小。就比如说上述代码中的const int& b = x;这里缩小的并不是变量x的权限,而是缩小的引用b作为别名的权限
在这里插入图片描述
再来看这里,这里要强调的是x++是可以的,但是b++是不可以的,因为引用过程中引用b经过const修饰后权限被缩小了,这里虽然我们不能通过引用b来改变变量x,但是我们可以直接对变量x进行操作(即x++)就可以了。
再来看看const int& m = 10;这条语句,首先这条语句是正确的,引用b是常量10的别名,既然10是常量即不可更改,那么就需要const进行修饰。说白了这里就是给常量区别名。

下面我们先来看一下隐式类型转换的代码:
在这里插入图片描述
发生类型转换的时候中间会产生临时变量,所以只要发生类型转换,都会产生临时变量。

在这里插入图片描述
请再来看下段代码:
在这里插入图片描述
上述代码的话为什么int& c = a;报错了,但是const int&c = a;没有报错。
这里依然是临时变量的问题,请看下图:
在这里插入图片描述
注意类型转换才会产生临时变量,相同类型不会产生临时变量。下面我们来看一看为什么不同类型会产生临时变量而相同类型不会产生临时变量的原因:
在这里插入图片描述
上述代码之所以会打印出来就是因为发生了类型转换,产生了临时变量。当运算符两边的内容不是同一类型的时候会发生类型提升,提升有提升的规则,一般时范围小的向范围大的进行提升。上述变量j和变量i是如何进行比较的呢?因为这两个变量不是同一个类型,所以这里依然会生成一个临时变量,对变量i进行提升,这个提升的过程其实就是生成一个临时变量的问题,这个临时变量在这里是8个字节,即生成double类型的临时变量,然后依靠这个double类型的临时变量区和double类型的变量j进行比较。

下面我们再来举一个权限放大的例子:
在这里插入图片描述
在这里插入图片描述
此时引用ret1经过const修饰后,相当于权限的平移,就不会报错了。

再来看一看权限的平移和权限的缩小的例子:
在这里插入图片描述

四、指针和引用的区别:

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

好了,以上就是对C++中引用的一些基本内容。
就到这里吧,再见啦各位!!!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为何C语言的函数调用要用到堆栈,而汇编却不需要自定义栈

一 ≠ 汇编不需要堆栈 汇编中一般不初始化&#xff0c;也就是直接使用系统的堆栈而已&#xff0c;自己定义堆栈还是要初始化的。 之前看了很多关于uboot的分析&#xff0c;其中就有说要为C语言的运行&#xff0c;准备好堆栈。 而自己在Uboot的start.S汇编代码中&#xff0c…

一文详细介绍查看和启用nginx日志(access.log和error.log),nginx错误日志的安全级别,自定义访问日志中的格式

文章目录 1. 文章引言2. Nginx访问日志(access.log)2.1 简述访问日志2.2 启用Nginx访问日志2.3 自定义访问日志中的格式 3. Nginx错误日志(error.log)3.1 简述错误日志3.2 启用错误日志3.3 Nginx错误日志的安全级别 4. 文末总结 1. 文章引言 我们在实际工作中&#xff0c;经常使…

学习spark笔记

✨ 学习 Spark 和 Scala 一 ​ &#x1f426;Spark 算子 spark常用算子详解&#xff08;小部分算子使用效果与描述不同&#xff09; Spark常用的算子以及Scala函数总结 Spark常用Transformations算子(二) Transformation 算子(懒算子)&#xff1a;不会提交spark作业&#…

SLAM论文速递:SLAM—— 流融合:基于光流的动态稠密RGB-D SLAM—4.25(2)

论文信息 题目&#xff1a; FlowFusion:Dynamic Dense RGB-D SLAM Based on Optical Flow 流融合:基于光流的动态稠密RGB-D SLAM论文地址&#xff1a; https://arxiv.org/pdf/2003.05102.pdf发表期刊&#xff1a; 2020 IEEE International Conference on Robotics and Automa…

flex布局属性详解

Flex布局 flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content其他orderflexalign-self 含义:Flex是Flexible Box的缩写&#xff0c;意为”弹性布局”&#xff0c;用来为盒状模型提供最大的灵活性。 flex-direction flex-direction属性决定主轴的方向&…

危险区域闯入识别系统 yolov8

危险区域闯入识别系统通过YOLOv8网络模型技术&#xff0c;危险区域闯入识别系统对现场画面中发现有人违规闯入禁区&#xff0c;系统立即抓拍告警同步回传后台。YOLOv8 提供了一个全新的 SOTA 模型&#xff0c;包括 P5 640 和 P6 1280 分辨率的目标检测网络和基于 YOLACT 的实例…

Model-Contrastive Federated Learning 论文解读(CVPR 2021)

Model-Contrastive Federated Learning 论文解读 对比学习SimCLR 对比学习的基本想法是同类相聚&#xff0c;异类相离 从不同的图像获得的表征应该相互远离&#xff0c;从相同的图像获得的表征应该彼此靠近 具体框架&#xff1a; T随机数据增强模块&#xff1a;随机裁剪然…

光波导相控阵技术

在简述电光效应和热光效应的基础上综述了国内外光波导相控阵技术研究进展&#xff0c;包括一维和二维光波导相控阵的技术途径、结构特点和性能指标&#xff0c;给出了光波导相控阵的优势以及在激光雷达、成像等领域的应用前景。结果表明&#xff0c;光波导相控阵技术正向着大扫…

JavaScript Debugger 调试断点模式

在代码中加入debugger&#xff0c;相当于断点停顿&#xff0c;可用于查看变量传递情况&#xff0c;比如&#xff1a;Vue组件中生命周期onLoad(options) &#xff0c;在上一页面进入下一页面后&#xff0c;传递进来的参数值。 备注 &#xff1a;options 参数为字符串&#xff0…

从需求分析到上线发布,一步步带你开发收废品小程序

在如今的环保和可持续性的大趋势下&#xff0c;废品回收已经成为了人们日常生活中不可或缺的一部分。收废品小程序的开发可以帮助人们更方便地找到回收废品的地点&#xff0c;并有效减少废品对环境造成的污染。因此&#xff0c;我们的收废品小程序需要满足以下需求&#xff1a;…

2023年电信推出新套餐:月租19元=135G流量+长期套餐+无合约期!

在三大运营商推出的流量卡当中&#xff0c;电信可以说是性价比最高的一个&#xff0c;相对于其他两家运营商&#xff0c;完全符合我们低月租&#xff0c;大流量的要求&#xff0c;所以&#xff0c;今天小编介绍的还是电信流量卡。 在这里说一下&#xff0c;小编推荐的卡都是免…

中国制造再击败一家海外企业,彻底取得垄断地位

中国制造已在13个行业取得领先优势&#xff0c;凸显出中国制造的快速崛起&#xff0c;日前中国制造又在一个行业彻底击败海外同行&#xff0c;再次证明了中国制造的实力。 一、海外企业承认失败 提前LGD宣布它位于广州的8.5代液晶面板生产线停产&#xff0c;预计该项目将出售给…

Linux命令rsync增量同步目录下的文件

业务场景描述 最近遇到一个问题&#xff0c;需要编写相应的Linux命令&#xff0c;增量同步/var/mysql里的所有文件到另外一个目录/opt/mysql&#xff0c;但是里面相关的日志文件xx.log是不同步的&#xff0c;这个场景&#xff0c;可以使用rsync来实现 什么是rsync命令&#x…

6、什么是类型断言?

虽然 TypeScript 很强大&#xff0c;但有时还不如我们了解一个值的类型方便&#xff0c;这时候我们更希望 TypeScript 不要帮我们进行类型检查&#xff0c;而是交给我们自己来&#xff0c;所以就用到了类型断言。类型断言有点像是一种类型转换&#xff0c;它把某个值强行指定为…

当,Kotlin Flow与Channel相逢

前言 之前的文章已经分析了Flow的相关原理与简单使用&#xff0c;Flow之所以用起来香&#xff0c;Flow便捷的操作符功不可没&#xff0c;而想要熟练使用更复杂的操作符&#xff0c;那么需要厘清Flow和Channel的关系。 本篇文章构成&#xff1a; 1. Flow与Channel 对比 1.1 Fl…

论文实验1、安装tensorflow运行节点嵌入相关方法

还是官方的教程好使 使用 pip 安装 TensorFlow 只有三步 1.安装python&#xff0c;版本太高不行&#xff0c;在推荐版本里选最高的。 2.安装python虚拟环境venv python -m venv --system-site-packages .\venv .\venv\Scripts\activate 3.在虚拟环境里装tensorflow pip…

开发人员应考虑使用 Edge浏览器的 8 个理由

1.无限访问ChatGPT 这是正确的。您可以通过 Bing 访问 GPT-4。但与 2021 年后没有数据的 ChatGPT 不同&#xff0c;必应通过从自己的搜索引擎中提取最新数据来对其进行补偿。 首先&#xff0c;点击Edge 浏览器左上角的Bing 小图标 Bing 具有三个选项卡&#xff1a;Chat、Compo…

VSCode连接远程服务器调试代码详细流程

文章目录 1.远程连接服务器2. 打开项目文件目录3. 配置调试环境 在研究人工智能项目时&#xff0c;很多时候本地机器性能不够&#xff0c;只能把代码拉倒服务器上&#xff0c;然后利用服务器资源来运行代码。遇到问题时需要调试&#xff0c;本文详细介绍利用VScode来调试远程服…

DAB-Deformable-DETR代码学习记录之模型构建

DAB-DETR的作者在Deformable-DETR基础上&#xff0c;将DAB-DETR的思想融入到了Deformable-DETR中&#xff0c;取得了不错的成绩。今天博主通过源码来学习下DAB-Deformable-DETR模型。 首先我么看下Deformable的创新之处&#xff1a; Deformable-DETR创新 多尺度融合 首先便是…

layui 表格中嵌入下拉框被遮挡

1、代码 单元格样式&#xff1a; * 设置下拉框的高度与表格单元相同 */.layui-table-cell {width: 100%;height: 100%;border: 1px;border-color: #F2F2F2;} 表格初始化后的回调&#xff1a; done: function (res, curr, count) {$(".layui-table-body, .layui-tabl…