これだけ覚えればOK!C#のfor文の使い方と実践例

C#

C#(シーシャープ)で繰り返し処理を行う際に最もよく使われるのが「for文」です。

繰り返しの回数が決まっている場合に特に便利で、簡潔に記述できるため、初心者が最初に学ぶべき構文のひとつです。

この記事では、C#におけるfor文の基本構文から、実践的な使用例、よくあるミスとその対策までをわかりやすく解説します。

こんな方におすすめです

  • C#プログラミングを始めたばかりの方
  • 繰り返し処理を効率的に書きたい
  • 配列やリストの処理を学びたい方
  • for文でエラーが出て困っている

この記事でできるようになること

  • for文の基本構文を完全に理解
  • 様々なパターンの繰り返し処理を書ける
  • 配列やリストを効率的に処理できる
  • よくあるエラーを回避できる
  • 実践的なプログラムを作成できる

それでは、まずfor文の基本構文から学んでいきましょう。

スポンサーリンク

for文の基本構文を理解しよう

for文の構造

基本の書き方

for (初期化; 条件; 更新)
{
    // 繰り返す処理
}

各部分の詳細説明

初期化

  • ループの最初に1回だけ実行される
  • 通常はカウンタ変数を定義・初期化
  • 例:int i = 0

条件

  • 毎回のループ開始前にチェックされる
  • trueの間はループを継続
  • falseになったらループ終了
  • 例:i < 5

更新

  • 各ループの最後に実行される
  • 通常はカウンタ変数を変更
  • 例:i++(iを1増加)

最初の例:基本的な数値の表示

0から4までの数字を表示

for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}

実行結果

0
1
2
3
4

実行の流れを詳しく見てみよう

Step 1:初期化 int i = 0

  • 変数iが作られ、0が代入される

Step 2:条件チェック i < 5

  • i = 0, 0 < 5 は true なのでループ実行

Step 3:処理実行 Console.WriteLine(i)

  • “0”が表示される

Step 4:更新 i++

  • iが1になる

Step 5:条件チェック i < 5

  • i = 1, 1 < 5 は true なのでループ継続

この流れを繰り返し

  • i = 2, 3, 4の時も同様に実行
  • i = 5になった時、5 < 5 は false なのでループ終了

より実用的な例

1から10までの合計を計算

int sum = 0;
for (int i = 1; i <= 10; i++)
{
    sum += i;  // sum = sum + i と同じ
}
Console.WriteLine($"1から10までの合計: {sum}");

実行結果

1から10までの合計: 55

九九の表を作成

for (int i = 1; i <= 9; i++)
{
    for (int j = 1; j <= 9; j++)
    {
        Console.Write($"{i * j:D2} ");  // 2桁で表示
    }
    Console.WriteLine();  // 改行
}

実行結果(一部):

01 02 03 04 05 06 07 08 09 
02 04 06 08 10 12 14 16 18 
03 06 09 12 15 18 21 24 27 
...

基本形を覚えたら、次は少し応用的な使い方に進んでみましょう。

応用例と実践的な使い方

配列の操作

配列のすべての要素を表示

string[] fruits = {"Apple", "Banana", "Cherry", "Date", "Elderberry"};

for (int i = 0; i < fruits.Length; i++)
{
    Console.WriteLine($"{i + 1}. {fruits[i]}");
}

実行結果

1. Apple
2. Banana
3. Cherry
4. Date
5. Elderberry

重要なポイント

  • 配列のサイズfruits.Length で取得
  • インデックスは0から始まるため、表示番号は i + 1
  • 範囲外アクセスを防ぐため i < fruits.Length を使用

配列の要素を検索

string[] names = {"太郎", "花子", "次郎", "美子", "一郎"};
string searchName = "花子";
int foundIndex = -1;

for (int i = 0; i < names.Length; i++)
{
    if (names[i] == searchName)
    {
        foundIndex = i;
        break;  // 見つかったらループを抜ける
    }
}

