C++のDo While ループについて

AI実装検定のご案内

C++のdo-whileループは、指定した条件が成立している間、同じ処理を繰り返すための構文です。

最大の特徴は、条件を確認する前に、ループ内の処理を実行することです。

そのため、条件が最初から成立していない場合でも、ループ内の処理は最低1回実行されます。

基本構文は次のとおりです。

do {
    // 繰り返したい処理
} while (条件式);

do-whileループでは、最後のwhile文の後にセミコロン;が必要です。

} while (条件式);

セミコロンを付け忘れると、コンパイルエラーになるため注意しましょう。

目次

do-whileループの処理の流れ

do-whileループは、次の順番で処理されます。

  1. doブロック内の処理を実行する
  2. whileの条件式を評価する
  3. 条件がtrueの場合は、再びループ内の処理を実行する
  4. 条件がfalseの場合は、ループを終了する

重要なのは、条件判定よりも先に、ループ内の処理が実行される点です。

1から5まで表示する例

次のプログラムでは、1から5までの整数を順番に表示します。

#include <iostream>

int main() {
    int number = 1;

    do {
        std::cout << number << '\n';
        number++;
    } while (number <= 5);

    return 0;
}

実行結果は次のとおりです。

1
2
3
4
5

処理の流れを詳しく見ると、次のようになります。

最初にnumberには1が代入されています。

int number = 1;

ループ内でnumberの値を表示した後、number++によって値を1増やします。

std::cout << number << '\n';
number++;

その後、次の条件を確認します。

number <= 5

numberが5以下であれば、再びループ内の処理を実行します。

最終的にnumberが6になると、条件式がfalseとなり、ループが終了します。

do-whileループは最低1回実行される

do-whileループの最も重要な特徴は、条件が最初からfalseであっても、ループ内の処理が1回実行されることです。

#include <iostream>

int main() {
    int number = 10;

    do {
        std::cout << "処理が実行されました\n";
    } while (number < 5);

    return 0;
}

このプログラムでは、条件式は次のようになります。

10 < 5

この条件はfalseです。

しかし、do-whileループでは条件を確認する前にループ内の処理を実行するため、次の文字列が1回表示されます。

処理が実行されました

「処理を最低1回は実行してから、繰り返すかどうかを判断したい」という場合に、do-whileループが適しています。

whileループとの違い

do-whileループとwhileループは、どちらも条件が成立している間、処理を繰り返す構文です。

ただし、条件を確認するタイミングが異なります。

whileループの場合

whileループは、ループ内の処理を実行する前に条件を確認します。

while (条件式) {
    // 繰り返したい処理
}

条件が最初からfalseの場合、ループ内の処理は一度も実行されません。

#include <iostream>

int main() {
    int number = 10;

    while (number < 5) {
        std::cout << "処理が実行されました\n";
    }

    return 0;
}

number < 5は最初からfalseであるため、このプログラムでは何も表示されません。

do-whileループの場合

do-whileループは、ループ内の処理を実行した後に条件を確認します。

do {
    // 繰り返したい処理
} while (条件式);

そのため、条件が最初からfalseであっても、ループ内の処理は1回実行されます。

whileループとdo-whileループの比較

項目whileループdo-whileループ
条件を確認するタイミング処理の前処理の後
最低実行回数0回1回
条件が最初からfalseの場合実行されない1回実行される
適している処理実行前に条件確認が必要な処理最低1回は実行したい処理

forループとの違い

C++には、主に次の3種類の繰り返し構文があります。

for
while
do-while

これらは多くの場合、相互に書き換えることができます。

ただし、処理の目的に合った構文を選ぶことで、プログラムの意図が分かりやすくなります。

forループが適している場合

forループは、繰り返す回数があらかじめ分かっている場合に適しています。

for (int i = 1; i <= 5; i++) {
    std::cout << i << '\n';
}

このコードでは、1から5までの整数を表示します。

初期化、条件判定、変数の更新を1行にまとめられるため、一定回数の繰り返しに向いています。

whileループが適している場合

whileループは、繰り返す回数が事前に分からず、処理を始める前に条件を確認したい場合に適しています。

int i = 1;

while (i <= 5) {
    std::cout << i << '\n';
    i++;
}

do-whileループが適している場合

do-whileループは、繰り返す回数が事前に分からず、処理を最低1回は実行したい場合に適しています。

int i = 1;

do {
    std::cout << i << '\n';
    i++;
} while (i <= 5);

do-whileループが適している場面

do-whileループは、最初の処理を必ず実行する必要がある場面で役立ちます。

代表的な使用例には、次のようなものがあります。

  • ユーザーから最低1回は入力を受け取る
  • メニューを最低1回は表示する
  • ゲームを最低1回は実行する
  • 処理後に再実行するか確認する
  • 条件を満たすまで再入力させる

