++i
和i++
的区别是什么?在for循环的增量块中应该使用哪个?++i
和i++
的区别是什么?在for循环的增量块中应该使用哪个?++i
将会增加i
的值,并返回增加后的值。
++i
将会增加i
的值,并返回增加后的值。
i = 1;
j = ++i;
(i is 2, j is 2)
i++
会将 i
的值加一,但会返回在自增之前 i
的原始值。
i = 1;
j = i++;
(i is 2, j is 1)
对于一个for
循环,两者都可以使用。 ++i
更常用,可能是因为它在K&R中被使用。
不管怎样,按照“比起i++
,更倾向于++i
”的指导方针就不会出错。
关于++i
和i++
效率的问题有一些评论。在任何非学生项目的编译器中,它们之间没有性能差异。您可以通过查看生成的代码来验证这一点,这两者将是相同的。
效率问题很有趣……以下是我的回答尝试:C语言中的i++和++i是否有性能差异?
正如@OnFreund所指出的,对于C++对象来说情况是不同的,因为operator++()
是一个函数,编译器无法知道如何优化创建临时对象以保存中间值。
for(int i=0; i<10; i++){ print i; }
与 for(int i=0; i<10; ++i){ print i; }
是否有所不同?我理解有些语言将根据你使用的方式给出不同的结果。 - aVeRTRACi++
,因为它的形式是“操作数-运算符”,类似于赋值语句中的“操作数-运算符-值”。换句话说,目标操作数位于表达式的左侧,就像在赋值语句中一样。 - David R Tribblei++
和print i
在不同的语句中,而是因为i++;
和i<10
是不同的。@jonnyflash的评论并没有太离谱。假设你有for(int i=0; i++<10){ print i; }
和for(int i=0; ++i<10){ print i; }
。这些将会以@johnnyflash在第一个评论中描述的方式有所不同。 - Adami++
被称为后增量,而++i
被称为前增量。
i++
i++
是后增量,因为它在操作结束后将i
的值增加1。
让我们看下面的例子:
int i = 1, j;
j = i++;
这里j = 1
,但i = 2
。这里i
的值将首先赋给j
,然后i
将被递增。
++i
++i
是前增量,因为它在操作之前将i
的值增加1。
这意味着j = i;
将在i++
之后执行。
让我们看下面的例子:
int i = 1, j;
j = ++i;
j = 2
但是i = 2
。在i
递增之后,i
的值将被赋给j
。
同样地,在j=i;
之前,++i
会被执行。for(i=0; i<5; i++)
printf("%d ", i);
和
for(i=0; i<5; ++i)
printf("%d ", i);
0 1 2 3 4
。for(i = 0; i<5;)
printf("%d ", ++i);
1 2 3 4 5
。++i
会增加变量的值并返回增加后的结果。
i++
会先返回变量的值,然后再增加它。
这是一个微妙的区别。
对于for循环,使用++i
,因为它稍微更快一些。i++
会创建一个额外的副本然后被丢弃掉。
请不要担心哪一个更"高效"(其实指的是速度)的问题。我们现在有编译器来处理这些事情。基于哪一个能更清晰地表达你的意图,请使用其中之一。
operator++(int)
(后缀版本)中,代码几乎必须创建一个临时变量,以便返回它。您确定编译器总是能够优化掉这种情况吗? - Peter - Reinstate Monica唯一的区别是变量递增和操作符返回值之间的顺序不同。
此代码及其输出解释了这种差异:
#include<stdio.h>
int main(int argc, char* argv[])
{
unsigned int i=0, a;
printf("i initial value: %d; ", i);
a = i++;
printf("value returned by i++: %d, i after: %d\n", a, i);
i=0;
printf("i initial value: %d; ", i);
a = ++i;
printf(" value returned by ++i: %d, i after: %d\n",a, i);
}
输出结果为:
i initial value: 0; value returned by i++: 0, i after: 1
i initial value: 0; value returned by ++i: 1, i after: 1
基本上,++i
在增加之后返回值,而 i++
在增加之前返回值。最终,在两种情况下,i
的值都会增加。
另一个例子:
#include<stdio.h>
int main ()
int i=0;
int a = i++*2;
printf("i=0, i++*2=%d\n", a);
i=0;
a = ++i * 2;
printf("i=0, ++i*2=%d\n", a);
i=0;
a = (++i) * 2;
printf("i=0, (++i)*2=%d\n", a);
i=0;
a = (i++) * 2;
printf("i=0, (i++)*2=%d\n", a);
return 0;
}
输出:
i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (i++)*2=0
当返回值被赋给另一个变量时,或者在与其他操作连接拼接并应用操作优先级的情况下进行增量操作时,区别是明显的 (i++*2
不同于++i*2
,以及(i++)*2
和(++i)*2
)。在许多情况下,它们是可以互换的。一个经典的例子是for循环的语法:
for(int i=0; i<10; i++)
具有相同的效果
for(int i=0; i<10; ++i)
预增量操作始终至少与后增量操作一样有效:事实上,后增量操作通常涉及保留先前值的副本并可能添加一些额外的代码。
正如其他人所建议的那样,由于编译器优化,它们许多次是同样有效的,可能会在for循环中出现这些情况。
为了不混淆这两个运算符,我采用了这个规则:
将操作符 ++ 相对于变量
i 的位置与
++ 操作相对于分配顺序相关联
换句话说:
++ 之前 i 表示必须在分配之前进行递增;
++ 之后 i 表示必须在分配之后进行递增:
++i
比i++
执行速度稍快,原因在于i++
在增加i之前可能需要创建i的一个本地副本,而++i
从不这样做。在某些情况下,一些编译器将尝试优化此过程...但并非总是可行,也并非所有编译器都这样做。
我尽量不过度依赖编译器的优化,所以我会遵循Ryan Fox的建议:当可以使用两者时,我使用++i
。
1;
时,变量 i
的值就像数字 1 一样,没有更多的“本地副本”。 - R.. GitHub STOP HELPING ICE现代编译器非常出色。所有优秀的编译器都足够聪明,能够意识到它正在看到for循环中的整数递增操作,并且会将两种方法优化为相同的高效代码。如果使用后缀递增比前缀递增导致程序运行时间更慢,那么你正在使用一个糟糕的编译器。
在操作时间复杂度方面,两种方法(即使实际上执行了复制操作)是等效的。在循环内部执行的指令数量应该远远超过递增操作中的操作数。因此,在任何规模较大的循环中,递增方法的惩罚都会被循环体的执行大大超越。换句话说,与其担心递增操作,你更应该关注优化循环中的代码。
++i
:是前缀自增,另一个是后缀自增。
i++
:先获取元素再将其递增。
++i
:递增 i 并返回元素。
示例:
int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);
输出:
i: 0
i++: 0
++i: 2
++i
(前缀操作):先增加值再赋值
例如:int i = 5
,int b = ++i
在这种情况下,先将6赋值给b,然后增加为7,以此类推。
i++
(后缀操作):先赋值再增加值
例如:int i = 5
,int b = i++
在这种情况下,先将5赋值给b,然后增加为6,以此类推。
在for循环中,通常使用i++
,因为我们通常在增加前使用i
的起始值。但根据程序逻辑可能会有所不同。