同じ処理を繰り返すことをループ(反復)と呼びます。C# には while・do-while・for・foreach の 4 種類のループ構文があります。
while 文で条件が成立する間ループできるbreak については break と continue(補足) を参照)do-while 文と while 文の違いを説明できるfor 文の 3 つの部分(初期化・条件・更新)を理解して書けるforeach 文で文字列の各文字を走査できる条件分岐の if 文は「条件が成立したとき、1 回だけ処理を実行する」構文でした。では「条件が成立し続ける間、何度でも繰り返したい」場合はどうすればよいでしょうか。たとえば「HP が 0 になるまで攻撃し続ける」「ユーザーが正しい値を入力するまで再入力を促す」といった処理です。これを実現するのが while 文です。
while 文はループの先頭で条件を評価し、true の間ブロックを繰り返します。条件が最初から false であれば、ブロックは 1 回も実行されません。
書式:while 文
1
2
3
4
while (条件式)
{
繰り返す処理
}
| 要素 | 説明 |
|---|---|
条件式 |
bool 型になる式。true の間ループを続ける |
{ } |
毎回実行されるブロック(ループ本体) |
実行の流れは次のとおりです。
true ならブロックを実行して 1 に戻るfalse になったらループを抜ける1
2
3
4
5
6
7
int count = 0;
while (count < 3)
{
Console.WriteLine($"count={count}");
count = count + 1;
}
1
2
3
count=0
count=1
count=2
count が 0・1・2 のときは count < 3 が true なのでループが続きます。count が 3 になると false になり、ループを抜けます。
flowchart TD
A([開始]) --> B["count = 0"]
B --> C{"countが3未満か"}
C -- true --> D["countを出力"]
D --> E["count = count + 1"]
E --> C
C -- false --> F([終了])
💡 ポイント:
count = count + 1はcount++と書くこともできます(インクリメント演算子)。
条件式に true を直接書くと、条件が永遠に成立するため無限ループになります。
1
2
3
4
while (true)
{
Console.WriteLine("永遠に繰り返す");
}
このコードはプログラムが止まらなくなります。無限ループはプログラムをフリーズさせる原因になるため、意図しない無限ループには注意が必要です。
無限ループを意図的に使いつつ途中で抜け出す方法(break)や、特定の繰り返しをスキップする方法(continue)については break と continue(補足) で詳しく解説しています。
条件式の変数を更新し忘れると、条件が永遠に true のままになり無限ループになります。
1
2
3
4
5
6
7
8
int count = 0;
// ❌ NG: count を更新していないので永遠に count < 3 が true
while (count < 3)
{
Console.WriteLine(count);
// count++ を書き忘れている
}
ループ変数を更新する処理を必ず書くようにしましょう。
while 文は条件を「ループの前」に判定するため、最初から条件が false であればブロックは 1 回も実行されません。しかし「まず 1 回は必ず実行し、その後継続するか判断したい」場面もあります。たとえばゲームのリトライ確認では「結果を表示してから続けるか尋ねる」という順番になり、最初の 1 回は必ず実行されます。そのような場合に使うのが do-while 文です。
書式:do-while 文
1
2
3
4
do
{
繰り返す処理
} while (条件式);
while 文との違いは条件判定のタイミングです。
| 条件判定 | ループ本体の最低実行回数 | |
|---|---|---|
while |
ループの前 | 0 回(最初から false なら実行されない) |
do-while |
ループの後 | 1 回(必ず 1 回は実行される) |
1
2
3
4
5
6
7
int count = 5;
do
{
Console.WriteLine($"count={count}");
count++;
} while (count < 3);
1
count=5
count が最初から 5 で count < 3 は false ですが、条件チェックはループ本体の後なので 1 回だけ実行されます。
flowchart TD
A([開始]) --> B["count = 5"]
B --> C["countを出力"]
C --> D["count++"]
D --> E{"countが3未満か"}
E -- true --> C
E -- false --> F([終了])
カウンター変数を使ったループでは while より for がよく使われます。カウンターの初期化・条件・更新を 1 行にまとめて書けるため、ループ変数の更新を忘れにくくなります。
書式:for 文
1
2
3
4
for (初期化式; 条件式; 更新式)
{
繰り返す処理
}
| 要素 | 説明 | 実行タイミング |
|---|---|---|
初期化式 |
ループ変数の準備(例: int i = 0) |
ループ開始時に 1 回だけ |
条件式 |
true の間ループを続ける |
ループ本体の前に毎回 |
更新式 |
ループ変数の更新(例: i++) |
ループ本体の後に毎回 |
1
2
3
4
for (int i = 0; i < 3; i++)
{
Console.WriteLine($"i={i}");
}
1
2
3
4
5
i=0
i=1
i=2
```実行の流れを追うと次のようになります。
① int i = 0 (初期化) ② i < 3 → true (条件チェック) ③ “i=0” を出力 (ループ本体) ④ i++ → i = 1 (更新) ② i < 3 → true ③ “i=1” を出力 ④ i++ → i = 2 ② i < 3 → true ③ “i=2” を出力 ④ i++ → i = 3 ② i < 3 → false → ループ終了
1
2
3
4
5
6
7
8
9
```mermaid
flowchart TD
A([開始]) --> B["int i = 0(初期化)"]
B --> C{"iが3未満か(条件)"}
C -- true --> D["iを出力(ループ本体)"]
D --> E["i++(更新)"]
E --> C
C -- false --> F([終了])
for は while の書き換えです。どちらも同じ処理を表します。
1
2
3
4
5
6
7
8
9
10
11
12
13
// for 文
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
// 同じ処理を while で書いた場合
int i = 0;
while (i < 5)
{
Console.WriteLine(i);
i++;
}
カウンターを使うループには for を、回数が事前に決まっていないループには while を使うのが一般的です。
for 文では「何番目の要素か」を表すインデックス(i など)を自分で管理する必要があります。しかし「先頭から順番に全要素を処理したい」だけの場面では、インデックスは本来不要なはずです。foreach 文はその煩わしさを解消する構文で、コレクション(複数の値のまとまり)から要素を 1 つずつ自動的に取り出してループします。
配列やリストといったコレクションについてはこの章では扱いませんが、文字列(string)も「文字(char)の並び」として扱えるため、foreach の動作を確認するのに最適です。配列と foreach の組み合わせは配列の基礎で詳しく学びます。
書式:foreach 文
1
2
3
4
foreach (型 変数名 in コレクション)
{
繰り返す処理
}
| 要素 | 説明 |
|---|---|
型 変数名 |
各要素を受け取る変数。var も使える |
コレクション |
複数の要素を持つデータ(文字列・配列・リストなど) |
foreach は「コレクションの要素を先頭から 1 つずつ取り出してループする」構文です。カウンター変数が不要なのでシンプルに書けます。
文字列(string)は文字(char)の並びとして扱えるため、foreach で 1 文字ずつ取り出せます。
1
2
3
4
5
6
string text = "Hello";
foreach (var ch in text)
{
Console.WriteLine(ch);
}
1
2
3
4
5
H
e
l
l
o
text の先頭から 1 文字ずつ ch に取り出し、すべての文字を処理し終えるとループを抜けます。
flowchart TD
A([開始]) --> C{"次の文字があるか"}
C -- ある --> D["chに次の文字を取り出す"]
D --> E["chを出力"]
E --> C
C -- ない --> F([終了])
💡 ポイント:
foreachの真価は配列やリストで発揮されます。配列については配列の基礎で詳しく学びます。
1
2
3
4
5
6
7
8
9
10
11
// ❌ NG: i++ で増えているのに i > 0 はすぐ false になり 1 回も実行されない
for (int i = 0; i > 0; i++)
{
Console.WriteLine(i);
}
// ✅ OK: 0 から始めて 5 未満の間ループ
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
1
2
3
4
5
6
string text = "Hello";
foreach (var ch in text)
{
ch = 'X'; // ❌ コンパイルエラー: foreach 変数は読み取り専用
}
foreach の変数は読み取り専用です。要素を変更したい場合は for でインデックスを使います。
while — 条件が true の間ループ。条件はループ前に判定break — ループを強制終了する。break と continue(補足) を参照do-while — while と同じだが条件はループ後に判定。必ず 1 回は実行されるfor — 初期化・条件・更新を 1 行に書けるカウンターループforeach — コレクションの要素を 1 つずつ取り出すループ。カウンター不要次のコードの出力結果を答えてください。
1
2
3
4
5
6
int i = 1;
while (i <= 4)
{
Console.WriteLine($"i={i}");
i += 2;
}
次のコードは何回ループしますか? また、最終的に count の値はいくつになりますか?
1
2
3
4
5
int count = 10;
do
{
count--;
} while (count > 10);
for 文を使って 5 4 3 2 1 と出力するコードを書いてください。
i=1 と i=3。i は 1 → 3 → 5 と変化し、5 になると i <= 4 が false になってループを抜ける。
1 回。最初に count-- で count が 9 になり、その後 count > 10 は false なのでループを抜ける。最終的な count の値は 9。
1
2
3
4
for (int i = 5; i >= 1; i--)
{
Console.WriteLine(i);
}
メソッド では、処理をまとめて名前をつけて再利用する方法を学びます。