Answers:
++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; }
我的理解没什么不同,有些语言会根据您使用的语言为您提供不同的结果。
i++
因为它的形式为“ operand-operator”,即赋值为“ operand-operator-value”。换句话说,目标操作数在表达式的左侧,就像在赋值语句中一样。
i++
和print i
在不同的语句中,而是因为i++;
和i<10
。@jonnyflash的话不是那么离谱。假设您有for(int i=0; i++<10){ print i; }
和for(int i=0; ++i<10){ print i; }
。它们的操作方式与@johnnyflash在第一条评论中描述的方式不同。
i ++被称为后增量,而++ i被称为前增量。
i++
i++
是post增量,因为它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
将j
在i
递增后分配给i
。同样,++i
将在之前执行j=i;
。
对于您的问题 ,应该在for循环的增量块中使用哪个?答案是,您可以使用任何一个..没关系。它将执行相同的for循环。的时间。
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
。
请不要担心其中一个更快的“效率”(速度)。这些天,我们有负责这些事情的编译器。使用任何一种有意义的方法,在此基础上可以更清楚地表明您的意图。
operator++(int)
(后缀版本)中,代码几乎必须创建一个临时文件,然后将其返回。您确定编译器总是可以优化它吗?
++i
增加值,然后返回。
i++
返回值,然后将其递增。
这是一个微妙的区别。
对于for循环,请使用++i
,因为它稍快一些。i++
将创建一个多余的副本,该副本将被丢弃。
究其原因++i
可以是略快于i++
是,i++
可以要求i的值的本地副本,它得到递增之前,而++i
从来不会。在某些情况下,某些编译器会在可能的情况下对其进行优化……但是,并非总是如此,并非所有编译器都这样做。
我尽量不要过分依赖编译器优化,因此我会遵循Ryan Fox的建议:当我可以同时使用两者时,我会使用++i
。
i
编写语句时,值的“本地副本”不多于值1的“本地副本” 1;
。
在循环中使用其中一个的有效结果是相同的。换句话说,循环将在两种情况下执行相同的操作。
在效率方面,选择i ++而不是++ i可能会涉及罚款。根据语言规范,使用后递增运算符应创建该运算符所作用的值的额外副本。这可能是额外操作的来源。
但是,您应该考虑上述逻辑的两个主要问题。
现代编译器很棒。所有优秀的编译器都非常聪明,足以意识到它在for循环中看到整数增量,并将两种方法优化为相同的有效代码。如果使用后增量而不是前增量实际上导致程序运行时间变慢,则说明您使用的是可怕的编译器。
就操作时间复杂度而言,这两种方法(即使实际上正在执行复制)是等效的。在循环内部执行的指令数应主要控制增量操作中的操作数。因此,在任何大小很大的循环中,执行循环体都会大大增加增量方法的代价。换句话说,您最好不用担心在循环中优化代码,而不必担心增量。
在我看来,整个问题可以归结为对样式的偏爱。如果您认为预增量更具可读性,请使用它。就个人而言,我更喜欢后期添加,但这可能是因为在我对优化一无所知之前这就是我所教过的。
这是过早优化的典型例子,而这样的问题有可能分散我们对设计中严重问题的注意力。但是,仍然要问一个好问题,因为在“最佳实践”中用法或共识并不一致。
我假设您现在已经理解了语义上的区别(尽管说实话,我想知道为什么人们在堆栈溢出时问“运算符X的含义是什么”问题,而不是阅读书籍或网络教程之类的东西。
但是无论如何,就使用哪一个而言,都忽略了性能问题,即使在C ++中,这也不大重要。这是决定使用哪个原则时应使用的原则:
说出您在代码中的意思。
如果您在语句中不需要先增值,请不要使用该形式的运算符。这是一个小问题,但是除非您使用的样式指南完全禁止一个版本支持另一个版本(又称骨头样式指南),否则您应该使用最能表达您想要做什么的形式。
QED,使用预递增版本:
for (int i = 0; i != X; ++i) ...
可以通过下面的简单C ++代码理解差异:
int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;
主要区别是
- i ++ Post(递增后)和
++ i Pre(递增之前)
- 如果
i =1
循环递增,则发布1,2,3,4,n
- 如果
i =1
循环像2,3,4,5,n
这个小代码可以帮助以不同于已发布答案的角度显示差异:
int i = 10, j = 10;
printf ("i is %i \n", i);
printf ("i++ is %i \n", i++);
printf ("i is %i \n\n", i);
printf ("j is %i \n", j);
printf ("++j is %i \n", ++j);
printf ("j is %i \n", j);
结果是:
//Remember that the values are i = 10, and j = 10
i is 10
i++ is 10 //Assigns (print out), then increments
i is 11
j is 10
++j is 11 //Increments, then assigns (print out)
j is 11
注意前后情况。
至于应该在for循环的增量块中使用哪一个,我认为我们可以做的最好的决定就是使用一个很好的例子:
int i, j;
for (i = 0; i <= 3; i++)
printf (" > iteration #%i", i);
printf ("\n");
for (j = 0; j <= 3; ++j)
printf (" > iteration #%i", j);
结果是:
> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3
我不了解您,但至少在for循环中,我看不出它的用法有什么不同。
以下C代码片段说明了前递增和后递减运算符之间的区别:
int i;
int j;
增量运算符:
i = 1;
j = ++i; // i is now 2, j is also 2
j = i++; // i is now 3, j is 2
预递增意味着在同一行上递增。后增量是指行执行后的增量。
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 OR condition if first line is already true then compiler doesn't check the rest. It is 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 address of x
std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
std::cout<<"address = "<<&x<<"\n"; //prints address of x
std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}
不久:
++i
而i++
如果你不是在一个函数写他们的工作原理相同。如果您使用类似function(i++)
或的产品function(++i)
,则可以看到区别。
function(++i)
表示首先将i加1,然后将其i
加到具有新值的函数中。
function(i++)
表示将第一个i
放入函数中,然后再递增i
1。
int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now
int j = ++i;
以及int k = i++;
即使有不涉及函数调用。
唯一的区别是变量的增量与运算符返回的值之间的运算顺序。
此代码及其输出说明了不同之处:
#include<stdio.h>
int main(int argc, char* argv[])
{
unsigned int i=0, a;
a = i++;
printf("i before: %d; value returned by i++: %d, i after: %d\n", i, a, i);
i=0;
a = ++i;
printf("i before: %d; value returned by ++i: %d, i after: %d\n", i, a, i);
}
输出为:
i before: 1; value returned by i++: 0, i after: 1
i before: 1; value returned by ++i: 1, i after: 1
因此,基本上++i
在增加值之后返回值,而++i
在增加值之前返回值。最后,在两种情况下,i
will的值都会增加。
另一个例子:
#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=2
当返回的值被分配给另一个变量或者当在级联与施加的操作优先级的其他操作进行增量(差异是清楚的i++*2
是,从不同的++i*2
,但(i++)*2
和(++i)*2
在许多情况下返回相同的值),他们是可互换的。一个经典的例子是for循环语法:
for(int i=0; i<10; i++)
具有相同的效果
for(int i=0; i<10; ++i)
为了不使两个运算符混淆,我采用了以下规则:
将操作员++
相对于变量的位置与操作相对于分配i
的顺序相关联++
换句话说:
++
在 分配之前i
必须先进行递增;++
after i
表示必须在分配后进行递增:您可以将其内部转换视为多个语句;
i++;
你可以这样认为,
i;
i = i+1;
++i;
你可以这样认为,
i = i+i;
i;
a = i ++表示一个包含当前i值a = ++ i表示一个包含递增i值
a = i++;
表示存储在其中的值a
将是i
递增之前的值,但是“不递增”表示i
未递增,这是完全错误的— i
递增,但是表达式的值是递增之前的值。
这是了解差异的示例
int i=10;
printf("%d %d",i++,++i);
输出:(10 12/11 11
取决于printf
函数自变量的求值顺序,在编译器和体系结构中会有所不同)
说明:
i++
-> i
打印,然后递增。(打印10,但i
将变为11)
++i
-> i
value递增并打印该值。(打印12,值i
也12)
i++
和之间没有序列点++i