簡介:結構化與邏輯程式設計

歡迎來到結構化程式設計 (Structured Programming) 的章節!別擔心這個名字聽起來很複雜,它其實只是一套規則與最佳實踐,能幫助我們寫出清晰、易讀且容易修正(除錯/debug)的程式碼。

你可以把結構化程式設計想像成拼樂高積木。與其隨意亂堆,你透過說明書(結構)來確保你的成品既穩固又合理。

掌握了這些概念後,你將學會如何將程式碼組織成強大且合乎邏輯的步驟。這對每一位電腦科學家來說都至關重要!


1. 結構化程式設計的基石

結構化程式設計完全依賴三個基礎控制結構。無論你編寫的程式有多複雜,終究都只會運用這三種技術。

1.1 循序結構 (Sequence / 按步執行)

循序結構是最基本的控制結構。這意味著程式中的指令會按照它們編寫的確切順序,一條接一條地執行。

類比: 參考食譜或綁鞋帶。你必須先完成第 1 步,才能繼續進行第 2 步,以此類推。

• 執行指令 A。
• 接著執行指令 B。
• 最後執行指令 C。

重點筆記: 循序結構決定了程式執行時由上而下的線性流向。

1.2 選擇結構 (Selection / 做出決策)

選擇結構(或稱條件式/Conditionals)允許程式根據特定條件為真(TRUE)或為假(FALSE)來做出決策,進而決定程式將執行哪一條指令路徑。

我們常用到的架構包括 IFELSE IF(有時寫作 ELIF)以及 ELSE

選擇結構如何運作:

1. 程式檢查一個條件(例如:氣溫是否高於 20 度?)。
2. 如果條件為 TRUE,則執行一段程式碼。
3. 如果條件為 FALSE,則可能執行另一段不同的程式碼(即 ELSE 的部分)。

範例:

IF (User_is_18_or_older) THEN
    DISPLAY "歡迎,請進。"
ELSE
    DISPLAY "拒絕存取。"
END IF

重要提示: 當你需要檢查多個條件時,請使用 ELSE IF (ELIF),而 ELSE 則會捕捉所有未符合上述條件的情況。

快速回顧: 選擇結構讓你的程式能從兩個或多個可能性中選擇一條路徑。

1.3 重複結構 (Iteration / 重複與迴圈)

重複結構是指將一段程式碼重複執行多次。這對於節省時間並提升程式效率極為有用(試想如果必須手寫 100 次 "print 'Hello'" 會有多累!)。

你需要知道兩種主要的重複結構類型:

1.3.1 固定次數重複 (Definite Iteration):FOR 迴圈

當你預先精確知道程式碼需要重複多少次時使用。這是一種計數控制迴圈 (count-controlled loop)

類比: 在健身房計算次數。你預先決定要做 10 個伏地挺身(迴圈精確重複 10 次)。

FOR Count FROM 1 TO 10 DO
    // 程式碼區塊將執行 10 次
END FOR

1.3.2 條件控制重複 (Indefinite Iteration):WHILE 與 REPEAT 迴圈

當你預先不知道程式碼需要重複的確切次數時使用。迴圈取決於條件:

1. 前測條件迴圈 (WHILE...DO...END WHILE): 在執行程式碼區塊之前檢查條件。如果一開始條件為假,迴圈本體可能根本不會執行。

WHILE (Score_is_less_than_100) DO
    Add_Points()
END WHILE

2. 後測條件迴圈 (REPEAT...UNTIL): 先執行程式碼區塊,然後在結尾測試條件。因為檢查是在底部進行,所以裡面的程式碼至少會執行一次

REPEAT
    Enter_Password()
UNTIL (Password_is_valid)

避免常見錯誤:無窮迴圈 (The Infinite Loop)!
如果迴圈中的條件永遠無法被滿足或改變(例如 WHILE 5 > 2 DO...),迴圈將會永遠執行下去,導致程式卡住或崩潰。請務必確保迴圈本體會更新條件中測試的變數!


2. 模組化程式設計:程序、函式與變數作用域