ユーザーの入力を繰り返し受け付ける

ユーザーに整数を入力してもらい、指定した範囲の値が入力されるまで繰り返す処理に、do-whileループを使用できます。

#include <iostream>

int main() {
    int number;

    do {
        std::cout << "1から10までの整数を入力してください: ";
        std::cin >> number;
    } while (number < 1 || number > 10);

    std::cout << "入力された整数は "
              << number
              << " です。\n";

    return 0;
}

実行例は次のとおりです。

1から10までの整数を入力してください: 20
1から10までの整数を入力してください: -3
1から10までの整数を入力してください: 7
入力された整数は 7 です。

条件式は次のようになっています。

number < 1 || number > 10

これは、次のどちらかが成立している間、入力を繰り返すという意味です。

  • 入力値が1未満
  • 入力値が10より大きい

つまり、1から10までの範囲外である間、ループが継続します。

なお、このコードは整数が入力されることを前提とした簡略例です。

文字列などが入力された場合には、別途入力エラーへの対応が必要です。

メニューを繰り返し表示する

操作メニューを表示し、ユーザーが終了を選択するまで処理を繰り返す場合にも、do-whileループが適しています。

#include <iostream>

int main() {
    int choice;

    do {
        std::cout << "\nメニュー\n";
        std::cout << "1. データを表示\n";
        std::cout << "2. 設定を変更\n";
        std::cout << "0. 終了\n";
        std::cout << "番号を選択してください: ";

        std::cin >> choice;

        if (choice == 1) {
            std::cout << "データを表示します。\n";
        } else if (choice == 2) {
            std::cout << "設定を変更します。\n";
        } else if (choice == 0) {
            std::cout << "プログラムを終了します。\n";
        } else {
            std::cout << "正しい番号を入力してください。\n";
        }

    } while (choice != 0);

    return 0;
}

このプログラムでは、メニューが必ず1回表示されます。

ユーザーが0を入力すると、次の条件がfalseになります。

choice != 0

その結果、ループが終了します。

この例も整数が入力されることを前提としています。

文字列入力まで安全に処理する場合は、入力状態を確認する必要があります。

カウントダウンを行う

do-whileループを使って、5から1までカウントダウンできます。

#include <iostream>

int main() {
    int count = 5;

    do {
        std::cout << count << '\n';
        count--;
    } while (count > 0);

    std::cout << "スタート!\n";

    return 0;
}

実行結果は次のとおりです。

5
4
3
2
1
スタート!

countの値を表示した後、count--によって1ずつ減らしています。

countが0になると、次の条件がfalseになり、ループが終了します。

count > 0

1から10までの合計を計算する

次のプログラムでは、1から10までの整数を加算しています。

#include <iostream>

int main() {
    int number = 1;
    int total = 0;

    do {
        total += number;
        number++;
    } while (number <= 10);

    std::cout << "合計は "
              << total
              << " です。\n";

    return 0;
}

実行結果は次のとおりです。

合計は 55 です。

次の記述は、totalnumberの値を加算する処理です。

total += number;

この例では、次の記述と同じ結果になります。

total = total + number;

breakでループを途中終了する

break文を使用すると、whileの条件に関係なく、ループを途中で終了できます。

#include <iostream>

int main() {
    int number = 1;

    do {
        std::cout << number << '\n';

        if (number == 3) {
            break;
        }

        number++;
    } while (number <= 10);

    std::cout << "ループを終了しました。\n";

    return 0;
}

実行結果は次のとおりです。

1
2
3
ループを終了しました。

本来はnumberが10以下である間、処理を繰り返す構造です。

しかし、numberが3になった時点でbreakが実行されるため、ループが終了します。

なお、ループが入れ子になっている場合、breakで終了するのは最も内側のループだけです。

continueで残りの処理をスキップする

continue文を使用すると、その回の残りの処理を飛ばして、次の条件判定へ進むことができます。

#include <iostream>

int main() {
    int number = 0;

    do {
        number++;

        if (number == 3) {
            continue;
        }

        std::cout << number << '\n';

    } while (number < 5);

    return 0;
}

実行結果は次のとおりです。

1
2
4
5

numberが3のときにcontinueが実行されるため、3を表示する処理だけがスキップされます。

do-whileループでcontinueを使う場合の注意点

do-whileループでcontinueが実行されると、ループの先頭へ直接戻るのではなく、末尾のwhile条件式へ進みます。

また、変数の更新処理をcontinueより後ろに置くと、更新処理が実行されず、無限ループになる可能性があります。

次のコードには問題があります。

int number = 1;

do {
    if (number == 3) {
        continue;
    }

    std::cout << number << '\n';
    number++;

} while (number <= 5);

