條件式 if-else

這章開始我們要來講一下控制流程 Control Flow 的概念!

在這之前我們看到的程式碼,在執行的時候程式都是由第一行按照順序執行到最後一行,這非常直觀。

但會不會有時候我們想要程式碼只執行某幾行、跳過某幾行、或是重複執行呢?當然有可能!讓我們繼續讀下去。

什麼是控制流程

在講 if-else 之前,我們先來說說什麼是控制流程。

舉一個簡單的例子來說,如果有一個程式需要使用者輸入正數才能執行,但使用者卻一直輸入負數,這樣這個程式碼是不是應該要一直重複要求使用者輸入呢?

然後又依照輸入的數字來看,如果大於 50 就做 A 動作,小於 100 就做 B 動作。這樣的一個程式碼執行下來,我們會發現有些程式碼其實不會執行到,有些則會不斷地被重複執行。

下面這張圖簡單的將控制流程給視覺化出來:

我們可以依照自己的一套邏輯去控制程式碼的走向以及結果,這就是控制流程的概念!

在學習這章以前,我們寫的程式碼都是非常單調而且線性的,這對真實世界來說是絕對不夠用的。

學習完這章以後,我們可以隨心所欲控制程式的邏輯走向,這讓我們可以創造出很多有趣的應用!也讓我們寫出的程式碼更貼近真實世界的應用!

分類

控制流程的種類有好幾種,常見的有下面這幾種:

分類 意義 C++ 語法
條件式 當某個條件為真時,則運行那一部分的程式碼,反之則跳過 if, switch
跳躍 程式碼會到特定的某一行開始執行 break, continue
迴圈 主要用途就是用來重複運行某段程式碼 while, for, do while
異常處理 專門處理 C++ 的錯誤運行,比如說除以 0 try, catch, throw

接下來我們會來分別討論上面表格提到的種類,以及提供一些具體例子!

條件式

第一個控制流程的分類我們要討論的是條件式。

如同前面講到的,條件式的應用在於當某個條件為真時,則運行那一部分的程式碼,反之則跳過

C++ 支援兩種條件式語法:if-elseswitch。下面我們分為兩段介紹。

if-else

其實 if-else 在我們講 指標 的那章就出現過了,那時候我們用來判斷是否遇見空指標,但那時候我們沒有仔細講解條件式如何運作。

其實 if-else 大家用看的應該就知道是什麼意思了,中文翻譯的話就是「如果…否則…」,也就是如果這個條件為真,就執行這個動作,否則就執行另一個動作。

這樣的 C++ 程式碼架構其實非常簡單:

if (condition) {
    codeA
    ...
}
else {
    codeB
    ...
}

如果 condition 成立,則會執行 codeA,否則執行 codeB。

我們來看一個更實際的例子:

int main() {
    std::cout << "Enter your age: "; int x{}; std::cin >> x;

    if (x > 85) {    // 以 85 歲分界
        std::cout << "You are very old!";
    }
    else {
        std::cout << "You are still young!";
    }

    return 0;
}

這段程式碼會要求你輸入你的年齡,依據你輸入的年齡以 85 歲做區分會有兩種不同的結果。

耶太棒了!我的程式可以知道我年輕還是老了!

誒但聰明的你可能就會問了,那我可不可以讓我的程式擁有多於兩種的結果?

答案是當然可以!我們可以在第一個 if 中再插入另一個條件式:

int main() {

    std::cout << "Enter your age: "; int x{}; std::cin >> x; 

    if (x > 85) {        // 以 85  歲分界
        if (x > 120) {   // 以 120 歲分界
            std::cout << "You are amazing!!!";
        }
        else {
            std::cout << "You are very old!";
        }
    }
    else {
        std::cout << "You are still young!";
    }
    return 0;
}

如上的程式碼就會出現三種不同的結果,並以不同的年齡作為區分標準。

當然,如果你想要,你可以再加上更多的 if-else。這樣的架構我們叫做巢狀 if( nested if)。

但是這麼做會有一個問題,就是當有很多個 if-else 時,那麼程式碼就會變得很難看。

