CodeGym /課程 /C# SELF /巢狀迴圈及其應用

巢狀迴圈及其應用

C# SELF
等級 4 , 課堂 5
開放

1. 前言

先來問個問題:為什麼我們要把一個迴圈放進另一個迴圈裡?其實很多時候,我們的資料或任務不是單純一條線,而是像表格、網格,甚至多維結構。假設你想印出乘法表、走訪二維陣列,或是計算所有元素對的交集,這時候一個迴圈就不夠用了——你需要巢狀迴圈。

在程式裡,巢狀迴圈就像兩個鬧鐘:外面的開始響,裡面那個每次都會響,直到外面的還在響。也就是說,每次外層「迭代」時,內層都會完整跑一遍(而且每次外層都會再來一次)。

一個很棒的例子就是時鐘和分鐘。時鐘是外層迴圈,從 023,分鐘是內層,從 059。每當外層變動一次,內層都會跑完所有值。

2. 巢狀迴圈語法

在 C# 裡,巢狀迴圈的語法跟一般迴圈沒兩樣——你只要在一個迴圈的 主體裡面 再寫一個就好。來看一下 forwhile 的例子:


for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 4; j++)
    {
        Console.Write($"{i},{j} ");
    }
    Console.WriteLine();
}
用巢狀 for 迴圈印出座標

這裡外層迴圈控制變數 i(從 02),內層控制 j(從 03)。每個 i,內層都會從 j=0 跑到 j=3。執行這段程式,你會看到很整齊的座標表格:

0,0 0,1 0,2 0,3 
1,0 1,1 1,2 1,3 
2,0 2,1 2,2 2,3 

while 也可以做到一樣:

int i = 0;
while (i < 3)
{
    int j = 0;
    while (j < 4)
    {
        Console.Write($"{i},{j} ");
        j++;
    }
    Console.WriteLine();
    i++;
}

注意:每次外層跑的時候,內層的變數(j)都要重新初始化,不然你只會看到一行!

3. 巢狀迴圈的實戰例子

例子 1:印出棋盤(8x8)

我們第一個任務——用巢狀 for 迴圈印出經典的棋盤(黑白格,# 代表黑格,_ 代表白格):


for (int row = 0; row < 8; row++)
{
    for (int col = 0; col < 8; col++)
    {
        if ((row + col) % 2 == 0)
            Console.Write("_");
        else
            Console.Write("#");
    }
    Console.WriteLine();
}
巢狀迴圈印出棋盤

結果:

_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_
_#_#_#_#
#_#_#_#_

重點:巢狀的好處就是每一行(row)都能完整走過所有欄(col)。如果沒巢狀,只會有一行或一欄,根本不像棋盤。

例子 2:乘法表

這是巢狀迴圈的經典範例!我們來印出 1-9 的乘法表:


for (int i = 1; i <= 9; i++)
{
    for (int j = 1; j <= 9; j++)
    {
        Console.Write($"{i * j,3} ");
    }
    Console.WriteLine();
}
巢狀迴圈印出乘法表

${i * j,3} 這個格式化會自動補空格,讓表格看起來很整齊。

結果:

   1   2   3   4   5   6   7   8   9
  2   4   6   8  10  12  14  16  18 
  3   6   9  12  15  18  21  24  27 
  4   8  12  16  20  24  28  32  36 
...
  9  18  27  36  45  54  63  72  81 

4. 巢狀迴圈的控制細節

巢狀迴圈裡 breakcontinue 的影響

這裡很多新手會搞混!如果你在內層用 breakcontinue,它只會影響 那一層。外層還是會繼續跑,完全沒事。


for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 5; j++)
    {
        if (j == 3)
            break; // 只跳出內層!
        Console.Write($"{i},{j} ");
    }
    Console.WriteLine();
}
break 只會跳出內層迴圈

結果:

0,0 0,1 0,2 
1,0 1,1 1,2 
2,0 2,1 2,2 

如果你想一次跳出兩層(比如在表格裡一找到就要馬上結束),通常會用 flag 或特殊寫法(像 return,如果在 function 裡)。

5. 巢狀迴圈的視覺化

有時候很難「看到」巢狀迴圈的執行順序。來看這個流程圖:

巢狀迴圈視覺化

用表格來看——如果 i13j14,總共會有幾次迭代?

i j(每個 i 都會跑這些) 內層迴圈次數
1 1, 2, 3, 4 4
2 1, 2, 3, 4 4
3 1, 2, 3, 4 4
總共:3 × 4 = 12

6. 巢狀迴圈常見錯誤與陷阱

常見錯誤——內層變數初始化錯誤。比如你在外層宣告,卻沒每次都重設,結果內層可能根本不會跑,或是跑錯。

int j = 0;
for (int i = 0; i < 3; i++)
{
    while (j < 4) // 哎呀!j 在第一次後可能已經等於 4 了。
    {
        Console.Write($"{i},{j} ");
        j++;
    }
    Console.WriteLine();
}

這樣只會跑一次。記得內層變數一定要 在外層裡面 初始化!

還有,如果你不小心在巢狀裡用一樣的變數名,編譯器會罵你:變數已經宣告過了。


for (int i = 0; i < 3; i++)
{
    for (int i = 0; i < 3; i++)
    {
        Console.Write($"{i},{i} ");
    }
    Console.WriteLine();
}
2
任務
C# SELF, 等級 4, 課堂 5
上鎖
西洋棋盤
西洋棋盤
2
任務
C# SELF, 等級 4, 課堂 5
上鎖
乘法表
乘法表
1
問卷/小測驗
迴圈,等級 4,課堂 5
未開放
迴圈
巢狀迴圈跟它們的應用
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION