C++中引用变量详解

目录

一、什么是引用?

二、引用的注意事项

三、引用的本质

四、常量引用

五、引用的使用场景​​​​​​​

六、引用和指针的区别


一、什么是引用?

引用实际上是给一个变量起别名,编译器不会为引用变量开辟一个新的内存空间,变量和它的引用变量共用同一块内存空间。就好比水浒传中的李逵有的别名,既可以叫做黑旋风,也可以叫铁牛,实际上都是同一个人。

语法:数据类型& 别名=原名

int main()
{
	int a = 10;
	int& b = a;//b是a的别名
	cout << "a=" << a << endl;//两者打印的结果是一样的
	cout << "b=" << b << endl;
	cout << "a的地址" << &a << endl;//两者地址是一样的
	cout << "b的地址" << &b << endl;
	return 0;
}

二、引用的注意事项

1、引用必须初始化

2、一个变量有多个引用

3、引用在初始化后,不可以改变其指向

int main()
{
	//1、引用必须初始化
	//int& a;

	//2. 一个变量可以有多个引用
	//int a = 10;
	//int& b = a;
	//int& c = a;

	//3、引用在初始化后,不可以改变其指向
	//int a = 20;
	//int b = 10;
	//int& c = a;//一旦初始化后,就不能修改
	//c = b;//赋值操作

	return 0;
}

三、引用的本质

引用本质就是一个指针常量,引用一旦初始化,其指向就不可以发生改变。

int main()
{
	int a = 10;
	//自定转化为int* const b=&a;
	//指针常量是指针的指向不可以改
	//也就说明了引用为什么不可以改
	int& b = a;
	//编译器发现b是引用,自动帮我们转化为*b=20;
	b = 20;
}

四、常量引用

当函数参数是引用的时候,有时需要用到常量引用,涉及到权限以及防止误操作。

权限方面不能放大,只能缩小。

例如一个变量是一个可读可写的权限,可以修改为只读的权限。

一个变量是只读的权限,不能修改为可读可写的权限。

int main()
{
	//权限平移
	int a = 10;
	int& b = a;

	//权限不能放大
	const int c = 20;//c是只读
	//int& d=c;//d是可读可写 c是只读,错误
	const int& d = c;//d是只读 权限平移

	//权限可以缩小
	int e = 30;//e可读可写
	const int& f = e;//f只读

	return 0;
}

如果使用引用传参,函数内如果不改变参数,建议使用const引用传参

例如一个函数实现打印的功能,使用引用传参,目的是为了打印,而函数内部依然可以改变形参,可能会涉及到误操作,可以加const修饰形参,防止形参改变实参。

//利用常量引用防止误操作修改实参
void ShowValue(const int& b)
{
	//b+=10;//误操作,改变了实参
	// 加入const之后,都是只读的权限,避免通过引用修改实参
	cout << b << endl;
}
int main()
{
	int a = 10;
	//该函数只是实现打印数据功能
	ShowValue(a);
	return 0;
}

五、引用的使用场景

1、引用做参数

作用:函数传参时,可以利用引用让形参修饰实参

优点:可以简化指针修改实参

总结:通过引用参数产生的效果同按地址传递是一样的,引用的语法更简单清楚

//引用做函数参数
void mySwap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	cout << "交换前a=" << a << endl;
	cout << "交换前b=" << b << endl;
	mySwap(a, b);
	cout << "交换后a=" << a << endl;
	cout << "交换后b=" << b << endl;
	return 0;
}
//交换前a=10 b=20
//交换后a=20 b=10

2、引用做返回值

作用:引用是可以作为函数的返回值的

注意:不能返回局部变量引用,可以返回静态变量引用

原因:局部变量是存放在栈区的,出了作用域便会销毁,而静态变量是存放在静态区的,

静态区上的数据在程序结束后系统释放

//这个程序使用引用返回本质是不对的,返回值没有保障
int& count()
{
	int n = 0;//n存放在栈区,出了作用域就被销毁
	n++;
	return n;
}
int main()
{
	int& ret = count();
	cout << ret << endl;
	cout << ret << endl;
	return 0;
}
//这个场景可以使用传引用返回
int& count()
{
	static int n = 0;//static修饰的变量n存放在静态区
	n++;
	return n;
}
int main()
{
	int& ret = count();
	cout << ret << endl;
	cout << ret << endl;
	return 0;
}

六、引用和指针的区别

语法角度:引用是没有开空间的,指针有开空间

int main()
{
	int a = 10;
	//语法角度,ra没有开空间
	int& ra = a;
	ra = 20;

	//语法角度,pa开了4or8byte空间
	int* pa =&a;
	*pa = 20;
	return 0;
}

底层角度:引用和指针都是开了空间的

 引用和指针的不同点:

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

 

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值