一、引用的本质
引用的本质在C++内部实现是一个指针常量。
- 在定义引用时
int& ref = a;会自动转换成int* const ref = &a;由于是指针常量,所以它的的指向不可改,但其指向的地址的值可以更改 - 使用引用时
ref = 20;转换成*ref = 20;
void func(int &ref){
ref = 100;
}
int main(){
int a = 10;
int& ref = a;//1.自动转换成 int* const ref = &a;
ref = 20;//2.自动转换成*ref = 20;
cout << "a:" << a << endl;
cout << "ref:" << ref << endl;
func(a);
return 0;
}
二、基本使用
2.1、语法
作用: 给变量起别名
语法: 数据类型 &别名= 原名
int a = 10;
int &b = a;
这段代码的含义为:首先a申请了一个整型大小的内存空间,a的地址是这块内存空间的地址,并把10这个值填入这块内存空间。然后b以a的内存空间完成了对自己的创建。

注意:
- 1、引用必须初始化。
- 2、别名变量的地址和原名相同。
这里就很好的解释了别名和原名的背后地址是一样的,所以如果改了别名,就相当于改了原名的地址上的值,所以原名代表的值也会改变。
int a = 10;
int &b = a;
cout << "a的地址是" << &a << endl;
cout << "b的地址是" << &b << endl;

- 3、引用在初始化后,就不可以改变了。
如果使用等号意图改变引用,那就会成为赋值操作。
int a = 10;
int &b = a;
int c = 20;
b = c;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
可以看到,本来应该是10的a、b变成了20。

2.2、引用做函数参数
优点:简化指针修改实参
这里以用引用实现了一个交换a和b的函数。
2.该函数使用了两个引用形参,其背后的地址为主函数中实参开辟的地址。
故地址不会因为这个函数的结束而被回收,而且直接作用在了主函数局部变量开辟的内存空间上。
故可以实现交换。
void swap(int &a, int &b){
int temp = a;
a = b;
b = temp;
}
1.由于只有在函数结束时,系统才会自动释放栈区的数据。
由于主函数的运行也就相当于整个程序的运行,
故主函数中的局部变量开辟的地址空间会一直存在知道程序结束。
int main(){
int a = 10;
int b = 20;
swap(a, b);
cout << "swapa = " << a << endl;//swapa = 20
cout << "swapb = " << b << endl;//swapb = 10
system("pause");
return 0;
}
2.3、引用做函数返回值
- 函数调用作为右值
- 函数调用作为左值
- 注意: 不要返回局部变量引用
#include <iostream>
using namespace std;
1.此处为错误示例,这里是由于a的地址会由于test01的结束而被释放,所以在a的地址被返回主函数后
a的地址立刻被释放了,从而产生报错。
int &test01(){
int a = 10; //局部变量存放在栈区,函数结束系统释放
return a;
}
2.与上个例子不同的是,这里的a是静态变量,其内存开辟在全局区
这里a的地址不会由于test02的结束而被释放,所以在a的地址被返回主函数后
a的地址仍然存在了,故可以输出a的值。
int &test02(){
static int a = 10;//静态变量存放在全局区,程序结束系统释放
return a;
}
int main(){
int &ref = test02();
cout << "ref = " << ref << endl;
3.此处将函数调用作为左值使用,test02()返回的引用其背后是a在全局区的地址,
然后将1000的值赋值给这个引用,也就相当于更改了a在全局区地址上的数据。
由于上面ref已经是这块地址上的引用了,所以ref的值也会被更改。
test02() = 1000;
cout << "ref = " << ref << endl;
system("pause");
return 0;
}
2.4、常量引用
常量引用主要是用来修饰形参,防止其他函数中的误操作修改了引用的值从而导致主函数中的引用值也被修改。
常量引用实质:
const int& ref = 10;
实际运行为:
int temp = 10;
const int& ref = temp;
下面是一段以const int& v作为形参的例子
在这里如果使用的是int& v作为形参,那么在showValue中的任何赋值语句都可以改变v的值从而影响到主函数
这个时候如果有赋值语句例如v = 1000,则会报错来提醒我们
所以,如果我们不希望v值被修改,我们可以使用常量引用来避免误操作
void showValue(const int& v){
//在这里如果接触下面这句话的注释会报错
//v = 1000;
cout << v << endl;
}
int main(){
int a = 10;
showValue(a);
system("pause");
return 0;
}
11万+

被折叠的 条评论
为什么被折叠?



