下面的for循环产生相同的结果,尽管一个使用后增量,另一个使用前增量。

代码如下:

for(i=0; i<5; i++) {
    printf("%d", i);
}

for(i=0; i<5; ++i) {
    printf("%d", i);
}

我得到了两个for循环相同的输出。我遗漏了什么吗?


当前回答

是的,你会得到完全相同的输出。为什么你认为他们应该给你不同的产出?

在这样的情况下,增量后或增量前很重要:

int j = ++i;
int k = i++;
f(i++);
g(++i);

你可以通过赋值或传递参数来提供一些值。你在for循环中两者都不做。它只会递增。后-和前-在那里没有意义!

其他回答

你可以在这里阅读谷歌的答案: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Preincrement_and_Predecrement

重点是,对于简单对象没有区别,但是对于迭代器和其他模板对象你应该使用预增量。

编辑:

这两者没有区别,因为您使用的是简单类型,所以没有副作用,而后增量或前增量在循环体之后执行,所以对循环体中的值没有影响。

你可以用这样一个循环检查它:

for (int i = 0; i < 5; cout << "we still not incremented here: " << i << endl, i++)
{
    cout << "inside loop body: " << i << endl;
}

for构造中的第三条语句只被执行,但它的求值被丢弃而不被处理。 当评估值被丢弃时,前后增量相等。 只有当它们的价值被取走时,它们才会有所不同。

因为在任何一种情况下,增量都是在循环体之后完成的,因此不会影响循环的任何计算。如果编译器是愚蠢的,使用后增量可能会稍微降低效率(因为通常它需要保留一个预值的副本以供以后使用),但我希望在这种情况下优化消除任何差异。

考虑for循环是如何实现的可能会很方便,本质上是转换为一组赋值、测试和分支指令。在伪代码中,预增量看起来像这样:

      set i = 0
test: if i >= 5 goto done
      call printf,"%d",i
      set i = i + 1
      goto test
done: nop

后增量至少会有另一个步骤,但它将是微不足道的优化

      set i = 0
test: if i >= 5 goto done
      call printf,"%d",i
      set j = i   // store value of i for later increment
      set i = j + 1  // oops, we're incrementing right-away
      goto test
done: nop

在计算i++或++i之后,i的新值在这两种情况下是相同的。前增量和后增量之间的区别在于表达式本身的求值结果。

++i增加i并计算为i的新值。

i++计算为I的旧值,并增加I。

这在for循环中无关紧要的原因是控制流大致是这样工作的:

测试条件 如果为假,终止 如果为真,则执行body 执行增量步骤

由于(1)和(4)是解耦的,可以使用前增量或后增量。

如果你这样写,那就很重要了:

for(i=0; i<5; i=j++) {
    printf("%d",i);
}

将比这样写的情况多迭代一次:

for(i=0; i<5; i=++j) {
    printf("%d",i);
}