一、引用的本质
我不会告诉你,引用是“别名”,这更加令人难以琢磨…
引用的本质就是带有const的指针
引用的本质就是带有const的指针
引用的本质就是带有const的指针
int & a = b <---> int *const a = &b
char & a = b <---> char *const a = &b
double & a = b <---> double *const a = &b
(结构体类型) &a = b <---> (结构体类型) *const a = &b
为什么要C++要出现“引用”?
通过上面的对比,可以得出几条结论:
- 引用比指针更加简化;
- 引用使用起来更加像普通变量一样赋值;
- 引用更加安全。因为新手一般不会定义
int *const a
这样的指针,而是直接int * a
,才会造成所谓的野指针(没有给指针初始化,不知道默认指向哪了),一个不小心修改野指针的内容,严重的可以导致电脑崩掉。
二、实验
下面通过几个实验来感受一下引用跟指针的区别,同时体会引用的应用场合。
实验一:定义
int main()
{
int a = 100;
int & p;
char str = 'b';
char *const Str;
return 0;
}
结论:引用和带有const的指针一样,被定义后都必须初始化。
因为const在中,代表指针不能再指向其它变量。正如一张身份证,身份证制作好了,就你的,不可能重新变成别人的。
实验二:sizeof测试大小
int main()
{
char a = 'a';
char &A = a;
cout << "sizeof(A):" << sizeof(A) << endl;
cout << "sizeof(a):" << sizeof(a) << endl;
char str = 'b';
char *const pstr = &str;
cout << "sizeof(pstr):" << sizeof(pstr) << endl; //地址的大小
cout << "sizeof(*pstr):" << sizeof(*pstr) << endl;
cout << "sizeof(str):" << sizeof(str) << endl;
return 0;
}
结论:
A是引用,sizeof(A)得到是所指向 a变量的大小。虽然如此,引用变量本身也是占用空间的。
可以参考此文章:
https://www.cnblogs.com/karottc/p/cpp-reference.html
实验三:sizeof测试结构体大小
假设引用在结构体中呢?那它占不占空间?
#include <iostream>
using namespace std;
typedef struct
{
int &age;
char name;
}student;
int main()
{
cout << "sizeof(student):" << sizeof(student) << endl;
return 0;
}
结论:在结构体中,引用和指针是一样的。
实验三:引用作为形参和返回值
这里才是引用大显身手的地方。
#include <iostream>
using namespace std;
int g_a = 123;
int & swap(int &a, int &b)
{
int c = a;
a = b;
b = c;
//return c;
return g_a;
}
int main()
{
int a = 10, b = 20;
cout << "swap返回值:" << swap(a, b) << endl;
cout << "a:" << a << endl;
cout << "b:" << b << endl;
return 0;
}
结论:
引用作为形参,操作的方法和普通变量一样。
不能返回局部变量,编译器会报错。
有时候,我们会看到这样定义函数:bool compare(const int &a, const int &b);
说明传入的参数在函数内部不能被修改,只能作为右值被访问。
三、最后
那是开头的那句话:引用的本质就是带有const的指针,是地址,所以才能实现传址调用的效果。