int i=-1;
int a=65;
int b=a*i + ++i;
b的值是多少?这里 =,+ 的结合性是从左到右,*,前缀增量 (++) 的结合性是从右到左。
那么对于 int b=a*i + ++i; 我应该考虑什么评估顺序?
左到右?右到左?为什么?
int i=-1;
int a=65;
int b=a*i + ++i;
b的值是多少?这里 =,+ 的结合性是从左到右,*,前缀增量 (++) 的结合性是从右到左。
那么对于 int b=a*i + ++i; 我应该考虑什么评估顺序?
左到右?右到左?为什么?
不要考虑关联性。考虑评估顺序,不幸的是在这种情况下它是未定义的。
在表达式中
int b=a*i + ++i;
您正在修改i
以及在调用未定义行为的同一表达式中使用它。
C99 指出:
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值。
此外,我建议您阅读c-faq: Q 3.8。
在这里您应该考虑运算符的优先级。这里表达式是根据运算符的优先级求解的,因此一次只应用一个关联性。
关联性出现在画面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
和评估首先按优先级排序,并且在按关联性排序的范围内排序。
有两件事关联性和优先级。
首先检查优先级,然后检查关联性。
在你的表达式中 int b=a*i + ++i;
++ 比 + 和 * 具有更高的优先级,因此将评估第一个 ++。在 + 和 * 之后,* 具有更高的优先级,因此 * 被评估。在最后 + 被评估。
这也是hacks建议的情况,您不应该修改和使用同一表达式中的值。(不是一个好习惯)