后缀运算符(如.和->组件选择运算符)的优先级高于一元*和&。因此,*foo->bar将被解释为*(foo->bar);运算符*将应用于foo->bar. 同样,&bar.foo将被解释为&(bar.foo)。
因此,给定以下声明:
nodeT example;
nodeT *test1 = &example;
nodeT **test2 = &test1;
ptr您将按如下方式访问该成员:
example.ptr- 子表达式example的类型为nodeT; 不需要间接,因此我们只需使用.组件选择运算符;
test1->ptr- 子表达式test1的类型为nodeT *; 有一层间接,所以我们需要在访问成员之前取消引用。 我们可以通过使用运算符(隐式地引用)来做到这一点,或者我们可以显式地取消引用自己并编写. test1ptr->test1test1(*test1).ptr
(*test2)->ptr- 子表达式test2的类型为nodeT **; 有两个间接级别,所以我们需要取消引用test2 两次才能访问该ptr成员。如果我们想使用->操作符,我们需要显式地取消引用它一次,或者我们取消引用它两次以使用.操作符 - (**test2).ptr。
.如果左侧操作数是structorunion类型,例如exampleor(*test1)或,则使用组件选择运算符(**test2)。->如果左侧操作数是指向astruct或union类型的指针,例如test1or ,则使用运算符(*test2)。
现在为了真正的乐趣 -ptr成员有类型nodeT *,所以如果你想得到ptr那个example.ptr指向,你会写example.ptr->ptr。子表达式example具有 type nodeT,因此我们使用了.组件选择运算符。然而 subexpressionexample.ptr有 type nodeT *,所以我们需要使用->组件选择操作符。或者,我们必须写(*example.ptr).ptr(记住,*example.ptr被解析为*(example.ptr))。
更进一步,我们可以这样写example.ptr->ptr->ptr,或
(*(*example.ptr).ptr).ptr:
example.ptr
example.ptr->ptr
(*example.ptr).ptr
example.ptr->ptr->ptr
(*(*example.ptr).ptr).ptr
由于test已经是 type nodeT *,所以它更简单一些:
test1->ptr
(*test1).ptr
test1->ptr->ptr
(*(*test).ptr).ptr
test1->ptr->ptr->ptr
(*(*(*test1).ptr).ptr).ptr
最后,test2:
(*test2)->ptr
(**test2).ptr
(*test2)->ptr->ptr
(*(**test2).ptr).ptr
(*test2)->ptr->ptr->ptr
(*(*(**test2).ptr).ptr).ptr