C#のwhile
文は、ある条件がtrue
である間だけ処理を繰り返す基本的なループ構文です。
繰り返し回数があらかじめ決まらない場面に強く、入力の待機や検索など「終わりの条件」で制御したいときに役立ちます。
ここでは基本の考え方から構文、実行の流れ、実用的なサンプルまで初心者向けに丁寧に解説します。
C#のwhile文とは?基本の考え方
条件がtrueの間だけ繰り返す
while
文は「条件判定 → 本体の実行 → 条件判定 → …」という流れで、条件がtrue
の間だけ処理を繰り返します。
条件がfalse
になると即座にループを抜けます。
回数ではなく状態でループを制御する点が、回数を指定するfor
文との大きな違いです。
例として想像しやすい場面
- ユーザーが「終了」と入力するまで待ち続ける
- ファイルの終端(EOF)に達するまで読み込む
- 検索で目的の値が見つかるまで探し続ける
いつ使うか(初心者向けの利用シーン)
「いつ終わるか」が外部の要因に依存する処理はwhile
が向いています。
たとえばコンソールからの入力、ネットワークからの受信、キューにアイテムがある間の処理などです。
反対に明確に回数が決まっている場合はfor
、コレクションの全要素を順に処理する場合はforeach
が読みやすくなります。
C#のwhile文 基本構文と書き方
基本構文(while 条件 ブロック)
最小の形は次の通りです。
// 条件が true の間、波括弧のブロックを繰り返す
while (条件)
{
// 繰り返したい処理
}
条件式のポイント
- 条件式は
bool
として評価されます(例:count < 10
、input != null
)。 - 副作用のある処理は条件に直接書かない方が読みやすく安全です。
条件の評価タイミングと実行の流れ
評価は常に「実行の前」です。
そのため、最初の判定でfalse
なら一度も実行されません。
実行の流れ
- 条件式を評価する
- 条件が
true
ならブロック内を実行する - 再び条件式を評価する
- 2〜3を繰り返す。条件が
false
になったら終了
変数の初期化と更新のコツ
「初期化 → ループ → 更新」の位置関係を明確にすることで、意図せぬ無限ループを防げます。
- 初期化はループの直前で行い、読み手に開始状態を示します。
- ループの最後で終了条件に関わる変数を必ず更新します。
- 条件式はシンプルに保ち、必要なら途中で補助変数を使って可読性を高めます。
以下に「やっていいこと/避けたいこと」の観点で整理します。
観点 | よい例 | 避けたい例 |
---|---|---|
初期化 | ループ直前でint i = 0; | どこで初期化されたか分からない |
更新 | ブロック末尾でi++; | 更新を条件式に埋め込んで見落とす |
条件 | i < max の単純比較 | ネガティブ条件を多段で重ねて可読性低下 |
サンプルコードで学ぶ while文の使い方
サンプル1 カウンタで回す基本のwhile
回数をカウンタ変数で制御する基本形です。
終了条件と更新の関係を確認しましょう。
using System;
class Program
{
static void Main()
{
// 1) 初期化: ループの外で開始値を設定
int count = 0;
// 2) 条件: count が 5 未満の間は繰り返す
while (count < 5)
{
Console.WriteLine($"count = {count}");
// 3) 更新: 終了条件に関わる変数を必ず更新する
count++; // これを忘れると無限ループになります
}
Console.WriteLine("Done");
}
}
count = 0
count = 1
count = 2
count = 3
count = 4
Done
- 初期化→条件→本体→更新の順番が読みやすさの鍵です。
- 終了条件に寄与する更新を忘れないことが最重要です。
サンプル2 ユーザー入力を受け付け続ける
ユーザーが「exit」または空行で終了するまで合計値を更新し続ける例です。
回数が未定な場面にwhile
が適しています。
using System;
class Program
{
static void Main()
{
Console.WriteLine("数値を入力してください。'exit' または空行で終了します。");
int sum = 0;
// 初回読み取り(初期化)
string? line = Console.ReadLine();
// 条件: 入力が空や 'exit' でない間、繰り返す
while (!string.IsNullOrWhiteSpace(line) && !line.Equals("exit", StringComparison.OrdinalIgnoreCase))
{
// 数値として解釈できれば合計に加算
if (int.TryParse(line, out int value))
{
sum += value;
Console.WriteLine($"現在の合計: {sum}");
}
else
{
Console.WriteLine("数値を入力してください(例: 10)。終了するには 'exit' か空行。");
}
// 更新: 次の入力を読み取る(これを忘れると前回の値のままで無限ループ)
line = Console.ReadLine();
}
Console.WriteLine($"最終合計: {sum}");
Console.WriteLine("入力を終了しました。");
}
}
数値を入力してください。'exit' または空行で終了します。
10
現在の合計: 10
abc
数値を入力してください(例: 10)。終了するには 'exit' か空行。
25
現在の合計: 35
exit
最終合計: 35
入力を終了しました。
終了条件は「入力の状態」によって決まるため、回数が読めないケースでwhile
が活躍します。
初回入力をループの前で取得(初期化)し、各周回の最後に次の入力へ更新するのが定型です。
サンプル3 配列をインデックスで走査する
配列をwhile
で走査し、合計と平均を求めます。
foreach
でも書けますが、while
はインデックス制御が明示的です。
using System;
class Program
{
static void Main()
{
int[] scores = { 72, 85, 90, 68, 100 };
int index = 0; // 初期化
int total = 0;
// 条件: index が配列の長さ未満の間
while (index < scores.Length)
{
int score = scores[index];
Console.WriteLine($"scores[{index}] = {score}");
total += score;
index++; // 更新: 次の要素へ進める
}
double average = (double)total / scores.Length;
Console.WriteLine($"合計: {total}, 平均: {average:F1}");
}
}
scores[0] = 72
scores[1] = 85
scores[2] = 90
scores[3] = 68
scores[4] = 100
合計: 415, 平均: 83.0
境界条件(index < scores.Length
)は厳密に。<=
と誤記すると範囲外アクセスの原因になります。
インデックス制御が必要なときはwhile
かfor
が適します。
while文の注意点とベストプラクティス(初心者向け)
終了条件は必ず更新する(無限ループを防ぐ)
終了条件に関わる値を各周回で確実に更新することが最重要です。
更新を忘れると無限ループになります。
例: カウンタcount
を条件に使うなら、ブロック内でcount++
を行います。
外部状態(入力、キューの有無)が条件なら、その状態を読み直す更新が必要です。
初回から条件がfalseだと実行されない
while
は「前判定」なので、最初の判定でfalse
なら本体は一度も実行されません。
初回も必ず1回は実行したい場合は、設計を見直して初期値を調整するか、処理の分割を考えましょう(本記事ではdo...while
は扱いません)。
条件式は読みやすくシンプルにする
可読性の高い条件式はバグを減らします。
複雑な論理式は補助のbool
変数で分割しましょう。
// 悪い例: 何を判定しているか一読で分かりにくい
while (!(items.Count == 0 || (!isActive && hasError)))
{
// ...
}
// よい例: 意味のある名前で意図を明確化
bool hasItems = items.Count > 0;
bool canProceed = isActive || !hasError;
while (hasItems && canProceed)
{
// ...
// 状態が変わるなら、ループ末尾で hasItems / canProceed を再評価する
}
コツ
- 否定の多重ネストを避け、肯定形で表現する
- 魔法の数字や複雑な比較は事前に変数へ分解する
- 条件に副作用(関数呼び出しで状態変更など)を混ぜない
まとめ
while
文は「条件がtrue
の間だけ繰り返す」というシンプルかつ強力な制御構文です。
回数未定の処理や外部状態に依存する処理で威力を発揮します。
正しく使うための要点は次の通りです。
終了条件に関わる更新を確実に行うこと、前判定であることを理解した初期化と条件設計にすること、そして条件式をシンプルに保つことです。
これらを守れば、読みやすく安全なループを実装できます。
今回のサンプルを土台に、入力、探索、監視などのさまざまな場面へ応用してください。