2011-04-28 94 views
4

我有下面的代码,我希望输出为:充分认识前缀增量(++)操作

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

(++counter)*(++counter)是因为一个变量而没有一个顺序点改性两次用C实际上未定义行为(即;)之间。结果可能因不同编译器而异。有些人可能选择使用格式化硬盘,但幸运的是,您的编译器没有。

除此之外,关于前缀增量的理解很少。 bar(++i)简写为

i += 1; 
bar(i); 
+0

+1对于过于迂腐的编译器。 – Thomas 2013-06-14 07:47:17

0

前缀增量意味着增量在剩下的操作之前完成。据我所知,官方要求是++计数器的评估不是原始数值。

很可能被扩展为一个单位中的语句之前,像这样:

counter = counter + 1; 
counter = counter + 1; 
printf("foo(%d) -- %d\n", counter, ((counter)*(counter))); 

这将创建你所看到的行为。我的建议是避免压力测试这些角落案例太多。

13

一旦您对变量使用++ - 前缀或后缀,您将无法在同一个变量上再次使用它,直到在下一个sequence point之后。如果你这样做,代码的行为是不确定的 - 编译器可以做任何想要的东西

代码中两个(++counter)表达式之间没有顺序点,所以你违反了这条规则。你必须写这样的事情,而不是:

while (counter < 5) { 
    printf("foo(%d) -- %d\n", counter, (counter+1) * (counter+2)); 
    counter += 2; 
} 
+3

很好的解释。 – 2011-04-28 00:31:13

0

你期望它做

++ C = 1 * + C = 2

= 1 * 2 = 2

什么是实际发生的事情是

+ C = 2 * + C = 2

= 4

正如其他人指出的 - 这是未定义的行为。编译器不需要透露它的内部工作,除非你强迫它通过将复杂的语句分解成更小的片断