[C#] #3 迴圈語句基本介紹、範例

C# 有幾個比較常見的迴圈語句 [1]

  • For 迴圈
  • Foreach 迴圈
  • While 迴圈
  • Do-while 迴圈

簡單來說迴圈語句是用來反复執行一個語句或者一塊程式。

Break & Continue

在任何時刻,可以使用 break 語句從迴圈中跳出。可以使用 continue 語句跳到迴圈中的下一個的迴圈。

for 迴圈

For 迴圈會一直執行,直到設定的變數變成 false。<br> For 迴圈有四個部分:

  1. 初始化器(initializer)
  2. 條件(condition)
  3. 疊代器(iterator)
  4. 迴圈主體(for loop body)

語句:

for (int i = 0; i < 5; i++)
{
    // for 迴圈主體
    Console.WriteLine(i);
}

初始化器(可選):int i = 0
條件(可選):i < 5
疊代器(可選):i++
主體(必須):Console.WriteLine(i)

初始化器只會在迴圈開始時執行一次。
條件每次迴圈執行時都會檢查,如果條件為 false,則退出迴圈。
疊代器會在每次迴圈後執行一次。
主體會在每次迴圈時執行一次。

範例 1:(普通的 for 迴圈)

for (int i = 0; i <= 3; i++)
{
    // for 迴圈主體
    Console.WriteLine(i);
}

輸出:
0
1
2
3

這個迴圈會執行 4 次,因為條件只有當 i 大於 3 時才為 false。

範例 2:(在迴圈主體中使用疊代器)

for (int num = 1; num < 5;)
{
    num++; // 可以在迴圈主體中寫入疊代器
    Console.WriteLine(num);
}

輸出:
2
3
4
5

範例 3:(在迴圈主體中使用條件與疊代器)

for (int temp = 10; ;)
{
    if (temp == 0)
    {
        break; // 如果 temp 為 0,則退出迴圈
    }
    Console.WriteLine(temp);

    temp -= 2; // 每次迴圈 temp 減少 2
}

輸出:
10
8
6
4
2

範例 4:(將初始化器放在迴圈外,條件和疊代器在迴圈內)

int counter = 5;

for (; ; )
{
    if (counter < 0 )
    {
        break;
    }

    if (counter == 3)
    {
        counter--;
        continue; // 當 counter 為 3 時,跳過此次迴圈的剩餘部分
    }

    Console.WriteLine("Counter: {0}", counter);
    counter--;
}

輸出:
Counter: 5
Counter: 4
Counter: 2
Counter: 1
Counter: 0


注意事項:

  1. 不建議寫無限迴圈條件(如 for (;;)),如果需要這樣的迴圈,最好使用 while 迴圈。
  2. 請小心條件與疊代器,這可能會導致無限迴圈,例如:
for (int i = 0; i < 5; i--) // 將導致無限迴圈,因為條件永遠不會成立 (i 一直減, 而條件是正5)
{
    Console.WriteLine(i);
}

巢狀(Nested) For 迴圈

巢狀 for 迴圈適合處理二維數據,例如在某些排序算法中。

範例 1:

List<List<int>> workersAge = new List<List<int>>
{
    new List<int>{1, 20},
    new List<int>{2, 25},
    new List<int>{3, 22},
    new List<int>{4, 18}
}; // 宣告一個 list, 每個 List 內有 List<int> 物件,形成一個二維陣列

Console.WriteLine("No   Age");
for (int i = 0; i < workersAge.Count; i++)
{
    for (int j = 0; j < workersAge[i].Count; j++)
    {
        Console.Write(workersAge[i][j] +  "    ");
    }
    Console.WriteLine();
}

輸出:
No Age
1 20
2 25
3 22
4 18

範例 2:(氣泡排序,最簡單的排序算法)

List<int> numbers = new List<int> { 4, 6, 2, 6, 1, 9, 8, 6, 3, 5 };
// 氣泡排序
for (int i = 0; i < numbers.Count - 1; i++)
{
    for (int j = i + 1; j < numbers.Count; j++)
    {
        if (numbers[i] > numbers[j]) // 交換元素
        {
            int temp = numbers[i];
            numbers[i ] = numbers[j];   
            numbers[j] = temp;
        }
    }
}

foreach(int i in numbers)
{
    Console.Write(i + " ");
}

輸出:
1 2 3 4 5 6 6 6 8 9

foreach 語句

Foreach 是一種特殊的迴圈,只會有用IEnumerable<T> 介面的物件。你不需要馬上理解 IEnumerable<T>,只需記住它代表可以被巡訪的集合,例如 List<t> 就使用了 IEnumerable<T> 介面。你也可以創建自己的可巡訪物件, 請參考 [2]

範例 1:

List<string> WeekDay = new List<string> {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};

Console.Write("Day in WeekDay: ");
foreach (string aDay in WeekDay)
{
    Console.Write(aDay + ", ");
}

輸出:
Day in WeekDay: Monday, Tuesday, Wednesday, Thursday, Friday

範例 2:(巢狀 Foreach)

List<List<int>> workersAge = new List<List<int>>
{
    new List<int>{1, 20 },
    new List<int>{2, 25 },
    new List<int>{3, 22 },
    new List<int>{4, 18 }
}; // 宣告一個 list, 每個 List 內有 List<int> 物件,形成一個二維陣列

Console.WriteLine("No   Age");
foreach(List<int> obj in workersAge)
{
    foreach(int age in obj) // 
    {
        Console.Write(age + "    ");
    }
    Console.WriteLine();
}

輸出:
No Age
1 20
2 25
3 22
4 18

While 迴圈

如果你理解 for 迴圈,那麼你會很快理解 while 迴圈。基本上,while 迴圈與 for 迴圈執行相同的工作,差別在於 while 迴圈沒有初始化和疊代部分,但仍有條件部分。可以說 for (;;)while 迴圈相同,但為了更好的可讀性,建議使用 while 迴圈。

範例 1:(普通的 while 迴圈)

int myBankAccount1 = 1000; // 單位:百萬(美元)

while(myBankAccount1 > 900)
{
    myBankAccount1 -= 20; // 同等於 myBankAccount1 = myBankAccount1 - 20
    Console.WriteLine("我買了一棟豪宅,我的銀行帳戶現在剩下: " + myBankAccount1 + " 百萬美元");
}

輸出:
我買了一棟豪宅,我的銀行帳戶現在剩下: 980 百萬美元
我買了一棟豪宅,我的銀行帳戶現在剩下: 960 百萬美元
我買了一棟豪宅,我的銀行帳戶現在剩下: 940 百萬美元
我買了一棟豪宅,我的銀行帳戶現在剩下: 920 百萬美元
我買了一棟豪宅,我的銀行帳戶現在剩下: 900 百萬美元

範例 2:(無條件,使用 break 和 continue)

while (true)
{
    if (myBankAccount2 <= 900)
    {
        break;
    }
     else if (myBankAccount2 == 940)
    {
        myBankAccount2 -= 40; // Same as myBankAccount2 = myBankAccount2 - 40
        Console.WriteLine("I purchased a mansion, my bank account is now: " + myBankAccount2 + " million USD");
        continue; // Skip the rest of the loop body
    }
    myBankAccount2 -= 20; // Same as myBankAccount2 = myBankAccount2 - 20
    Console.WriteLine("I purchased a mansion, my bank account is now: " + myBankAccount2 + " million USD");
}

輸出: 我買了一棟豪宅,我的銀行帳戶現在剩下: 980 百萬美元
我買了一棟豪宅,我的銀行帳戶現在剩下: 960 百萬美元
我買了一棟豪宅,我的銀行帳戶現在剩下: 940 百萬美元
我買了一棟豪宅,我的銀行帳戶現在剩下: 900 百萬美元

注意: 使用 while(true) 會創建無限迴圈,因此使用時請小心。如果使用 while(true),請確保在迴圈內有條件並使用 break 語句。

Do-while 迴圈

do-while 迴圈與 while 迴圈相似,主要區別在於 do-while 迴圈無論條件如何,都至少會執行一次,並且結構也有些不同。我們來看一下語句結構。
記住:do-while 迴圈無論條件如何,都會執行至少一次。

範例 1:

do
{   
    // 此程式區塊會執行一次,不管條件如何
    myFriendBankAccount -= 1000;
    Console.WriteLine("他收購了一家公司,他的銀行帳戶現在剩下: " + myFriendBankAccount);
}
while (myFriendBankAccount > 4000); // while 迴圈的條件在底部

輸出:
他收購了一家公司,他的銀行帳戶現在剩下: 4000

注意: 它會執行 do 區塊一次,不論 while 條件如何。

範例 2:(使用 while(true) 條件)

int mySisterBankAccount = 2000; // 單位:百萬(美元)

do
{
    if (mySisterBankAccount > 3000)
    {
        Console.WriteLine("我姐姐現在擁有了很多錢");
        break; // 當條件滿足時,退出迴圈
    }

    mySisterBankAccount += 500;
    Console.WriteLine("成功賣出十萬件衣服");

} while (true);

輸出:
成功賣出十萬件衣服
成功賣出十萬件衣服
成功賣出十萬件衣服
我姐姐現在擁有了很多錢

References :

[1] https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/iteration-statements#c-language-specification

[2] https://vegeee-csharp.blogspot.com/2017/02/c-ienumerableienumerator-ienumerable.html