第二章 变量和基础

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种状态之一:

  1. 指向一个对象。

  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)不指向任何对象,在试图使用一个指针之前代码可以首先检查它是否为空。


黄奋斗
163 声望19 粉丝