do-while文とは?
C++における「ループ(繰り返し)処理」を実現する構文の一つがdo-while
文です。
while
文と非常によく似ていますが、決定的な違いが一つあります。それは、ループ本体(繰り返したい処理)を最低1回は必ず実行し、その後に条件判定を行う点です。
この「後判定」の特性から、「まず一度実行してみて、条件が満たされていれば繰り返す」といった種類の処理を記述するのに適しています。
do-while文の基本構文
do-while
文は、do
キーワード、処理内容を記述するブロック{}
、そしてwhile
キーワードと条件式で構成されます。
do {
// このブロック内の処理が
// まず一度、必ず実行されます。
// (ループ本体と呼びます)
} while (条件式); // 条件式が true の間、ループを繰り返します。
while
文と異なり、構文の最後にセミコロン(;
)が必須である点に注意が必要です。
do-while文の具体的な使用例
do-while
文がどのような場面で役立つか、3つの異なるユースケースを見ていきましょう。
ユースケース1:入力値の検証
ユーザーから特定の条件を満たす値を受け取りたい場合、do-while
文は「条件を満たさない限り、再入力を求める」という処理を簡潔に記述できます。
例えば、商品の個数など「必ず0より大きい数値」を入力させたい場合です。
#include <iostream>
#include <limits> // 入力エラー判定のため
int main() {
int quantity;
do {
std::cout << "商品の個数を入力してください (1以上の整数): ";
// 入力が数値として正しいかチェック
if (!(std::cin >> quantity)) {
std::cout << "エラー: 数値を入力してください。" << std::endl;
std::cin.clear(); // エラーフラグをクリア
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 入力バッファをクリア
quantity = 0; // ループを継続させるために条件外の値(0)をセット
} else if (quantity <= 0) {
std::cout << "エラー: 1以上の数値を入力してください。" << std::endl;
}
} while (quantity <= 0); // 条件 (0以下) が true の間ループ
// この時点で、quantity には必ず1以上の整数が入っている
std::cout << "承りました。個数: " << quantity << std::endl;
return 0;
}
まず一度入力を求め、その入力値(quantity
)が条件(quantity <= 0
)を満たす間、ループが継続されます。
ユースケース2:正解するまで繰り返す処理
「まず一度試行し、特定の条件(例:正解)を満たすまで繰り返す」というロジックにも適しています。
#include <iostream>
int main() {
int userAnswer;
const int correctAnswer = 15; // クイズの答え
std::cout << "簡単な計算クイズです。" << std::endl;
do {
// 1. まず一度、問題を出して入力を促す
std::cout << "8 + 7 はいくつ?: ";
std::cin >> userAnswer;
if (std::cin.fail()) {
std::cout << "数値を入力してください。" << std::endl;
std::cin.clear();
std::cin.ignore(10000, '\n');
userAnswer = 0; // 不正解として扱う
} else if (userAnswer != correctAnswer) {
std::cout << "違います。もう一度考えてみましょう。" << std::endl;
}
} while (userAnswer != correctAnswer); // 答えが一致しない間、ループ
std::cout << "正解です!" << std::endl;
return 0;
}
ユースケース3:処理の実行と再試行
「メインの処理を一度実行し、その後でユーザーに継続の意思を確認する」という流れのプログラムです。
#include <iostream>
#include <string>
int main() {
double balance = 10000.0; // 口座残高
char continueFlag;
do {
// 1. メインの処理(引き落とし)
double withdrawAmount;
std::cout << "現在の残高: " << balance << "円" << std::endl;
std::cout << "引き落とし額を入力してください: ";
std::cin >> withdrawAmount;
if (std::cin.fail() || withdrawAmount <= 0) {
std::cout << "無効な金額です。" << std::endl;
std::cin.clear();
std::cin.ignore(10000, '\n');
} else if (withdrawAmount > balance) {
std::cout << "残高が不足しています。" << std::endl;
} else {
balance -= withdrawAmount; // 残高を更新
std::cout << withdrawAmount << "円を引き落としました。" << std::endl;
std::cout << "新しい残高: " << balance << "円" << std::endl;
}
// 2. 処理後に、繰り返しを判定
std::cout << "さらに引き落としを続けますか? (Y/N): ";
std::cin >> continueFlag;
} while (continueFlag == 'Y' || continueFlag == 'y'); // 'Y'か'y'ならループ継続
std::cout << "ご利用ありがとうございました。" << std::endl;
return 0;
}
この例では、まず残高の操作が一度実行され、その後にcontinueFlag
の値がチェックされます。
while
文とdo-while
文の違い
最後に、while
文(前判定)とdo-while
文(後判定)の違いを明確にしておきます。
while文(前判定) ループに入る前に条件を判定します。条件が最初からfalse
の場合、ループ本体は一度も実行されません。
int i = 10;
while (i < 5) {
// この処理は一度も実行されない
std::cout << "whileループ" << std::endl;
}
do-while文(後判定) ループ本体を一度実行してから条件を判定します。条件が最初からfalse
であっても、ループ本体は必ず1回実行されます。
int i = 10;
do {
// この処理は必ず1回実行される
std::cout << "do-whileループ" << std::endl;
} while (i < 5); // 判定はここで行われる
まとめ
do-while
文は、「処理を最低1回は実行したい」という場合に非常に便利なループ構文です。特にユーザーからの入力を受け付けたり、再試行させたりする処理においてコードを簡潔にします。構文の最後のセミコロン(;
)を忘れないよう注意し、while
文との使い分けを意識することが重要です。