++ i和i ++有什么区别?

The*_*i.9 818 c for-loop pre-increment post-increment

在C中,使用++i和之间有什么区别i++,哪些应该在for循环的增量块中使用?

Mar*_*son 1009

对于一个for循环,要么工作.++i似乎更常见,也许是因为这是K&R中使用的.

在任何情况下,遵循准则"宁可++ii++",你会不会出问题.

有一对夫妇的关于效率的意见++ii++.在任何非学生项目编译器中,都没有性能差异.您可以通过查看生成的代码来验证这一点,这些代码是相同的.

效率问题很有意思......这是我尝试回答的问题: 在C中i ++和++ i之间是否存在性能差异?

正如On Freund所说,对于C++对象来说它是不同的,因为它operator++()是一个函数,编译器无法知道如何优化临时对象的创建来保存中间值.

  • jonnyflash,两者都将以相同的方式运行,因为i和print的增量在不同的语句中.任何支持C风格++的语言都应如此.++ i和i ++之间的唯一区别是在同一语句中使用操作的值. (25认同)
  • 因为在大多数情况下它们生成相同的代码,所以我更喜欢`i ++`,因为它的形式是"操作数 - 运算符",是一个赋值"操作数 - 运算符 - 值".换句话说,目标操作数位于表达式的左侧,就像它在赋值语句中一样. (16认同)
  • 达到最终状态后,这种效果会不会再次出现?例如,`for(int i = 0; i <10; i ++){print i; 这不会比`for(int i = 0; i <10; ++ i){print i; 我的理解是,根据您使用的语言,某些语言会给您不同的结果. (6认同)
  • @MarkHarrison,它的运行方式相同,不是因为`i ++`和`print i`在不同的语句中,而是因为`i ++;`和`i &lt;10`。@jonnyflash的话不是那么离谱。假设您有`for(int i = 0; i ++ &lt;10){print i; }和`for(int i = 0; ++ i &lt;10){print i; }`。它们的操作方式与@johnnyflash在第一条评论中描述的方式不同。 (2认同)
  • @sam,因为在典型的for循环中,++ i部分没有副作用(例如,赋值). (2认同)

Par*_*rag 164

i ++被称为Post Increment,++ i被称为Pre Increment.

i++

i++是增量后,因为它i在操作结束后将值增加1.

让我们看看以下示例:

int i = 1, j;
j = i++;
Run Code Online (Sandbox Code Playgroud)

这里的价值j = 1但是i = 2.这里的值i将被分配给j第一个然后i将递增.

++i

++i是预增量,因为它i在操作之前将值增加1.这意味着j = i;将在之后执行i++.

让我们看看以下示例:

int i = 1, j;
j = ++i;
Run Code Online (Sandbox Code Playgroud)

这里的价值j = 2但是i = 2.这里的值iji 增加之后分配给i.同样++i将在之前执行j=i;.

对于你应该在for循环的增量块中使用的问题 答案是,你可以使用任何一个..没关系.它将执行你的for循环相同的no.时间.

for(i=0; i<5; i++)
   printf("%d ",i);
Run Code Online (Sandbox Code Playgroud)

for(i=0; i<5; ++i)
   printf("%d ",i);
Run Code Online (Sandbox Code Playgroud)

两个循环都会产生相同的输出.即0 1 2 3 4.

它只在你使用它的地方很重要.

for(i = 0; i<5;)
    printf("%d ",++i);
Run Code Online (Sandbox Code Playgroud)

在这种情况下输出将是1 2 3 4 5.


And*_*ter 39

请不要担心哪一个更快的"效率"(速度,真的).这些天我们有编译器来处理这些事情.使用任何有意义的使用,在此基础上更清楚地显示您的意图.

  • 我希望这意味着 '_use 前缀 (inc|dec)rement 除非你真的需要 (inc|dec) 之前的旧值,很少有人这样做,但假设教材使用的比例令人眼花缭乱,为那些甚至不知道它是什么的 postfix 用户创造了一个货物崇拜_'..! (3认同)
  • 我不确定“这些天的编译器......照顾这些事情”是否普遍正确。在自定义的`operator++(int)`(后缀版本)中,代码几乎必须创建一个将被返回的临时文件。您确定编译器总是可以优化它吗? (2认同)

Rya*_*Fox 32

++i 递增值,然后返回它.

i++ 返回值,然后递增它.

这是一个微妙的差异.

对于for循环,请使用++i,因为它稍快一些.i++将创建一个被丢弃的额外副本.

  • 我不知道任何编译器至少对整数产生影响. (23认同)
  • 它不是更快**.忽略这些值(只有副作用有效),编译器可以/将生成完全相同的代码. (4认同)

Shi*_*ala 29

i ++: - 在这种情况下,首先分配值,然后发生增量.

++ i: - 在这种情况下,首先完成增量,然后分配值

下面是图像可视化,这里也是一个很好的实用视频(http://www.youtube.com/watch?v=lrtcfgbUXm4),它演示了相同的内容.

在此输入图像描述


Oys*_*erD 20

究其原因++i 可以是略快于i++是,i++可以要求i的值的本地副本,它得到递增之前,而++i从来不会.在某些情况下,如果可能的话,一些编译器会对其进行优化......但并非总是可行,并非所有编译器都这样做.

我尽量不要太依赖编译器优化,所以我会遵循Ryan Fox的建议:当我可以使用两者时,我会使用++i.

  • -1代表C++回答C问题.当你写一个语句`1;`时,没有"i"值的"本地副本"比值1的"本地副本". (11认同)

Fra*_*Boi 18

唯一的区别是变量的增量和运算符返回的值之间的操作顺序。

此代码及其输出解释了差异:

#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);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

i initial value: 0; value returned by i++: 0, i after: 1
i initial value: 0;  value returned by ++i: 1, i after: 1
Run Code Online (Sandbox Code Playgroud)

所以基本上++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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2
Run Code Online (Sandbox Code Playgroud)

很多时候没有区别

当返回的值被分配给另一个变量或者当在级联与施加的操作优先级的其他操作进行增量(差异是清楚的i++*2是,从不同的++i*2,但(i++)*2(++i)*2在许多情况下返回相同的值),他们是可互换的。一个经典的例子是 for 循环语法:

for(int i=0; i<10; i++)
Run Code Online (Sandbox Code Playgroud)

具有相同的效果

for(int i=0; i<10; ++i)
Run Code Online (Sandbox Code Playgroud)

要记住的规则

为了不混淆这两个运算符,我采用了以下规则:

将运算符++相对于变量的位置与相对于赋值i++操作顺序相关联

换句话说:

  • ++ before i表示必须赋值之前进行递增;
  • ++ after i表示必须赋值进行递增:


dus*_*der 13

使用任何一种的有效结果都是相同的.换句话说,循环在两个实例中都会做同样的事情.

在效率方面,选择i ++ over ++ i可能会受到惩罚.就语言规范而言,使用后增量运算符应该创建运算符所作用的值的额外副本.这可能是额外操作的来源.

但是,您应该考虑前面逻辑的两个主要问题.

  1. 现代编译器很棒.所有优秀的编译器都足够聪明,可以意识到它在for循环中看到了整数增量,并且它会将两种方法优化为相同的高效代码.如果使用后增量超过预增量实际上会导致程序运行时间变慢,那么您使用的是可怕的编译器.

  2. 就操作时间复杂性而言,这两种方法(即使实际执行副本)也是等效的.在循环内执行的指令数应该显着地增加增量操作中的操作数.因此,在任何有效大小的循环中,增量方法的代价将被循环体的执行大大掩盖.换句话说,你最好不要担心在循环中优化代码而不是增量.

在我看来,整个问题简单归结为一种风格偏好.如果您认为预增量更具可读性,那么请使用它.就个人而言,我更喜欢后加入,但这可能是因为在我对优化有所了解之前,这就是我所教授的内容.

这是过早优化的典型例子,这样的问题有可能让我们分散设计中的严重问题.然而,这仍然是一个很好的问题,因为在"最佳实践"中没有统一的使用或共识.


Usm*_*man 13

他们都增加了数字.++ i相当于i = i + 1.

i ++和++我非常相似但不完全相同.两者都递增数字,但++ i在计算当前表达式之前递增数字,而i ++在计算表达式之后递增数字.

示例:

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
Run Code Online (Sandbox Code Playgroud)


Tal*_*ick 8

简而言之,两者之间的区别在于步骤,请查看下图。

在此输入图像描述

例子:

int i = 1;
int j = i++;
Run Code Online (Sandbox Code Playgroud)

结果j1

int i = 1;
int j = ++i;
Run Code Online (Sandbox Code Playgroud)

结果j2

注意:在这两种情况下,i值都是2


Sci*_*ech 7

++i:是前增加,其他是后增加。

i++:获取元素,然后递增。
++i:使i递增,然后返回元素。

例:

int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);
Run Code Online (Sandbox Code Playgroud)

输出:

i: 0
i++: 0
++i: 2
Run Code Online (Sandbox Code Playgroud)


小智 6

不久:

++ii++如果你不是在一个函数写他们的工作原理相同。如果你使用类似的东西,function(i++)或者function(++i)你可以看到不同之处。

function(++i)说首先将 i 增加 1,然后将其i放入具有新值的函数中。

function(i++)i在增加i1之后首先放入函数中。

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
Run Code Online (Sandbox Code Playgroud)

  • 差异并没有真正与函数调用相关(并且您可以在不进行函数调用的情况下发现差异)。即使不涉及函数调用,`int j = ++i;` 和`int k = i++;` 之间也存在差异。 (3认同)

Ana*_*s23 6

++i(前缀操作):增量,然后将值
(例如): int i = 5int b = ++i 在这种情况下,6被分配给b的第一和然后递增到7等。

i++(后缀操作):分配,然后递增值
(例如): int i = 5int b = i++ 在这种情况下,5分配给b的第一和然后递增到6等等。

如果使用for循环:i++最常用的原因是,通常i在递增for循环之前,我们使用of的起始值。但是,根据您的程序逻辑,它可能会有所不同。

  • 最后一个语句似乎是错误的, ++​​i 和 i++ 在 for 循环中以相同的方式工作,但你的句子表明不然。 (2认同)

小智 5

我假设您现在已经理解了语义上的区别(尽管说实话,我想知道为什么人们在堆栈溢出时问“运算符X的含义是什么”问题,而不是阅读书籍或网络教程之类的东西。

但是无论如何,就使用哪一个而言,都忽略了性能问题,即使在C ++中,这也不大可能重要。这是决定使用哪个原则时应使用的原则:

说出您在代码中的意思。

如果您在语句中不需要先增值,请不要使用该形式的运算符。这是一个小问题,但是除非您使用的样式指南完全禁止一个版本支持另一个版本(又称骨头样式指南),否则您应该使用最能表达您想要做什么的形式。

QED,使用预递增版本:

for (int i = 0; i != X; ++i) ...
Run Code Online (Sandbox Code Playgroud)


Gop*_*pan 5

主要区别是

  • i ++ Post(递增后)和
  • ++ i Pre(递增之前

    • 如果i =1 循环递增,则发布1,2,3,4,n
    • 如果i =1 循环像2,3,4,5,n


小智 5

可以通过下面的简单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;
Run Code Online (Sandbox Code Playgroud)


Udd*_*tam 5

Pre-crement 意味着在同一行上增加。后增量是指在该行执行后增量。

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
Run Code Online (Sandbox Code Playgroud)

当它带有 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
}
Run Code Online (Sandbox Code Playgroud)

数组中

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
}
Run Code Online (Sandbox Code Playgroud)

在 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)
}
Run Code Online (Sandbox Code Playgroud)


小智 5

以下C代码片段说明了前和后递增和递减运算符之间的区别:

int  i;
int  j;
Run Code Online (Sandbox Code Playgroud)

增量运算符:

i = 1;
j = ++i;    // i is now 2, j is also 2
j = i++;    // i is now 3, j is 2
Run Code Online (Sandbox Code Playgroud)


car*_*m85 5

i ++和++ i

这个小代码可以帮助以不同于已发布答案的角度显示差异:

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);
Run Code Online (Sandbox Code Playgroud)

结果是:

//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 
Run Code Online (Sandbox Code Playgroud)

注意前后情况。

for循环

至于应该在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);
Run Code Online (Sandbox Code Playgroud)

结果是:

> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3 
Run Code Online (Sandbox Code Playgroud)

我不了解您,但至少在for循环中,我看不出它的用法有什么不同。