第二章 变量和基础
2.3 复合类型
2.3.1 引用
2.3.2 指针
作为一种复合类型,与引用相似,指针实现了对其他对象的间接访问:
指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。
指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。
2.3.2.1 定义指针类型*
定义指针类型的方法将声明符写成*d
的形式,其中d
是变量名。如果在一个语句中定义了几个指针变量,每个变量面前都必须有符号*
:
int *ip1,*ip2;
double dp,*dp2;
2.3.2.2 获取对象的地址&
指针存放某个对象的地址,要想获取该地址,需要使用取地址符(操作符&)。
int *ip1, *ip2; // ip1和ip2是指向int型对象的指针
double dp, *dp2; // dp2是指向double型对象的指针,dp是double型对象
在声明语句中,指针的类型实际上被用于指定它所指向的对象的类型,所以二者必须匹配。如果指针指向了一个其他类型的对象,对该对象的操作将发生错误。
2.3.2.3指针值
指针的值(即地址)应属下列4种状态之一:
指向一个对象。
指向紧邻对象所占空间的下一个位置。
空指针,意味着指针没有指向任何对象。
无效指针,是除上述情况的其他值。试图拷贝或以其他方式访问无效指针的值都将引发错误,编译器并不负责检查此类错误。
尽管第2种和第3种形式的指针是有效的,但显然这些指针没有指向任何具体对象,所以试图访问此类指针(假定的)对象的行为不被允许。
2.3.2.4 利用指针访问对象
如果指针指向了一个对象,则允许使用 解引用符(操作符*
)来访问该对象。
int ival = 42;
int *p = &ival; // p存放着变量ival的地址,或者说p是指向变量ival的指针
cout << *p;
对指针解引用会得出所指的对象,因此如果给解引用的结果赋值,实际上也就是给指针所指的对象赋值:
*p = 0;
cout << * p
【注意】解引用操作仅适用于那些确实指向了某个对象的有效指针。
像&
和*
,既能作表达式里的运算符,也能作为声明的一部分出现,符号的上下文决定了符号的意义:
int i = 42;
int &r = i; // &紧随类型名出现,因此是声明的一部分,r是一个引用
int *p; // *紧随着类型名出现,因此是声明的一部分,p是一个指针
p = &i; // &出现在表达式中,是一个取地址符
*p = i; // *出现在表达式中,是一个解引用符
int &r2 = *p; // &是声明的一部分,*是一个解引用符
在声明语句中,&
和*
用于组成复合类型;在表达式中,它们的角色又转变为运算符。
2.3.2.5 空指针
空指针(null pointer)不指向任何对象,在试图使用一个指针之前代码可以首先检查它是否为空。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。