歡迎來到程式設計概念!

各位未來的程式設計師,大家好!這個章節是真正有趣的地方。我們將從理解電腦如何運作(硬體與資料)轉變為向電腦發出具體、循序漸進的指令——這正是程式設計的核心所在!

學習這些基本概念將使你能夠設計、編寫並理解任何演算法,為 Paper 2 的實作解題作好萬全準備。如果剛開始覺得程式碼很陌生,請別擔心;我們會將所有內容拆解成易於理解的部分。讓我們開始吧!

8.1 程式設計概念:建構基礎

8.1.1 變數與常數

你可以將變數與常數想像成電腦記憶體中具有名稱的儲存盒。

變數 (Variables)

變數是指記憶體中的一個位置,用於儲存一個在程式執行期間可以改變的值。
範例:玩家的「分數」(Score) 會隨著遊戲進行而改變。

常數 (Constants)

常數是指記憶體中的一個位置,用於儲存一個在程式執行期間不能改變的值。
範例:圓周率 (\(\pi\)) 的值或固定的「稅率」(TaxRate)。

在虛擬碼 (pseudocode) 中,我們使用關鍵字來宣告它們:

  • 變數宣告:
    DECLARE TotalScore : INTEGER
  • 常數宣告:
    CONSTANT MaxAttempts ← 3
  • 賦值: 我們使用賦值運算子 將數值放入變數中。
    TotalScore ← 100

8.1.2 基本資料型態 (Data Types)

當你宣告變數或常數時,必須告訴電腦它將儲存什麼類型的資料。這有助於電腦配置正確數量的記憶體空間並防止錯誤。
比喻:資料型態就像是給容器貼標籤——如果標籤寫著「水」,你就絕對不會嘗試把電存進去!

你需要掌握的基本資料型態包括:

  • INTEGER (整數): 一個整數(正數、負數或零)。沒有小數點。
    字面值:5, -100, 0
  • REAL (實數/浮點數): 可以包含小數部分的數字。
    字面值:3.14, -0.5, 4.0
  • CHAR (字元): 單個字母、數字或符號。需用單引號包圍。
    字面值:'A', '7', '@'
  • STRING (字串): 一系列字元(文字)。需用雙引號包圍。
    字面值:"Hello World", "CS0478"
  • BOOLEAN (布林值): 只能是 TRUE(真)或 FALSE(假)的邏輯值。
    字面值:TRUE, FALSE
重點回顧:

如果你要儲存某人的年齡,請使用 INTEGER。如果要儲存姓名,使用 STRING。如果要在檢查燈是亮著(ON)還是熄滅(OFF),請使用 BOOLEAN

8.1.3 輸入與輸出 (I/O)

程式需要與使用者互動。這是透過 I/O 指令來處理的。

  • INPUT (輸入): 從使用者(通常是鍵盤)讀取資料並將其存入變數。
    語法:INPUT <變數>
    範例:INPUT UserName
  • OUTPUT (輸出): 將資料或訊息顯示給使用者(通常是螢幕)。
    語法:OUTPUT <數值/變數>
    範例:OUTPUT "Hello, ", UserName

8.1.4 (f) 運算子 (Operators)

運算子是用來執行計算或比較的特殊符號。

算術運算子 (Arithmetic Operators)

用於執行數學運算:

  • + (加法)
  • - (減法)
  • * (乘法)
  • / (除法,結果為 REAL)
  • ^ (次方,例如 \(2^3\))
  • DIV: 整數除法(返回商數,捨棄餘數)。
    範例:DIV(10, 3) 返回 3
  • MOD: 取餘數(返回整數除法後的餘數)。
    範例:MOD(10, 3) 返回 1

記憶小技巧: MOD 是除完後的「餘數」或「剩餘部分」。DIV 是除法中「完整包含了幾次」。

關聯運算子 (Relational Operators)

用於比較兩個數值,並始終返回一個 BOOLEAN 結果(TRUE 或 FALSE)。

  • = (等於)
  • < (小於)
  • <= (小於或等於)
  • > (大於)
  • >= (大於或等於)
  • <> (不等於)
邏輯運算子 (Logical Operators)

用於結合多個布林條件。

  • AND: 僅當所有條件皆為 TRUE 時,結果才為 TRUE。
  • OR: 只要至少有一個條件為 TRUE,結果即為 TRUE。
  • NOT: 反轉條件(TRUE 變為 FALSE,FALSE 變為 TRUE)。

範例:IF (Age > 18) AND (IsCitizen = TRUE) THEN...

運算子重點總結: 算術運算子產生數字。關聯與邏輯運算子產生 BOOLEAN 值(用於決策)。

8.1.4 控制結構:順序、選擇、迭代

(a) 順序 (Sequence)

順序是最簡單的控制結構。指令按照它們出現的順序,一個接一個地執行。這是程式的預設流程。

範例:
1. Total ← 0
2. Number1 ← 10
3. Total ← Total + Number1

(b) 選擇 (Selection)

選擇允許程式根據條件(布林測試)來決定執行哪個程式碼區塊。

