C++ 入門指南 4.01
單元 8 - 迴圈
程式 (program) 中的迴圈 (loop) 就是在特定程式區塊 (block) 中,重複執行相同的工作
C++ 中有四種迴圈,一種是 while 迴圈 (while loop) ,另一種則是 do-while 迴圈 (do-while loop) ,其餘兩種都是用關鍵字是 for ,簡稱 for 迴圈 (for loop) , while 迴圈屬於前測試迴圈, do-while 迴圈屬於後測試迴圈,兩種 for 迴圈則用於固定次數的工作。
前測試迴圈是在迴圈主體開始前,先進行迴圈結束的條件測試,後測試迴圈則相反,在進行完迴圈主體的工作後,才進行迴圈結束的條件測試。
我們先來看看 while 迴圈的寫法
int i = 10 // 設定控制變數 while (i > 0) { // 迴圈工作區 cout << i << endl; i--; // 調整控制變數值 }
這個迴圈所進行的工作很簡單,先在命令列上印出 10 ,然後一路倒數到 1 為止。迴圈有三個地方要注意
- 設定控制變數
- 結束條件測試
- 調整控制變數值
while 迴圈的控制變數 (control variable) 必須在 while 之前就先設定好,此例中將控制變數 i 設定為 10 。然後進入 while 的地方,條件 (condition) 就在 while 之後的小括弧中,此例中為當控制變數 i 大於 0 時,迴圈便會重複執行。迴圈工作區,也就是 while 底下用大括弧圍住的程式區塊,這裡,我們只有簡單的印出控制變數 i 的值,迴圈工作區的最後需要有調整控制變數值的地方。
我們先寫成完整的範例,來編譯 (compile) 看看結果吧!
#include <iostream> using namespace std; int main(void) { cout << endl; int i = 10; // 設定控制變數 while (i > 0) { // 迴圈工作區 cout << i << endl; i--; // 調整控制變數值 } cout << endl; return 0; } /* 《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:while_demo.cxx 功能:示範 while 陳述 作者:張凱慶 */
編譯執行結果如下
當我們明確知道重複次數的時候,我們得利用控制變數來記錄 while 迴圈所進行次數,這樣 while 迴圈才會有結束的一天,不然若是三個與控制變數相關的部份,漏了任一部份時,就有可能導致無窮迴圈 (infinite loop) 的發生,例如
int i = 10 // 設定控制變數 while (i > 0) { // 迴圈工作區 cout << i << endl; // 沒有調整控制變數值 }
這樣一來,控制變數 i 永遠大於 0 ,所以迴圈會一直重複執行,此例會不斷的在命令列印出 10 ,直到強制結束程式的執行為止。
以上的 while 迴圈是介紹有明確重複次數的用法,若是迴圈沒有明確重複次數,那就得另行設計結束迴圈的方式,例如控制變數等於某一個值之時,再利用 break 跳出迴圈。
do-while 迴圈是把結束條件放在最後,其餘跟 while 迴圈相同,也就是說,進入 do-while 迴圈是先做第一次,然後才進行條件測試,例如把上面的倒數計時程式改寫成 do-while 迴圈
int i = 10; // 設定控制變數 do { // 迴圈工作區 cout << i << endl; i--; // 調整控制變數值 } while (i > 0);
關鍵字 do 後面的大括弧就是迴圈工作區,右大括弧之後才接關鍵字 while 進行迴圈條件測試,因此 do-while 迴圈無論無何都會先進行迴圈工作一次。
大多數的 do-while 也能夠用 while 替代,這方面視情況再選擇用後測試迴圈或前測試迴圈囉!
繼續看到 for 迴圈, for 迴圈有兩種,第一種是把控制變數的設定、迴圈結束條件測試、控制變數的調整全都寫在小括弧之中,如下
for (int i = 10; i > 0; i--) { cout << i << endl; }
for 之後的小括弧用兩個分號區隔三個項目,依序是控制變數的設定、迴圈結束條件、控制變數的調整。這個 for 迴圈與上面的 while 迴圈功能完全相同,寫成完整的範例程式,如下
#include <iostream> using namespace std; int main(void) { cout << endl; for (int i = 10; i > 0; i--) { cout << i << endl; } cout << endl; return 0; } /* 《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:for_demo.cxx 功能:示範 for 陳述 作者:張凱慶 */
在 for 迴圈習慣上會把控制變數的宣告直接放進小括弧中,當然也可以在小括弧外先宣告,然後才在小括弧裡設定初值。
編譯後執行,結果如下
小括弧中的兩個分號與條件是必須的,因此如果寫成
int i = 1; for (; i > 0;) { cout << i << endl; }
這會使 for 迴圈變成一個無窮迴圈。
至於第二種 for 迴圈,這是 C++11 新增的種類,可用控制變數暫存複合物件的元素,概念跟上述第一種 for 迴圈一樣,形式如下
for (auto i: a) { cout << i << endl; }
以上的變數 a 是含有 auto 型態元素的複合資料型態,例如陣列,至於 auto 真實是什麼資料型態,由原始的 a 決定,這裡 i 宣告為 auto 的用意是讓編譯器自動配對資料型態。寫成完整例子如下
#include <iostream> using namespace std; int main(void) { int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; cout << endl; for (auto i: a) { cout << i << endl; } cout << endl; return 0; } /* 《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:for_demo2.cxx 功能:示範 for 陳述 作者:張凱慶 */
編譯後執行,結果如下
以上是 C++11 新增的寫法,如在命令列編譯請在編譯時加上參數 -std=c++11 ,或參考如何在 Geany 中編譯 C++11 等各種新 C++ 標準的程式。
習慣上, for 迴圈通常用於具有明確重複次數的迴圈,因為全部的控制機制都放在 for 之後的小括弧中, while 迴圈用於沒有明確重複次數的迴圈,例如接收使用者輸入的迴圈,當使用者輸入結束指令的時候,迴圈才會結束,不然程式會一直等待使用者的輸入。
倒是提醒一點, for 迴圈可以用 while 迴圈替代,反之亦然,自己偏好哪一種也就可以用哪一種囉!
迴圈的主要用途就是進行重複工作,這樣可以減少程式中一再重複相同的程式碼,另外還有一種可以有效減少相同程式碼的概念就是函數 (function) 了,接下來我們繼續討論函數吧!
中英文術語對照 | |
---|---|
區塊 | block |
編譯 | compile |
條件 | condition |
控制變數 | control variable |
do-while 迴圈 | do-while loop |
for 迴圈 | for loop |
函數 | function |
無窮迴圈 | infinite loop |
迴圈 | loop |
程式 | program |
while 迴圈 | while loop |
重點整理 |
---|
1. 迴圈用於重複性質的工作,有三個地方需注意,分別是控制變數、結束條件以及調整控制變數值。 |
2. while 迴圈為前測試迴圈,通常用於非明確執行次數的迴圈, do-while 迴圈則是後測試迴圈。 |
3. for 迴圈將設定控制變數、結束條件、調整控制變數值都寫在 for 之後的小括弧中,通常用於有明確執行次數的迴圈。 |
4. while 、 do-while 、 for 三種迴圈都可互相替代。 |
5. 無窮迴圈是指結束條件永遠為真,一直執行的迴圈。 |
6. 利用 break 陳述可提前跳出迴圈。 |
7. 利用 continue 陳述可使迴圈直接進行下一輪。 |
問題與討論 |
---|
1. 很多情況都需要 while true 迴圈,這不是無窮迴圈嗎?那為什麼 還要 while true 迴圈呢? |
2. while 迴圈與 for 迴圈要如何互相替代? |
3. while 迴圈與 do-while 迴圈要如何互相替代? |
4. 遞迴是一種用於重複工作的演算法,遞迴跟迴圈有什麼不同呢? |
練習 |
---|
1. 寫一個程式 exercise0801.cxx ,將上述 while 迴圈範例改用 do-while 來寫。 參考程式碼 |
2. 寫一個程式 exercise0802.cxx ,比較 while 迴圈與 do-while 迴圈的不同。 參考程式碼 |
3. 寫一個程式 exercise0803.cxx ,利用迴圈計算 1 到 1000 的總和。 參考程式碼 |
4. 承上題,另寫一個程式 exercise0804.cxx ,改成接受使用者輸入,計算 1 到使用者輸入整數的總和。 參考程式碼 |
5. 迴圈中若有其他迴圈稱之為巢狀迴圈,利用巢狀迴圈及 '*' 寫一個程式 exercise0805.cxx,印出一個高 5 、底 5 的等腰直角三角形。 參考程式碼 |
6. 承上題,另寫一個程式 exercise0806.cxx ,將三角形倒過來印。 參考程式碼 |
7. 承上題,另寫一個程式 exercise0807.cxx ,改成接收使用者輸入邊長。 參考程式碼 |
8. 寫一個程式 exercise0808.cxx ,利用巢狀迴圈印出九九乘法表。 參考程式碼 |
9. 寫一個程式 exercise0809.cxx ,在 while true 迴圈中接受使用者的輸入,當使用者輸入 'e' 的時候利用 break 跳出迴圈。 參考程式碼 |
10. 寫一個程式 exercise0810.cxx ,計算 10 的階層,也就是從正整數 1 乘以正整數 2 ,一路乘到正整數 10 。 參考程式碼 |
11. 承上題,另寫一個程式 exercise0811.cxx ,改成接受使用者輸入,計算使用者輸入的階層數。 參考程式碼 |
12. 費氏數列為 1 、 1 、 2 、 3 、 5 、 8 、 13 .... ,也就是後面的數字為前兩個數字的總和,寫一個程式 exercise0812.cxx ,計算出第 20 個數字。 參考程式碼 |
13. 承上題,另寫一個程式 exercise0813.cxx ,改成接受使用者輸入,計算使用者輸入的第幾個費氏數。 參考程式碼 |
相關教學影片