是否有差异++i
,并i++
在一个for
循环?它只是一个语法的东西吗?
a ++被称为后缀.
将1添加到a,返回旧值.
++ a被称为前缀.
将1添加到a,返回新值.
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
foreach
和while
循环取决于您使用的增量类型.对于像下面这样的for循环,没有区别,因为你没有使用i的返回值:
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
如果使用了已评估的值,则增量类型变得很重要:
int n = 0; for (int i = 0; n < 5; n = i++) { }
预增量++ 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++中,通常首选预增量,您可以使用任何一种.
这是因为如果使用后增量,则可能需要编译器生成创建额外临时变量的代码.这是因为变量的先前值和新值都需要保持在某处,因为在被评估的表达式的其他地方可能需要它们.
因此,至少在C++中,可能存在性能差异,指导您选择使用哪种.
当递增的变量是具有重写的++运算符的用户定义类型时,这主要是一个问题.对于原始类型(int等),没有性能差异.但是,除非后增量运算符肯定是必需的,否则值得坚持使用预增量运算符作为指导.
这里还有一些讨论:https://web.archive.org/web/20170405054235/http :
//en.allexperts.com/q/C-1040/Increment-operators.htm
在C++中,如果您正在使用STL,那么您可能正在使用带迭代器的for循环.这些主要有重写的++运算符,所以坚持预增量是一个好主意.编译器总是变得更聪明,而较新的编译器可能能够执行优化,这意味着没有性能差异 - 特别是如果增加的类型是在头文件中内联定义的(因为STL实现经常是这样),以便编译器可以看到该方法已实现,然后可以知道哪些优化可以安全执行.即便如此,它仍然值得坚持预增量,因为循环执行很多次,这意味着很小的性能损失很快就会被放大.
在C#等其他语言中,++运算符不能重载,没有性能差异.在循环中用于推进循环变量,前后增量运算符是等效的.
更正:允许在C#中重载++.看来,与C++相比,在c#中你不能独立地重载前后版本.所以,我认为如果在C#中调用++的结果没有分配给变量或者作为复杂表达式的一部分使用,那么编译器会将++的前后版本缩减为等效执行的代码.
在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
i ++读取i的值然后递增它.
++ i递增i的值然后读取它.
问题是:
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
增加它是否重要?不,它不会因为增量操作的返回值无关紧要.i
将在for循环体内的代码执行后递增.
既然你在循环中询问差异,我想你的意思是
for(int i=0; i<10; i++) ...;
在这种情况下,您在大多数语言中没有区别:无论您是否写入i++
,循环的行为都相同++i
.在C++中,您可以编写自己的++运算符版本,并且可以为它们定义单独的含义,如果它i
是用户定义的类型(例如,您自己的类).
之所以无关紧要,是因为你没有使用的值i++
.另一件事是当你这样做的时候
for(int i=0, a = 0; i<10; a = i++) ...;
现在,有是有差别,因为其他人指出,i++
是指增量,但评估的前值,但++i
意味着增量,但计算结果为i
(因此它会评估为新值).在上述情况下,a
分配i的先前值,而i增加.
正如此代码所示(请参阅注释中的差异化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)是preincrement,一个(i ++)是postincrement.不同之处在于从表达式立即返回的值.
// Psuedocode int i = 0; print i++; // Prints 0 print i; // Prints 1 int j = 0; print ++j; // Prints 1 print j; // Prints 1
编辑:Woops,完全忽略了循环方面的事情.当for循环是'step'部分(for(...; ...;))时,for循环没有实际的区别,但它可以在其他情况下发挥作用.
这是一个Java-Sample和Byte-Code,post-和preIncrement在Bytecode中没有区别:
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."":()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 (int i = 0; i < 4; ++i){ cout<两个循环都将打印0123.
但是当您在循环中使用增量/减量后的值时,差异就会出现,如下所示:
预增量循环:
for (int i = 0,k=0; i < 4; k=++i){ cout<输出:0 0 1 1 2 2 3 3
后增量循环:
for (int i = 0, k=0; i < 4; k=i++){ cout<输出:0 0 1 0 2 1 3 2
我希望通过比较输出来区分.这里要注意的是增量/减量总是在for循环结束时执行,因此可以解释结果.
10> David Morton..:就在这里.差异在于返回值."++ 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.