C++ 入門指南 4.01

單元 8 - 迴圈

-unit8-

程式 (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 為止。迴圈有三個地方要注意

  1. 設定控制變數
  2. 結束條件測試
  3. 調整控制變數值

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 陳述
   作者:張凱慶 */

編譯執行結果如下

-whiledemo-

當我們明確知道重複次數的時候,我們得利用控制變數來記錄 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 迴圈習慣上會把控制變數的宣告直接放進小括弧中,當然也可以在小括弧外先宣告,然後才在小括弧裡設定初值。

編譯後執行,結果如下

-fordemo-

小括弧中的兩個分號與條件是必須的,因此如果寫成

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 陳述
   作者:張凱慶 */

編譯後執行,結果如下

-fordemo2-

以上是 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. whiledo-whilefor 三種迴圈都可互相替代。
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 ,利用迴圈計算 11000 的總和。 參考程式碼
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. 費氏數列為 11235813 .... ,也就是後面的數字為前兩個數字的總和,寫一個程式 exercise0812.cxx ,計算出第 20 個數字。 參考程式碼
13. 承上題,另寫一個程式 exercise0813.cxx ,改成接受使用者輸入,計算使用者輸入的第幾個費氏數。 參考程式碼

相關教學影片

上一頁 單元 7 - 選擇
回 C++ 入門指南 4.01 目錄
下一頁 單元 9 - 函數
回 C++ 教材
回程式語言教材首頁