numberが3になると、continueによってnumber++が実行されません。

そのため、numberは3のままとなり、何度も同じ処理を繰り返す無限ループになります。

更新処理が確実に実行されるよう、処理の順番に注意しましょう。

int number = 1;

do {
    if (number == 3) {
        number++;
        continue;
    }

    std::cout << number << '\n';
    number++;

} while (number <= 5);

無限ループを作る方法

条件式を常にtrueにすると、無限ループになります。

do {
    // 繰り返し実行する処理
} while (true);

通常は、ループ内にbreakなどの終了処理を用意します。

#include <iostream>

int main() {
    int number;

    do {
        std::cout << "整数を入力してください。0で終了します: ";
        std::cin >> number;

        if (number == 0) {
            break;
        }

        std::cout << "入力値: "
                  << number
                  << '\n';

    } while (true);

    std::cout << "終了しました。\n";

    return 0;
}

ユーザーが0を入力すると、breakが実行され、無限ループから抜けます。

終了条件を用意しない場合、処理が繰り返され続けるため注意が必要です。

do-whileループでよくある間違い

do-whileループでは、セミコロンの付け忘れや条件式の間違いによって、コンパイルエラーや無限ループが発生することがあります。

whileの後のセミコロンを忘れる

正しい書き方は次のとおりです。

do {
    std::cout << "Hello\n";
} while (condition);

誤った書き方は次のとおりです。

do {
    std::cout << "Hello\n";
} while (condition)

最後のセミコロンがないため、コンパイルエラーになります。

条件式を逆にする

次のコードでは、1から10までの正しい値が入力されている間、入力処理を繰り返します。

do {
    std::cin >> number;
} while (number >= 1 && number <= 10);

「1から10までの範囲外である間、再入力させる」という目的には適していません。

正しくは、次のように記述します。

do {
    std::cin >> number;
} while (number < 1 || number > 10);

do-whileの条件式には、ループを終了する条件ではなく、ループを続ける条件を書くことが重要です。

変数を更新し忘れる

次のコードでは、numberの値が変化しません。

int number = 1;

do {
    std::cout << number << '\n';
} while (number <= 5);

numberは常に1であるため、条件式は常にtrueとなり、無限ループになります。

正しくは、ループ内でnumberの値を更新します。

int number = 1;

do {
    std::cout << number << '\n';
    number++;
} while (number <= 5);

単に変数を更新すればよいわけではなく、最終的に条件式がfalseになる方向へ値を変化させる必要があります。

通常のwhileループに余分なセミコロンを付ける

do-whileループでは、末尾のセミコロンが必要です。

do {
    std::cout << "処理\n";
} while (condition);

一方、通常のwhileループでは、条件式の直後にセミコロンを付けると、空のループになります。

while (condition);
{
    std::cout << "処理\n";
}

この場合、while (condition);のセミコロンがループ本体として扱われます。

後ろの波括弧はwhileループとは関係のない、独立したブロックです。

conditionが常にtrueの場合は、空の無限ループとなり、その後の処理には進みません。

文字列が入力された場合のエラー処理

数値を入力してもらうプログラムでは、ユーザーが必ず整数を入力するとは限りません。

例えば、次のコードでabcと入力すると、std::cinは入力に失敗します。

int number;

do {
    std::cout << "整数を入力してください: ";
    std::cin >> number;
} while (number < 1 || number > 10);

入力に失敗すると、std::cinはエラー状態になります。

その状態を解除しない限り、その後の入力処理も失敗し続けます。

入力エラーに対応した例

入力形式と入力範囲の両方を確認する場合は、次のように記述できます。

#include <iostream>
#include <limits>

int main() {
    int number = 0;
    bool validInput = false;

    do {
        std::cout << "1から10までの整数を入力してください: ";

        if (!(std::cin >> number)) {
            std::cout << "整数を入力してください。\n";

            std::cin.clear();

            std::cin.ignore(
                std::numeric_limits<std::streamsize>::max(),
                '\n'
            );

            validInput = false;
        } else if (number < 1 || number > 10) {
            std::cout << "1から10までの範囲で入力してください。\n";
            validInput = false;
        } else {
            validInput = true;
        }

    } while (!validInput);

    std::cout << "入力された整数は "
              << number
              << " です。\n";

    return 0;
}

このプログラムでは、次の2種類のエラーを分けて処理しています。

  • 整数以外が入力された
  • 整数ではあるが、1から10までの範囲外だった

std::cin.clear()の役割

次の処理は、入力ストリームのエラー状態を解除します。

std::cin.clear();

文字列を整数として読み込もうとした場合、std::cinは失敗状態になります。

そのままでは次の入力も受け付けられないため、clear()を使用して状態を戻します。

