来自K& R的The C Programming Language第123页
(p ++) - > x在访问x后递增p。 (最后一组括号是不必要的。为什么?)
为什么没有必要考虑->
比++
更强大?
编辑:将给定的表达式与++p->x
进行对比,后者评估为++(p->x)
,它将增加x
,而不是p
。所以在这种情况下,括号是是必要的,如果我们想要增加(++p)->x
,我们必须写p
。
答案 0 :(得分:5)
唯一可能的解释是:
p++(->x)
这并不意味着什么。它甚至都没有效。 唯一以有效方式解释此问题的方法是(p++)->x
。
答案 1 :(得分:4)
正是因为->
比。 (它没有,谢谢@KerrekSB。)++
绑定更强大的
在访问x后增加p 。
首先,您访问x
的{{1}},然后增加p
。这完全符合p
和->
运算符的评估顺序。
编辑:哇,这些编辑......
那么当你写+
时会发生什么呢?可以解释为++p->x
或++(p->x)
(实际选择哪一个只是一个语言设计问题,K& R认为在第一种情况下进行评估是个好主意。问题在于(++p)->x
的情况下不存在这种歧义,因为它只能被解释为p++->x
。其他替代方案(p++)->x
,p(++->x)
和p(++->)x
实际上只是语法错误的“表达式”。
答案 2 :(得分:3)
最大咀嚼策略表示p++->x
分为以下预处理令牌:
p
然后++
然后->
然后x
在p++->x
表达式中,有两个运算符,postfix ++
运算符和postifx ->
运算符。两个运算符都是后缀运算符,它们具有相同的优先级,并且在解析表达式时没有歧义。 p++->x
相当于(p++)->x
。
对于++p->x
表达式,情况不同。
在++p->x
中,++
不是后缀运算符,而是++
一元运算符。 C为后缀运算符提供了比所有一元运算符更高的优先级,这就是++p->x
实际上等同于++(p->x)
的原因。
编辑:由于史蒂夫的评论,我改变了答案的第一部分。
答案 3 :(得分:2)
后增量和成员访问运算符都是后缀表达式并绑定它们。考虑到它们适用于左侧的主要或后缀表达式,不会有歧义。
在
p++->x
postfix - ++运算符只能应用于它左边的表达式(即p
)。
类似地 - > x只能访问其左侧的表达式,即p++
。不需要将该表达式写为(p++)
,但也没有任何伤害。
在效果描述中的“之后”,不表示增量和成员访问的时间顺序。它仅表示p++
的结果是增量前的值p
,并且该值是用于成员访问的值。
答案 4 :(得分:1)
表达式p++
会生成一个值为p
的指针。稍后,执行++
部分,但出于解释表达式的目的,它可能也不存在。 ->x
使编译器将成员x
的偏移量添加到p
中的原始地址并访问该值。
如果您将语句更改为:
p->x; p++;
它会做同样的事情。
优先顺序实际上完全相同,可以看作here - 但它并不重要。