我们知道,变量名是一段连续存储空间的别名,是一个标号(王老师口中的“门牌号”)。程序中通过变量来申请并且命名内存空间,通过变量的名字我们可以使用存储空间。那么问题来了,对一段连续的内存空间,我们只能取一个名字吗? 这就引入了 引用 的概念。
1:关于引用
引用是C++的概念,属于C++编译器对C的扩展。引用可以看做一个已定义变量的别名。
语法:type & name = var ; name就是var的别名。
void main()
{
int you = 18;
int & me = you; //me就是you的别名。
//int & c; //报错。普通引用在声明时必须用其他的变量进行初始化
printf("you:%d me:%d\n",you,me);
system("pause");
}
普通引用在声明时必须用其他的变量进行初始化,引用作为函数参数声明时不用进行初始化。
说明引用很像一个常量。
void main()
{
int you = 18;
int & me = you;
printf("&you:%d\n", &you);
printf("&me:%d\n", &me);
system("pause");
}
you和me就是同一块内存空间的“门牌号“。
2:引用为何存在--存在的意义
a:引用作为其他变量的别名而存在,因此在一些场合可以替代指针。
b:引用对于指针来说具有更好的可读性和实用性。
# include "iostream"
using namespace std;
void swap1(int * x, int * y)
{
int z = 0;
z = *x;
*x = *y;
*y = z;
}
void swap2(int & x,int & y)
{
int z = 0;
z = x;
x = y;
y = z;
}
void main()
{
int a, b;
a = 10;
b = 20;
swap1(&a, &b);
printf("a:%d,b:%d\n",a,b);
swap2(a,b);
printf("a:%d,b:%d\n", a, b);
system("pause");
}
可以看出,swap1和swap2完成了同样的交换功能。(注:第二行a:10,b:20是交换了a 20 b 10之后的结果)。
3:引用的本质
a:引用在C++中的内部实现是一个常指针,即 int & me = you 相当于 int * const me = & you ,C++编译器帮我们程序员取了地址。
b:C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占的空间大小与指针相同。
struct you
{
char name[64]; //64
int age; //4
int & a; //4
};
void main()
{
printf("sizeof(you):%d\n",sizeof(you));
system("pause");
}
从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++编译器为了实用性而做出的细节隐藏。
引用 VS 间接赋值:
间接赋值三个条件:
1:定义变量(实参形参)
2:建立关联,实参取地址传给形参
3:*p形参间接修改实参的值
12 3 ->函数调用 1 23 -> 引用(C++编译器偷偷地传了地址)
引用在实现上只不过是把间接赋值的3个条件后面2步合二为一。