iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
Software Development

程式基礎概念討論系列 第 10

[DAY 10] 讓重複的事情不用一提再提的迴圈陳述式 (上):while 迴圈

  • 分享至 

  • xImage
  •  

在我們了解了條件陳述式後,下一個要討論的就是迴圈陳述式了。當我們在編寫程式時,有時候有些程式碼會需要重複執行多遍、或是讓程式多次執行相似的行為。如果我們為了重複執行而把相似的程式碼重複編寫多次的話,不只會耗費掉我們大量的心力和時間,也會讓程式變得更難維護和缺少應對不同狀況的彈性。

舉例來說,當我們想要透過程式來列出九九乖法表時,如果把程式碼重複編寫多次的話:[Python]

print("1 x 1 = " + str(1 * 1))
print("1 x 2 = " + str(1 * 2))
print("1 x 3 = " + str(1 * 3))
print("1 x 4 = " + str(1 * 4))
.
.
.
print("9 x 7 = " + str(9 * 7))
print("9 x 8 = " + str(9 * 8))
print("9 x 9 = " + str(9 * 9))

這時候我們會發現程式碼實際上是一直在重複著非常相似的句子,當我們使用變數 a 跟變數 b 來把這些句子之間的不同之處取代時,我們就可以很清晰的看到它們的句子架構一模一樣:

print("[a] x [b] = " + str([a] * [b])

那我們是不是可以讓程式來代替我們進行這些重複的行為?在這樣的想法下,便誕生了迴圈陳述式。

迴圈陳述式

迴圈陳述式 (Loop Statements) 是用來讓程式重複執行指定的行為的陳述式。迴圈陳述式的概念可以說是條件陳述式的一種延伸應用方式,它的主要構成部分有:

  1. 迴圈的開始
  2. 用來檢查是否繼續執行迴圈的條件 (主要為布林值資料或比較運算式)
  3. 跳轉動作
  4. 重複執行的陳述式 (可多於一項)
  5. 能影響作為條件的變數或運算式的值的部分
  6. 迴圈的結束

根據不同種類的迴圈陳述式,這些構成部分的排列跟執行的順序可能會有所變化,也有迴圈陳述式會在同一句的程式碼中包含多個構成部分,但這些構成部分還是會全部出現在陳述式中。

以下是一個簡單的迴圈陳述式的範例架構:

// 迴圈的開始部分
如果 條件為真 時:
    執行 陳述式 (可多於一項)
    改變某些能影響條件的變數
    跳轉到迴圈的開始部分
否則:
    跳轉到迴圈的結束部分
// 迴圈的結束部分

從上面的架構中,我們會發現迴圈陳述式其實是一個不斷重複執行的條件陳述式,只是每次在執行完陳述式時,我們會回到開始部分及再一次進行條件陳述式的條件判斷行為。因此在執行完陳述式後我們在不再需要執行迴圈時在迴圈中改變跟條件有關的變數來確保迴圈能夠結束而不會陷入無法停止一直執行迴圈部分的無限迴圈 (infinity loop)

迴圈陳述式主要有 while 迴圈 (While Loop) 跟 for 迴圈 (For Loop) 兩種,而今天我們會討論的是 while 迴圈。

while 迴圈陳述式

while 迴圈陳述式是 while 迴圈中最基本的架構。while 迴圈陳述式的基本架構如下:

while 條件:
    陳述式

當我們把構成部分放進去看時:

[迴圈的開始部分]
while 條件:[檢查條件部分, 條件為假時跳轉到迴圈的結束部分]
    陳述式 [重複執行部分, 改變某些能影響條件的變數部分]
    [跳轉到迴圈的開始部分]
[迴圈的結束部分]

現在,就讓我們使用 while 迴圈陳述式來再次挑戰列出九九乖法表吧:[Python]

# 準備用來檢查及迴圈中使用的變數
a = 1
b = 1
# 迴圈開始
while a < 10: # 檢查條件來決定是否執行迴圈:a 是否少於 10 (1)
    print(str(a) + " x " + str(b) + " = " + str(a * b)) # 顯示: [a] x [b] = [a*b]
    b += 1 # b = b + 1
    if b > 9: # 如果:b 大於 9 時 (2)
        b = 1 
        a += 1 # 改變迴圈檢查的變數 a
# 迴圈結束

這樣一來,程式碼便變得比之前的版本簡潔,也更容易進行後續的調整及修改,例如把檢查條件改變後我們就能讓程式列出 1 到我們指定數字的乖法表了。

當然,像上面的例子中我們其實有兩次檢查條件的部分,因此也可以使用巢狀架構來讓程式看起來更直觀一點:[Python]

# 準備用來檢查及迴圈中使用的變數
a = 1
b = 1
# 迴圈 1 開始
while a < 10: # 檢查條件來決定是否執行迴圈:a 是否少於 10 (1)
    b = 1
    # 迴圈 2 開始
    while b < 10: # 檢查條件來決定是否執行迴圈:b 是否少於 10 (2)
        print(str(a) + " x " + str(b) + " = " + str(a * b)) # 顯示: [a] x [b] = [a*b]
        b += 1 # 改變迴圈 2 條件檢查的變數 b
    # 迴圈 2 結束
    a += 1 # 改變迴圈 1 條件檢查的變數 a
# 迴圈 1 結束

不過,需要注意的是,當我們在巢狀架構中使用的 while 迴圈越多,我們越容易陷入混亂而出改變錯誤迴圈檢查的變數而引發無限迴圈。因此,我會較推薦大家避開使用或儘可能使用較少的迴圈數的巢狀 while 迴圈。

do while 迴圈陳述式

do while 迴圈陳述式是 while 迴圈的一個延伸變體,因此有些程式語言並不會提供 do while 迴圈陳述式。從上面 while 迴圈陳述式的架構中,我們可以知道 while 迴圈陳述式是先檢查條件後再執行迴圈的內容。因此,在一些極端的情況下,會出現程式在第一次檢查條件時便直接跳到結束部分,也就是說迴圈的內容完全被略過掉而沒有被執行。這時,有人便提出了先執行一次迴圈的內容才檢查條件的概念來避開這些迴圈的內容完全沒有被執行的情況,那就是 do while 迴圈陳述式。do while 迴圈陳述式的基本架構如下:

do:
    陳述式
while 條件

當我們把構成部分放進去看時:

do:[迴圈的開始部分]
    陳述式 [重複執行部分, 改變某些能影響條件的變數部分]
while 條件 [檢查條件部分, 條件為真時跳轉到迴圈的開始部分, 否則跳轉到迴圈的結束部分]
[迴圈的結束部分]

我們可以發現它的架構除了把檢查條件部分放在重複執行部分的後面外,跟一般的 while 迴圈陳述式的運作方式是一樣的。而這樣的改動便讓我們能必定執行重複執行的部分最少一次

接下來,就讓我們來看一下使用 do while 迴圈陳述式來列出九九乖法表的例子吧:[C#]

using System;

public class MultipleList
{
    public static void Main(string[] args)
    {
        int a = 1, b = 1; // 準備用來檢查及迴圈中使用的變數
        do { // 迴圈開始
            Console.WriteLine(a.ToString() + " x " + b.ToString() + " = " + (a * b).ToString());  // 顯示: [a] x [b] = [a*b]
            b++; // b = b + 1
            if (b > 9) { // 如果:b 大於 9 時
                b = 1;
                a++; // 改變迴圈檢查的變數 a
            }
        } while (a < 10); // 檢查條件來決定是否執行迴圈:a 是否少於 10
    }
}

大家可能會發現,當我們執行上面的例子時,無論使用 while 迴圈陳述式跟 do while 迴圈陳述式都會有一樣的結果。結合它們各自的設計目的來看的話,我們便能知道在一般的狀況下,大家可以隨自己喜好來挑選使用這兩個 while 迴圈,只有在需要應對極端的狀況時,我們才需要根據是否需要執行迴圈的內容最少一次來決定使用哪一種 while 迴圈


上一篇
[DAY 9] 把所有可能全都列出來的條件陳述式 (下): switch 陳述式
下一篇
[DAY 11] 讓程式重複指定次數的迴圈陳述式(下):for 迴圏
系列文
程式基礎概念討論30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言