C++11中的 “右值引用” 此处先不作讨论,本篇讨论的是常规的 “左值引用” 。
一、引用
引用 是对象(或变量)的别称。
定义引用时,必须要初始化,程序将引用和初始值绑定到一起,之后无法让引用重新绑定,即引用不能再改变(被赋值)。
定义了引用后,对其进行的所有操都是在其绑定的对象上进行。
引用本身不是对象(没有存储空间),故不能定义引用的引用。请看下面的例子:
int i = 1024;
int &a;//错误,引用定义时必须初始化
int &a = i;//正确,a是i的引用(另一个名字)
int &b = 10;//错误,引用的初始化值必须是一个对象(变量),不能是一个数值
double &c = i;//错误,引用类型和对象不一致
清楚了以上内容后,下面代码输出是什么呢?
int i,&r = i;
i = 5;
r = 10;
cout<<i<<" "<<r<<endl;
.
.
.
.
.
.
.
没错,答案是:
10 10
牢记:引用就是绑定到对象上。
二、指针
指针大家都知道指向对象的地址,和指针一起用的是取地址符号 " & "。
int i = 1024;
int *p = &i;//p存放变量i的地址
1.指针也要求定义的类型和指向的类型匹配一致(const和类型转换除外 ),不能把int型变量直接赋值给指针。
int *p2 = i;//错误,不能把int型变量直接赋值给指针
int *p3 = p;//正确,p3指向i的地址(int型的指针)
因此指针值有以下四种情况:
1.指向一个对象;
2.指向紧邻对象的下一个位置;
3.空指针;
4.无效指针;
2.要想访问指针指向的对象,可使用解引用符号 * ,
int i = 1024;
int *p4 = &i;
cout<<*p4;//等价于:cout<<i;
在C++11之后,表示空指针不在用NULL了,而用nullptr;
3.void* 指针是一种特殊指针类型,可以存放任意类型的对象:
int i = 1024;
double *p5 = &i;//错误,指针和对象类型不一致
void *p6 = &i;//正确,void*可存放任意类型
定义多个变量:
int* p1,p2;//p1是int型指针,p2是int型变量。
4.指向指针的指针(即多级指针)
int i = 1024;
int *pa = &i;//pa指向int型的数
int **pb = &pa;//pb指向int型指针pa
同理访问多级指针的对象需要多级解引用。
cout<<i<<"\n"
<<*pa<<"\n"
<<**pb<<"\n"<<endl;//多次解引用
/*输出的都是i的值1024*/
5.指向指针的引用
首先明确:引用不是一个对象,不存在指向引用的指针;而指针是对象,存在指向指针的引用。
int i = 42;
int *p;
int *&r = p;//r是对指针p的引用
r = &i;//给r赋值就是令p指向i的地址
*r = 0;//r解引用也是对p解引用,为i赋值为0
如何理解 r 呢?
从右向左阅读 r 的定义:
离 r 最近的符号 & 对变量影像最直接,因此 r 是一个引用无疑;
再往左的其余部分用于确定 r 引用的类型,这里引用的是一个int型指针;
因此 r 是一个指向int型指针 p 的引用。