C#で開発を行う上で欠かせないのが「for文」に代表されるループ処理です。繰り返し処理は配列やListの操作・条件付きのデータ処理・パフォーマンスチューニングに至るまで、あらゆる場面で活用されます。
本記事では、C#のfor文の基本構文からforeach文との違いなどを初心者にも理解しやすく解説します。C#でより効率的なコードを書きたい方は、ぜひご一読ください。
目次
1.C#のfor文とは
C#におけるfor文は、繰り返し処理を行う際に最も頻繁に使われる構文の1つです。特に、繰り返し回数が明確な場合や、配列やコレクションの要素に順番にアクセスしたいときに活躍します。
基本構文
for (初期化; 条件式; 更新処理) { // 繰り返し実行される処理 } |
各部分の役割は次のとおりです。
初期化:ループの開始時に一度だけ実行される。通常はカウンター変数の初期化
条件式:この式がtrueである限り、ループ処理が続行される
更新処理:1回のループの最後に実行され、カウンター変数の更新などに使われる
実際のコード例
例えば、「0から9までの数字を順番に出力する」処理は以下のように記述できます。
for (int i = 0; i < 10; i++) { Console.WriteLine(i); } |
このコードではiが0から始まり、10未満の間はループが継続し、各ループの最後にiが1ずつ増加していきます。
for文の特長
for文の大きな利点は、初期化・条件式・更新処理を1行でまとめて記述できることです。これにより、繰り返しの流れが一目で把握でき、可読性が高くなります。
また、カウンター変数を使って、インデックス指定で配列やListなどの要素にアクセスできる点も実用的です。この構造によって柔軟な処理や条件分岐も容易に組み込めます。
2.C# for文を使用した配列の操作
C#において配列(Array)は、複数のデータを一括で扱うための基本的なコレクション型です。そして、for文はこの配列の要素を順番に処理するための非常に効率的な手段です。
配列のインデックスは0から始まるため、for文との組み合わせによって、すべての要素に対して個別の操作が可能になります。
配列を使った基本的なfor文の例
以下は、配列内の文字列をfor文で順番に出力するコード例です。
string[] fruits = { "Apple", "Banana", "Cherry", "Date" };
{ Console.WriteLine(fruits[i]); } |
このコードでは配列fruitsの長さ(Lengthプロパティ)を条件式に指定することで、配列の範囲外アクセスを防ぎつつ、すべての要素を安全にループ処理できます。
値の加工やフィルタ処理
for文を活用すれば、配列内の値に対して加工や条件分岐を伴う処理を組み込むことができます。以下は、数値配列のうち、偶数だけを2倍にして出力する例です。
int[] numbers = { 1, 2, 3, 4, 5, 6 };
{ if (numbers[i] % 2 == 0) { Console.WriteLine(numbers[i] * 2); } } |
このように、インデックス付きのループは、特定条件に応じた処理の制御にも非常に便利です。
多次元配列とfor文の組み合わせ
C#では、2次元以上の配列も扱うことができます。こうした配列に対しては、for文を入れ子(ネスト)にすることでアクセスできます。
int[,] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
{ for (int j = 0; j < matrix.GetLength(1); j++) // 列数 { Console.Write(matrix[i, j] + " "); } Console.WriteLine(); } |
このコードでは、GetLength(0)が行数、GetLength(1)が列数を表しており、行・列のすべての要素にアクセスしています。
3.C# Listコレクションとfor文の連携
C#は配列(Array)の他に、柔軟性の高いList<T>というコレクションクラスが用意されています。Listは要素数の増減が可能で、追加・削除・検索といった操作が容易に行えるため、実務で頻繁に使われるデータ構造の1つです。
for文とListを組み合わせることで、要素の内容を自在に操作しながら繰り返し処理を行うことができます。
Listに対するfor文の基本的な使い方
まずは、Listの要素をfor文で順番に出力する基本例を見てみましょう。
List<string> cities = new List<string> { "Tokyo", "Osaka", "Nagoya" };
{ Console.WriteLine(cities[i]); } |
配列ではLengthを使いましたが、ListではCountプロパティが要素数の取得に使われます。この点を間違えるとエラーや意図しない挙動につながるため注意が必要です。
要素の加工・条件分岐処理
Listとfor文の組み合わせは、要素の加工や条件分岐処理にも非常に適しています。例えば、名前の一覧から3文字以下のものだけを出力するコードは次のようになります。
List<string> names = new List<string> { "Ken", "Lisa", "Bob", "Alex" };
{ if (names[i].Length <= 3) { Console.WriteLine(names[i]); } } |
このように、要素の中身に応じて柔軟な分岐を組み込めるのは、for文ならではの強みです。
要素の追加・削除とfor文の注意点
要素の追加はAdd()メソッドで簡単に行えますが、削除操作をfor文の中で行う際は注意が必要です。以下のコードは一見正常に動作するように見えますが、実行時に意図しない結果になる可能性があります。
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
{ if (numbers[i] % 2 == 0) { numbers.RemoveAt(i); // インデックスずれが発生する可能性あり } } |
要素を削除するとインデックスが繰り上がるため、次の要素を飛ばしてしまうことがあります。こういった場合には逆順ループが効果的です。
for (int i = numbers.Count - 1; i >= 0; i--) { if (numbers[i] % 2 == 0) { numbers.RemoveAt(i); // 安全に削除できる } } |
関連記事
【C#】Listと配列との違いや初期化・削除・要素数取得・型指定なしの使い方を紹介
4.C# for文の制御構文|continueとbreak
C#のfor文では、ループの進行を制御するための特別なキーワードとして、continueとbreak が用意されています。これらを活用することで、より柔軟かつ効率的なループ処理が可能になります。
ここでは、それぞれの役割や使いどころ、具体的なコード例を通して理解を深めていきましょう。
continue文:ループをスキップする
continue文は、現在のループの処理をスキップし、次のループへ強制的に移行します。
例えば、数値の中から奇数だけを出力したい場合、偶数のときにcontinueで処理を飛ばすようにします。
for (int i = 1; i <= 10; i++) { if (i % 2 == 0) { continue; // 偶数はスキップ } Console.WriteLine(i); } |
このように、特定の条件で処理を省きたいときにcontinueを使うと、コードがすっきりします。
break文:ループを途中で終了する
break文は、ループを強制的に終了させる構文です。通常、条件が満たされる限りループは続きますが、特定の条件に達したらループを打ち切りたい場合に便利です。
以下の例では、数値が5に達したらそれ以降のループを終了します。
for (int i = 1; i <= 10; i++) { if (i == 5) { break; // iが5になったらループ終了 } Console.WriteLine(i); } |
breakは、早期終了の手段として、検索処理やエラーチェックなどでも頻繁に使われます。
関連記事
C#演算子完全ガイド:比較・Nullの基礎からオーバーロード・優先順位などの応用まで徹底解説
5.C# for文の無限ループの作成と注意点
無限ループとは、終了条件が永遠に満たされないループ処理のことを指します。通常はバグとして扱われることもありますが、一部の用途では意図的に無限ループを使うことが有効です。
C#においては、for文・while文・do-while文のいずれでも無限ループが作成できますが、ここではfor文を使った無限ループに焦点を当てます。
無限ループの用途と実用例
無限ループは、外部からの入力を常に監視するような常駐処理や、イベントループのような場面で活用されます。
例えば、ユーザーからの入力を繰り返し受け付ける処理は下記のとおりです。
for (;;) { Console.Write("コマンドを入力してください(exitで終了): "); string input = Console.ReadLine();
if (input == "exit") { break; // 明示的に終了 }
} |
このように、無限ループとbreak文を組み合わせることで、外部条件によってループを終了させることができます。
無限ループの注意点
無限ループは便利な反面、以下のようなリスクや注意点があります。
終了条件を忘れるとアプリケーションがフリーズする
CPU使用率が高騰する可能性がある
意図せずメモリリークやスタックオーバーフローが発生する場合がある
デバッグ中に無限ループに陥ると、アプリケーションの挙動が止まり、開発効率が低下する原因にもなります。常に「どこで、どのように終了するか」を設計段階で明確にしておくことが重要です。
6.C# for文とforeach文の適切な使い分け
C#のforeach文は、配列やコレクションの要素を順番に処理するための構文です。for文と異なり、インデックス管理やステップ調整が不要で、シンプルで読みやすいループ処理が可能になります。基本構文は以下の通りです。
foreach (var item in collection) { // 各 item に対する処理 } |
for文の方が適しているケース
以下のような処理では、foreachよりfor文のほうが有利です。
インデックスを利用した処理
for文は、ループカウンタを明示的に扱えるため、インデックスに基づいた処理が必要な場面に最適です。例えば、リストの各要素に「何番目か」の番号を付けて表示したい場合や、偶数番目/奇数番目など要素の位置によって処理を分岐させたいときに活用できます。
List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
{ Console.WriteLine($"{i + 1}番目: {names[i]}"); } |
このような「順番を意識した処理」は、foreachでは直接インデックスを取得できないため、for文が有利です。
要素の加工・削除を伴う処理
コレクションの要素を加工したり、条件に応じて削除したりする処理では、for文の方が適しています。foreach文では、コレクションを変更しようとするとInvalidOperationException(無効な操作)が発生します。
例えば、リスト内の偶数をすべて削除したいケースを考えてみましょう。foreachでこの処理を行うと、例外が出ますがfor文であればインデックス制御により安全に処理できます。
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
for (int i = numbers.Count - 1; i >= 0; i--) { if (numbers[i] % 2 == 0) { numbers.RemoveAt(i); } } |
このように、for文なら安全かつ柔軟に要素の追加・削除・更新処理が行えるため、加工を伴う処理には非常に向いています。
条件付きで一部の処理をスキップ・中断したいとき
for文ではcontinueやbreakといった制御構文を柔軟に使用できるため、特定の条件で処理をスキップしたり、ループそのものを中断する処理にも向いています。
例えば、「空の文字列はスキップ」「特定の値が来たらループ終了」という条件付き処理を行いたい場合、次のようなコードが書けます。
List<string> words = new List<string> { "apple", "", "banana", null, "stop", "cherry" };
{ if (string.IsNullOrEmpty(words[i])) { continue; // 空文字やnullはスキップ }
{ break; // "stop"が出たらループ終了 }
} |
このように、for文を使えば条件ごとに処理の分岐や終了制御がしやすく、複雑な要件にも柔軟に対応できます。foreachでもbreakは使えますが、continueや要素のスキップ処理は構造的に制限が多く、for文の方が自由度は高いです。
foreach文が適しているケース
以下のような処理では、for文よりforeach文のほうが有利です。
読み取り専用で全要素を処理したいとき
foreach文は、要素のインデックスを気にせず、すべての要素を順番に処理する場面に最適です。特に、コレクションの中身を変更せずに「表示」「集計」「検証」などを行いたいときに非常に便利で、シンプルかつ可読性が高いというメリットがあります。
以下は、Listの文字列を順に出力する典型的な例です。
List<string> fruits = new List<string> { "Apple", "Banana", "Cherry" };
{ Console.WriteLine(fruit); } |
for文に比べて記述量が少なく、処理の意図がストレートに伝わるため、初学者から上級者まで幅広く好まれる書き方です。
コレクションの要素数が変わらないことが保証されているとき
foreach文では、ループ中にコレクションを変更することができません(RemoveやAddなど)。しかし、「要素数が変わらない」ことが前提であれば、foreachの方が安全で堅牢なループ処理が実現できます。
例えば、配列のすべての要素がnullでないかチェックしたい場合、下記のようになります。
string[] colors = { "Red", "Green", "Blue" }; bool allNotNull = true;
{ if (string.IsNullOrEmpty(color)) { allNotNull = false; break; } }
|
コレクションの型がIEnumerable<T>であるとき
C#の多くのコレクション型(List・配列・Dictionaryなど)は、IEnumerable<T>インターフェースを実装しており、foreachに最適化されています。
特に、LINQのクエリ結果やyield returnで生成されるイテレーターなど、インデックスを持たないデータ構造に対してはfor文よりもforeachが向いています。
IEnumerable<int> evens = Enumerable.Range(1, 10).Where(n => n % 2 == 0);
{ Console.WriteLine(num); } |
関連記事
C# foreach完全ガイド|基本構文からコレクション操作・LINQ連携・ループ制御まで徹底解説
C#とは?基本文法や特徴、メリット、開発分野まで初心者に必要な情報をわかりやすく解説
7.まとめ
C#のfor文はループ処理の中でも特に柔軟性が高く、配列やListの操作・無限ループや制御構文との連携など、多彩な活用が可能です。
foreach文との違いを理解し、目的に応じて使い分けることで、コードの可読性と実行効率が大きく向上します。
本記事が皆様にとって少しでもお役に立てますと幸いです。
「フリーランスボード」は、数多くのフリーランスエージェントが掲載するITフリーランスエンジニア・ITフリーランス向けの案件・求人を一括検索できるサイトです。
開発環境、職種、単価、稼働形態、稼働日数など様々な条件から、あなたに最適なフリーランス案件・求人を簡単に見つけることができます。
単価アップを目指す方や、自分の得意なスキルを活かせる案件に参画したい方は、ぜひ「フリーランスボード」をご利用ください。