C中的表达评估

时间:2011-07-23 17:24:44

标签: c undefined-behavior expression-evaluation

为什么下面的C代码会打印12 12 12

int main(int argc, char const *argv[]) {
  int a = 2, *f1, *f2;
  f1 = f2 = &a;
  *f2 += *f2 += a += 2.5;
  printf("%i %i %i\n", a, *f1, *f2);
  return 0;
}

3 个答案:

答案 0 :(得分:11)

*f2 += *f2 += a += 2.5;

这一行有Undefined Behavior因为您在同一个表达式中多次更改*f2(即a)的值而没有插入序列点。 UB意味着您的程序可能会打印“Hello World”,它可能会崩溃,可能会打印12 12 1212 12 1029或者它可能会开始吃掉你的大脑。不要依赖未定义的行为。

引用C ++标准(我知道这个问题标记为C,但我没有C标准,我知道同样的规则在C中存在)

  

除非另有说明,否则单个操作员的操作数和个体的子表达式的评估顺序   表达式和副作用发生的顺序是未指定的.5)之前的表达式   和下一个序列点标量对象的评估值最多只能修改一次   一个表达。此外,只能访问先前值以确定要存储的值。   对于完整的子表达式的每个允许排序,应满足本段的要求   表达;否则行为 未定义

答案 1 :(得分:1)

它会为所有人打印相同的值,因为您只指向一个int变量:a

打印出12,因为a + 2.5 = 4aint),然后将其添加到自身两次。


@Downvoters:为什么这么消极?我想我的答案说明这个编译器正在这个示例代码上做什么,这应该有助于OP了解行为。我同意Armen Tsirunyan的回答是正确的(即应该得到勾号)和behaviour is undefined according to the standard。但是标准已经实现了,我还没有看到编译器编译代码,然后在运行时突然抛出它并说Undefined behaviour!

答案 2 :(得分:1)

我因为*f2*f1指向a(整数)。

所以*f2 = &a = 2*f1 = &a = 2

此时您添加了2.5的值(因为a是一个整数,您将获得4)。

比你有

a = 4
f2 = 4
f1 = 4

此时您执行f2+f1+a = 12.