for ループ(C#)
指定した回数だけ処理を繰り返す『for』ループの基本構文です。『C#』の for 文は「初期化式・条件式・更新式」の3つをセミコロンで区切って宣言し、条件式が true である限りブロックを繰り返し実行します。
構文
for 文の基本形と主要なパターンです。
// 基本的なfor文です。
for (初期化式; 条件式; 更新式) {
// 条件式がtrueの間、繰り返し実行されます。
}
// カウントアップ(0から始めてn未満まで)の最も一般的な書き方です。
for (int i = 0; i < n; i++) {
// iが 0, 1, 2, ... n-1 の順に変化します。
}
// カウントダウン(n-1から0まで)です。
for (int i = n - 1; i >= 0; i--) {
// iが n-1, n-2, ... 0 の順に変化します。
}
// ステップを変更する書き方です(例: 2ずつ増やす)。
for (int i = 0; i < n; i += 2) {
// iが 0, 2, 4, ... の順に変化します。
}
// break でループを途中で抜けます。
for (int i = 0; i < n; i++) {
if (条件) {
break; // ループ全体を終了します。
}
}
// continue でその周だけスキップします。
for (int i = 0; i < n; i++) {
if (条件) {
continue; // この周の残り処理をスキップして次の周へ進みます。
}
}
各部の役割
| 部分 | タイミング | 説明 |
|---|---|---|
| 初期化式 | ループ開始前に1回だけ | カウンタ変数を宣言・初期化します。複数変数をカンマで並べることもできます。 |
| 条件式 | 各周の実行前に毎回 | bool を返す式を書きます。false になった瞬間にループを終了します。省略すると無限ループになります。 |
| 更新式 | 各周の実行後に毎回 | カウンタを増減します。i++・i--・i += 2 などを使います。複数式をカンマで並べることもできます。 |
サンプルコード
ForLoopBasic.cs
カウントアップ・カウントダウン・ステップ変更・break・continue の基本パターンです。
using System;
class ForLoopBasic {
static void Main() {
// --- カウントアップ: 処理回数を数えます ---
Console.WriteLine("=== 処理開始 ===");
for (int i = 1; i <= 5; i++) {
Console.WriteLine("処理 " + i + " 回目完了");
}
Console.WriteLine("\n=== 逆順表示 ===");
string[] items = { "item_a", "item_b", "item_c", "item_d", "item_e" };
for (int i = items.Length - 1; i >= 0; i--) {
Console.WriteLine((i + 1) + "番: " + items[i]);
}
// --- ステップ変更: 偶数番目の要素だけ表示します ---
Console.WriteLine("\n=== 偶数インデックスのみ ===");
for (int i = 0; i < items.Length; i += 2) {
Console.WriteLine("items[" + i + "] = " + items[i]);
}
Console.WriteLine("\n=== item_c を探索 ===");
for (int i = 0; i < items.Length; i++) {
Console.WriteLine(items[i] + " を確認中...");
if (items[i] == "item_c") {
Console.WriteLine("item_c を発見!探索終了。");
break; // ループを抜けます。
}
}
// --- continue: item_a はスキップして残りだけ表示します ---
Console.WriteLine("\n=== フィルタリング(item_a を除く) ===");
for (int i = 0; i < items.Length; i++) {
if (items[i] == "item_a") {
continue; // この周をスキップして次へ進みます。
}
Console.WriteLine(items[i]);
}
}
}
コンパイルして実行すると次のようになります。
dotnet script ForLoopBasic.cs === 処理開始 === 処理 1 回目完了 処理 2 回目完了 処理 3 回目完了 処理 4 回目完了 処理 5 回目完了 === 逆順表示 === 5番: item_e 4番: item_d 3番: item_c 2番: item_b 1番: item_a === 偶数インデックスのみ === items[0] = item_a items[2] = item_c items[4] = item_e === item_c を探索 === item_a を確認中... item_b を確認中... item_c を確認中... item_c を発見!探索終了。 === フィルタリング(item_a を除く) === item_b item_c item_d item_e
NestedForLoop.cs
多重ループと、多重ループを抜けるための2つのパターン(bool フラグとメソッド化)です。
using System;
class NestedForLoop {
static void Main() {
// C# にはラベル付きbreakがありません。
// 多重ループを一気に抜けるには bool フラグかメソッド化を使います。
string[] items = { "item_a", "item_b", "item_c" };
int[] scores = { 90, 80, 120 };
Console.WriteLine("=== スコアチェック ===");
for (int i = 0; i < items.Length; i++) {
Console.WriteLine(items[i] + ": スコア " + scores[i]);
}
// --- boolフラグで多重ループを抜けるパターン ---
Console.WriteLine("\n=== スコア 90 超えを探索 ===");
int targetScore = 90;
bool found = false;
for (int i = 0; i < items.Length; i++) {
for (int j = 0; j < scores.Length; j++) {
if (i == j && scores[j] > targetScore) {
Console.WriteLine("発見: " + items[i] + "(スコア: " + scores[j] + ")");
found = true;
break; // 内側のループを抜けます。
}
}
if (found) {
break; // 外側のループも抜けます(フラグによる多重ループ脱出)。
}
}
// --- メソッド化による多重ループ脱出パターン ---
// returnを使えばネストの深さに関わらず一気に抜けられます。
string result = FindMatch(items, scores, targetScore);
Console.WriteLine("\n=== メソッド化パターン ===");
Console.WriteLine(result);
}
// 多重ループをメソッドとして切り出すと return で一気に脱出できます。
static string FindMatch(string[] names, int[] values, int threshold) {
for (int i = 0; i < names.Length; i++) {
for (int j = 0; j < values.Length; j++) {
if (i == j && values[j] > threshold) {
return names[i] + " が最初に条件を満たしました(スコア: " + values[j] + ")";
}
}
}
return "条件を満たす要素が見つかりませんでした。";
}
}
コンパイルして実行すると次のようになります。
dotnet script NestedForLoop.cs === スコアチェック === item_a: スコア 90 item_b: スコア 80 item_c: スコア 120 === スコア 90 超えを探索 === 発見: item_c(スコア: 120) === メソッド化パターン === item_c が最初に条件を満たしました(スコア: 120)
よくあるミス
off-by-one エラー(1つずれるミス)
< と <= を間違えると、ループの回数が1回多くなったり少なくなったりします。配列の範囲外アクセス(IndexOutOfRangeException)につながる場合もあります。
int[] arr = { 10, 20, 30 };
// 間違い: i <= arr.Length だと arr[3] にアクセスして例外が発生します。
for (int i = 0; i <= arr.Length; i++) {
Console.WriteLine(arr[i]); // i == 3 で IndexOutOfRangeException
}
for (int i = 0; i < arr.Length; i++) {
Console.WriteLine(arr[i]);
}
更新式の書き忘れによる無限ループ
更新式(i++ など)を書き忘れると、条件式が永遠に true のまま無限ループになります。
for (int i = 0; i < 10; ) {
Console.WriteLine(i); // i は常に 0 のまま止まりません。
}
IDE によっては更新式の欠落を警告してくれる場合があります。意図的に省略する場合(ループ内で条件に応じて増減する場合など)はコメントで意図を明示してください。
概要
『C#』の for 文は「初期化式・条件式・更新式」の3つをセミコロンで区切った宣言が特徴です。C# にはラベル付き break が存在しないため、多重ループを一気に抜けたい場合は bool フラグを使うか、ループ処理をメソッドに切り出して return で脱出するパターンが一般的です。
ループ変数 i は for 文のブロック内にのみ存在するスコープとなります。ループ終了後に i の値を使いたい場合は、for 文の外で変数を宣言しておく必要があります。
コレクション(配列・リスト)を順に処理するだけなら foreach の方がシンプルに書けます。インデックスが不要な場合は foreach を、インデックスや逆順・ステップが必要な場合は for を選択してください。LINQ による関数的な繰り返し処理は『Enumerable.Where』や『Enumerable.Select』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。