隨著程式規模擴大,管理起來會變得更加困難。模組化程式設計 (Modular Programming)(或稱由上而下設計/top-down design)透過將龐大的程式分解成較小、獨立的迷你程式(稱為模組 (modules)子程式 (sub-programs))來解決此問題。

2.1 為什麼要使用模組(子程式)?

使用程序與函式非常重要,因為它能促進:

可讀性 (Readability): 主程式看起來更簡潔,更容易理解。
可維護性 (Maintainability): 如果發生錯誤(bug),你只需要查看該小型模組,而不需要翻遍整個龐大的程式。
可重用性 (Reusability): 你可以在程式的不同部分重複使用同一個模組(例如:計算稅額),甚至在不同程式中重複使用,而無需重新編寫。

2.2 程序 (Procedures)

程序是一組已命名的指令序列,旨在執行特定的任務。

• 它們用於執行某個動作(例如:顯示訊息、儲存檔案)。
• 程序執行完其指令後,會將控制權交回給主程式。
• 關鍵點在於,它們不一定會回傳值

範例: 一個程序可能名為 DisplayWelcomeMessage()。它執行其動作(顯示訊息)然後結束。它不會進行計算或回傳任何結果。

2.3 函式 (Functions)

函式與程序相似,但有一個關鍵差異:

• 函式旨在計算出一個數值
• 函式必須回傳一個值給主程式(或呼叫它的程式碼區段)。
• 它們就像迷你計算機。

範例: 一個函式可能名為 CalculateArea()。你給它寬與高,它執行計算,並回傳計算後的面積值。

記憶小撇步: Function (函式) 總是會回傳一個 Final (最終) 答案(數值)。而程序只是單純遵循指令。

2.4 參數 (Parameters / 傳遞資料)

我們如何將資料傳入程序與函式,讓它們完成工作?我們使用參數 (Parameters)(有時稱為引數 / Arguments)。

參數是一種用來在呼叫子程式時,將資料或資訊傳入其中的變數。

類比: 如果你的函式是果汁機,參數就是你放入果汁機的配料(水果、牛奶),這樣它才能製作果昔。

當你定義一個函式或程序時,你需要指定它所預期的參數:

FUNCTION CalculateArea (Width, Height)
    Area = Width * Height
    RETURN Area
END FUNCTION

當主程式呼叫 (calls) 此函式時,它會提供實際的資料:

My_Space = CalculateArea(10, 5) // 10 和 5 是被傳入的值

在此範例中:WidthHeight 是函式中定義的參數,而 105 則是使用函式時傳遞給這些參數的數值。

2.5 變數作用域:區域變數與全域變數

作用域 (Scope) 是指變數在程式不同部分中的可見性與可存取性:

區域變數 (Local Variables): 在特定子程式(函式或程序)內部宣告。它們在子程式執行時被建立,並在子程式結束時被銷毀。無法從該子程式外部存取或修改它們。
全域變數 (Global Variables): 在主程式中宣告,可在整個程式中的任何地方存取。

為什麼優先使用區域變數:
區域變數可以防止意外的副作用(對程式其他部分資料造成的非預期變更)、使子程式自成一體且更易於重用,並在子程式執行完畢後釋放記憶體。

你知道嗎? 模組化程式設計在 1960 年代是一個革命性的概念!在那之前,程式碼通常被寫成一長串令人困惑的區塊,讓除錯成為一場徹底的惡夢。結構化程式設計讓複雜軟體的誕生變得可能!


快速回顧盒:結構化程式設計精華

三大控制結構:

1. 循序結構 (Sequence): 按照先後次序做 A,接著做 B,最後做 C。
2. 選擇結構 (Selection): 使用 IF、ELSE IF (ELIF) 和 ELSE 檢查條件。
3. 重複結構 (Iteration): 使用固定次數迴圈 (FOR) 或條件控制迴圈 (WHILE、REPEAT...UNTIL) 重複程式碼。

模組化程式設計與作用域:

程序 (Procedure): 執行任務;不需要回傳值。
函式 (Function): 計算數值;必須回傳值。
參數 (Parameter): 呼叫時傳入子程式的資料。
區域作用域 (Local Scope): 變數僅限於子程式內部,避免非預期的全域副作用。