C++ “为什么有什么区别?”++;我";及;i++&引用;在一个循环中?

C++ “为什么有什么区别?”++;我";及;i++&引用;在一个循环中?,c++,c,post-increment,pre-increment,C++,C,Post Increment,Pre Increment,在我看来 for(int i = 0; i < 2; i++) for(int i=0;i

在我看来

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

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

不应该做同样的事情。对于第二个例子,从循环开始,我就应该等于1,这对我来说更符合逻辑。

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

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


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

在您的上下文中,这是相同的。
++i
i++
之间的区别在于操作顺序。如果您是一个疯狂邪恶的C程序员,您可能会编写如下代码:

int i = 3;
if( ++i++ == 4 ) 
    printf( "%d\n", i);
哪个会输出

5
因为在if测试中我会是4岁,但在测试之后我会是5岁

但不要这样做。

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


至于哪一个更符合逻辑,当然是一个有争议的问题。建议您使用团队的风格或任何适合您的工作。

尽管在考虑返回值时,
++i
i++
具有不同的功能,但在几乎所有情况下,编译器都会针对for循环将
i++
优化为
++i


如果您不知道区别是什么,
++i
递增然后返回新的
i
的值,而
i++
递增然后返回旧的
i
的值。前者在技术上效率更高,因为您不必存储中间值,但总体而言,它们没有太大差异,除非您尝试编写代码并同时使用返回值。

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

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


如果我们有一个“复杂”类型,比如一个带有
操作符++(int)
的结构或类,以及
opterator++()
,可能会有一个小的差异[或者在极端情况下,有一个大的差异],因为必须复制对象。假设我们有一个
bigmath
类,我们的
i
是一个1000位长的值。现在我们必须在增量的中间做一个(1000)个数字的拷贝。如果编译器能够“理解”发生的事情,它可能会删除该副本,但它不能保证发生

在我的第一学期,我的讲师煞费苦心地向全班同学解释了这一点。据我回忆,我很确定它的来龙去脉主要与“return”值有关,例如:

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

如果你有这个:

a = 1;
b = ++a;
c = 10;
d = c++;
那么这些值将是

a = 2
b = 2
c = 11
d = 10
(d)这是因为c返回的是'post'++'而不是通常的'pre'++'

在循环中,它完全没有区别,因为增量在循环语句中,而不是在其后的操作中。唯一能起作用的是

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

for(i=0;i在您的情况下是相同的,因为没有使用表达式的返回值。

在此上下文中,它们做完全相同的事情。从功能和性能角度来看。对于重载
operator++()
operator++(int)的用户定义类型,它们可能不同
,但如果你这样做,而他们的行为(在循环中)不同,你就错了。Scott Meyer在他的“有效的C++”一书中非常清楚地说明了这一点:++i原地递增;i++创建一个临时值并递增。首选第一个,除非编译器为您优化它,因为这样可以避免您创建临时值。让Scott MeyersI假设每个编译器都能够优化此情况。它可能输出5,或者可能会邀请您的岳母来喝茶。您可以没有关于未定义行为的代码的理由。废话。现在我必须保留这个答案,即使它被否决,只是为了保留这个评论。谢谢迈克(
for(i = 0; i<5;)
    printf("%d ",++i);