所以如果你真的有很多條件式,更推薦的做法是將這些 if-else 「壓平」。

要做到這點我們需要借用新的語法:else if (condition)else if (condition)讓我們可以新增非常多的條件,同時又可以達到易讀性。

int main() {

    std::cout << "Enter your age: "; int x{}; std::cin >> x; 

    if (x > 120) {
        std::cout << "You are amazing!!!"; } else if (x > 85) {
        std::cout << "You are very old!";
    }
    else {
        std::cout << "You are still young!";
    }
    return 0;
}

這段程式碼也會產生如前一段程式碼一樣的結果。

值得注意的是,我們需要先判斷 x > 120 的情況,再判斷 x > 85 的情況。

如果相反過來,先判斷 x > 85,那麼就算 x 大於 120,也不會被偵測到。

switch

前面我們講到了我們可以利用很多的 ifelse if 和  else 來產生很多不同的條件。但這麼做仍然會降低程式碼的易讀性和效率。

讓我們來看看這個例子:

int main() {

    std::cout << "Enter a number: ";
    int x{};
    std::cin >> x; 

    if (x == 0) {
        std::cout << "x is zero";
    }
    else if (x == 1) {
        std::cout << "x is one";
    }
    else if (x == 2) {
        std::cout << "x is two";
    }
    else {
        std::cout << "x is unknown";
    }
    return 0;
}

這是一個非常簡單的程式碼,相信大家都看得懂。

但是,C++ 在執行這樣的程式碼時是非常沒有效率的,因為假如變數 x 是 3,那麼 x 就會被檢測三次,最後程式碼才知道原來 x 並等於 0、1 或是 2。那麼有沒有方式可以讓這樣的程式碼執行的更有效率呢?

當然有!那就是 switch!讓我們來透過 switch 重寫上面的程式碼

int main() {

    std::cout << "Enter your age: ";
    int x{};
    std::cin >> x; 

    switch (x) {
        case 0:
            std::cout << "x is zero";
            return 0;
        case 1:
            std::cout << "x is one";
            return 0;
        case 2:
            std::cout << "x is two";
            return 0;
        default:
            std::cout << "x is unknown";
            return 0;
    }
    return 0;
}

相信聰明的你們可以很快地理解上面程式碼的意思。其實 switch 的概念很簡單,只要傳進 switch 的值(在這個例子就是 x)符合任意一個 case 後面的值,那麼就會執行那個 case 底下的程式碼。如果都不符合任何一個,那麼就會執行 default 。

這個跟前面提到的 if else 的區別在於,switch 只需要比對一次就好,因此在執行方面來的更有效率。

在閱讀上,也讓讀程式碼的人可以更清晰地知道所有可能的 case

值得注意的一點是,在每一個 case 的最後,我們都有一個 return 0;。這是因為告訴程式碼說,執行到這一行就要停止了。

我們可以試著拿掉所有的 return 0; 看看會發生什麼事:

int main() {

    int x = 1;

    switch (x) {
        case 0:
            std::cout << "x is zero" << std::endl;    // 跳過
        case 1:
            std::cout << "x is one" << std::endl;     // 符合條件,執行以下程式碼
        case 2:
            std::cout << "x is two" << std::endl;     // 被執行
        default:
            std::cout << "x is unknown" << std::endl; // 被執行
    }
    return 0;
}

這邊我們讓 x 為 1,執行程式碼後我們會發現輸出的結果竟然是這樣:

x is one
x is two
x is unknown

這是因為就像我們前面講的,C++ 會執行符合 case 以下的所有程式碼,想當然這通常並不會是我們要的結果,因此我們會像先前一樣利用 return 來結束。

其實除了 return 外還有另一種方法,那就是利用 break。這個我們會在下一章講到。

總結

這章我們了解了如何利用各種方法做到程式設計中的控制流程,包括 ifelseswitch 等等。

有了控制流程的方法,我們所設計出來的程式碼才會更加人性化。

那我們這章就到這裡啦!

下一章我們繼續介紹其他控制流程的方法!