C++引用详解

❤️ 引用(&)

💟 1、引用

🖊 1.1 概念

引用变量是一个别名,也就是说,它是某个已存在变量的名字。一旦把引用初始化为某个变量,就可以使用该引用名称或者变量名称来指向变量。

🖊 1.2 书写形式

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

int main()
{
	int a = 10;
	int& ra = a;    //  ra为a的引用
	return 0;
}

✏️ 1.3 注意事项

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

在vs编译器调试下我们可以看到,a和ra的值相同,并且他们的地址也相同。如图:
在这里插入图片描述

2、引用类型必须和引用实体类型是同种类型的。

int类型的数据必须使用相应类型的引用,否则编译器会报错!!!
在这里插入图片描述

🖤 2、引用特性

1、引用在定义时必须初始化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sKZ4ec7j-1668688148688)(C:\Users\25584\AppData\Roaming\Typora\typora-user-images\image-20221117122117325.png)]

2、一个变量可以有多个引用
在这里插入图片描述

3、引用一旦引用一个实体,再不能引用其他实体
在这里插入图片描述

执行ra = b这条语句后,并不是改变了ra这个引用,ra仍为a的引用,从图中可以看到ra的地址仍为a的地址。

💛 3、常引用

int main()
{
	const int a = 10;
	int& ra = a;  //权限放大,不行 
	const int& rra = a;  //权限平移可以

	int b = 20;
	const int& rb = b;  //权限缩小,可以
	     const int& rc = 10;  //权限平移,必须加上const
	return 0;
}

小结:

指针和引用赋值中,权限可以平移、缩小,但是不能放大。

所以当引用做参数时,为了防止权限放大,都是一般用const 引用

引用在可以被定义为const的情况下,应当尽量被定义成const。

💘 4、引用使用的场景

🐒 4.1 引用做参数

void Swap(int& left,int& right)
{
    int tmp = left;
    left = right;
    right = tmp;
}
void Swap1(int* left,int* right)
{
    int tmp = *left;
    *left = *right;
    *right = tmp;
}
//引用做参数相当于C语言中的指针做参数

🐷 4.2 引用做返回值

//正确形式
int& Count_1()
{
    static int n = 0;  //静态变量,存储在静态区
    n++;
    return n;
}
//错误形式
int& Count_2()
{
    int m = 0;  //局部变量,存储在栈中
    m++;
    return m;
}

解释:

函数运行时,系统需要给该函数开辟独立的栈空间用来保存该函数的形参,局部变量以及一些寄存器的信息等。

但函数运行结束后,该函数对应的栈空间就被系统回收了,但是对应的内存还在。

如果这时使用传引用返回,由于那块空间已经不属于此函数,再去访问数据时,得到的结果就是随机值

解决方法:

- 为局部变量加上static修饰,这样变量就存储在静态区
- 使用全局变量(不推荐)

总结:

如果函数返回时,出了函数作用域,如果返回对象还在(还没返回系统),则可以使用引用返回,如果已经还给系统,则必须使用传值返回。

💚 5、引用和指针的区别

1、引用概念上定义一个变量的别名,指针存储一个变量地址。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LtUKbDL2-1668688148690)(C:\Users\25584\AppData\Roaming\Typora\typora-user-images\image-20221117200343908.png)]

ra的地址和a的地址相同,b的地址和 pb的地址不同

2、引用在定义时必须初始化,指针则没有要求

3、引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6Ife0UV-1668688148690)(C:\Users\25584\AppData\Roaming\Typora\typora-user-images\image-20221117200637019.png)]

可以将c的地址赋值给pb,即指针可以指向任何一个同类型的实体,但是引用不可以

4、没有NULL引用,但是有NULL指针。

5、在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所在字节个数(32位平台下为4个字节,64为平台下为8个字节)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bvRZmZoa-1668688148691)(C:\Users\25584\AppData\Roaming\Typora\typora-user-images\image-20221117200920631.png)]

6、引用自加即引用实体加1,指针自加即指针向后偏移一个类型字节的大小。

7、有多级指针,但是没有多级引用。

8、访问实体方式不同,指针需要显示解引用,引用编译器自己处理。

9、引用比指针使用起来相对更安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kunmu.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值