和上一节的引用类似,指针(pointer)是“指向(point to)”另外一种类型的复合类型。与引用类似,指针也实现了对其他对象的间接访问。然后指针和引用相比有许多不同。其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。其二,指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。
因为引用不是对象,没有实际地址,所以不能定义指向引用的指针。
指针的值(即地址)应属下列4种状态之一:
1)指向一个对象
2)指向紧邻对象所占空间的下一个位置
3)空指针,意味着指针没有指定任何对象
4)无效指针,也就是上述情况之外的其他值
试图拷贝或以其他方式访问无效指针的值都将引发错误。编译器并不负责检查此类错误,这一点和试图使用未经初始化的变量是一样的。访问无效指针的后果无法预计,因此程序员必须清楚任意给定的指针是否有效。因此解引用符也只适用于那些确实指向了某个对象的有效指针。
所谓的解引用符就是使用操作符*来访问指针指向的对象。
int ival= 42;
int *p= &ival; // p存放着变量ival的地址,或者说p是指向变量ival的指针
cout<<*p; // 由符号*得到指针p所指的对象,输出42
*p= 0; // 由符号*得到指针p所指的对象,即可经由p为变量ival赋值
cout<<*p; // 输出0
取地址符(&)和解引用符(*)的多重含义:
int i= 42;
int &r= i; // &紧随类型名出现,因此是声明的一部分,r是一个引用
int *p; // *紧随类型名出现,因此是声明的一部分,p是一个指针
p= &i; // &出现在表达式中,是一个取地址符
*p= i; // *出现在表达式中,是一个解引用符
int &r2= *p; // &是声明的一部分,*是一个解引用符
空指针(null pointer)不指向任何对象,在试图使用一个指针之前代码可以检查它是否为空。下面有3种生成空指针的方式:
// 需要首先#include cstdlib
inht *p1=NULL;
过去的程序会用到一个名为NULL的预处理变量(preprocessor variable)来给指针赋值,这个变量在头文件cstdlib中定义,它的值就是0。
int *p2= 0;
直接将p2初始化为字面常量0
int *p3= nullptr;
这是C++11新标准所引入的一种方法。
需要注意的是不能将int变量直接赋值给指针,即便int变量的值恰好等于0也不行。
void*是一种特殊的指针类型,可用于存放任意对象的地址。
但是不能直接操作void*指针,因为我们并不知道这个对象到底是什么类型,也就无法确定能在这个对象上做哪些操作。
原文地址:http://blog.csdn.net/nomasp/article/details/45890361