Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的表达式求值_C_Undefined Behavior_Expression Evaluation - Fatal编程技术网

C语言中的表达式求值

C语言中的表达式求值,c,undefined-behavior,expression-evaluation,C,Undefined Behavior,Expression Evaluation,为什么下面的C代码打印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; } 由于在同一表达式中多次更改了*f2(即a)的值,且没有插入序列点,因此此行具有错误。UB意味着您的程序可能会打印“Hello World”,可能会崩

为什么下面的C代码打印
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;
}
由于在同一表达式中多次更改了
*f2
(即
a
)的值,且没有插入序列点,因此此行具有错误。UB意味着您的程序可能会打印“Hello World”,可能会崩溃,可能会打印
12 12
12 12 1029
,也可能会开始吞噬您的大脑。不要依赖未定义的行为

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

除非另有说明,单个运算符的操作数和单个运算符的子表达式的求值顺序 表达式以及副作用发生的顺序未指定。53 下一个序列点,一个标量对象的存储值应通过计算最多修改一次 一种表达方式。此外,只有在确定要存储的值时,才能访问先前的值。 完整表达式子表达式的每个允许顺序应满足本段的要求 表达方式;否则,行为是未定义的


它为所有变量输出相同的值,因为您只指向一个
int
变量:
a

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



@下层选民:为什么如此消极?我想我的答案说明了这个编译器在这个示例代码上做了什么,这应该有助于OP理解其行为。我同意他的答案是正确的(即应该打勾),而且答案是正确的。但是标准已经实现了,我还没有看到编译器编译代码,然后在运行时突然举手说
未定义的行为*f2
*f1
指向
a
(一个整数)

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

此时,将
2.5
的值添加到a中(因为
a
是一个整数,所以将获得
4

比你有

a = 4
f2 = 4
f1 = 4

在这一点上,你做了f2+f1+a=12。

真正的问题是你为什么要这样写代码?面试问题:p,也会加上这个标签。可悲的是,他们问这样的问题让我很恼火。至少本周这个无用的UB问题有一点多样性…我希望他们问这个问题的目的是让你回答代码有未定义的行为,即使没有,它也令人反感地混淆,永远不应该被编写…我同意,但我无能为力,也没有所谓的“未定义行为”选项,这是未定义的行为,实际上,根据标准,是的。我只是说这个例子似乎在做什么。我同意OP需要理解这是一种未定义的行为。这是一种未定义的行为,事实上,你能解释一下投票失败的原因吗?我没有投你反对票,但我真的会投你反对票,因为你在这篇文章上的傲慢态度。用“事实上你错了,这是你的错”来评论有效的答案,这值得自我批评一下。尤其是当你真的没有回答这个问题时,彼得回答了,你只是引用了一个标准,称之为“魔法”@SomeoneRandom:我确实回答了这个问题。彼得刚才猜到了。我希望有一天你会明白语言是它的标准,而不是别的。同时,请随意投票否决我你的答案是“我不知道,它是随机的,可能是任何东西”这根本不是真的,每次都会产生相同的结果。是的,语言是由它的标准来定义的,但是他没有问任何关于这一点的问题,他想要解释为什么它产生了它所做的事情。因此,你没有回答这个问题。@SomeoneRandom:“我不知道,它是随机的,它可能是任何东西”是正确的答案。“每次都会产生相同的结果”不是真的。例如,违反我在回答中引用的规则的表达式的结果通常根据优化级别而有所不同。
a = 4
f2 = 4
f1 = 4