3.5 if / else if / else

現在我們有了條件判斷的工具(比較和邏輯運算子),我們需要根據這些條件分支執行不同的程式碼if 語句就是用來做這件事的。

基本 if 語句

if (條件) {
    // 條件為 true 時執行
}

if/else 語句

if (條件) {
    // 條件為 true 時執行
} else {
    // 條件為 false 時執行
}

if/else if/else 語句

if (條件1) {
    // 條件1為 true 時執行
} else if (條件2) {
    // 條件1為 false,條件2為 true 時執行
} else if (條件3) {
    // 條件1、2 為 false,條件3為 true 時執行
} else {
    // 以上條件都為 false 時執行
}

if / else 的排版

延續 1.5 學過的排版習慣,if / else 也有一套大家公認好讀的寫法,重點在縮排大括號的位置

// ✓ 好的排版:層次分明
if (score >= 60) {
    cout << "Passed";
} else {
    cout << "Failed";
}

// ✗ 不好的排版:擠成一團、沒縮排,看不出結構
if(score>=60){cout<<"Passed";}else{cout<<"Failed";}
規則 ✓ 好的做法 ✗ 不好的做法 為什麼
if 後空一格 if (x > 5) if(x>5) if 是關鍵字,和 ( 空一格,跟函式呼叫區別開
左大括號接行尾 if (x > 5) { { 另起一行 { 放在條件同一行行尾,省一行、更緊湊
內容縮排一層 { } 裡的語句往右縮 2~4 格 頂著最左邊寫 一眼看出「這些是 if 成立時要做的事」
else 貼著 } } else { else 另起一行 else 跟右大括號同一行,讀起來連貫

(條件裡的運算子一樣要在周圍加空格,例如寫 score >= 60 而不是 score>=60——這點 1.5 已經講過。)

大括號可以省略嗎?

if(或 else)底下只有一行要執行時,大括號 { } 其實可以省略:

// 這兩種寫法完全一樣
if (score >= 60)
    cout << "Passed";

if (score >= 60) {
    cout << "Passed";
}

但這裡藏著一個新手最常踩的坑:省略大括號時,if 只管緊接著的「那一行」。如果條件成立時你想做兩件以上的事,就一定要用大括號把它們框起來,否則只有第一行受 if 控制:

// ✗ 錯誤:以為兩行都屬於 if
if (score >= 60)
    cout << "Passed\n";
    cout << "恭喜你!\n";   // 這行其實「永遠」會印,跟 if 完全無關!

// ✓ 正確:多行一定要用大括號框起來
if (score >= 60) {
    cout << "Passed\n";
    cout << "恭喜你!\n";
}

範例程式碼:把流程圖變成程式

還記得單元開頭〈想像一下…〉的那張成績判斷流程圖嗎?現在我們已經備齊所有工具,可以把它翻成程式了。先把圖再看一次:

圖 3-1:成績判斷流程圖

流程圖「從上往下、每個菱形做一次判斷」的結構,正好對應 if / else if / else:第一個菱形 score >= 60 就是 if,第二個菱形 score >= 50 就是 else if,兩個都不成立時的最後一條路就是 else

#include <iostream>
using namespace std;

int main() {
    int score;
    cin >> score;  // 讀入分數

    if (score >= 60) {                    // 第一個菱形:score >= 60?
        cout << "Passed" << endl;         // 成立 → 通過
    } else if (score >= 50) {             // 第二個菱形:score >= 50?
        cout << "Make-up Exam" << endl;   // 成立 → 補考
    } else {                              // 兩個菱形都不成立
        cout << "Retake Course" << endl;  // → 重修
    }

    return 0;
}

執行結果(輸入 55)

Make-up Exam

邏輯等效性

有時候,同一個邏輯可以用不同的方式寫。例如:

// 方式1:if/else if(推薦)
if (score >= 90) {
    cout << "A";
} else if (score >= 80) {
    cout << "B";
} else if (score >= 70) {
    cout << "C";
}

// 方式2:單獨的 if(較差)
if (score >= 90) {
    cout << "A";
}
if (score >= 80 && score < 90) {  // 注意:要加額外的上界條件
    cout << "B";
}
if (score >= 70 && score < 80) {
    cout << "C";
}

方式1 更清潔且避免錯誤,因為 else if 自動確保只有一個分支會執行。

短路求值的實用時機

還記得 3.3 提過的短路求值嗎?&& 左邊如果是 false,右邊就完全不會被計算。這個特性可以幫我們在條件裡先做安全檢查,避免程式當掉。

想像你要算一位同學的平均分數:把總分 total 除以考試科目數 count。但萬一他還沒考任何一科(count 是 0),total / count 就變成「除以 0」——這在數學裡沒有意義,程式真的算下去會直接當掉

我們可以把「科目數不是 0」放在 && 的左邊當守門員

int total, count;   // total:總分,count:考了幾科
cin >> total >> count;

// 還沒考任何一科時 count 是 0。
// && 左邊 (count != 0) 為 false,右邊的 total / count 就不會被計算,
// 因此不會發生「除以 0」把程式弄當掉。
if (count != 0 && total / count >= 60) {
    cout << "平均及格!" << endl;
}

順序很重要:如果反過來寫成 if (total / count >= 60 && count != 0),當 count 是 0 時,左邊的 total / count被計算 → 立刻當掉,右邊那位守門員根本來不及擋。所以要把「保護用」的條件放在前面,讓它先攔下來。

動手試試看

寫一個程式,輸入一個月份數字(1-12),輸出該月有多少天(假設非閏年)。用 if/else if/else 實現。