1.指针是变量的地址,引用是变量的别名。
指针本身也是一个变量,指针的值是另一个变量的内存地址,指针指向这个变量,指针和指针指向的变量是两个不同的变量。引用是给变量起了一个别名,可以认为引用于原变量是同一个变量,只是这个变量有两个不同的名字。
(1)sizeof运算符的意义不同,指针进行sizeof得到的是指针本身占用的空间,返回结果为4个字节;而引用进行sizeof得到的是原变量占用的空间,返回结果取决于原变量的数据类型。
(2)自增++运算符的意义不同,指针进行自增运算是对指针本身自增,使指针指向下一个地址空间,指针指向的变量没有改变;引用进行自增运算是对原变量的自增,改变原变量的值。这种性质可以扩展到其他操作符上。
2.指针是可以不被初始化,引用必须初始化。
指针在定义时可以不被初始化,此时指针的值是一个随机的内存地址;引用在定义时必须初始化,从而绑定某个变量,成为该变量的别名。
3.指针本身可以被修改,引用本身不能被修改。
指针在使用过程中可以修改指针的值,使指针指向不同的内存地址;引用在其生命周期内永远是初始化中变量的别名,不能修改引用本身让其成为另一个变量的别名。
4.指针可以为NULL(0),引用不能为NULL。
指针可以初始化或赋值为空,此时指针不指向任何内存地址,称为空指针;引用不能初始化为空,不存在空引用的概念。
5.指针可以定义为二重指针(**a),引用不能定义二重引用。
指针在使用时可以定义为二重指针(**a),称为指向指针的指针,表示指针指向的变量也是一个指针;引用在使用时不能定义二重引用(&&a),因为引用只是一个变量的别名,二重引用没有任何实际意义。
6.指针需要先解引用,引用直接使用。
指针本身的值是内存地址,想要操作指针指向的变量需要使用解引用操作符;引用作为变量的别名直接使用就相当于操作引用绑定的变量。
代码:
int main(int argc, char* argv[])
{
int a = 10,b=20;
int &r = a;
int *p = &a;
int * &rp = p;
if ((int)&r == (int)&a)
{
cout << "&r == &a"<<endl;//zq
}
else
{
cout << "&r != &a"<<endl;
}
if ((int)&p == (int)&a)
{
cout << "&p == &a"<<endl;
}
else
{
cout << "&p != &a"<<endl;//zq
}
r = b;
cout << "a = "<<a<<endl;//20
cout << "b= "<<b<<endl;//20
(*p)++;
(*rp)++;
cout << "a = "<<a<<endl;//22
cout << "b= "<<b<<endl;//20
getchar();
return 0;
}