i ++和++ i在循环中的区别?

for循环中, ++ii++是否有区别? 这只是一个语法的东西?

一个++被称为后缀。

将1加1,返回旧值。

++ a被称为前缀。

给a加1,返回新的值。

C#:

 string[] items = {"a","b","c","d"}; int i = 0; foreach (string item in items) { Console.WriteLine(++i); } Console.WriteLine(""); i = 0; foreach (string item in items) { Console.WriteLine(i++); } 

输出:

 1 2 3 4 0 1 2 3 

foreachwhile循环取决于您使用的增量types。 像下面的for循环,没有区别,因为你不使用我的返回值:

 for (int i = 0; i < 5; i++) { Console.Write(i);} Console.WriteLine(""); for (int i = 0; i < 5; ++i) { Console.Write(i); } 

0 1 2 3 4
0 1 2 3 4

如果使用所评估的值,则增量types变得显着:

 int n = 0; for (int i = 0; n < 5; n = i++) { } 

预增加++我递增i的值并评估为新增值。

 int i = 3; int preIncrementResult = ++i; Assert( preIncrementResult == 4 ); Assert( i == 4 ); 

后递增i ++递增i的值并评估为原始未递增的值。

 int i = 3; int postIncrementResult = i++; Assert( postIncrementtResult == 3 ); Assert( i == 4 ); 

在C ++中,预增量通常是首选,你也可以使用。

这是因为如果您使用后增量,它可能要求编译器必须生成代码创build一个额外的临时variables。 这是因为被增量的variables的前一个值和新值都需要保存在某个地方,因为在被评估的expression式的其他地方可能需要它们。

因此,至less在C ++中,可能会有性能差异,指导您select使用哪一个。

当被增加的variables是用户定义的types并且被重载的++运算符时,这主要只是一个问题。 对于原始types(int等),没有性能差异。 但是,值得坚持前置增量操作符作为指导,除非后增加操作符是绝对需要的。

这里有更多的讨论:
http://en.allexperts.com/q/C-1040/Increment-operators.htm

在C ++中,如果您使用STL,那么您可能正在使用for循环与迭代器。 这些主要是覆盖++运算符,所以坚持预增加是个好主意。 编译器会一直变得更聪明,而新版本可能会执行优化,这意味着没有性能差异 – 尤其是如果增量types在头文件中内联定义(如STL实现通常),以便编译器可以看到该方法被执行,然后可以知道哪些优化是安全的执行。 即便如此,仍然值得坚持预增加,因为循环会执行很多次,这意味着很小的性能损失很快就会被放大。


在其他语言(如C ++)中,不能重载++运算符,性能没有差别。 在循环中使用来推进循环variables,前后增量运算符是等价的。

更正:在C#中重载++是允许的。 看来,虽然,与c + +相比,在c#中,你不能独立重载前后版本。 所以,我假设如果在C#中调用++的结果没有被赋值给一个variables,或者被用作复杂expression式的一部分,那么编译器会将++的前后版本降低到等效执行的代码。

在c#中, 在for循环中使用没有区别。

 for (int i = 0; i < 10; i++) { Console.WriteLine(i); } 

输出相同的东西

 for (int i = 0; i < 10; ++i) { Console.WriteLine(i); } 

正如其他人所指出的那样,当用于一般的i ++和++时,我有一个微妙而显着的区别:

 int i = 0; Console.WriteLine(i++); // Prints 0 int j = 0; Console.WriteLine(++j); // Prints 1 

我++读取我的价值,然后增加它。

++我递增我的价值,然后读取它。

既然你问一个循环的差异,我想你的意思

 for(int i=0; i<10; i++) ...; 

在这种情况下,你在大多数语言中没有任何区别:无论你是否编写i++++i ,循环的行为都是一样的。 在C ++中,可以编写自己的++运算符版本,如果i是用户定义的types(例如,您自己的类),则可以为它们定义单独的含义。