std::cin.ignore()の役割

次の処理は、現在の入力行に残っている文字を、改行まで読み捨てます。

std::cin.ignore(
    std::numeric_limits<std::streamsize>::max(),
    '\n'
);

std::cin.clear()だけでは、入力バッファー内に不正な文字が残ったままです。

そのため、std::cin.ignore()を使用して、入力行の残りを削除します。

std::numeric_limitsを使用するため、次のヘッダーファイルが必要です。

#include <limits>

ネストしたdo-whileループ

do-whileループの中に、別のdo-whileループを記述することもできます。

ループの中にループを配置する構造を、ネストまたは入れ子と呼びます。

次の例では、1から3までの掛け算の一覧を表示します。

#include <iostream>

int main() {
    int row = 1;

    do {
        int column = 1;

        do {
            std::cout << row
                      << " × "
                      << column
                      << " = "
                      << row * column
                      << '\n';

            column++;
        } while (column <= 3);

        row++;

    } while (row <= 3);

    return 0;
}

実行結果は次のとおりです。

1 × 1 = 1
1 × 2 = 2
1 × 3 = 3
2 × 1 = 2
2 × 2 = 4
2 × 3 = 6
3 × 1 = 3
3 × 2 = 6
3 × 3 = 9

外側のループがrowを管理し、内側のループがcolumnを管理しています。

内側のループが終了すると、外側のループのrowが1増えます。

do-whileループを関数内で使う

入力処理を関数として分離すると、プログラムの役割が分かりやすくなります。

次の例では、正の整数が入力されるまで処理を繰り返します。

#include <iostream>
#include <limits>

int getPositiveNumber() {
    int number = 0;
    bool validInput = false;

    do {
        std::cout << "正の整数を入力してください: ";

        if (!(std::cin >> number)) {
            std::cout << "整数を入力してください。\n";

            std::cin.clear();
            std::cin.ignore(
                std::numeric_limits<std::streamsize>::max(),
                '\n'
            );

            validInput = false;
        } else if (number <= 0) {
            std::cout << "1以上の整数を入力してください。\n";
            validInput = false;
        } else {
            validInput = true;
        }

    } while (!validInput);

    return number;
}

int main() {
    int value = getPositiveNumber();

    std::cout << "入力された値は "
              << value
              << " です。\n";

    return 0;
}

getPositiveNumber()関数は、正しい値が入力されるまで処理を繰り返し、入力された正の整数を返します。

入力処理を関数に分けることで、main()関数の内容を簡潔にできます。

std::endlと改行文字の違い

C++では、次のようにstd::endlを使用して改行できます。

std::cout << number << std::endl;

ただし、std::endlは改行するだけでなく、出力バッファーを強制的にフラッシュします。

単純に改行するだけであれば、次のように'\n'を使用できます。

std::cout << number << '\n';

通常の出力では、不要なフラッシュを避けられる'\n'がよく使用されます。

一方、出力を即座に画面へ反映させたい場合などは、std::endlが適していることもあります。

do-whileループを使うか判断する基準

do-whileループを使用するか迷った場合は、次の点を確認しましょう。

条件を確認する前に、処理を最低1回は実行する必要があるか

この質問に対して「はい」と答えられる場合は、do-whileループが適している可能性があります。

例えば、次のような処理です。

  • 最初にメニューを表示する
  • 最初にユーザーから入力を受け取る
  • 最初にゲームを実行する
  • 処理後にもう一度実行するか確認する
  • 入力内容を確認してから再入力を求める

一方、処理を実行する前に条件を確認する必要がある場合は、whileループの方が適しています。

繰り返す回数が明確な場合は、forループを使用すると処理の意図を表現しやすくなります。

C++のdo-whileループのまとめ

C++のdo-whileループは、ループ内の処理を実行した後で条件を判定する繰り返し構文です。

基本構文は次のとおりです。

do {
    // 繰り返す処理
} while (条件式);

do-whileループの重要なポイントは、次のとおりです。

  • ループ内の処理は最低1回実行される
  • 条件がtrueである間、処理を繰り返す
  • 条件判定はループ内の処理を実行した後に行われる
  • 最後のwhile文の後にはセミコロンが必要
  • ユーザー入力やメニュー表示に適している
  • breakを使うとループを途中で終了できる
  • continueを使うと残りの処理をスキップできる
  • 更新処理を忘れると無限ループになる可能性がある
  • 数値入力では、文字列が入力された場合のエラー処理も必要になる
  • 条件式には、ループを続ける条件を記述する

特に、「最初の1回は必ず処理を実行したい」という場面でdo-whileループを使用すると、処理の意図が分かりやすいプログラムを作成できます。

以上、C++のDo While ループについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次