2013-06-03 91 views
0

在我看来,那为什么在for循环中“++ i”和“i ++”有什么区别?

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

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

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

+1

在这种情况下,他们做同样的事情。在功能和性能上都是如此。对于用户定义的类型,它们可能会有所不同,在这些类型中,你重载'operator ++()'和'operator ++(int)',但是如果你这样做并且它们的行为不同(在循环中),你会做错了。 –

+3

Scott Meyer在他的“Effective C++”中清楚地说明了这一点:++我增加了位置;我++创建一个临时的并递增。第一个是首选,除非编译器为你优化它,因为它可以让你不必创建临时文件。 – duffymo

+0

使Scott Meyers –

回答

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位数字进行(额外)复制。如果编译器能够“理解”发生了什么,它可能会删除该副本,但不一定会发生。

3

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

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

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

1

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

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

这将输出

5 

因为我的,如果测试期间为4,但5测试之后。

但不这样做。

+1

它可能输出5,或者它可能会邀请你的婆婆轮茶。你不能推断未定义行为的代码。 –

+1

垃圾。现在我必须保留这个答案,即使它只是为了维护这个评论而被低估。谢谢迈克。 :( – PaulProgrammer

2

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

至于哪一个更合乎逻辑肯定是一个值得商榷的问题。建议你带着你团队的风格或任何工作为你服务。

2

虽然++ii++有不同的功能,当你正在做的返回值考虑在内,在几乎所有情况下,编译器将优化i++++i为循环。

如果你不知道其中的差别是,++i增量什么,然后返回新i的价值,而i++递增,然后返回旧i值。前者是在技术上效率更高,因为您不必存储中间值,但总体而言,除非您尝试执行代码高尔夫并使用返回值,否则它们确实没有那么大的差别。

0

我的讲师不厌其烦在我的第一个学期来解释这种对类。从我记得我很确定,我很肯定它的来龙去脉,主要是与'返回'值,例如:

++我会增加我的价值,并返回增加的值,直到操作已完成,尽管i ++也会增加该值,但如果在操作期间调用该变量,它将返回未递增的值。

所以,如果你有这样的:

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

那么值将

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

(d这是因为C已经返回用的,而不是“后” ++通常的'pre'++)。

在循环中它使绝对没有区别,因为增量是在循环语句不是在它之后的操作。它将使差的唯一时间是

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

其中0值不会是印刷和5值会是这样,因为其增加了打印操作期间。

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

0

你的情况是一样的,因为你的表达式的返回值没有被使用。

相关问题