IF 陳述式

用於一種或兩種可能的結果:

IF <條件> THEN
    <陳述式>
ELSE
    <陳述式>
ENDIF
CASE 陳述式

用於根據單一變數的值有多種可能的結果時。

INPUT Grade
CASE OF Grade
    'A' : OUTPUT "優異"
    'B' : OUTPUT "良好"
    OTHERWISE OUTPUT "需改進"
ENDCASE
巢狀陳述式 (8.1.5)

巢狀陳述式 (Nested statement) 是指將一個選擇或迭代結構完整放置在另一個結構內部。這對於複雜邏輯至關重要。
考試中通常不需要編寫超過三層的巢狀結構。

巢狀 IF 範例:

IF Score > 50 THEN
    IF Score > 90 THEN // 巢狀 IF
        OUTPUT "頂尖成績!"
    ELSE
        OUTPUT "及格"
    ENDIF
ELSE
    OUTPUT "不及格"
ENDIF

(c) 迭代 (Iteration/Looping)

迭代意味著多次重複一段程式碼。主要有三種類型:

1. 計數循環 (FOR Loop)

當你準確知道循環需要運行多少次時使用。

  • 它會自動初始化、檢查並遞增(或遞減)計數器變數。
FOR Counter ← 1 TO 10
    OUTPUT "循環次數: ", Counter
NEXT Counter
2. 前置條件循環 (WHILE Loop)

在循環執行之前先檢查條件。如果條件初始即為 FALSE,則循環內部的程式碼將永遠不會執行(執行零次)。

WHILE <條件> DO
    <陳述式>
ENDWHILE
3. 後置條件循環 (REPEAT UNTIL Loop)

在循環執行之後才檢查條件。這保證了循環內部的程式碼至少會執行一次。循環會持續進行,直到條件變為 TRUE 為止。

REPEAT
    <陳述式>
UNTIL <條件>

常見錯誤提醒: WHILE 循環在條件為 TRUE 時持續運行。REPEAT UNTIL 循環則是「直到」條件變為 TRUE 時停止(也就是說,只要條件還是 FALSE,它就會繼續運行)。

8.1.4 (d, e) 累加、計數與字串處理

(d) 累加與計數 (Totalling and Counting)

這是循環內常用的兩種模式:

  • 計數 (Counting): 追蹤某個事件發生了多少次。通常將計數變數初始化為 0,並在每次事件發生時加 1。
    範例:NumberOfStudents ← NumberOfStudents + 1
  • 累加 (Totalling/Accumulation): 維持數值的累積總和。通常將總數變數初始化為 0,並在每次出現新數值時將其加上。
    範例:TotalSales ← TotalSales + CurrentSaleValue

(e) 字串處理 (String Handling)

這是用於操作文字(STRING 資料)的標準函式。

  • LENGTH(<識別碼>): 返回字串中的字元數量。
    範例:LENGTH("Cat") 返回 3。
  • LCASE(<識別碼>): 將字串或字元轉換為小寫
  • UCASE(<識別碼>): 將字串或字元轉換為大寫
  • SUBSTRING(<識別碼>, <開始位置>, <長度>): 返回字串的一部分。你需要指定開始位置以及要包含的字元數量。
    注意:虛擬碼通常使用 1 作為第一個字元的起始位置,但課程大綱確認在不同程式系統中可能使用 0 或 1。請遵循你題目中使用的慣例,若未指定則使用 1。
    範例:SUBSTRING("Program", 3, 4) 返回 "ogra"。
你知道嗎? 在許多程式語言(如 Python)中,字串索引從 0 開始,而不是 1!但在 IGCSE 虛擬碼中,除非另有說明,否則以 1 為開頭是常見的做法。

8.1.6 程序、函式與變數範圍

隨著程式越來越大,我們需要將其拆解成較小、可重複使用的程式區塊。

程序 (Procedures) 與函式 (Functions)

程序和函式都是可重複使用的副程式,但它們有一個關鍵區別:

  • 程序 (Procedure): 一個執行任務但不會返回數值的已命名程式區塊。它是透過 CALL 關鍵字來呼叫的。
    範例:CALL DisplayMenu()
  • 函式 (Function): 一個執行任務並必須返回單一數值到呼叫點的已命名程式區塊。它通常作為運算式的一部分使用。
    範例:Area ← CalculateArea(5, 10)
參數 (Parameters)

參數是傳遞給程序或函式的數值,以便副程式可以使用它們。它們就像是副程式的輸入。

// 定義一個帶有一個參數的程序
PROCEDURE Line(Size : INTEGER)
    // ... 使用 Size 的陳述式 ...
ENDPROCEDURE

// 呼叫程序
CALL Line(60)

你可能需要處理最多帶有三個參數的程序與函式。

區域與全域變數 (Local and Global Variables)

範圍 (Scope) 是指程式中變數可以被存取的區域。

  • 全域變數 (Global Variable): 在程式的最開始(主程式體)宣告。它可以在程式的任何地方被存取與修改,包含在程序與函式內部。
  • 區域變數 (Local Variable): 在特定的程序或函式內部宣告。它只能在該副程式內部使用。一旦副程式結束,區域變數就會被銷毀。
    就像是一張只有你自己能讀的祕密臨時便條紙。