if (foundIndex != -1)
{
    Console.WriteLine($"{searchName}は{foundIndex + 1}番目にあります");
}
else
{
    Console.WriteLine($"{searchName}は見つかりませんでした");
}

配列の最大値と最小値を見つける

int[] numbers = {45, 23, 89, 12, 67, 34, 91, 56};
int max = numbers[0];
int min = numbers[0];

for (int i = 1; i < numbers.Length; i++)
{
    if (numbers[i] > max)
    {
        max = numbers[i];
    }
    if (numbers[i] < min)
    {
        min = numbers[i];
    }
}

Console.WriteLine($"最大値: {max}");
Console.WriteLine($"最小値: {min}");

様々なループパターン

逆順にループする

// 10から0まで2ずつ減らしながら表示
for (int i = 10; i >= 0; i -= 2)
{
    Console.WriteLine(i);
}

実行結果

10
8
6
4
2
0

特定の条件をスキップ

// 1から20まで、3の倍数以外を表示
for (int i = 1; i <= 20; i++)
{
    if (i % 3 == 0)
    {
        continue;  // 3の倍数はスキップ
    }
    Console.Write($"{i} ");
}

実行結果

1 2 4 5 7 8 10 11 13 14 16 17 19 20

ネストしたfor文(二重ループ)

// 星印でピラミッドを作成
for (int i = 1; i <= 5; i++)
{
    // 空白を印刷
    for (int j = 5; j > i; j--)
    {
        Console.Write(" ");
    }
    
    // 星を印刷
    for (int k = 1; k <= i; k++)
    {
        Console.Write("* ");
    }
    
    Console.WriteLine();  // 改行
}

実行結果

    * 
   * * 
  * * * 
 * * * * 
* * * * * 

Listの操作

Listの要素を処理

using System;
using System.Collections.Generic;

List<int> scores = new List<int> {85, 92, 78, 95, 88, 76, 90};

// 80点以上の点数のみ表示
Console.WriteLine("80点以上の成績:");
for (int i = 0; i < scores.Count; i++)
{
    if (scores[i] >= 80)
    {
        Console.WriteLine($"{i + 1}番目: {scores[i]}点");
    }
}

// 平均点を計算
int total = 0;
for (int i = 0; i < scores.Count; i++)
{
    total += scores[i];
}
double average = (double)total / scores.Count;
Console.WriteLine($"平均点: {average:F1}点");

文字列の操作

文字列の各文字を処理

string text = "Hello, World!";
int vowelCount = 0;
string vowels = "aeiouAEIOU";

for (int i = 0; i < text.Length; i++)
{
    char currentChar = text[i];
    
    // 母音かどうかチェック
    for (int j = 0; j < vowels.Length; j++)
    {
        if (currentChar == vowels[j])
        {
            vowelCount++;
            break;
        }
    }
}

Console.WriteLine($"文字列「{text}」には母音が{vowelCount}個あります");

インデックスを使って要素を操作できるのがfor文の利点です。また、繰り返しのパターンも柔軟に設定できます。

より複雑なループを扱う際に注意したい「よくあるミス」について、次に見ていきましょう。

よくあるエラーと注意点

代表的なエラーパターン

エラー1:無限ループ

問題のあるコード

// 危険!無限ループになる
for (int i = 0; i >= 0; i++)  // 条件が常にtrue
{
    Console.WriteLine(i);  // 永遠に続く
}

なぜ無限ループになるのか

  • i >= 0 という条件は、iが0以上である限り常にtrue
  • i++ でiは増加し続けるため、条件がfalseになることがない

正しい修正例

// 正しい書き方
for (int i = 0; i < 10; i++)  // 明確な終了条件
{
    Console.WriteLine(i);
}

エラー2:配列の範囲外アクセス

問題のあるコード

int[] numbers = {1, 2, 3, 4, 5};

// 危険!配列の範囲を超える
for (int i = 0; i <= numbers.Length; i++)  // <= が問題
{
    Console.WriteLine(numbers[i]);  // numbers[5]でエラー
}

