间接寻址运算符和 address-of 运算符

一元间接寻址运算符 (*) 通过指针间接访问一个值。 操作数必须是指针类型。 操作的结果是操作数所寻址的值;即其操作数指向的地址处的值。 结果的类型是操作数寻址的类型。

如果操作数的类型为指向类型的指针,则间接寻址运算符的结果为类型 。 如果操作数指向函数,则结果是函数指示符。 如果指向对象,则结果为指定对象的左值。

如果指针值无效,则间接寻址运算符的结果不确定。 以下是使指针值无效的一些最常见条件:

  • 该指针为 null 指针。

  • 在引用过程中,该指针在对象生存期结束后指定其地址。 (例如,对象已超出范围或已解除分配。)

  • 该指针指定未针对所指向的对象类型正确对齐的地址。

  • 该指针指定执行程序未使用的地址。

一元 address-of 运算符 (&) 给出其操作数的地址 。 操作数必须是以下任意一个:

  • 一个 lvalue,指定未声明 register 且不是位字段的对象。

  • 一元取消引用 (*) 或数组取消引用 ([]) 运算符的结果。

  • 一个函数指示符。

操作数类型为 operand_type 时,结果的类型为指向 operand_type 的指针。

如果操作数是一元 * 运算符的结果,则不对两个运算符进行运算,并且结果像是同时省略了这两个运算符。 结果不是 lvalue,运算符约束仍适用。 如果操作数是 [] 运算符的结果,则不会对 & 运算符以及 [] 运算符暗含的一元 * 进行运算。 其结果与删除 & 运算符并将 [] 运算符更改为 + 运算符的效果相同。 否则,结果为指向对象或操作数指定的函数的指针。

示例

下面的示例使用这些常用声明:

int *pa, x;
int a[20];

此语句使用 address-of 运算符 (&) 来获取数组 a 的第六个元素的地址。 结果存储在指针变量 pa 中:

pa = &a[5];

间接寻址运算符 (*) 在此示例中用于访问存储在 pa 中的地址的 int 值。 将此值分配给整数变量 x

x = *pa;

此示例表明对 x 的地址应用间接运算符的结果与 x 相同:

assert( x == *&x );

此示例演示用于声明指向函数的指针的等效方法:

int roundup( void );     /* Function declaration */

int  *proundup  = roundup;
int  *pround  = &roundup;
assert( pround == proundup );

一旦声明函数 roundup,将声明并初始化指向 roundup 的两个指针。 第一个指针为 proundup,它仅通过函数名称进行初始化;第二个指针为 pround,它在初始化中使用 address-of 运算符。 初始化是等效的。

请参阅

间接寻址运算符:*
address-of 运算符:&