條件式 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-else
和 switch
。下面我們分為兩段介紹。
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
前面我們講到了我們可以利用很多的 if
、else 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
。這個我們會在下一章講到。
總結
這章我們了解了如何利用各種方法做到程式設計中的控制流程,包括 if
、else
、switch
等等。
有了控制流程的方法,我們所設計出來的程式碼才會更加人性化。
那我們這章就到這裡啦!
下一章我們繼續介紹其他控制流程的方法!