5
int i=-1;
int a=65;
int b=a*i + ++i;

b的值是多少?这里 =,+ 的结合性是从左到右,*,前缀增量 (++) 的结合性是从右到左。

那么对于 int b=a*i + ++i; 我应该考虑什么评估顺序?

左到右?右到左?为什么?

4

3 回答 3

5

不要考虑关联性。考虑评估顺序,不幸的是在这种情况下它是未定义的。
在表达式中

int b=a*i + ++i;   

您正在修改i以及在调用未定义行为的同一表达式中使用它。

C99 指出:

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值

此外,我建议您阅读c-faq: Q 3.8

于 2014-03-19T17:02:58.520 回答
2

在这里您应该考虑运算符的优先级。这里表达式是根据运算符的优先级求解的,因此一次只应用一个关联性。
关联性出现在画面when the operator has same precedence中,在这种情况下,关联性将是相同的。
在您的问题b=a*i + ++i i中使用了两次结果undefined behavoiur

否则它将被评估为,
++ 后跟 * 然后 + operation according to precedence。如果遵循这一点,答案将是,

b=a*i + ++i
b=65*i + 0
b=65*0 + 0
b=0 + 0
b=0

但是编译器可以使用 i 的存储值而不是使用 ++i 之后的值,

b=a*i + ++i
b=a*-1 + 0
b=-65 + 0
b=-65

这会导致未定义的行为,因为 b 可以是 0 或 -65。而且您还可以看到,associativity doesn't create problem while evaluating因为operators with same precedence will have same associativity和评估首先按优先级排序,并且在按关联性排序的范围内排序。

于 2014-03-19T17:04:28.897 回答
-1

有两件事关联性和优先级。

首先检查优先级,然后检查关联性。

在你的表达式中 int b=a*i + ++i;

++ 比 + 和 * 具有更高的优先级,因此将评估第一个 ++。在 + 和 * 之后,* 具有更高的优先级,因此 * 被评估。在最后 + 被评估。

这也是hacks建议的情况,您不应该修改和使用同一表达式中的值。(不是一个好习惯)

于 2014-03-19T17:23:23.157 回答