C++入门超详细——引用

目录

引用

1.认识什么是引用

2.认识“&”符号

3.引用的定义

4.引用的特点

传引用返回

传值返回:生成一个返回对象拷贝作为函数调用返回值

传引用返回,顾名思义,就是在返回值后面加&,如下的int& 

总结传引用传参和传引用返回

权限的放大和缩小

权限的放大

权限的缩小

引用和指针的区别

最后总结


引用

1.认识什么是引用

在小学的时候,我们经常给其他同学起外号,像脖子比较长的同学,我们会给那个同学取名“长颈鹿”,“长颈鹿”就是这位同学的别名,引用也可以这样理解,在语法层面上,引用就是取别名。

2.认识“&”符号

在我们学习编程语言时,&符号有多种含义

int c = a & b;    //转化为二进制进行与运算
int* p = &a;      //取地址
int& j=a          //引用

3.引用的定义

引用不是新开辟一个空间去定义一个变量,是给一个已知的变量取别名,编译器不会给引用变量开辟空间,初始变量和引用变量共用一块空间

int a = 0;
int& b = a;
int c = a;
c++;
cout << c << " " << a << endl;
b++;
cout << b << " " << a << endl;

如上,b是a的别名,我们上面也提到了,a和b是共用同一块空间,是不是b++的同时,a也跟着++呢?很显然 输出结果如下:

4.引用的特点

1.引用必须初始化

2.引用不能给空指针

3.一个变量可以有多个引用

4.引用没有二级引用

5.引用的意义

像以前我们写一个Swap交换函数如下

void swap(int* p1, int* p2)
{
	int* tmp = p1;
	p1 = p2;
	p2 = tmp;
}
int main()
{
	int a = 2, b = 1;
	swap(&a, &b);
	return 0;
}

这样写的很繁琐,要取地址,在swap函数还要用指针,当我们学了引用,我们可以简便快捷的写一个Swap函数,如下:

void swap(int& x1, int& x2)
{
	int tmp = x1;
	x1 = x2;
	x2 = tmp;
}
int main()
{
	int a = 1;
	int b = 2;
	swap(a, b);
	cout << a << " " << b;
	
	return 0;
}

x1,x2分别是a和b的别名,改变x1,x2相当于改变a和b的值!

所以引用本身是一个变量,但是这个变量又仅仅是另外一个变量一个别名,它不占用内存空间,它不是指针哦!仅仅是一个别名

传引用返回

在认识传引用返回之前,我们复习一下我们已经学习的传值返回

传值返回:生成一个返回对象拷贝作为函数调用返回值

传引用返回,顾名思义,就是在返回值后面加&,如下的int& 

int& count()
{
	int n = 0;
	n++;
	return n;
}
int main()
{
	int ret = count();
	cout << ret << endl;
	return 0;
}

ret发生越界了,却仍正常输出值,但这属于侥幸
返回值取得是n的别名(即tmp),而tmp空间上的值就是n原来的数,但这是侥幸,如果有的编译器销毁后n被置成随机值,tmp就会取到随机值
越界:好比申请房间,里面存一个变量,理论上除非别人非法入侵,变量是不会被修改的。但你把房间退了,里面还留着你的东西,就无法保障它不丢失,即使你下回去房间还没租给别人,所以东西被你找到了,也只能说是侥幸(因为换一个房间/编译器,是否还能保证找到就不好说了)

如果是调用第二次就不一样了‘

第一次输出的时候,n销毁了,第二次输出时,已经寻找不到了,输出随机值

总结传引用传参和传引用返回

如果函数返回时,除了函数的作用域,如果返回对象还在,则可以使用传引用返回,如果该对象已经还给系统了,则必须使用传值返回

传引用传参(任何时候都可以)

1.能提高效率

2.改变了形参会影响实参

传引用返回(出了函数作用域对象还在可以使用)

1.提高效率

2.修改返回对象

权限的放大和缩小

1.权限可以平移

2.可以缩小

3.不能放大

权限的放大

const int a = 0;
int& b = a;

这里无法编译通过,定义a是常量,定义b为a的引用时,这是权限的放大,我们应该更改为

const int a = 0;
const int& b = a;

这样我们更改了 这是权限的平移,可以编译通过

权限的缩小

int x = 0;
const int& c = x;

当我们遇到这种情况时

int fun()
{
	int a = 0;
	return a;
}
int main()
{
	int& ret = fun();
	return 0;
}

这样是编译不通过的,因为传值返回时,会产生一个临时变量,临时变量具有常性,定义引用的时候是int, 这是权限的放大,所以我们应该加一个const

int fun()
{
	int a = 0;
	return a;
}
int main()
{
	const int& ret = fun();
	return 0;
}

引用和指针的区别

使用场景:
指针和引用用途基本是相似的(能用指针的地方基本能用引用,能用引用的地方也基本能用指针),它们一般都是用于做一些参数、返回值的地方,它们有提高效率、做输出型参数返回对象这样的,但一般这些场景引用更合适的。
指针有引用替代不了的地方:如C++中这种链表、链式结构的场景,引用无法替代。
a.引用必须在定义的时候初始化(指针可以初始化,也可以不初始化)
b.引用指向一个实体后,就不能再引用其他实体
指针更强大,更危险,更复杂;引用相对局限一些,更安全,更简单

最后总结

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

本文部分采用如下链接的原文
原文链接:https://blog.csdn.net/SHIE_Ww/article/details/126580559

以下就是本篇的全部内容啦!感谢大家观看!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值