引用和指针的外形特别像,明显的区别是初始化的时候,指针可以为空,以后再赋值,而引用必须在声明时就初始化,并且与某个变量关联以后,将一直为那个变量“效忠”,它更像是一种const型的指针。
int &alia = val;
上面这个声明,其实是下面表达式的隐式表达
const int *ptr = val;
*ptr和&alia是同样的意义。
#include <iostream> using namespace std; int main() { int val = 101; int &alia = val; cout<<"val="<<val<<endl; cout<<"alia="<<alia<<endl; alia++; cout<<"val="<<val<<endl; cout<<"alia="<<alia<<endl; cout<<"addr of val = "<<&val<<endl; cout<<"addr of alia = "<<&alia<<endl; return 0; }
两者的值和地址都一样
#include <iostream> using namespace std; int main() { int val = 101; int &alia = val; cout<<"val="<<val<<endl; cout<<"alia="<<alia<<endl; cout<<"addr of val = "<<&val<<endl; cout<<"addr of alia = "<<&alia<<endl; int val1 = 202; alia = val1; cout<<"val1="<<val1<<endl; cout<<"alia="<<alia<<endl; cout<<"val="<<val<<endl; cout<<"addr of val1 = "<<&val1<<endl; cout<<"addr of alia = "<<&alia<<endl; return 0; }
看似将引用通过赋值改变了,其实该引用所代表的的变量也同样被改变了,而且引用的地址没有改变,所以,引用没有变(依然效忠于原来的变量)。
int val = 101; int *ptr = &val; int &alia = *ptr; int val1 = 202; ptr = &val1;
操作完以后,alia引用依然不变
引用型参数
C语言中,想要在函数参数不按值传递,只有一种办法:传指针。C++则提供了多一种传址的方式:传递引用。传递给调用函数的参数不再是参数变量的一份拷贝,而是参数变量本身(同一个变量,具有形参和实参两个名字而已)。
#include <iostream> using namespace std; void swapv(int a, int b); void swapp(int *p, int *q); void swapa(int &a, int &b); int main() { int val1=1; int val2=2; cout<<"val1 = "<<val1; cout<<" val2 = "<<val2<<endl<<endl; cout<<"swap by alias!"<<endl; swapa(val1, val2); cout<<"val1 = "<<val1; cout<<" val2 = "<<val2<<endl<<endl; val1=1; val2=2; cout<<"val1 = "<<val1; cout<<" val2 = "<<val2<<endl<<endl; cout<<"swap by pointers!"<<endl; swapp(&val1, &val2); cout<<"val1 = "<<val1; cout<<" val2 = "<<val2<<endl<<endl; val1=1; val2=2; cout<<"val1 = "<<val1; cout<<" val2 = "<<val2<<endl<<endl; cout<<"swap by value!"<<endl; swapv(val1, val2); cout<<"val1 = "<<val1; cout<<" val2 = "<<val2<<endl<<endl; return 0; }
传引用和传指针都改变了实参的值,所以在挑用这种按地址传参的调用,要想不改变原变量的值,可以通过传递const型引用,这样在被调用函数中视图修改参数时会被编译器发现!传引用对实参的限制比传值多,引用是一个变量的别名,所以必须不能对引用做额外的处理
void func(int &ra); int val = 10; int &alia = val; func(alia + 3.0);
这种编译器会发现的错误,原因在于传引用改变了参数变量的类型,此时编译器不会对变量类型进行处理,而是直接抛出错误(如果是传值,则不存在这个问题,编译器会强制转换变量类型)。