決まった回数だけ処理を繰り返す場面は、配列の走査や集計、表の生成など、C#のあらゆる場面に登場します。
本記事では、forループの基本から、つまずきやすい境界条件、よく使うパターン、エラー回避のコツ、他ループとの使い分けまで、初心者の方が迷わず書けるよう丁寧に解説します。
forループとは?
forループは「開始値」「継続条件」「増減方法」を明示し、決まった回数だけ処理を繰り返す構文です。
配列や範囲のインデックスを使って順序よく処理したいときに最もよく使います。
回数が明確な繰り返しに強く、ループ変数を自由に操作できることが特徴です。
C# forループの基本構文と書き方
初期化式・条件式・反復式の意味と実行順序
構文
// for (初期化式; 条件式; 反復式) { 本体 }
for (int i = 0; i < 5; i++)
{
// 繰り返し処理
}
実行順序
- 初期化式を最初に一度だけ実行(例:
int i = 0
) - 条件式を評価し、true なら本体へ、false でループ終了(例:
i < 5
) - 本体を実行
- 反復式を実行(例:
i++
) - 2 に戻る
この順序を正しく理解すると、境界条件ミスや無限ループを避けやすくなります。
0からn-1まで回す最小サンプルコード
最も基本的で頻出するパターンです。
配列やListの走査に直結します。
using System;
int n = 5;
for (int i = 0; i < n; i++) // 0,1,2,3,4 の5回
{
Console.WriteLine(i);
}
0
1
2
3
4
1からnまで回す書き方と比較(<= と < の違い)
「1からn」なら、i = 1
で開始し、i <= n
で終了条件を表現します。
一方で「0からn-1」では i < n
を使うのが定番です。
using System;
int n = 5;
// 1 から n まで(<= を使う)
for (int i = 1; i <= n; i++)
{
Console.Write(i + " ");
}
Console.WriteLine();
// 0 から n-1 まで(< を使う)
for (int i = 0; i < n; i++)
{
Console.Write(i + 1 + " "); // 表示は 1..n に合わせたければ +1 する
}
Console.WriteLine();
1 2 3 4 5
1 2 3 4 5
表で直感を整理しておきます。
欲しい範囲 | 初期化 | 条件 | 典型用途 |
---|---|---|---|
0 から n-1 | int i = 0 | i < n | 配列、Listの走査 |
1 から n | int i = 1 | i <= n | 回数nを自然数で数える |
初心者向けサンプルコード集:よく使うC# forループパターン
逆順ループ(デクリメント)とステップ幅の指定(i+=2 など)
逆順に回す(デクリメント)
using System;
// 10,9,8,...,1 と逆順に出力する
for (int i = 10; i >= 1; i--)
{
Console.Write(i + " ");
}
Console.WriteLine();
10 9 8 7 6 5 4 3 2 1
ステップ幅を変える(2刻みや任意幅)
using System;
// 偶数だけを取り出す: 0,2,4,6,8
for (int i = 0; i < 10; i += 2)
{
Console.Write(i + " ");
}
Console.WriteLine();
// 5刻みで増加: 0,5,10,15
for (int i = 0; i <= 15; i += 5)
{
Console.Write(i + " ");
}
Console.WriteLine();
0 2 4 6 8
0 5 10 15
ネストしたforループで二次元配列・九九を処理する
二次元配列の走査
using System;
int[,] grid = {
{ 1, 2, 3 },
{ 4, 5, 6 }
};
int rows = grid.GetLength(0); // 行数
int cols = grid.GetLength(1); // 列数
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
Console.Write(grid[r, c] + " ");
}
Console.WriteLine();
}
1 2 3
4 5 6
九九(例として 1〜3 の部分表)
using System;
// 見やすさのため 1..3 で例示
for (int a = 1; a <= 3; a++)
{
for (int b = 1; b <= 3; b++)
{
Console.Write($"{a}×{b}={a * b} ");
}
Console.WriteLine();
}
1×1=1 1×2=2 1×3=3
2×1=2 2×2=4 2×3=6
3×1=3 3×2=6 3×3=9
配列・Listのインデックス走査(Length/Countの使い方)
using System;
using System.Collections.Generic;
int[] numbers = { 10, 20, 30 };
List<string> names = new List<string> { "Alice", "Bob", "Carol" };
// 配列は Length
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine($"numbers[{i}] = {numbers[i]}");
}
// List<T> は Count
for (int i = 0; i < names.Count; i++)
{
Console.WriteLine($"names[{i}] = {names[i]}");
}
numbers[0] = 10
numbers[1] = 20
numbers[2] = 30
names[0] = Alice
names[1] = Bob
names[2] = Carol
合計値・平均値を求めるforループのサンプル
using System;
int[] scores = { 80, 95, 70, 100 };
int sum = 0;
for (int i = 0; i < scores.Length; i++)
{
sum += scores[i];
}
double average = (double)sum / scores.Length;
Console.WriteLine($"合計: {sum}");
Console.WriteLine($"平均: {average:F1}"); // 小数1桁で表示
合計: 345
平均: 86.3
エラー回避とベストプラクティス
オフバイワンエラー対策:< と <= の使い分け
配列やListのインデックスは0始まりで最大が「長さ-1」です。
したがって範囲は「0 から Length-1」。
このとき条件は i < Length
が正解で、i <= Length
は範囲外アクセスになります。
- 正しい:
for (int i = 0; i < array.Length; i++)
- 危険:
for (int i = 0; i <= array.Length; i++)
→array[array.Length]
で例外
また「1 から n」を回したいときは i <= n
とセットで覚えるとミスを減らせます。
無限ループ・セミコロンの誤用に注意
反復式の更新を忘れる
// 悪い例: i++ を忘れると i は増えず、条件がずっと true になり得る
for (int i = 0; i < 10; /* i++ を忘れた */)
{
Console.WriteLine(i);
// 修正案: 末尾で i++ するか、反復式に i++ を戻す
i++;
}
for の直後にセミコロン
// 悪い例: セミコロンにより「空ループ」になる
for (int i = 0; i < 3; i++); // ← ここでループが終わっている
{
Console.WriteLine("このブロックは1回だけ実行される");
}
修正はセミコロンを外すだけです。
ループ変数のスコープ、命名、境界値の事前計算
スコープ: for (int i = ... )
の i
はループの外から見えません。外で使いたいときはループ外で宣言します。
命名: 単純な数え上げは i
, j
, k
で十分。意味があるなら index
, row
, col
などにすると可読性が上がります。
境界値の事前計算: コレクションの長さを毎回プロパティから読むより、ループ前にローカル変数へ取り出すと意図が明確になり、場合によってはパフォーマンスにも良い影響があります。
using System;
int[] data = { 1, 2, 3, 4, 5 };
int len = data.Length; // 事前計算
for (int index = 0; index < len; index++)
{
Console.WriteLine(data[index]);
}
他のループとの違いと使い分け
foreachとの違い:コレクション走査とインデックス操作の要否
foreach
はコレクションの全要素を順に処理するのに適し、コードが簡潔になります。
インデックスが不要で「読み取り中心」なら foreach
を、インデックスが必要(位置を使う、書き換える、部分範囲だけ処理する等)なら for
を選びます。
using System;
using System.Collections.Generic;
List<int> list = new() { 10, 20, 30 };
// foreach: 簡潔、インデックスなし
foreach (int x in list)
{
Console.WriteLine(x);
}
// for: インデックスが使えるので位置を活用できる
for (int i = 0; i < list.Count; i++)
{
list[i] += i; // 位置に応じて更新
}
注意点として、foreach
はコレクションを走査中に要素の追加・削除ができません(例外が発生)。
要素を変更・挿入・削除するなら for
の方が安全です。
while/do-whileとの違い:回数主導か条件主導か
- for: 回数主導。開始値・条件・増減をひとまとめに書ける。回数が決まっている処理に最適。
- while: 条件主導。継続条件だけ先に書く。回数が不定の入力待ちや状態監視に向く。
- do-while: 少なくとも1回は実行したいときに使う(末尾で条件判定)。
using System;
// while の例: 合計が100を超えるまで入力を加算
int sum = 0;
while (sum <= 100)
{
sum += 30; // 入力の代わりに定数で例示
}
Console.WriteLine(sum);
// do-while の例: 少なくとも1回メニューを表示したい
int choice;
do
{
Console.WriteLine("1) Start 0) Exit");
choice = 0; // 入力の代わりに固定値
} while (choice != 0);
120
1) Start 0) Exit
よくある疑問(FAQ)とチェックリスト
break/continueの使い方と早期終了のパターン
break
はループ全体を終了し、continue
はその周回の残りをスキップして次へ進みます。
条件に応じた早期終了で、無駄な計算を省けます。
using System;
int[] data = { 3, 8, 2, 7, 9, 1 };
for (int i = 0; i < data.Length; i++)
{
if (data[i] > 8)
{
Console.WriteLine($"9超えを発見: index={i}, value={data[i]}");
break; // 目的を達したので打ち切り
}
if (data[i] % 2 == 0)
{
continue; // 偶数はスキップ
}
Console.WriteLine($"奇数: {data[i]}");
}
奇数: 3
9超えを発見: index=4, value=9
forとLINQの違い:可読性とパフォーマンスの観点から選ぶ
LINQ(System.Linq
)は宣言的に「何をしたいか」を表現でき、集計や変換を簡潔に書けます。
一方で繰り返し処理の最小コストは通常 for
が有利です。
大量データ・ホットパスでは for
、可読性や保守性重視では LINQ を選ぶ、と覚えるとよいでしょう。
using System;
using System.Linq;
int[] nums = { 1, 2, 3, 4, 5 };
// for で合計
int sum = 0;
for (int i = 0; i < nums.Length; i++)
{
sum += nums[i];
}
Console.WriteLine($"for sum = {sum}");
// LINQ で合計
int linqSum = nums.Sum();
Console.WriteLine($"LINQ sum = {linqSum}");
for sum = 15
LINQ sum = 15
チェックポイント(書く前に軽く確認)
- 目的の範囲は「0..n-1」か「1..n」か。条件は
<
と<=
のどちらが適切か。 - 反復式(例:
i++
,i+=2
)は正しく進むか。境界で停止するか。 - 対象が配列かListか。長さは
Length
とCount
のどちらか。 - インデックスが必要か。不要なら
foreach
の方が読みやすいか。 - 大量データでパフォーマンスが重要か。LINQとforのトレードオフを理解して選ぶ。
まとめ
forループは、開始値・条件・増減を一ヶ所にまとめて記述できる、回数主導の基本構文です。
配列やListを「0..n-1」で走査する場合は i = 0
と i < n
が鉄則で、1から数えるときは i = 1
と i <= n
を使います。
デクリメントや任意ステップ、ネストによる二次元処理、合計・平均の計算など、日常的なタスクはほぼ網羅できます。
オフバイワン、更新忘れ、セミコロン誤用といった典型エラーを避け、スコープと命名、境界値の事前計算で読みやすさと安全性を高めましょう。
さらに、foreach
や while
、そして LINQ との使い分けを理解すれば、用途に最適な表現を選べるようになります。
初心者のうちは本記事のパターンを素直に真似し、動作と出力を確かめながら手を慣らしていくのが上達への近道です。