while / do-while(C#)
条件が真である限り処理を繰り返す『while』文と、必ず1回は実行してから条件を評価する『do-while』文の基本構文です。『C#』では繰り返し回数が事前にわからない場合に while / do-while を使い、条件式には必ず bool 型を使わなければなりません。
構文
// while文の基本構文です。条件式がtrueの間、繰り返し実行されます。
while (条件式) {
// 条件式がtrueのときに実行されます。
// ループ内で条件式をfalseにする処理を必ず入れないと無限ループになります。
}
// do-while文の基本構文です。まずブロックを実行し、その後に条件式を評価します。
do {
// 必ず1回は実行されます。
// 条件式がtrueなら繰り返し、falseなら終了します。
} while (条件式);
// 無限ループとbreakの組み合わせです。
// 脱出条件がループ内に複数ある場合や、サービスループに使います。
while (true) {
// 何らかの処理を行います。
if (脱出条件) {
break; // ループを終了します。
}
}
while と do-while の違い
| 構文 | 条件評価のタイミング | 最低実行回数 | 主な用途 |
|---|---|---|---|
| while | ブロック実行前(前判定) | 0回(条件が最初からfalseなら実行されません) | 回数不定の繰り返し全般 |
| do-while | ブロック実行後(後判定) | 1回(条件がfalseでも必ず1回は実行されます) | 入力検証・メニュー選択など、最低1回の実行が必要な処理 |
サンプルコード
WhileBasic.cs
using System;
class WhileBasic {
static void Main() {
// --- while: エネルギーチャージ ---
// チャージを繰り返してエネルギーを規定値まで高めます。
int energy = 100;
int target = 500;
Console.WriteLine("=== エネルギーチャージ ===");
while (energy < target) {
energy += 80; // 1回のチャージで80増加します。
Console.WriteLine("チャージ中... 現在: " + energy);
}
Console.WriteLine("目標値 " + target + " に到達しました!");
// --- while: 対象アイテム探索 ---
// 対象アイテムを見つけるまで探索を続けます。
Console.WriteLine("\n=== 対象アイテムを探索 ===");
string[] items = { "stone_a", "tool_b", "target_item", "part_c", "document_d" };
int index = 0;
while (index < items.Length) {
Console.WriteLine("発見: " + items[index]);
if (items[index] == "target_item") {
Console.WriteLine("対象アイテムを確保しました。探索終了。");
break; // 発見したのでループを抜けます。
}
index++;
}
// --- while と continue: レベル1スキップ ---
// レベルが1のものはスキップして、それ以外だけを処理します。
Console.WriteLine("\n=== タスク処理リスト ===");
int[] taskLevels = { 4, 1, 2, 1, 3, 1, 4 };
int i = 0;
while (i < taskLevels.Length) {
int grade = taskLevels[i];
i++;
if (grade == 1) {
Console.WriteLine("レベル1のタスクはスキップ(対象外)");
continue; // この周をスキップして次へ進みます。
}
Console.WriteLine("レベル" + grade + "のタスクを処理しました。");
}
}
}
コンパイルして実行すると次のようになります。
dotnet script WhileBasic.cs === エネルギーチャージ === チャージ中... 現在: 180 チャージ中... 現在: 260 チャージ中... 現在: 340 チャージ中... 現在: 420 チャージ中... 現在: 500 目標値 500 に到達しました! === 対象アイテムを探索 === 発見: stone_a 発見: tool_b 発見: target_item 対象アイテムを確保しました。探索終了。 === タスク処理リスト === レベル4のタスクを処理しました。 レベル1のタスクはスキップ(対象外) レベル2のタスクを処理しました。 レベル1のタスクはスキップ(対象外) レベル3のタスクを処理しました。 レベル1のタスクはスキップ(対象外) レベル4のタスクを処理しました。
DoWhileBasic.cs
using System;
class DoWhileBasic {
static void Main() {
// --- do-while: オプション選択メニュー ---
// メニューを必ず1回表示してから入力を受け付けます。
// 有効な番号(1〜3)が選ばれるまで繰り返します。
Console.WriteLine("=== オプション選択メニュー ===");
string[] options = { "option_a", "option_b", "option_c" };
int choice = 0; // 選択番号です(初期値は範囲外にしておきます)。
do {
// ブロックは条件に関わらず必ず実行されます。
Console.WriteLine("使用するオプションを選んでください:");
for (int i = 0; i < options.Length; i++) {
Console.WriteLine(" " + (i + 1) + ": " + options[i]);
}
Console.Write("番号を入力 > ");
// ここでは固定値でシミュレートします(実際は Console.ReadLine() で取得)。
choice = 2; // ユーザーが「2」を入力したと仮定します。
Console.WriteLine(choice); // 入力値を表示します。
} while (choice < 1 || choice > options.Length); // 範囲外なら再入力させます。
Console.WriteLine(options[choice - 1] + " を選択しました。");
// --- do-while: エネルギー蓄積 ---
// 必要なエネルギー量に達するまで蓄積を繰り返します。
// 最初の蓄積は必ず実行されます。
Console.WriteLine("\n=== エネルギー蓄積 ===");
int storedEnergy = 0;
int requiredEnergy = 300;
int chargeCount = 0;
do {
storedEnergy += 120; // 1回の蓄積で120増加します。
chargeCount++;
Console.WriteLine(chargeCount + "回目の蓄積: " + storedEnergy + " / " + requiredEnergy);
} while (storedEnergy < requiredEnergy); // 必要量に満たなければ繰り返します。
Console.WriteLine("準備完了(" + chargeCount + "回の蓄積で実行可能)");
}
}
コンパイルして実行すると次のようになります。
dotnet script DoWhileBasic.cs === オプション選択メニュー === 使用するオプションを選んでください: 1: option_a 2: option_b 3: option_c 番号を入力 > 2 option_b を選択しました。 === エネルギー蓄積 === 1回目の蓄積: 120 / 300 2回目の蓄積: 240 / 300 3回目の蓄積: 360 / 300 準備完了(3回の蓄積で実行可能)
ServiceLoop.cs
using System;
class ServiceLoop {
static void Main() {
// サービスループは終了シグナルを受けるまで処理を継続します。
// 脱出条件が複数ある場合や、条件が複雑な場合に while(true) が有効です。
Console.WriteLine("=== 監視システム 起動 ===");
int tick = 0;
bool emergency = false;
while (true) {
tick++;
Console.WriteLine("[ティック " + tick + "] 異常をスキャン中...");
// 3ティック目に緊急事態が発生したとシミュレートします。
if (tick == 3) {
emergency = true;
Console.WriteLine("[警告] 異常を検知しました!");
}
// 緊急事態ならば対応モードへ移行してループを抜けます。
if (emergency) {
Console.WriteLine("[対応] 緊急対応を実行します。");
break; // 緊急事態に対応してサービスループを終了します。
}
// 5ティック経過したら正常終了とみなします。
if (tick >= 5) {
Console.WriteLine("[正常] 脅威なし。監視終了。");
break; // 正常終了でループを抜けます。
}
}
Console.WriteLine("=== 監視システム 停止 ===");
}
}
コンパイルして実行すると次のようになります。
dotnet script ServiceLoop.cs === 監視システム 起動 === [ティック 1] 異常をスキャン中... [ティック 2] 異常をスキャン中... [ティック 3] 異常をスキャン中... [警告] 異常を検知しました! [対応] 緊急対応を実行します。 === 監視システム 停止 ===
よくあるミス
ループ変数の更新を忘れて無限ループになる
while 文の条件式を false にする更新処理をループ内に入れ忘れると、条件が永遠に true のまま無限ループになります。特に break や continue を使うルートで更新処理がスキップされるケースに注意してください。
// NG: index が更新されないため無限ループになります。
int index = 0;
while (index < 5) {
Console.WriteLine(index);
// index++; を忘れています。
}
do-while の末尾にセミコロンを付け忘れる
do-while 文は } while (条件式); の末尾にセミコロンが必要です。忘れるとコンパイルエラーになります。while 文にはセミコロンが不要なため、混同しやすいポイントです。
// NG: セミコロンがないためコンパイルエラーになります。
// do {
// // 処理
// } while (condition)
//
// OK: 末尾にセミコロンを付けます。
do {
Console.WriteLine("processing");
} while (false);
概要
『C#』の while 文は繰り返し回数が事前に決まっていない処理に適しています。条件式の評価は「ブロックの実行前」に行われるため、最初から条件が false の場合はブロックが一度も実行されません。ループ内で条件式をいつか false にする更新処理を必ず入れてください。更新処理を忘れると無限ループになります。
do-while 文は「後判定」ループです。ブロックを必ず1回実行してから条件を評価するため、最低1回の実行が保証されます。入力検証やメニュー選択のように「まず処理してから、続けるかどうかを判定する」パターンに適しています。末尾の } while (条件式); にはセミコロンが必要な点に注意してください。
while (true) による無限ループは、ゲームのメインループや常駐サービスなど「明示的な終了条件が複数ある」場面で有効なパターンです。この場合は必ず break でループを抜ける経路を確保してください。回数が決まっている繰り返しには for 文の方が適しています(『for文』を参照)。コレクションの全要素を順に処理するだけなら foreach が最もシンプルです。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。