完全理解前缀增量(++)操作

时间:2011-04-28 00:21:39

标签: c

我有以下代码,我希望输出为:

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);
}

4 个答案:

答案 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

正如其他人所指出的那样 - 这是未定义的行为。除非你通过将复杂的语句分解成更小的部分来强制它,否则编译器不需要显示它的内部工作