-
22-10-2019 - |
题
为什么以下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;
}
解决方案
*f2 += *f2 += a += 2.5;
这条线有 不确定的行为 因为您改变了价值 *f2
(IE a
)不止一次在同一表达式中没有中间序列点。 UB意味着您的程序可能会打印“ Hello World”,它可能会崩溃,可能会打印 12 12 12
或者 12 12 1029
或者它可能开始吃你的大脑。不要依靠不确定的行为。
引用C ++标准(我知道这个问题是标记C,但我没有C标准,我知道C中相同的规则在C中都有)
除了指出,未指定的单个运算符的操作数和单个表达式的子表达的顺序,以及在上一个序列上的副作用的顺序。53)在上一个序列和下一个序列点之间,标量对象应修改其存储的值最多一次通过评估表达式。此外,应仅访问先验值以确定要存储的值。本段的要求应满足完整表达的子表达式的每个允许排序;否则行为是 不明确的.
其他提示
它为所有人打印出相同的值,因为您只指向一个 int
多变的: a
.
它打印出来 12
因为 a + 2.5 = 4
(a
是一个 int
),然后将其添加到两次。
@DownVoters:为什么如此负面?我认为我的答案说什么 这个编译器 正在做 此示例代码, ,这应该有助于OP理解行为。我同意 Armen Tsirunyan的答案是正确的(即应该得到tick),并且 行为是根据标准不确定的. 。但是已经实施了标准,我还没有看到编译器的编译器,然后在运行时突然投掷双手说道 Undefined behaviour!
.
我是因为 *f2
和 *f1
指向 a
(整数)。
所以 *f2 = &a = 2
和 *f1 = &a = 2
此时,您将其添加到 2.5
(因为 a
是整数,您将获得 4
).
比你拥有的
a = 4
f2 = 4
f1 = 4
在这一点上 f2+f1+a = 12.
不隶属于 StackOverflow