C++引用&引用在函数中的使用场景
引用:引用概念:给已定义的变量取别名,变量类型与引用类型必须要一样,不创建新空间;引用的理解:C++新增了一种复合类型变量------引用变量 。引用就是已定义变量的一个别名(通俗的理解就是,当定义了一个变量,该变量名就相当于我们人身份证上的名字,引用就是平时朋友之间起的外号);引用的作用:引用变量和原变量完全相同。引用定义int main(){int a=10;int& ra=a;//r
·
- 引用概念:给已定义的变量取别名,变量类型与引用类型必须要一样,不创建新空间;
- 引用的理解:C++新增了一种复合类型变量------引用变量
引用就是已定义变量的一个别名
(通俗的理解就是,当定义了一个变量,该变量名就相当于我们人身份证上的名字,引用就是平时朋友之间起的外号);- 引用的作用:引用变量和原变量完全相同。
定义

ra就是a的引用,对变量ra和变量a进行取地址操作,它们的地址是相同的
注意事项:
- 引用必须要初始化(若引用作为函数参数,则不需初始化);
- 引用类型和变量类型必须相同;
- ra被引用后就不能再被别的变量引用;
- 实体生命周期>引用生命周期(身份证只有一张贯穿一生,而在不同时候我们有不同的外号);
- 不能建立引用数组。
常引用
常引用的特点:使用常引用后,引用变量的值不能被修改
需要用到常引用的场景

原因:
根据现象得出rd不是d的别名
- rd是12的引用(rd值为12是因为发生隐式类型转换,不能转化则报错)
- rd和d的类型不同,就会将d值的整数部分取出,创建临时变量存储该值;
- 所以rd引用的是临时变量,但是程序员不知道临时变量的地址和名字;
- 在修改变量的值时要知道该变量名或地址
所以这种情况就无法对变量进行操作
所以说明该临时变量具有常量属性(不能修改)
所以在取别名时要用常引用- 当函数参数为const引用时,实参如果和引用形参不匹配,C++会生成临时变量
引用和指针的区别
相同:
- 效率差不多;
- 传参时可以达到相同的效果→修改形参都可以改变外部实参
- 在底层实现原理一样,汇编指令一样
- 在语法概念上,引用就是一个别名没有独立的空间,引用和实体共用一块空间;
为了让用户更好的理解引用(c++在代码层面的表示与底层有很多不同)
在底层;
引用有自己的空间,该空间实际放置的是其在代码层面所引用实体的地址
不同:
- 引用在定义时必须初始化,指针没有要求
- 引用在初始化时引用一个实体后,就不能再引用其他实体;
指针可以在任何时候指向任何一个同类型 实体- 没有NULL引用,但有NULL指针(同第一点)
- 在sizeof中含义不同:引用结果为引用类型的大小;
指针始终是地址空间所占字节个数(sizeof只关心类型)- 引用自加(ra++)即引用的实体增加1;
指针自加(pa++,指针指向连续的空间自加才有意义)即指针向后偏移一个类型的大小- 有多级指针,但是没有多级引用 (右值引用)
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
- 引用比指针使用起来相对更安全
引用作为函数参数:

可以结合传值和传址的优点:
- 在C语言阶段,要对函数对两个值进行交换,函数参数必须是指针
传址不能传值,而C++为我们提供了引用,我们可以将引用作为函数参数- 表面上:形参位置没有开辟新空间,看似是直接操作a和b变量
- 实质上:引用作为参数传递在底层和传地址是一模一样的
可以理解为C++编译器对传址进行了优化,结合传值和传址的优点,就像内联函数是对宏的优化。
注:函数是引用参数,实参必须是变量
例1:num=test(x+2);
例2:int arr[3]={1,2,3};num=test(arr[1]);
- 上述test函数形参是普通参数,则传参正确,
- 如果是引用参数则错误
const修饰引用参数的好处:
- 使用const可以避免无意中修改数据的编程错误;
- 使用const使函数能够处理const和非const实参,否则将只能接受非const 数据;
- 使用const引用使函数能够正确生成并使用临时变量。
引用作为函数返回值
- 传值返回
指函数返回一个值的拷贝,意味着函数返回时会将这个值从函数内部复制一份到调用方的内存中,从而创建一个新的对象
这个新对象的值与函数内部的对象相同,但是这两个对象是完全独立的
传值返回对于较大的对象来说,需要大量的内存复制,可能影响程序性能。- 传引用返回
意味着函数返回的是对象的地址,而不是对象本身的副本。
需要注意,函数返回一个对象的引用或指针,那么调用方必须确保这个对象在函数返回后仍然有效,否则会导致访问非法内存- 传引用的返回值实际上是函数返回值的别名,
因此如果原变量的生命周期已经结束,那么就不能作为传引用的返回值
比如说在函数内部定义的局部变量,在函数结束时就会被销毁,不能作为传引用的返回值
注: 函数返回值应保证返回的实体不受函数结束的影响
例如:返回值是引用参数,全局变量,静态变量
- 函数的形参是在函数调用时分配在栈上的,
函数执行完毕后,这部分栈空间会被自动回收,形参变量也随之消失
因此形参只在函数执行期间有效,函数调用结束后就会被销毁。- 参数部分的指针变量即使在函数调用结束后,指针变量所指向的内存空间不会被释放

通过ret,外界就可以操作num,这种操作是十分危险的
后两次输出值是乱码的原因:
- 调用函数就要给函数开辟栈空间,后续调用函数也需要空间
编译器就从上次结束的位置开辟;- 第一次调用结束空间回收,但栈上的数据未删除
编译器会保存一次数据,所以能看到上一次栈空间内的数据- 所以使用引用作为返回类型,不能返回栈空间中的变量
当函数的返回值为引用类型时,函数的返回值可以作为左值被赋值,并且函数调用test()就变成表达式,也就是说test()就是返回值num的别名
更多推荐


所有评论(0)