我有以下代码,我希望输出为:
foo(0) -- 2 /* 1*2 */
foo(2) -- 12 /* 3*4 */
foo(4) -- 30 /* 5*6 */
但我已经
了foo(2) -- 4
foo(4) -- 16
foo(6) -- 36
代替。有人可以向我解释发生了什么吗?
include <stdio.h>
int main()
{
int counter; /* counter for loop */
counter = 0;
while (counter < 5)
printf("foo(%d) -- %d\n", counter, ((++counter)*(++counter)));
return (0);
}
答案 0 :(得分:13)
在变量上使用++
- 前缀或后缀 - 后,在下一个sequence point之后才能再次对同一变量使用它。如果这样做,代码的行为是未定义的 - 允许编译器执行它想要的任何内容。
代码中的两个(++counter)
表达式之间没有序列点,因此您违反了此规则。你必须写这样的东西,而不是:
while (counter < 5) {
printf("foo(%d) -- %d\n", counter, (counter+1) * (counter+2));
counter += 2;
}
答案 1 :(得分:4)
(++counter)*(++counter)
实际上是C中的未定义行为,因为变量被修改两次而中间没有序列点(即;
)。结果可能因不同的编译器而异。有些人可能选择加入格式化硬盘,但幸运的是你的编译器没有。
除此之外,关于前缀增量几乎没有被理解。 bar(++i)
是
i += 1;
bar(i);
答案 2 :(得分:0)
前缀增量表示增量在其余操作之前完成。据我所知,官方要求是++计数器的评估不是原始值。
它很可能在声明之前作为增量扩展,如下所示:
counter = counter + 1;
counter = counter + 1;
printf("foo(%d) -- %d\n", counter, ((counter)*(counter)));
这将创建您所看到的行为。我的建议是避免过多地对这些角落情况进行压力测试。
答案 3 :(得分:0)
你期待着它
++ c = 1 * ++ c = 2
= 1 * 2 = 2
实际发生的是
++ c = 2 * ++ c = 2
= 4
正如其他人所指出的那样 - 这是未定义的行为。除非你通过将复杂的语句分解成更小的部分来强制它,否则编译器不需要显示它的内部工作