你好,未來的電腦科學家!這一章非常重要。我們將不再僅僅是編寫程式碼,而是要學習如何像專業軟體工程師一樣去「設計」程式。「結構化編程」(Structured Approach)是構建大型、可靠且易於理解的軟體之基本技術。試著將其想像成整理你的程式開發工具箱,讓你不僅能蓋出簡單的小屋,還能建造出摩天大樓!

不用擔心這些術語聽起來太正式,我們會用簡單的例子把它們拆解開來。

3.3.1 結構化編程方法

結構化編程是一種程式設計理念。這意味著我們利用一組有限的邏輯控制結構(例如選擇結構和疊代結構)來構建程式,而最重要的是,透過將程式拆解為較小且獨立的程式區塊來完成。

結構化設計的核心概念

課程大綱「程式設計」部分中的兩個基本概念,能幫助我們有效地運用結構化編程:

1. 分解(Decomposition) (課程大綱 3.3.2)
比喻:準備一頓豐盛的大餐。

分解是指將複雜的問題拆解為若干個更小、更易於管理的子問題(或任務)的過程。每個子問題都應執行一個可識別的、具體的任務。在編程中,這些任務通常透過子程式(subroutines)來實現。

2. 抽象(Abstraction) (課程大綱 3.3.2)
比喻:使用遙控器。

抽象是指為了簡化問題的解決方案而移除不必要的細節。當編寫子程式時,你只需要知道它「做什麼」(what),而不一定需要知道它「如何」(how)執行內部的每一個計算。這能簡化整個程式的結構。

重點回顧:目標

結構化編程的主要目標是確保程式碼清晰、合乎邏輯且易於測試,這通常透過受控的模組來達成。

3.3.1.1 模組化編程

模組化編程(Modularised programming)是分解原則的實際應用。與其編寫一個巨大的程式碼區塊,我們不如建立獨立、可重複使用的區塊,這些區塊稱為模組(modules)子程式(subroutines)(例如程序 Procedures 或函數 Functions)。

子程式是一個有命名的「獨立」程式碼區塊,可以透過在程式語句中寫下其名稱來執行(呼叫)(課程大綱 3.1.2.7)。

模組化的優點
  • 更容易除錯(Debug):如果程式出錯,你會知道錯誤被限制在特定的模組內,因此更容易隔離並修正它。
  • 可重用性(Reusability):一旦編寫好一個模組(例如計算稅率的函數),它可以在同一個程式中多次使用,甚至在完全不同的程式中使用。
  • 可維護性(Maintainability):如果需求變更,你只需要更新一個特定的模組,而不需要更動系統的其他部分。
  • 團隊合作:多名程式設計師可以同時開發不同的模組,從而加快開發速度。

3.3.1.2 控制流程與數據:參數與變數作用域

為了讓模組以結構化的方式有效協作,我們需要嚴格的規則來規範它們如何交換數據以及如何管理變數。

A. 參數與回傳值

模組使用參數(parameters)從呼叫它的程式接收輸入數據,並使用回傳值(return values)將結果傳回。

  • 參數:呼叫子程式時傳遞「進去」的數據。
  • 回傳值:由子程式計算得出並傳回給呼叫者的數據。

例子:如果你有一個名為 CalculateArea(計算面積)的模組,參數可能是 (Length, Width)(長、寬),而回傳值將會是 Area(面積)。

B. 區域變數與全域變數的使用

作用域(scope)的概念定義了變數在程式中哪些地方可以被存取或修改。控制作用域對於結構化非常重要,因為它可以防止模組意外地干擾彼此的數據。

1. 全域變數(Global Variables) (課程大綱 3.1.2.7)

  • 定義:宣告在任何子程式之外的變數,可在整個程式中存取和修改。
  • 風險:如果多個模組都能更改同一個全域變數,就很難追蹤為什麼以及何時會出現意外的數值。這是不好的結構!

2. 區域變數(Local Variables) (課程大綱 3.1.2.7)

  • 定義:宣告在特定子程式(或程式碼區塊)內的變數。
  • 可存取性:它們僅在子程式執行時存在,並且僅能在該子程式內存取。
  • 優點(良好習慣):將變數的作用域限制在區域層級是良好的編程習慣。這能確保一個模組內的動作不會對程式的其他部分產生預期之外的副作用。

你知道嗎?
當子程式執行完畢後,區域變數就會「死亡」,從而釋放記憶體。而全域變數則會一直存在,直到整個程式結束為止。

避免常見錯誤!

過度依賴全域變數違背了模組化的初衷。如果你的模組經常需要讀取或寫入全域數據,它們就不是真正獨立的。請改用參數和回傳值來傳遞資訊!

3.3.1.3 設計結構:階層圖與結構圖

使用結構化編程時,我們需要工具在編寫程式碼之前將模組的分解與關係視覺化。這就是圖表發揮作用的地方。

A. 階層圖(Hierarchy Charts)

階層圖(或 H-Chart)以由上而下的方式顯示程式中模組之間的關係。它顯示了誰呼叫了誰

  • 最頂層的方框代表主程式。
  • 下方的每一層顯示了被上一層模組呼叫的子模組。
  • 它們純粹專注於控制流程(執行的順序)。

比喻:公司的組織架構圖。執行長(主程式)將任務分派給經理(模組 A、模組 B),再由經理分派給員工(子模組)。

B. 結構圖(Structure Charts)

結構圖比階層圖更詳細。它們不僅顯示控制流程(誰呼叫誰),還顯示了模組之間的數據流(data flow)

  • 它們使用帶標籤的箭頭來指示哪些數據(參數和回傳值)在模組之間傳遞。
  • 這些圖表有助於設計師確保模組真正獨立,並僅透過定義好的介面(參數)進行通訊。

設計圖表的關鍵總結:
階層圖展示了模組化的拆解與控制。結構圖則增加了關於這些模組之間交換的特定數據的詳細資訊。

總結:為什麼結構很重要?

結構化編程方法依賴於三大支柱:

  1. 模組化:將程式拆解為獨立的子程式。
  2. 受控的數據交換:使用參數和回傳值,而不是依賴全域變數。
  3. 受控的作用域:在模組內部使用區域變數,以防止對程式其餘部分產生預期之外的副作用。

遵循這種方法,你能確保程式穩健、易於維護且邏輯清晰——這是任何優秀程式設計師的必備技能!