if 條件判斷


為了應付程式可能遇到的各種狀況,C++ 提供了 if 條件判斷陳述,它的語法如下:

if(條件式)
    陳述句一;
else
    陳述句二;

當條件式成立時,執行陳述句一,要不然就執行陳述句二;如果條件式不成立時並不想作任何事,else 可以省略。

if 後若有兩個以上的陳述句,稱為複合陳述句(compound statement),此時必須使用 {} 將複合陳述句包括起來,例如:

if(條件式) {
    陳述句一;
    陳述句二;
}
else {
    陳述句三;
    陳述句四;
}

下面來寫個簡單的程式,判斷使用者的輸入是奇數還是偶數:

#include <iostream>
using namespace std;

int main() { 
    int input = 0; 

    cout << "輸入整數:"; 
    cin >> input; 

    int remain = input % 2; 
    if(remain == 1) 
        cout << input << " 為奇數" << endl; 
    else 
        cout << input << " 為偶數" << endl; 

    return 0;
}

執行結果:

輸入整數:10
10 為偶數

這個程式很簡單,使用餘數運算來計算除以 2 後的餘數,偶數的餘數會是 0,而奇數會是 1,由此判斷輸入為奇數還是偶數;事實上,這個程式也可以這麼寫:

#include <iostream>
using namespace std;

int main() { 
    int input = 0; 

    cout << "輸入整數:"; 
    cin >> input; 

    if(input % 2) {
        cout << input << " 為奇數" << endl; 
    }
    else { 
        cout << input << " 為偶數" << endl; 
    }

    return 0;
}

在 C++ 中 0 在條件式中相當於 false,而非 0 值都被視為 true,因此可以直接將餘數運算的結果當作條件式來使用,另外,現在程式設計鼓勵,就算只有一行陳述句,也要撰寫 {},原因稍後就會談到。

if 中可以再設定執行的條件。例如:

if(條件式一) {
    陳述句一;

    if(條件式二) {
        陳述句二;
    }

    陳述句三;
}

這只個簡單的例子,其中陳述句二要執行,必須同時滿足條件式一與二才行;再來看個例子:

if(條件式一) {
    陳述句一;
    // 其它陳述句
}
else
    if(條件式二) {
        陳述句二;
    }

如果條件式一不滿足,就會執行 else 的陳述,而在這邊進行條件式二的測試,如果滿足就執行條件式二,由於 C++ 是個自由格式語言,可以適當的排列這個程式:

if(條件式一) {
    陳述句一;
    // 其它陳述句
}
else if(條件式二) {
    陳述句二;
}

基於這個方式,可以如下設定多個條件:

if(條件式一) {
    陳述一;
}
else if(條件式二) {
    陳述句二;
} 
else if(條件式三) {
    陳述句三;
}
else {
    陳述句四;
}

陳述句四會在條件式一、二、三都不成立時執行;下面這個程式是個簡單的例子,處理學生的成績等級問題:

#include <iostream>
using namespace std;

int main() { 
    int score = 0; 

    cout << "輸入分數:"; 
    cin >> score; 

    if(score >= 90) {
        cout << "得 A" << endl; 
    }
    else if(score >= 80 && score < 90) {
        cout << "得 B" << endl; 
    }
    else if(score >= 70 && score < 80) {
        cout << "得 C" << endl; 
    }
    else if(score >= 60 && score < 70) {
        cout << "得 D" << endl; 
    }
    else {
        cout << "得 E(不及格)" << endl; 
    }

    return 0;
}

執行結果:

輸入分數:60
得 D

在這邊要注意的是,ifelse 是就最近的一組來配對,例如下面這個程式依縮排來看,你覺得有無問題存在?

if(條件式一)
    if(條件式二)
        陳述句一;
else
    陳述句二;

很多人都會以為條件式一的 if 會與 else 配對,但事實上是條件式二的 ifelse 配對,加上括號的話就可以一目瞭然了:

if(條件式一) {
    if(條件式二)
        陳述句一;
    else
    陳述句二;
}

如果想避免這種錯誤,在程式中多使用括號是必要的,多寫一些總是比少寫一些來得保險一點。

Apple 曾經提交一個 iOS 上的安全更新,原因是在某個函式中有兩個連續的縮排:

...       
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
        goto fail;
        goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
        goto fail;
...

因為縮排在同一層,閱讀程式碼時開發者也就沒注意到,又沒有用 {} 定義區塊,結果就是 goto fail 無論如何都會被執行到的錯誤。

對於底下的寫法:

int size = foo.getSize();
if(size == 10) {
    //...
}

size 如果只用於 if 判斷或其區塊,在 C++ 17 時可以寫為(目前我用的 g++ 必須加上 -std=c++17 才可以通過編譯):

if(int size = foo.getSize(); size == 10) {
    //...
}