トラック6・🔀制御構造

do-while文と入力チェック

読む目安 約10分・ゴール:do-while の「まず1回は実行する」性質を理解し、入力のやり直しループを書ける

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

アンケートを取ります。「まず1回は必ず質問する。答えが変だったら、もう一度聞く」。while だと「聞く前に条件を確かめる」ことになって、少し不自然です。こういうときはdo-while文が素直に書けます。

do {
    処理
} while (継続条件);   // ← セミコロンを忘れずに

whileとの違いは1点だけ。条件を確かめるのが後なので、条件が最初から偽でも本体は必ず1回は実行されます。「とりあえずやってみて、駄目ならもう一度」という形です。

入力チェックで使ってみましょう。

#include <stdio.h>

int main(void) {
    int n;

    do {
        printf("1〜10の数を入力: ");
        if (scanf("%d", &n) != 1) {   // 数字以外が入力された
            printf("数字を入れてください\n");
            return 1;
        }
    } while (n < 1 || n > 10);

    printf("%d を受け付けました\n", n);
    return 0;
}

「範囲外なら、もう一度聞く」がそのまま条件になっています。

注目してほしいのが scanf の戻り値をチェックしている点です。scanfは「読み取りに成功した項目の数」を返すので、%d が1つなら成功時は 1 が返ります。!= 1 なら数字ではなかった、と判定できます。ここで抜けずに聞き直そうとすると、読めなかった文字が入力に残ったままなので、同じ失敗を延々と繰り返す無限ループになります(第4トラックで見た scanf の罠です)。今はひとまず、戻り値を見て抜ける形にしておきます。

ビット「まず1回やってから考える」が do-while。入力のやり直しはこれが一番素直に書けるよ

罠を2つ。

その1、末尾のセミコロン。 } while (条件); の ; を忘れるとコンパイルエラーになります。これは即座に怒られるので、まだ親切な部類です。

その2、条件の向き。 これが本命です。while に書くのは「続ける条件」であって、「やめる条件」ではありません。「1〜10なら受け付ける」と考えて while (n >= 1 && n <= 10); と書いてしまうと、意味が完全に裏返ります。

    // 間違い: 正しい値を入れるほど聞き直される
    do {
        printf("1〜10の数を入力: ");
        scanf("%d", &n);
    } while (n >= 1 && n <= 10);

5 を入れると「範囲内だから続ける」となって何度も聞かれ、99 を入れた瞬間に抜けてしまう。チェックの意味が消えています。書いたら「どういうときに、もう一度聞きたいのか」を日本語で言い直して、そのまま条件に翻訳してください。「範囲外なら、もう一度」→ n < 1 || n > 10 です。

師範do-while の条件は「続ける」条件じゃ。「やめる」条件を書けば、世界が裏返る

まとめます。do-while は本体を必ず1回実行してから条件を見る。末尾にセミコロンが要る。条件は「続ける条件」——入力チェックなら「範囲外なら続ける」。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

1〜10の範囲の数が入力されるまで聞き直す do-while です。空欄に入るものを選んでください。

int n;
do {
    printf("1〜10の数を入力: ");
    scanf("%d", &n);
} while (____);
  1. n < 1 || n > 10
  2. n >= 1 && n <= 10
  3. n < 1 && n > 10
  4. n != 1
答えを見る

正解:A(n < 1 || n > 10)

while に書くのは「続ける条件」=「もう一度聞き直す条件」です。範囲外、つまり「1より小さい または 10より大きい」なら聞き直すので n < 1 || n > 10。n >= 1 && n <= 10 は「範囲内なら続ける」で意味が裏返り、正しい値を入れるほど何度も聞かれます。n < 1 && n > 10 は1より小さくかつ10より大きい数=存在しないので、必ず1回で抜けてしまいチェックになりません。

確認問題 2

アイに「1〜10の数を入力してもらい、範囲外なら聞き直すプログラム」を頼みました。アイの答案にバグはあるでしょうか。あるなら、その行はどこですか。

1#include <stdio.h>
2
3int main(void) {
4    int n;
5
6    do {
7        printf("1〜10の数を入力: ");
8        scanf("%d", &n);
9    } while (n >= 1 && n <= 10);
10
11    printf("%d を受け付けました\n", n);
12    return 0;
13}
答えを見る

判定:バグあり(9行目)

9行目の条件が裏返っています。do-while に書くのは「続ける条件」なので、n >= 1 && n <= 10(範囲内なら続ける)では、正しい値を入れるほど何度も聞き直されます。逆に 99 のような範囲外の値を入れた瞬間に抜けてしまい、チェックの意味がありません。正しくは while (n < 1 || n > 10);(範囲外なら続ける)です。アイのコードは形はきれいで、コンパイルも通り、一見それらしく動いてしまう——AIの答案で一番多いタイプの間違いです。

「制御構造」の目次

  1. 流れを変える——制御構造の全体像
  2. if文——もしも、の分かれ道
  3. else if / else の分かれ道設計
  4. 条件式の罠——= と == の悲劇
  5. 論理演算子と短絡評価
  6. switch文とfallthrough
  7. for文——回数が決まった繰り返し
  8. while文——条件が決める繰り返し
  9. do-while文と入力チェック
  10. breakとcontinueの使いどころ
  11. ループのネストと九九表
  12. 無限ループとの付き合い方

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版