后缀运算符(如.
和->
组件选择运算符)的优先级高于一元*
和&
。因此,*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 *
; 有一层间接,所以我们需要在访问成员之前取消引用。 我们可以通过使用运算符(隐式地引用)来做到这一点,或者我们可以显式地取消引用自己并编写. test1
ptr
->
test1
test1
(*test1).ptr
(*test2)->ptr
- 子表达式test2
的类型为nodeT **
; 有两个间接级别,所以我们需要取消引用test2
两次才能访问该ptr
成员。如果我们想使用->
操作符,我们需要显式地取消引用它一次,或者我们取消引用它两次以使用.
操作符 - (**test2).ptr
。
.
如果左侧操作数是struct
orunion
类型,例如example
or(*test1)
或,则使用组件选择运算符(**test2)
。->
如果左侧操作数是指向astruct
或union
类型的指针,例如test1
or ,则使用运算符(*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