在C语言中,使用++i和i++之间的区别是什么,在for循环的增量块中应该使用哪个?
当前回答
++i将增加i的值,然后返回增加后的值。 I = 1; J = ++i; (i = 2, j = 2) i++将增加I的值,但返回I被增加前的原始值。 I = 1; J = i++; (i = 2, j = 1)
对于For循环,两者都可以。++i似乎更常见,也许是因为这是K&R中使用的。
在任何情况下,遵循“优先选择++i而不是i++”的指导方针,您都不会出错。
这里有一些关于++i和i++的效率的评论。在任何非学生项目的编译器中,都不会有性能差异。您可以通过查看生成的代码来验证这一点,它们是相同的。
效率问题很有趣……以下是我试图回答的问题: 在C语言中i++和++i之间有性能差异吗?
正如@OnFreund指出的那样,对于c++对象是不同的,因为操作符++()是一个函数,编译器不知道优化掉一个临时对象的创建来保存中间值。
其他回答
预填充是指在同一行上的增量。后增量是指行执行后的增量。
int j = 0;
System.out.println(j); // 0
System.out.println(j++); // 0. post-increment. It means after this line executes j increments.
int k = 0;
System.out.println(k); // 0
System.out.println(++k); // 1. pre increment. It means it increments first and then the line executes
当它带有OR和AND操作符时,它变得更有趣。
int m = 0;
if((m == 0 || m++ == 0) && (m++ == 1)) { // False
// In the OR condition, if the first line is already true
// then the compiler doesn't check the rest. It is a
// technique of compiler optimization
System.out.println("post-increment " + m);
}
int n = 0;
if((n == 0 || n++ == 0) && (++n == 1)) { // True
System.out.println("pre-increment " + n); // 1
}
在数组中
System.out.println("In Array");
int[] a = { 55, 11, 15, 20, 25 };
int ii, jj, kk = 1, mm;
ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
System.out.println(a[1]); // 12
jj = a[1]++; // 12
System.out.println(a[1]); // a[1] = 13
mm = a[1]; // 13
System.out.printf("\n%d %d %d\n", ii, jj, mm); // 12, 12, 13
for (int val: a) {
System.out.print(" " + val); // 55, 13, 15, 20, 25
}
在c++中,指针变量的后/前增量
#include <iostream>
using namespace std;
int main() {
int x = 10;
int* p = &x;
std::cout << "address = " << p <<"\n"; // Prints the address of x
std::cout << "address = " << p <<"\n"; // Prints (the address of x) + sizeof(int)
std::cout << "address = " << &x <<"\n"; // Prints the address of x
std::cout << "address = " << ++&x << "\n"; // Error. The reference can't reassign, because it is fixed (immutable).
}
++i可以比i++稍微快一点的原因是,i++可以在i的值被递增之前要求它的本地副本,而++i从不这样做。在某些情况下,一些编译器会尽可能地优化它……但这并不总是可能的,并不是所有编译器都这样做。
我尽量不太依赖编译器优化,所以我会遵循Ryan Fox的建议:当我可以使用两者时,我会使用++ I。
唯一的区别是变量的增量和运算符返回值之间的操作顺序不同。
这段代码及其输出解释了区别:
#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返回的值是在它被加1之后,而i++返回的值是在它被加1之前。最后,在这两种情况下,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的位置与++操作相对于赋值的顺序相关联
换言之:
++ before I表示必须在赋值之前进行递增; I之后的++表示必须在赋值之后进行递增:
++i将增加i的值,然后返回增加后的值。 I = 1; J = ++i; (i = 2, j = 2) i++将增加I的值,但返回I被增加前的原始值。 I = 1; J = i++; (i = 2, j = 1)
对于For循环,两者都可以。++i似乎更常见,也许是因为这是K&R中使用的。
在任何情况下,遵循“优先选择++i而不是i++”的指导方针,您都不会出错。
这里有一些关于++i和i++的效率的评论。在任何非学生项目的编译器中,都不会有性能差异。您可以通过查看生成的代码来验证这一点,它们是相同的。
效率问题很有趣……以下是我试图回答的问题: 在C语言中i++和++i之间有性能差异吗?
正如@OnFreund指出的那样,对于c++对象是不同的,因为操作符++()是一个函数,编译器不知道优化掉一个临时对象的创建来保存中间值。
你可以把它的内部转换看作是多条语句:
// case 1
i++;
/* you can think as,
* i;
* i= i+1;
*/
// case 2
++i;
/* you can think as,
* i = i+i;
* i;
*/