エラーメッセージ

System.IndexOutOfRangeException: Index was outside the bounds of the array.

正しい修正例

int[] numbers = {1, 2, 3, 4, 5};

// 正しい書き方
for (int i = 0; i < numbers.Length; i++)  // < を使用
{
    Console.WriteLine(numbers[i]);
}

エラー3:変数のスコープ問題

問題のあるコード

// ループ外でiを使おうとしてエラー
for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}

Console.WriteLine(i);  // エラー!iはここでは使えない

正しい修正例

// ループ外で変数を定義
int i;
for (i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}

Console.WriteLine($"ループ終了後のi: {i}");  // 正常に動作

一般的なミスとその対策

ミス1:off-by-one エラー

よくある間違い

int[] array = new int[10];

// 間違い:配列サイズを1つ超えている
for (int i = 1; i <= array.Length; i++)
{
    array[i] = i;  // array[10]でエラー
}

正しい書き方

int[] array = new int[10];

// 正しい:0から9まで
for (int i = 0; i < array.Length; i++)
{
    array[i] = i + 1;
}

ミス2:更新部分の間違い

問題のあるコード

// 間違い:iが更新されない
for (int i = 0; i < 10; /* i++が抜けている */)
{
    Console.WriteLine(i);  // 無限ループ
}

正しい書き方

// 正しい:更新部分を忘れずに
for (int i = 0; i < 10; i++)
{
    Console.WriteLine(i);
}

ミス3:ネストしたループでの変数名の混同

問題のあるコード

// 間違い:同じ変数名を使用
for (int i = 0; i < 3; i++)
{
    for (int i = 0; i < 3; i++)  // 変数名が重複
    {
        Console.WriteLine(i);
    }
}

正しい書き方

// 正しい:異なる変数名を使用
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 3; j++)  // 異なる変数名
    {
        Console.WriteLine($"i={i}, j={j}");
    }
}

デバッグのコツ

デバッグ用の出力を追加

int[] numbers = {10, 20, 30, 40, 50};

for (int i = 0; i < numbers.Length; i++)
{
    // デバッグ用の出力
    Console.WriteLine($"Debug: i={i}, numbers[i]={numbers[i]}");
    
    // 実際の処理
    if (numbers[i] > 25)
    {
        Console.WriteLine($"Found: {numbers[i]}");
    }
}

条件を段階的にチェック

int[] data = {1, 2, 3, 4, 5};

// まず単純なループで動作確認
for (int i = 0; i < data.Length; i++)
{
    Console.WriteLine($"Processing index {i}");
}

// 次に実際の処理を追加
for (int i = 0; i < data.Length; i++)
{
    Console.WriteLine($"Processing index {i}: value = {data[i]}");
    // ここに複雑な処理を追加
}

エラーの原因を事前に知っておくことで、より安全にfor文を活用できます。

実践的なプログラム例

例1:成績管理システム

using System;

class Program
{
    static void Main()
    {
        // 5人の学生の成績
        string[] students = {"田中", "佐藤", "鈴木", "高橋", "渡辺"};
        int[] scores = {85, 92, 78, 95, 88};
        
        Console.WriteLine("=== 成績一覧 ===");
        for (int i = 0; i < students.Length; i++)
        {
            string grade = GetGrade(scores[i]);
            Console.WriteLine($"{students[i]}: {scores[i]}点 ({grade})");
        }
        
        // 統計情報の計算
        int total = 0;
        int maxScore = scores[0];
        int minScore = scores[0];
        string topStudent = students[0];
        
        for (int i = 0; i < scores.Length; i++)
        {
            total += scores[i];
            
            if (scores[i] > maxScore)
            {
                maxScore = scores[i];
                topStudent = students[i];
            }
            
            if (scores[i] < minScore)
            {
                minScore = scores[i];
            }
        }
        
        double average = (double)total / scores.Length;
        
        Console.WriteLine("\n=== 統計情報 ===");
        Console.WriteLine($"平均点: {average:F1}点");
        Console.WriteLine($"最高点: {maxScore}点 ({topStudent})");
        Console.WriteLine($"最低点: {minScore}点");
    }
    
