把指针和引用放在一起说,不表示指针和引用很相似,难以区分,实际上他们的共同点非常少。指针和引用都跟内存中的某块地址绑定在一起。正是因为这个共同点,初学者常常把引用等同于指针。这是灾难性的。
(一)从概念上区分指针和引用
指针可以理解为一种特殊的数据对象。一般的变量值,是由一系列比特位表示的数字或字符。而指针的变量值,当然也是一个长整型数值,但这个长整型值有特殊的涵义,它表示内存块的地址。
如果是非const的指针,它的值是可以变化的。
引用是C++引入的概念,C里面没有。它是一个变量别名。怎么理解?引用初始化的时候,赋给该引用的地址,必须是用过的,即跟一个已知变量绑定的。也就是说,不能给赋给引用没使用过的内存,引用的值也不能为NULL。也就是说,至始至终,引用只是一个已知变量的别名。它不独立存在。在编译器的符号表中,变量本名和别名指向同一地址。
(二)指针和变量的行为差别很大
理解了指针和引用的概念,也就不难理解以下它们的差别。
指针定义的时候不必初始化,可以是NULL值。引用则都不可以。
指针的值是可变的。引用一经初始化,它的值是不可更改的。注意,一旦定义了一个引用,访问它和访问变量名本身的方式和效果是一致的。这是理解引用的关键。如:
int x = 0; int& a = x;
执行a++,x和a的值都是1。执行x++效果是一样的。
如果定义 int y = 0; 并让 a = y; 效果是a和x的值变成0,并不是引用a跟变量y的地址绑定。同样的规则对类,结构和数组都适用。
相应的,如果定义了一个指针p,执行p++,其涵义完全不同。C++对指针的自增运算符做了重载。
常量指针和指向常量的指针都是C++支持的。由于引用生来就是常量,所以不存在常量引用的说法。但是绑定到常量的引用是有意义的。
引用的大小由对应的对象大小决定。指针的大小由操作系统的位数来决定。32位操作系统一般4个字节。64位操作系统一般是8个字节。
引用是类型安全的,而指针不是。后面有会一章专门来介绍指针。
(三)为什么要引入引用的概念?
没有引入引用之前,C中的函数调用,如果要保存更改到输入参数,只能通过指针来实现。这样做,有两个劣势。其一,不够直观。其二,涉及到对象传递,效率低下。下面结合一个引用的例子,来说明引用作为地址参数传递,是如何克服这两缺点的。试看:
#include
using namespace std;
void exchange(int& x,int& y){
int temp = x;
x = y;
y = temp;
}
int main(){
int x=1,y=2;
exchange(x,y);
cout << x='<< x <