上面没有关系的原因是因为你不使用i++的值。 另一件事是当你这样做

 for(int i=0, a = 0; i<10; a = i++) ...; 

现在有一个区别,因为正如其他人所指出的那样, i++意味着增量,但是评价为以前的值 ,但是++i表示增量,但是评价为i (因此它将评价为新的值)。 在上述情况下, a被分配i的前一个值,而i被增加。

如代码所示(请参阅注释中的dissambled MSIL),C#3编译器在for循环中不区分i ++和++ i。 如果我采用i ++或++ i的价值,肯定会有差异(这是在Visutal Studio 2008 / Release Build中编译的):

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace PreOrPostIncrement { class Program { static int SomethingToIncrement; static void Main(string[] args) { PreIncrement(1000); PostIncrement(1000); Console.WriteLine("SomethingToIncrement={0}", SomethingToIncrement); } static void PreIncrement(int count) { /* .method private hidebysig static void PreIncrement(int32 count) cil managed { // Code size 25 (0x19) .maxstack 2 .locals init ([0] int32 i) IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: br.s IL_0014 IL_0004: ldsfld int32 PreOrPostIncrement.Program::SomethingToIncrement IL_0009: ldc.i4.1 IL_000a: add IL_000b: stsfld int32 PreOrPostIncrement.Program::SomethingToIncrement IL_0010: ldloc.0 IL_0011: ldc.i4.1 IL_0012: add IL_0013: stloc.0 IL_0014: ldloc.0 IL_0015: ldarg.0 IL_0016: blt.s IL_0004 IL_0018: ret } // end of method Program::PreIncrement */ for (int i = 0; i < count; ++i) { ++SomethingToIncrement; } } static void PostIncrement(int count) { /* .method private hidebysig static void PostIncrement(int32 count) cil managed { // Code size 25 (0x19) .maxstack 2 .locals init ([0] int32 i) IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: br.s IL_0014 IL_0004: ldsfld int32 PreOrPostIncrement.Program::SomethingToIncrement IL_0009: ldc.i4.1 IL_000a: add IL_000b: stsfld int32 PreOrPostIncrement.Program::SomethingToIncrement IL_0010: ldloc.0 IL_0011: ldc.i4.1 IL_0012: add IL_0013: stloc.0 IL_0014: ldloc.0 IL_0015: ldarg.0 IL_0016: blt.s IL_0004 IL_0018: ret } // end of method Program::PostIncrement */ for (int i = 0; i < count; i++) { SomethingToIncrement++; } } } } 

一个(++ i)是预增量,一个(i ++)是后增量。 不同之处在于从expression式立即返回的值。

 // Psuedocode int i = 0; print i++; // Prints 0 print i; // Prints 1 int j = 0; print ++j; // Prints 1 print j; // Prints 1 

编辑:Woops,完全忽略了事物的循环方面。 当“step”部分(for(…; …;))for循环没有实际的区别,但是在其他情况下可以起作用。

这是一个Java-Sample和Byte-Code,post-和preIncrement在字节码中没有区别:

 public class PreOrPostIncrement { static int somethingToIncrement = 0; public static void main(String[] args) { final int rounds = 1000; postIncrement(rounds); preIncrement(rounds); } private static void postIncrement(final int rounds) { for (int i = 0; i < rounds; i++) { somethingToIncrement++; } } private static void preIncrement(final int rounds) { for (int i = 0; i < rounds; ++i) { ++somethingToIncrement; } } 

}

