为什么在for循环中“++ i”和“i ++”之间有什么区别?

时间:2013-06-03 23:19:08

标签: c++ c post-increment pre-increment

在我看来

for(int i = 0; i < 2; i++)

for(int i = 0; i < 2; ++i)

不应该做同样的事情。对于第二个例子,对我来说,更自然的是,自循环开始以来我应该等于1。

7 个答案:

答案 0 :(得分:4)

在一些处理器上,例如PDP-11,VAX-11和68K,某些指令的模式相当于*ptr++*--ptr。根据编写代码的确切方式,编译器可能或可能不容易使用这些指令 - 因此,使用*++ptr*ptr++的“正确”变体[这更好取决于关于循环内部实际循环中的用法,可以在这些特定情况下在性能上产生相当大的差异。然而,对于ARM和x86(我认为,PowerPC和MIPS,因此覆盖了几乎所有现代处理器),这种类型的构造无论如何都不是指令集的一部分,并且编译器现在比它们更加聪明,比如说,10年或20年前。

任何合理的编译器都会对基本类型执行相同的操作,i++++i不是问题。

如果我们有一个“复杂”类型,例如带有operator++(int)opterator++()的结构或类,则可能会有一些小差异[或者在极端情况下,差异很大],因为必须复制对象。假设我们有一个bigmath类,我们的i是一个1000位长的值。现在我们必须在增量中间创建一个1000位数的(n额外)副本。如果编译器能够“理解”正在发生的事情,它可能会忽略该副本,但不能保证会发生。

答案 1 :(得分:3)

在我看来,他们应该做同样的事情。两者都具有递增i的效果。

唯一的区别是表达式的; i++给出增量前的值,++i给出增量后的值。但在这种情况下,该值被丢弃,表达式仅评估其副作用;所以代码的效果没有区别。

在某些情况下(如果i不是int,但某些用户定义类型的重载运算符太复杂,编译器无法理解),++i可能更有效。这是因为i++需要制作副本以返回旧值,而++i只需要返回对新值的引用。当然,一个足够疯狂的用户定义类型可能会使两个重载做完全不同的事情。但对于简单类型,那里也没有区别。

答案 2 :(得分:2)

在您的示例中:没有区别。如果该类型是用户定义的类型,则可能存在很大差异。

哪一个更合乎逻辑肯定是一个值得商榷的问题。建议你选择你的团队风格或适合你的工作。

答案 3 :(得分:2)

虽然++ii++在考虑返回值时具有不同的功能,但在几乎所有情况下,编译器都会将i++优化为++i for for loops。

如果您不知道++i递增的区别是什么,然后返回新i的值,而i++递增,然后返回旧值{ {1}}。前者在技术上更有效率,因为你不需要存储一个中间值,但总的来说,除非你尝试编码高尔夫并使用返回值,否则它们确实没有那么大的差别价值观也是如此。

答案 4 :(得分:1)

在你的背景下,它是一样的。 ++ii++之间的差异是操作顺序。如果你是一个疯狂的邪恶C程序员,你可能会编写这样的代码:

int i = 3;
if( ++i++ == 4 ) 
    printf( "%d\n", i);

将输出

5

因为在测试期间我会是4,但是在测试之后我会是5。

但不要这样做。

答案 5 :(得分:0)

我的讲师在第一学期努力向全班解释这个问题。从我记得我很确定它的来龙去断主要与'返回'值有关,例如:

++我将递增i的值,并返回递增的值,直到操作完成,而尽管i ++也将递增值,如果在操作期间调用该变量,它将返回un-递增的值。

所以,如果你有这个:

a = 1;
b = ++a;
c = 10;
d = c++;

那么值将是

a = 2
b = 2
c = 11
d = 10

(这是因为c已经使用'post'++'返回,而不是通常的'pre'++'。

在一个循环中它完全没有区别,因为增量是在循环语句中而不是在它之后的操作中。它唯一会产生影响的是

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

其中0值不会被打印,而5值将是,因为它在打印操作期间递增。

清除泥e ??不要问我为什么这个被编程到C!在我看来,它似乎是多余的,并且很少会出现任何需要它的程序,可以通过一行额外的代码改变另一个变量中的值来解决问题!

答案 6 :(得分:0)

在你的情况下它是相同的,因为你的表达式的返回值没有被使用。