代码之家  ›  专栏  ›  技术社区  ›  Corey Ogburn

之间的差异(;;)而在C#(真)中呢?

c#
  •  17
  • Corey Ogburn  · 技术社区  · 15 年前

    在语法上,我看到它们无限循环,直到到达break语句,但是它们编译成相同的东西了吗?是不是因为没有检查的条件,所以速度会稍微快一点?除了代码可读性之外,还有什么区别吗?

    7 回复  |  直到 15 年前
        1
  •  36
  •   Fredrik Mörk    15 年前

    鉴于此输入:

    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
    

    我想说,非常相似(甚至完全相同)。

        2
  •  21
  •   Mike Caron    15 年前

    for(;;) while(true) 还有一张支票是真的。

    我更喜欢

        3
  •  2
  •   T.E.D.    15 年前

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

    如果一个比另一个快,C编译器的编写者就需要一些东西来展示给他们。。。

        4
  •  1
  •   Jerry Coffin    15 年前

    如果可以的话,我建议你看一个稍微不同的问题。如果您经常使用这两种方法中的任何一种,那么您的代码结构可能很差。虽然像嵌入式系统这样的东西确实可以永远运行,但大多数普通代码中的循环却不能。写一个循环 声称 if (whatever) break; )作为

    break

        5
  •  0
  •   DarLom    15 年前

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

        6
  •  0
  •   EdoDodo    15 年前

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

        7
  •  0
  •   Wil P    15 年前

    调试程序集一直符合while(true)。使用反射器,你可以看到结果。

        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;
                }
            }
        }
    

    检查 ExecuteFor 反射器中的方法。

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

    同一代码的优化版本会为

    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.");
    }