C# 的跳躍語法( break continue goto 與 return)

最近看了一段程式,感覺跑的順序跟預期的不同,查了 msdn 文件,順手做了個紀錄。 文件請務必看英文版,中文版的錯很大,完全不是同個意思XD

12ERROR

break

終止最近一層的 迴圈(while,do,for,foreach) 或 switch,接著執行後續程式碼

  • 程式碼範例 1 :單層迴圈

    for (int i = 1; i <= 100; i++)
    {
        if (i == 5)
        {
            break;
        }
        Console.WriteLine(i);
    }
    Console.WriteLine("end");
    
    • 跑第五次時遇到 break 跳離最近一層的 迴圈switch –> 接著執行 Console.WriteLine("end");
    • 執行結果

      1break

  • 程式碼範例 2 :雙層迴圈

    for (int a = 1; a <= 3; a++)
    {
        for (int i = 1; i <= 100; i++)
        {
            if (i == 5)
            {
                break;
            }
            Console.WriteLine($"第二層:{a}_{i}");
        }
        Console.WriteLine($"第一層:{a}");
    }
    
    Console.WriteLine("end");
    
    • 僅會跳離最近一層迴圈(本例來看就是變數 i 這層),外層 (變數 a 這層不受影響)
    • 執行結果

      2break2

continue

會跳離最近一層迴圈該次迴圈(該次迴圈 continue 之後的內容皆不會執行),執行(while,do,for,foreach)的下一個迭代(迴圈內容)

  • 程式碼範例 1 :單層迴圈

    for (int i = 1; i <= 10; i++)
    {
        if (i < 9)
        {
            continue;
        }
        Console.WriteLine(i);
    }
    
    Console.WriteLine("end");
    
    • i < 9 就跳離接著執行迴圈下一個內容直到 i >=9 才會執行到 Console.WriteLine(i);
    • 執行結果

      3continue

  • 程式碼範例 2 :雙層迴圈

    for (int a = 1; a <= 3; a++)
    {
        for (int i = 1; i <= 10; i++)
        {
            if (i < 9)
            {
                continue;
            }
            Console.WriteLine($"第二層:{a}_{i}");
        }
        Console.WriteLine($"第一層:{a}");
    }
    
    Console.WriteLine("end");
    
    • 僅會跳離最近一層迴圈(本例來看就是變數 i 這層),外層 (變數 a 這層不受影響)
    • 執行結果

      4continue2

goto

  1. 改執行標記程式碼區段位置

    for (int i = 1; i <= 10; i++)
    {
        if (i >= 9)
        {
            goto TestLabel;
        }
        Console.WriteLine(i);
    }
    
    Console.WriteLine("end");
        
        
    TestLabel:
        Console.WriteLine("Test goto label");
        Console.WriteLine("Test goto label1");
            
            
            
    Console.WriteLine("Test goto labe end");
    
    • i >= 9 就會跳至 TestLabel 重新開始執行
    • 執行結果

      6goto1

  2. 改執行 switch 中其他 case 區段或是 default 區段

    int n = default(int);
    int cost = default(int);
    n = 2;
    //n = 3;
    switch (n)
    {
        case 1:
            Console.WriteLine("case 1");
            cost += 25;
            break;
        case 2:
            Console.WriteLine("case 2");
            cost += 25;
            goto case 1;
        case 3:
            Console.WriteLine("case 3");
            cost += 50;
            goto default;
        default:
            Console.WriteLine("default");
            break;
    }
    Console.WriteLine($"n={n},end:{cost}");
    
    • n = 2 執行 case 2 後改執行 case 1

      • 執行結果

        5goto1

    • n = 3 執行 case 3 後改執行 default

      • 執行結果

        5goto2

  3. 用來跳離巢狀迴圈

    for (int a = 1; a <= 3; a++)
    {
        for (int i = 1; i <= 10; i++)
        {
            if ( a ==2 && i == 9)
            {
                goto TestLabel;
            }
            Console.WriteLine($"第二層:{a}_{i}");
        }
        Console.WriteLine($"第一層:{a}");
    }
    
    TestLabel:
    Console.WriteLine("Test goto label");
    Console.WriteLine("Test goto label1");
    Console.WriteLine("Test goto labe end");
    
    • 第一層執行第二次,第二層執行至第九次時,跳至 TestLabel 重新開始執行
    • 執行結果

      7gotoloop

return

  • 會停止所在方法的執行,將程式執行權回歸原呼叫方法並回傳值

    void Main()
    {
        Console.WriteLine("before function");
        Console.WriteLine($"call function result:{Getint()}");
        Console.WriteLine("after function");
        
    }
        
    int Getint()
    {
        Console.WriteLine("call function");
        int result= default(int);
        return result;
    }
    
    • 執行結果

      8return1

  • 可用來跳出迴圈,switch

    • 迴圈

      void Main()
      {
          for (int i = 1; i <= 10; i++)
          {
              if (i >= 9)
              {
                  return;
              }
              Console.WriteLine(i);
          }
              
          Console.WriteLine("end");
      }
      
      • 執行結果

        9return2

    • switch

      void Main()
      {
          int n = default(int);
          int cost = default(int);
          n = 2;
          //n = 3;
          switch (n)
          {
              case 1:
                  Console.WriteLine("case 1");
                  cost += 25;
                  break;
              case 2:
                  Console.WriteLine("case 2");
                  return;
                  cost += 25;
                  goto case 1;
              case 3:
                  Console.WriteLine("case 3");
                  cost += 50;
                  goto default;
              default:
                  Console.WriteLine("default");
                  break;
          }
          Console.WriteLine($"n={n},end:{cost}");
      }
      
      • 執行結果

        9return3

  • void 方法可以不寫 return,也沒回傳值,僅用來轉換程式執行權

    void Main()
    {
        Console.WriteLine("before function");
        test();
        Console.WriteLine("after function");
    }
        
    void test()
    {
        Console.WriteLine("CALL test");
        return ;
        Console.WriteLine("after return");
    }
    
    • 執行結果

      10return4

  • return 被 try 包著,會先執行 finally 內容

    void Main()
    {
        Console.WriteLine("before function");
        test();
        Console.WriteLine("after function");
    }
        
    void test()
    {
        try
        {           
            Console.WriteLine("function try");
            return;
        }
        catch (Exception ex)
        {
            Console.WriteLine("catch"); 
            throw;
        }
        finally
        {
            Console.WriteLine("function finally");
        }
            
    }
    
    • 執行結果

      11return5

參考資料

  1. break (C# Reference)
  2. continue (C# Reference)
  3. goto (C# Reference)
  4. return (C# Reference)