而现在的字节码(javap -private -c PreOrPostIncrement):

 public class PreOrPostIncrement extends java.lang.Object{ static int somethingToIncrement; static {}; Code: 0: iconst_0 1: putstatic #10; //Field somethingToIncrement:I 4: return public PreOrPostIncrement(); Code: 0: aload_0 1: invokespecial #15; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: sipush 1000 3: istore_1 4: sipush 1000 7: invokestatic #21; //Method postIncrement:(I)V 10: sipush 1000 13: invokestatic #25; //Method preIncrement:(I)V 16: return private static void postIncrement(int); Code: 0: iconst_0 1: istore_1 2: goto 16 5: getstatic #10; //Field somethingToIncrement:I 8: iconst_1 9: iadd 10: putstatic #10; //Field somethingToIncrement:I 13: iinc 1, 1 16: iload_1 17: iload_0 18: if_icmplt 5 21: return private static void preIncrement(int); Code: 0: iconst_0 1: istore_1 2: goto 16 5: getstatic #10; //Field somethingToIncrement:I 8: iconst_1 9: iadd 10: putstatic #10; //Field somethingToIncrement:I 13: iinc 1, 1 16: iload_1 17: iload_0 18: if_icmplt 5 21: return } 

问题是:

在for循环中,++ i和i ++是否有区别?

答案是:

为什么每一个其他的答案都不得不详细解释前后递增的时候,甚至没有被问及?

这个for循环:

 for (int i = 0; // Initialization i < 5; // Condition i++) // Increment { Output(i); } 

将不使用循环转换为此代码:

 int i = 0; // Initialization loopStart: if (i < 5) // Condition { Output(i); i++ or ++i; // Increment goto loopStart; } 

现在,如果你把i++++i放在Increment这里,这有什么关系吗? 不,不是因为增量操作的返回值不重要。 在for循环体的代码执行之后, i将会增加。

如果在循环中没有使用增量后的值,则没有区别。

 for (int i = 0; i < 4; ++i){ cout<<i; } for (int i = 0; i < 4; i++){ cout<<i; } 

这两个循环将打印0123。

但是,当你在你的循环中使用递增/递减之后的值如下所示:

预增量循环:

 for (int i = 0,k=0; i < 4; k=++i){ cout<<i<<" "; cout<<k<<" "; } 

输出:0 0 1 1 2 2 3 3

后增量循环:

 for (int i = 0, k=0; i < 4; k=i++){ cout<<i<<" "; cout<<k<<" "; } 

输出:0 0 1 0 2 1 3 2

我希望通过比较输出结果可以看出差异。 这里需要注意的是,递增/递减总是在for循环结束时执行,因此可以解释结果。

在这两种情况下没有实际的差异,“ i ”会增加1。

但在expression式中使用它时会有所不同,例如:

 int i = 1; int a = ++i; // i is incremented by one and then assigned to a. // Both i and a are now 2. int b = i++; // i is assigned to b and then incremented by one. // b is now 2, and i is now 3 

就在这里。 区别在于返回值。 “++ i”的返回值将是增加i 的值。 “i ++”的返回值将是递增的值。 这意味着代码如下所示:

 int a = 0; int b = ++a; // a is incremented and the result after incrementing is saved to b. int c = a++; // a is incremented again and the result before incremening is saved to c. 

因此,a是2,b和c是1。

我可以像这样重写代码:

 int a = 0; // ++a; a = a + 1; // incrementing first. b = a; // setting second. // a++; c = a; // setting first. a = a + 1; // incrementing second. 

除了循环和性能差异外,还有更多的++ i和i ++。 ++我返回一个l值,我++返回一个r值。 基于此,有很多事情可以做(++ i),但不能(i ++)。

 1- It is illegal to take the address of post increment result. Compiler won't even allow you. 2- Only constant references to post increment can exist, ie, of the form const T&. 3- You cannot apply another post increment or decrement to the result of i++, ie, there is no such thing as I++++. This would be parsed as ( i ++ ) ++ which is illegal. 4- When overloading pre-/post-increment and decrement operators, programmers are encouraged to define post- increment/decrement operators like: T& operator ++ ( ) { // logical increment return *this; } const T operator ++ ( int ) { T temp( *this ); ++*this; return temp; } 

在JavaScript中,由于以下i ++可能会更好地使用:

 var i=1; alert(i++); // before, 1. current, 1. after, 2. alert(i); // before, 2. current, 2. after, 2. alert(++i); // before, 2. current, 3 after, 3. 

虽然数组(我认为所有)和一些其他函数和调用使用0作为起点,你将不得不将我设置为-1,使循环与数组使用时, 使用++

当使用i ++时 ,以下值将使用增加的值。 你可以说i ++是人类数量的方式,因为你可以从0开始。

正如@Jon B所说,for循环没有区别。

但在一段whiledo...while循环,你可以find一些差异,如果你正在与++ii++

 while(i++ < 10) { ... } //compare then increment while(++i < 10) { ... } //increment then compare 

循环可以有所不同。 这是post / pre-increment的实际应用。

  int i = 0; while(i++ <= 10) { Console.Write(i); } Console.Write(System.Environment.NewLine); i = 0; while(++i <= 10) { Console.Write(i); } Console.ReadLine(); 

虽然第一个数到11,循环11次,第二个没有。

大多数情况下,这是相当简单的使用(x – > 0); – 循环遍历数组的所有元素(在此免除foreach构造)。

他们都增加了数量。 ++i相当于i = i + 1

i++++i非常相似,但不完全一样。 既增加数字,但++i递增目前的expression式计算之前的数字,而i++计算expression式后递增数字。

 int i = 3; int a = i++; // a = 3, i = 4 int b = ++a; // b = 4, a = 

检查这个链接 。

这令我难以置信,为什么人们可能会在for循环中将增量expression式写成i ++。

在for循环中,第三个组件是一个简单的增量语句,如

 for (i=0; i<x; i++) 

要么

 for (i=0; i<x; ++i) 

执行结果没有任何区别。

是的,在for循环中++ii++是有区别的,尽pipe在不寻常的用例中。 当在for块中在循环testingexpression式中使用带有递增/递减运算符的循环variables时,或者在循环variables之一中使用循环variables时 。 不,这不仅仅是一个语法的东西。

因为i在一个代码意味着评估expressioni和操作员并不意味着评估,而只是一个操作;

  • ++i表示i增加1的值,然后评估i
  • i++意味着评估i ,然后增加i的值1。

所以,从两个expression式中得到的结果是不同的,因为评估的结果各不相同。 --ii--

例如;

 let i = 0 i++ // evaluates to value of i, means evaluates to 0, later increments i by 1, i is now 1 0 i 1 ++i // increments i by 1, i is now 2, later evaluates to value of i, means evaluates to 2 2 i 2 

在不寻常的使用情况下,然而下一个例子听起来有用或不重要,它显示了一个区别

 for(i=0, j=i; i<10; j=++i){ console.log(j, i) } for(i=0, j=i; i<10; j=i++){ console.log(j, i) } 

对于用户自定义的types,这些运算符可能(但不应该 )在循环索引的上下文中具有有意义的不同语义,并且可以(但不应该)影响所描述的循环的行为。

另外,在c++ ,使用预增量表单( ++i )通常是最安全的,因为它更容易优化。 (Scott Langham 把我打败了,诅咒你,Scott)

我不知道其他语言,但在Java ++中,我是一个前缀增量 ,意思是:将i增加1,然后在我所驻留的expression式中使用i的新值,而i ++后缀增量 ,表示以下:在expression式中使用i的当前值,然后将其增加1.示例:

 public static void main(String [] args){ int a = 3; int b = 5; System.out.println(++a); System.out.println(b++); System.out.println(b); 

}和输出是:

  • 4
  • 6

我++; ++ i; 两者都是相似的,因为它们没有用在expression式中。

 class A { public static void main (String []args) { int j = 0 ; int k = 0 ; ++j; k++; System.out.println(k+" "+j); }} prints out : 1 1 
Interesting Posts