    static string GetGrade(int score)
    {
        if (score >= 90) return "A";
        else if (score >= 80) return "B";
        else if (score >= 70) return "C";
        else if (score >= 60) return "D";
        else return "F";
    }
}

例2:簡単な暗号化プログラム

using System;

class Program
{
    static void Main()
    {
        string message = "Hello World";
        int shift = 3;  // シーザー暗号のシフト量
        
        Console.WriteLine($"元のメッセージ: {message}");
        
        // 暗号化
        string encrypted = "";
        for (int i = 0; i < message.Length; i++)
        {
            char c = message[i];
            
            if (char.IsLetter(c))
            {
                // アルファベットの場合のみ暗号化
                char shifted = ShiftCharacter(c, shift);
                encrypted += shifted;
            }
            else
            {
                // アルファベット以外はそのまま
                encrypted += c;
            }
        }
        
        Console.WriteLine($"暗号化: {encrypted}");
        
        // 復号化
        string decrypted = "";
        for (int i = 0; i < encrypted.Length; i++)
        {
            char c = encrypted[i];
            
            if (char.IsLetter(c))
            {
                char shifted = ShiftCharacter(c, -shift);  // 逆方向にシフト
                decrypted += shifted;
            }
            else
            {
                decrypted += c;
            }
        }
        
        Console.WriteLine($"復号化: {decrypted}");
    }
    
    static char ShiftCharacter(char c, int shift)
    {
        if (char.IsUpper(c))
        {
            return (char)((c - 'A' + shift + 26) % 26 + 'A');
        }
        else
        {
            return (char)((c - 'a' + shift + 26) % 26 + 'a');
        }
    }
}

例3:数字当てゲーム

using System;

class Program
{
    static void Main()
    {
        Random random = new Random();
        int secretNumber = random.Next(1, 101);  // 1-100の乱数
        int maxAttempts = 7;
        bool gameWon = false;
        
        Console.WriteLine("数字当てゲーム!");
        Console.WriteLine("1から100までの数字を当ててください。");
        Console.WriteLine($"チャンスは{maxAttempts}回です。\n");
        
        for (int attempt = 1; attempt <= maxAttempts; attempt++)
        {
            Console.Write($"試行 {attempt}/{maxAttempts}: ");
            
            // ユーザー入力の取得と検証
            string input = Console.ReadLine();
            if (!int.TryParse(input, out int guess))
            {
                Console.WriteLine("有効な数字を入力してください。");
                attempt--; // 無効な入力は回数にカウントしない
                continue;
            }
            
            if (guess == secretNumber)
            {
                Console.WriteLine($"正解!{attempt}回で当てました!");
                gameWon = true;
                break;
            }
            else if (guess < secretNumber)
            {
                Console.WriteLine("もっと大きな数字です。");
            }
            else
            {
                Console.WriteLine("もっと小さな数字です。");
            }
            
            // 残り回数の表示
            if (attempt < maxAttempts)
            {
                Console.WriteLine($"残り{maxAttempts - attempt}回\n");
            }
        }
        
        if (!gameWon)
        {
            Console.WriteLine($"残念!正解は {secretNumber} でした。");
        }
    }
}

まとめ

for文の重要性

C#のfor文は、構造がシンプルでありながら柔軟性が高く、プログラムの効率化に欠かせない存在です。

この記事の要点

基本構文の理解

  • 初期化、条件、更新の三要素
  • 実行の流れを正確に把握
  • ループ変数のスコープを理解

実践的な応用

  • 配列とListの効率的な処理
  • ネストしたループの活用
  • 条件分岐との組み合わせ

エラー対策

  • 無限ループの回避
  • 配列の範囲外アクセス防止
  • 変数スコープの適切な管理

コメント

タイトルとURLをコピーしました