4.4 do-while 迴圈

while 迴圈先檢查條件再執行。如果你想至少執行一次,再檢查條件(例如玩遊戲時「先玩一局,再問要不要繼續」),就用 do-while

do-while 迴圈的結構:

do {
    程式碼區塊
} while (條件式);

注意 while 後面有分號。

執行流程:

  1. 執行程式碼區塊
  2. 檢查條件式
  3. 如果為 true,回到步驟 1
  4. 如果為 false,結束迴圈
圖 4-3:do-while 迴圈執行流程

whilefor 最大的不同:條件式被放到最後才檢查,所以不論條件成不成立,程式碼區塊都會先跑一次——這就是「至少執行一次」的由來。

範例程式碼

範例:計算 n + (n-1) + ... + 1 的結果(假設輸入的 n \ge 1

#include<iostream>
using namespace std;
int main() {
    int n;
    cin >> n;           // 讀入一個數字

    int answer = 0;     // 累加總和

    // 至少執行一次:把 n 加到 answer,然後 n 減 1
    do {
        answer += n;    // 加上當前的 n
        n -= 1;         // n 減 1
    } while (n > 0);     // 只要 n > 0 就繼續

    cout << answer << "\n";
    return 0;
}

執行結果:(假設輸入為 5

15

逐圈追蹤(輸入 5):注意 do-while 是先執行、後檢查,所以「檢查 n > 0」那一欄在每一圈的最後才發生:

圈數 進迴圈前 n answer += n n -= 1 n > 0
1 5 5 4 是 → 再一圈
2 4 9 3 是 → 再一圈
3 3 12 2 是 → 再一圈
4 2 14 1 是 → 再一圈
5 1 15 0 否 → 停

得到 5 + 4 + 3 + 2 + 1 = 15

(其實這種「固定加到 1」的加總,用 whilefor 一樣好寫;do-while 真正發揮的場合,是下面「先拿到資料才能檢查」那種至少得先做一次的情境。)

while vs do-while:差在哪一次

兩者只差在檢查條件的時機while 先檢查再做,所以條件一開始就不成立時一次都不做do-while 先做再檢查,所以至少做一次

這個差別在「先拿到資料才有得檢查」時最有用。例如「請使用者輸入 1 到 9 的數字,不合法就一直重問」——你得先讀一次才知道合不合法,do-while 剛好:

int x;
do {
    cin >> x;                 // 先讀一次
} while (x < 1 || x > 9);     // 不在範圍內就再要一次

換成 while 就得在迴圈外面先多讀一次(叫做「預讀」),把讀取寫兩遍,比較囉嗦:

int x;
cin >> x;                     // 得先預讀一次,迴圈才有東西可檢查
while (x < 1 || x > 9) {
    cin >> x;                 // 同一句又寫一遍
}

這就是 do-while 存在的理由:省掉那次重複的預讀。

動手試試看

  1. (觀察差異)do-while 寫「印出 1 到 n」,然後輸入 n = 0 試試看——會印出什麼?再和 4.3for 版本比一比,想想為什麼不一樣。
  2. (輸入驗證) 一直請使用者輸入一個數字,直到輸入的數字落在 1 到 100 之間為止,最後把這個合法的數字印出來。