C++详细分析引用的使用及其底层原理C语言

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

举个形象的例子,鲁智深又被叫做"花和尚",这里的花和尚和鲁智深都是同一个人,花和尚就是鲁智深的引用,说白了引用其实就是取外号。

intmain(){inta;int&b=a;}这时b就是a的外号。下面的这种没有初始化的做法是错误的

intmain(){int&b;//引用必须初始化,这里没有进行初始化。}在生活中,我们可能有多个名字,在家中父母可能叫你小名,在外面别人可能叫你的全名或者外号

其实也就是一个变量可以有多个外号,也就是可以有多个引用。

intmain(){inta;int&b=a;int&c=a;}这里的b和c都是a的外号,b,c,a三个变量指向的都是同一块内存空间。

形象的来说,就是你和你的亲弟弟不能用同一个名字

下图c是a的引用,那么现在他就不能做b的引用了。

在讲引用做参数之前,我们先需要了解一下,参数传值和参数传引用的区别。

1.参数传值

下图实参传递了a,形参b对其进行了接收并修改,但是实参a最终并没有受到影响,这又是为什么呢?

原来,参数传值的时候,形参会生成一份实参数据的拷贝,也就是说实参和形参指向的不是同一块空间,所以形参的修改不会影响实参。

2.引用传参

下图进行了引用传参,形参的修改对实参产生了影响,我们可以大胆推测形参和实参是一块空间。

原来,引用传参的时候,形参不再是实参的拷贝,而是实参的一个引用,也就是说实参和形参指向的是同一块内存空间,形参的改变会影响实参。

1.实参传值:

缺点:形参会生成一份实参数据的拷贝,当数据量很大时,在一定程度上就会影响程序的运行速度

优点:因为形参是实参的拷贝,所以形参的操作不会影响实参,可以防止实参数据遭到污染。

2.实参传引用

缺点:形参的操作对实参会产生影响,形参的错误操作会让实参数据遭到修改。

优点:因为形参是实参的引用,一定程序上,可以提高程序的运行速度

在了解引用做返回值时,我们还是得先了解传值返回和传引用返回的区别。其实原理和上面大致相同。

1.传值返回

在返回c的时候,返回的不是c的本体,而是将c拷贝在一块临时空间里,所以返回的其实是这块临时空间。然后ret再次拷贝一个和这块临时空间一样数据的空间。

这块有点像俄罗斯套娃,需要多画图理解。我一开始也有点懵逼。多画图就清晰了。

但是问题又来了,这块临时拷贝空间又存储在哪里呢?

当c比较小的时候(4字节或者8字节),一般是存储在寄存器中。

当c比较大的时候,临时变量放在该函数的栈帧上面。

接下来我们通过观察代码的反汇编进行证明:

分析这段代码的汇编,在进入add函数以后,先是将a的值给了eax,然后将b的值加上a,接着将eax里的值给了c。最后对c进行返回,在返回c的时候生成一个临时拷贝,c将自己的值又给到了寄存器eax中。

最后回到主函数,eax将值给了ret。

这里进行的是传引用返回,也就是说ret其实就是c的别名。传引用返回,返回的就是本体,而不是拷贝。因为这里c是一个局部变量,在函数结束以后,栈帧被销毁,局部变量的空间被系统回收了。这时ret再去访问c的内容就可能造成非法访问,并且c的值可能已经被修改了。

形象的来说:就是你原先买了一个房子,后面你又将其卖给了别人,后面你想再次进入这个房子,但是这间房子已经不属于你了,你进房子的操作就属于非法访问了。

所以,传引用返回时,返回的对象不能是出函数就被系统回收的。也就是说返回的变量不能是一个局部变量。

1.引用的权限可以缩小

intmain(){inta=10;constint&b=a;//权限的缩小}这里变量a是可读可写的,而b是a的引用,b只能对a这块内存空间进行读取,不能进行修改,这就是权限的缩小,这在C++中是可以的。

2.引用的权限不能放大

intmain(){constinta=10;int&b=a;//权限的缩小}这里变量a指向的空间是只能读取的,不能进行修改,而a的引用b,是可以对a指向的这块空间进行修改的,使得权限得到了放大,这种语法在C++中是错误的。

总结:引用可以进行权限的缩小,但是不能进行权限的放大

下图中的代码(1)和(2)是否能够正常运行?

doubled=11.1;inta=d;(1)int&ret=d;(2)答案:(1)可以运行通过,(2)不行。

代码(1)是普通的隐式类型转换。

而在了解代码(2)的错误原因之前,我们需要回顾一些知识:

1.类型转换

doubled=11.1;

inta=d;

d的类型是double,a的类型是int,类型不同,正如下图所示,在发生隐式类型转换的时候,需要将d的值存到一个int类型的临时变量里,然后将这个临时变量的值赋予给a。

2.整形提升

inta=10

charc=‘b’;

if(a>c){

}

这里并不是拿c直接和a进行比较,而是将c赋值到一个int的临时变量里,通过这个临时变量去和a进行比较。

结论:右值是具有常性的,是不可修改的。

这里的右值不能通过字面意思(处于式子右边的值)进行理解,以下的几种情况一般都是属于右值。

1.表达式的计算结果:如:5+3=8,这里的8就是右值。

2.常量:如a=5,这里的5就是右值。

3.一些隐式类型转换产生的临时变量。如

inta;

doubled;

d=a;

这里隐式类型转换产生的临时变量也是一种右值。

在明白了这些基础原理以后,我们开始学习为什么代码int&ret=d;(2)是错误的。

这里引用的变量其实是一块临时空间,而临时空间是右值是不能修改的,这种引用的方式本质上其实就是权限的放大,因此编译不能通过。

intmain(){inta;int&b=a;int*p=&a;}这里通过调试模式观看这段代码的反汇编。

这里的lea是取地址的意思。从汇编代码可以看出,在底成实现的时候,引用和指针的实现方式是一样的,所以说:引用的底层是通过指针实现的

THE END
1.万科C区高层89方三房视野开阔超安静双灯湖,万科金域中央B区C6、连接客厅和厨房之间是您和家人享受美味的餐厅,让您热情的招待亲朋好友 业主心态 业主换房出售 本人就在佛山 看好就可以签约 稳定不返价 服务介绍 专做广佛一二手住宅,商铺,公寓,写字楼租售,有丰富的地产经验,看好专业谈价,一个电话就有一个专业的团队帮到您。 展开更多 https://foshan.anjuke.com/prop/view/A7020328167
2.千灯湖C+价格19500元/平米,期房千灯湖C+楼盘千灯湖C+价格19500元/平米,期房。千灯湖C+价格19500元/平米,购房者在选购房产时应该考虑到房价是否合适,是否符合个人预算,并且在选择房屋时还需要用心思考。 家是有温度的居所,每个家庭的结构不同,对空间的需求也不尽相同。户型的好坏会直接影响到居住感。千灯湖C+户型有1室-1室,物业费5元/㎡·月。 http://fs.goufang.com/news/29919.html
3.佛山公寓翘楚!千灯湖C+公寓怎么样?月供2400,品质生活不打折!作为佛山公寓的天花板,南海千灯湖C+公寓以卓越的品质和优越的地理位置,成为众多购房者和投资者的理想之选。那么,千灯湖C+公寓怎么样?让我们一起看看。 及时楼市资讯,就上楼盘网 长按识别二维码,查看详情! 作为佛山公寓的天花板,南海千灯湖C+公寓以卓越的品质和优越的地理位置,成为众多购房者和投资者的理想之选。那https://m.loupan.com/fs/news/202409/5375555
4.房大全C+系统APP扫码 APP下载 APP扫码登录电脑Mac:【获取中】http://www.0792zaixian.com/
5.c++代码,买房子11111编程语言CSDN问答为您找到c++代码,买房子11111相关问题答案,如果想了解更多关于c++代码,买房子11111 c++ 技术问题等相关问答,请访问CSDN问答。https://ask.csdn.net/questions/8072925
6.OpenJudgeNOI题库(2022.11.19)116题星空的技术博客http://ybt.ssoier.cn:8088/problem_show.php?pid=1001 《啊哈C语言》精华版全套/c++基础课程https://www.bilibili.com/video/BV1xK4y157xA 啊哈C语言 第7讲 3、04输出保留3位小数的浮点数 https://www.bilibili.com/video/BV19f4y147FB https://blog.51cto.com/u_1443208/5870378
7.买房子题解2808买房子,使用c++解决 李强| 2023-04-11 09:39:24 题号:2808 语言:C++浏览:110评论:0评分:8.0 编写题解 2808: 买房子 风轻云| 2023-12-19 20:59:59 题号:2808 语言:Python浏览:138评论:1评分:7.3 2808: 买房子 张传伟| 2023-04-22 15:29:17 题号:2808 语言:JAVA浏览:106评论:0评分:4.5 https://blog.dotcpp.com/tijie/p2808/
8.深圳,有关房子的朝向woaidongmao我买的房子是正南正北正西方向的。当时刚刚起步的一些房地产信息网站,比如深圳房信网,焦点网之类,给浏览者传递一个信息:南北通透的房子就是好房子。另外一个信息是:在北方要讲究朝向,而在深圳,朝向无关紧要——当然,西北向还是最差的。 一个仅仅24岁,初次置下房产的女孩,除了听信这些类似真理的话,还能怎么样http://www.cppblog.com/woaidongmao/archive/2012/07/09/182308.html
9.如何系统有效的学习股票知识(通用18篇)1、单词最基础,这是老生常谈的问题,有砖才能盖房子的道理我想大家都明白。词汇教材不要太厚的那种,太厚的词汇手册会从精神上把你打垮,但要求尽量全面。单词不时从头到尾死记,你可能背到r就把a打头的全忘了,第一次从头到尾,以后尽量穿插,甚至倒过来记,并及时复习,今天记下的明天还有印象,后天就模糊了,后天https://www.360wenmi.com/f/file1384hh4l.html
10.C++笔试题打印版.pdfC++笔试题 1 .多态类中的虚函数表是C o m p ile -T im e ,还是 Run-T ime 时建立的? 答案:虚拟函数表是在编译期就建立了,各 虚拟函数这时被组织成了一 虚拟函数的入 口地址的数组.而对象的 隐藏成员一虚拟函数表指针是在运行期一也就是构造函数被调用时进行初始化的,这是实现多态的关键. 2 .将https://m.book118.com/html/2022/0827/8060103121004132.shtm
11.46家公司的笔试题目汇总6.c++里面如何声明const void f(void)函数为c程序中的库函数? 7.下列哪两个是等同的 int b; a const int* a = &b; b const* int a = &b; c const int* const a = &b; d int const* const a = &b; 8.内联函数在编译时是否做参数类型检查? https://www.diyifanwen.com/qiuzhijianli/msshiti/466267.htm
12.opengl绘制房子天空草地积分:50 编程:opengl 语言:C/C++ 软件:Visual Studio 标签: 【1、环境介绍:】软件 :visual studio 编程语言 :opengl 使用的库 :glut 【2、内容介绍— opengl绘制房子、天空、草地— 纹理贴图— 层次建模— 鼠标按键交互:旋转 缩放 【3、操作(英文输入法)】— 按键’左’ –控制左旋转;— 按键’右’http://www.opengldn.com/1565.html
13.编程竞赛宝典C++语言和算法入门int a,b,c;定义了a、b、c这3个整型变量,C++语言规定变量必须要先定义才能使用。定义变量相当于向计算机内存申请“房子”,变量只有住进“房子”里才允许使用,数据类型规定的存储空间有多大,分配的“房子”就有多大。例如定义了两个变量,如图1.14所示。因为a是整型变量,所以内存给它分配了4字节的空间;因为x是超长https://www.epubit.com/bookDetails?id=UB77a9ce8133887
14.C++深入浅出类的封装思想图文案例,通俗易懂2你呢,背井离乡在二线城市当一个程序员,工作了几年也赚了不少钱,此时你就想把一直以来的出租屋换成一个崭新的房子,想要在你所处的城市买个房,虽然交不起所有的钱,但首付还是可以的,不过呢还差那么几万块钱,于是呢就想到了你大学时候的室友,也是个铁瓷很要好的朋友,想找他结点钱 https://developer.aliyun.com/article/1382949
15.循环控制~16买房子罗小罗佳油循环控制~16买房子 题目描述: 输入: 一行,包含两个正整数N(10 <= N <= 50), K(1 <= K <= 20),中间用单个空格隔开。 输出: 如果在第20年或者之前就能买下这套房子,则输出一个整数M,表示最早需要在第M年能买下,否则输出Impossible。 1#include<stdio.h>2intmain(){3intN,K;//N:年薪,K:https://www.cnblogs.com/luoxiaoluo/p/16788104.html