為什麼要用區域變數? 它們可以防止意外干擾。如果兩個不同的程序都使用了名為 i 的變數,如果 i 分別在兩個程序內宣告為區域變數,它們就不會衝突。

8.1.7 函式庫常式與 8.1.8 可維護的程式

8.1.7 函式庫常式 (Library Routines)

這些是程式環境中內建的預寫函式,可以節省你的時間。除了字串函式、MOD 和 DIV 之外,你需要知道的主要函式還有:

  • ROUND(<識別碼>, <位數>): 將一個 REAL 數值四捨五入到指定的小數位數。
    範例:ROUND(3.14159, 2) 返回 3.14
  • RANDOM(): 返回一個介於 0 到 1 之間的隨機 REAL 數值(包含 0 和 1)。
    要生成 1 到 10 之間的隨機整數:Value ← ROUND (RANDOM() * 10, 0)

8.1.8 建立可維護的程式

所謂可維護的程式,是指讓其他人(或未來的自己)能夠輕鬆理解、偵錯與更新的程式。

關鍵特性包括:

  • 有意義的識別碼: 為變數、常數、程序和函式使用描述性的名稱(例如使用 MaximumScore 而不是 MS)。
  • 註解: 使用 // 來加入註解,解釋程式碼的功能,特別是針對複雜的部分。
  • 使用程序與函式: 將程式碼拆解成邏輯上的子部分,使主程式流程更簡潔。
副程式重點總結: 程序負責執行任務;函式則會回傳數值。始終使用有意義的名稱和註解,以保持程式的可維護性。

8.2 陣列:儲存資料列表

8.2.1 陣列的宣告與使用

陣列 (Array) 是一種資料結構,用於儲存固定數量且類型相同的項目,並透過索引(一個數字)來存取。

比喻:陣列就像是一排編號的郵箱,每個郵箱按順序排列。

1. 一維 (1D) 陣列

一維陣列是一個簡單的清單或向量。

宣告:

DECLARE StudentNames : ARRAY[1:30] OF STRING // 30 個元素,索引由 1 到 30

使用: 元素使用方括號 [ ] 來存取。

StudentNames[1] ← "Ali" // 將 "Ali" 放入第一個位置
OUTPUT StudentNames[5] // 輸出位置 5 的數值
2. 二維 (2D) 陣列

二維陣列是一個清單的清單,通常可視為表格或網格(列與欄)。

宣告:

DECLARE Board : ARRAY[1:3, 1:3] OF CHAR // 一個 3x3 的網格(類似圈圈叉叉遊戲)

使用: 第一個索引通常是列 (Row),第二個是欄 (Column)。

Board[2, 3] ← 'X' // 將 'X' 放入第 2 列第 3 欄

8.2.2 & 8.2.3 陣列與迭代的使用

由於陣列索引是連續的數字,陣列幾乎總是與迭代(循環)一起處理,特別是 FOR 循環

這讓你能夠有系統地讀取或寫入陣列中的每個元素。

// 將數值寫入陣列(從使用者輸入讀取)
FOR Index ← 1 TO 30
    INPUT StudentNames[Index]
NEXT Index

// 從二維陣列中讀取數值(需要巢狀迭代)
FOR Row ← 1 TO 3
    FOR Column ← 1 TO 3
        OUTPUT Board[Row, Column]
    NEXT Column
NEXT Row

8.3 檔案處理:永久儲存

8.3.1 檔案的目的

當程式執行時,變數儲存在臨時的 RAM(主記憶體)中。當程式關閉後,這些資料就會消失。
將資料存入檔案的目的是為了將資料永久保留(在二次儲存裝置如硬碟中),以便程式下次執行時能夠提取。

8.3.2 檔案操作

在虛擬碼中處理檔案時,必須遵循特定步驟:

步驟 1: 開啟檔案 (OPEN)

  • 你必須指定模式FOR READ(讀取現有資料)或 FOR WRITE(建立新檔案或覆蓋現有檔案)。
  • OPENFILE "Scores.txt" FOR READ

步驟 2: 讀取 (READ) 或寫入 (WRITE) 資料

  • READFILE: 從檔案中讀取單一資料項目或一行文字,並存入變數。
  • READFILE "Scores.txt", PlayerName // 讀取一個項目/行到 PlayerName
  • WRITEFILE: 將變數中的單一資料項目或一行文字寫入檔案。
  • WRITEFILE "Scores.txt", NewScore

步驟 3: 關閉檔案 (CLOSE)

  • 當完成操作後,必須 CLOSE 檔案以確保所有資料正確儲存,並且檔案不會再被其他程式鎖定。
  • CLOSEFILE "Scores.txt"
檔案重點總結: 存取前務必 OPEN,結束後務必 CLOSE。若以 FOR WRITE 開啟,檔案中原本的資料將會遺失!