C#中for(;;)和while(true)之间的区别?

从语法上来说,我看到它们无限循环直到达到break语句,但它们是否编译成同一个东西? 因为它没有条件可以检查吗? 除了代码可读性之外,还有差别吗?

鉴于此输入:

 private static void ForLoop() { int n = 0; for (; ; ) { Console.WriteLine(n++); } } private static void WhileLoop() { int n = 0; while (true) { Console.WriteLine(n++); } } 

…你得到这个输出:

 .method private hidebysig static void ForLoop() cil managed { // Code size 14 (0xe) .maxstack 3 .locals init ([0] int32 n) IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: ldloc.0 IL_0003: dup IL_0004: ldc.i4.1 IL_0005: add IL_0006: stloc.0 IL_0007: call void [mscorlib]System.Console::WriteLine(int32) IL_000c: br.s IL_0002 } // end of method Program::ForLoop .method private hidebysig static void WhileLoop() cil managed { // Code size 14 (0xe) .maxstack 3 .locals init ([0] int32 n) IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: ldloc.0 IL_0003: dup IL_0004: ldc.i4.1 IL_0005: add IL_0006: stloc.0 IL_0007: call void [mscorlib]System.Console::WriteLine(int32) IL_000c: br.s IL_0002 } // end of method Program::WhileLoop 

非常相似,我会说(相同,甚至)。

在现代编译器中,绝对没有。

然而,从历史上看, for(;;)实现为单个跳转,而while(true)也检查为true。

我更喜欢while(true) ,因为它使我更清楚我在做什么。

我没有检查输出代码,但应该没有任何区别。 任何体面的编译器都会做足够简单的循环优化,以查看条件是一个常量表达式,因此不需要检查每次迭代。

如果一个比另一个更快,那么C#编译器编写者需要向他们发出一些声音……

如果可能的话,我建议你看一个有点不同的问题。 如果您经常使用这些中的任何一个,那么您可能很难构建代码。 虽然嵌入式系统确实可以永远运行,但大多数普通代码中的循环都没有。 编写一个声称永远运行的循环通常意味着你已经隐藏了内部循环的退出条件,其他一些控制流(例如, if (whatever) break; )作为循环的真正退出。

这通常应该避免。 虽然有些情况下break语句是有意义的,但它们通常应该处理exception情况,而不是编写一个循环说一件事而是另一件事(即说“永远运行”,但确实“运行直到满足条件” )。

他们编译成同样的东西。 您可以编写一个实现这两种方法的测试应用程序,然后使用ILDASM来确认它们是否相同。

正如其他人所提到的,对于任何现代编译器,它应该完全没有区别。

我在我的计算机上进行了一次简短的测试,使用其中一个进行了几次操作,并且它们总是花费大约相同的时间。 当然,由于其他过程正在运行,这些测试并非100%准确,但如果速度存在差异(应该没有)那么它就是微观测试。

调试程序集符合while(true)。 使用reflection器,您可以看到结果。

  static void Main(string[] args) { ExecuteWhile(); ExecuteFor(); } private static void ExecuteFor() { for (; ; ) { Console.WriteLine("for"); string val = Console.ReadLine(); if (string.IsNullOrEmpty(val)) { Console.WriteLine("Exit for."); break; } } } private static void ExecuteWhile() { while (true) { Console.WriteLine("while"); string val = Console.ReadLine(); if (string.IsNullOrEmpty(val)) { Console.WriteLine("Exit while."); break; } } } 

检查Reflector中的ExecuteFor方法。

 private static void ExecuteFor() { while (true) { Console.WriteLine("for"); if (string.IsNullOrEmpty(Console.ReadLine())) { Console.WriteLine("Exit for."); return; } } } 

相同代码的优化版本为ExecuteFor生成不同的结果

 private static void ExecuteFor() { do { Console.WriteLine("for"); } while (!string.IsNullOrEmpty(Console.ReadLine())); Console.WriteLine("Exit for."); } 

对于详细程度,这里是优化的ExecuteWhile

 private static void ExecuteWhile() { do { Console.WriteLine("while"); } while (!string.IsNullOrEmpty(Console.ReadLine())); Console.WriteLine("Exit while."); }