基礎から学ぶC#入門 90日コース | 配列・コレクション・文字列 - Day 22:多次元配列

C# 90日で身につけるC#
スポンサーリンク
スポンサーリンク

Day 22 のゴールと全体像

Day 22 では、配列を一歩進めて 多次元配列(特に二次元配列) を学びます。 二次元配列は「行と列を持つ表」のような形でデータを表現できるので、 表形式のデータやマップ、座標などを扱うときにとても便利です。

学ぶ内容は次の 3 つです。

  • 二次元配列
  • 行と列
  • データ表現

これらをステップバイステップでかみ砕きながら、 「一次元配列(1列の箱の並び)」から「二次元配列(表形式)」への発想の広がりを体験していきます。

二次元配列とは

一次元配列との違いをイメージする

一次元配列は「1列に並んだ箱」でした。

int[] numbers = { 1, 2, 3, 4, 5 }; // 1列に並んだ 5 個の箱
C#

これに対して、二次元配列は

「行」と「列」を持つ、表(テーブル)のような箱の並び

です。

イメージとしては、次のような表です。

列0列1列2
行0123
行1456

このような「行 × 列」のデータを、二次元配列で表現できます。

行と列

インデックスが 2 つになる

一次元配列では、インデックスは 1 つだけでした。

numbers[0]; // 1つ目の要素
C#

二次元配列では、

「行インデックス」と「列インデックス」の 2 つ

を指定します。

matrix[行インデックス, 列インデックス];
C#

例えば、次のような二次元配列を考えます。

int[,] matrix = new int[2, 3]; // 2 行 3 列の二次元配列
C#

この配列には、

  • 行インデックス:01
  • 列インデックス:012

が存在します。

要素のイメージはこうです。

列0列1列2
行0[0,0][0,1][0,2]
行1[1,0][1,1][1,2]

コードで書くと次のようになります。

int[,] matrix = new int[2, 3];

// 行0
matrix[0, 0] = 1;
matrix[0, 1] = 2;
matrix[0, 2] = 3;

// 行1
matrix[1, 0] = 4;
matrix[1, 1] = 5;
matrix[1, 2] = 6;
C#

二次元配列の初期化とデータ表現

new と波括弧で表形式のデータを初期化する

二次元配列は、次のように初期化できます。

int[,] matrix = new int[,]
{
    { 1, 2, 3 }, // 行0
    { 4, 5, 6 }  // 行1
};
C#

この書き方は、

  • 1 行ごとに { ... } でまとめる
  • 行を縦に並べることで「表の形」をそのままコードに表現する

という特徴があります。

例:座席表を二次元配列で表現する

例えば、映画館の座席表を「行 × 列」で表現したいとします。

using System;

class Program
{
    static void Main(string[] args)
    {
        // 2 行 3 列の座席表(0: 空席, 1: 予約済み)
        int[,] seats = new int[,]
        {
            { 0, 1, 0 }, // 行0
            { 1, 0, 0 }  // 行1
        };

        // 座席表を表示する
        for (int row = 0; row < seats.GetLength(0); row++) // 行数
        {
            for (int col = 0; col < seats.GetLength(1); col++) // 列数
            {
                Console.Write(seats[row, col] + " ");
            }
            Console.WriteLine(); // 行の終わりで改行
        }

        Console.ReadLine();
    }
}
C#

重要ポイント:

  • GetLength(0) は「0 番目の次元(行)の長さ」を返します。
  • GetLength(1) は「1 番目の次元(列)の長さ」を返します。
  • 二次元配列では Length ではなく GetLength(次元番号) を使うのが基本です。

二次元配列をループで扱う

行 × 列の二重ループ

二次元配列をすべて回したいときは、

行用のループ × 列用のループ

という 二重ループを使います。

using System;

class Program
{
    static void Main(string[] args)
    {
        int[,] matrix = new int[,]
        {
            { 1, 2, 3 },
            { 4, 5, 6 }
        };

        // 行数:matrix.GetLength(0)
        // 列数:matrix.GetLength(1)
        for (int row = 0; row < matrix.GetLength(0); row++)
        {
            for (int col = 0; col < matrix.GetLength(1); col++)
            {
                Console.Write(matrix[row, col] + " ");
            }
            Console.WriteLine();
        }

        Console.ReadLine();
    }
}
C#

重要ポイント:

  • 行インデックス(row)は 0 〜 GetLength(0) - 1
  • 列インデックス(col)は 0 〜 GetLength(1) - 1
  • 「行ごとに列を回す」というイメージで書くと分かりやすいです。

例題:九九表を二次元配列で作る

二次元配列で「表」を作る練習

九九(1〜9 × 1〜9)の表を、二次元配列で作ってみます。

using System;

class Program
{
    static void Main(string[] args)
    {
        // 9 行 9 列の二次元配列を作成
        int[,] kuku = new int[9, 9];

        // 値を代入(行と列を使って掛け算の結果を入れる)
        for (int row = 0; row < 9; row++)
        {
            for (int col = 0; col < 9; col++)
            {
                // row と col は 0 〜 8 なので、+1 して 1 〜 9 にします
                kuku[row, col] = (row + 1) * (col + 1);
            }
        }

        // 九九表を表示
        for (int row = 0; row < 9; row++)
        {
            for (int col = 0; col < 9; col++)
            {
                Console.Write($"{kuku[row, col],2} "); // 2 桁で揃えて表示
            }
            Console.WriteLine();
        }

        Console.ReadLine();
    }
}
C#

ここでの重要ポイント:

  • 二次元配列は「表形式のデータ」を自然に表現できる。
  • 行と列のインデックスをうまく使うことで、規則的なデータを簡単に生成できる。
  • 表示の仕方を工夫すると、見やすい出力が作れます。

練習テンプレート:二次元配列の基本形

行 × 列のデータを扱うためのひな型

二次元配列の感覚をつかむための、基本テンプレートを示します。

using System;

class Program
{
    static void Main(string[] args)
    {
        // 2 行 3 列の二次元配列
        int[,] matrix = new int[,]
        {
            { 1, 2, 3 }, // 行0
            { 4, 5, 6 }  // 行1
        };

        // 行数と列数を取得
        int rows = matrix.GetLength(0);
        int cols = matrix.GetLength(1);

        // 全要素を表示
        for (int row = 0; row < rows; row++)
        {
            for (int col = 0; col < cols; col++)
            {
                Console.Write(matrix[row, col] + " ");
            }
            Console.WriteLine();
        }

        Console.ReadLine();
    }
}
C#

このテンプレートをベースに、

  • 行数・列数を増やしてみる
  • 値を別の意味に変えてみる(点数表、座席表、マップなど)
  • 行と列を入れ替えて表示してみる

といった練習をすると、二次元配列の使い方が自然に身についていきます。

Day 22 のまとめ

Day 22 では、一次元配列から一歩進んで 二次元配列 を学びました。

  • 二次元配列:行と列を持つ「表形式の配列」
  • 行と列:インデックスが 2 つ([行, 列])になる
  • データ表現:座席表・九九表など、表形式のデータを自然に表現できる

という流れで、

「配列で表を表現する」

という新しい視点を身につけました。

次のステップでは、

  • 二次元配列を使った簡単なゲームのマップ
  • 三次元配列(必要になったときに)
  • あるいは、より柔軟なコレクション(List や Dictionary)

などに進んでいくことで、 「データをどう構造化して表現するか」というプログラミングの核心に近づいていきます。

ぜひ、二次元配列を使って、 自分なりの「表」をいくつか作ってみてください。


自分の思考を見るay 22 ミニ課題のゴールと全体像

Day 22 のミニ課題では、二次元配列を使って「クラス別成績表」を作ることを目標にします。 ここまで学んだ「二次元配列」「行と列」「データ表現」を、 実際のプログラムの形に落とし込んでいく練習になります。

ここでは、

  • 「クラス × 科目」の成績表を二次元配列で表現する
  • 行と列に「意味」を持たせて設計する
  • 成績表をきれいに表示する

という流れで、ステップバイステップで解説していきます。

クラス別成績表を二次元配列で考える

何を「行」にして、何を「列」にするか

まず、「クラス別成績表」をどう構造化するかを考えます。

例として、次のような状況を想定します。

  • クラスは 3 クラス(A・B・C)
  • 科目は 3 科目(国語・数学・英語)
  • 各クラスごとに、各科目の平均点を記録したい

これを表にすると、次のようになります。

国語数学英語
クラスA807590
クラスB708588
クラスC908095

この表を二次元配列で表現するとき、

  • → クラス(A・B・C)
  • → 科目(国語・数学・英語)

という対応関係を持たせると分かりやすいです。

二次元配列で成績表を定義する

行 × 列の意味をコメントで明示する

まずは、二次元配列で成績表を定義してみます。

using System;

class Program
{
    static void Main(string[] args)
    {
        // クラス別成績表を二次元配列で表現します。
        // 行:クラス(0: A, 1: B, 2: C)
        // 列:科目(0: 国語, 1: 数学, 2: 英語)
        int[,] scores = new int[,]
        {
            { 80, 75, 90 }, // クラスAの成績(国語, 数学, 英語)
            { 70, 85, 88 }, // クラスBの成績
            { 90, 80, 95 }  // クラスCの成績
        };

        Console.ReadLine();
    }
}
C#

重要ポイント:

  • 二次元配列の「行」と「列」に、はっきりと意味を持たせることが大事です。
  • コメントで「行はクラス」「列は科目」と書いておくと、後から見ても分かりやすくなります。

成績表をきれいに表示する

行と列のラベルを別配列で持つ

成績表を表示するとき、

  • 「クラス名」
  • 「科目名」

も一緒に表示すると、ぐっと分かりやすくなります。 そこで、クラス名と科目名を一次元配列で持っておきます。

using System;

class Program
{
    static void Main(string[] args)
    {
        // クラス別成績表(二次元配列)
        int[,] scores = new int[,]
        {
            { 80, 75, 90 }, // クラスA
            { 70, 85, 88 }, // クラスB
            { 90, 80, 95 }  // クラスC
        };

        // クラス名(行に対応)
        string[] classNames = { "クラスA", "クラスB", "クラスC" };

        // 科目名(列に対応)
        string[] subjectNames = { "国語", "数学", "英語" };

        // 行数と列数を取得します
        int classCount = scores.GetLength(0); // 行数(クラス数)
        int subjectCount = scores.GetLength(1); // 列数(科目数)

        // 見出し行(科目名)を表示
        Console.Write("        "); // クラス名の分だけスペースを空ける
        for (int s = 0; s < subjectCount; s++)
        {
            Console.Write($"{subjectNames[s],6}"); // 科目名を揃えて表示
        }
        Console.WriteLine();

        // 各クラスごとに成績を表示
        for (int c = 0; c < classCount; c++)
        {
            // 行の先頭にクラス名を表示
            Console.Write($"{classNames[c],6} ");

            // 各科目の点数を表示
            for (int s = 0; s < subjectCount; s++)
            {
                Console.Write($"{scores[c, s],6}");
            }

            Console.WriteLine(); // 行の終わりで改行
        }

        Console.ReadLine();
    }
}
C#

重要ポイント:

  • GetLength(0) → 行数(ここではクラス数)
  • GetLength(1) → 列数(ここでは科目数)
  • ラベル(クラス名・科目名)を別配列で持つことで、 二次元配列の「意味」がはっきりします。

クラス別の平均点を計算する

行ごとに平均を出す

成績表があるなら、クラスごとの平均点も出したくなります。 ここでは、各クラス(各行)の平均点を計算して表示してみます。

using System;

class Program
{
    static void Main(string[] args)
    {
        int[,] scores = new int[,]
        {
            { 80, 75, 90 }, // クラスA
            { 70, 85, 88 }, // クラスB
            { 90, 80, 95 }  // クラスC
        };

        string[] classNames = { "クラスA", "クラスB", "クラスC" };
        string[] subjectNames = { "国語", "数学", "英語" };

        int classCount = scores.GetLength(0);
        int subjectCount = scores.GetLength(1);

        // 成績表の表示(前の例と同じ)
        Console.Write("        ");
        for (int s = 0; s < subjectCount; s++)
        {
            Console.Write($"{subjectNames[s],6}");
        }
        Console.WriteLine();

        for (int c = 0; c < classCount; c++)
        {
            Console.Write($"{classNames[c],6} ");

            int sum = 0; // このクラスの合計点

            for (int s = 0; s < subjectCount; s++)
            {
                int score = scores[c, s];
                Console.Write($"{score,6}");
                sum += score; // 合計に加算
            }

            double average = (double)sum / subjectCount; // 平均点を計算
            Console.Write($"  平均:{average:F1}"); // 小数1桁で表示

            Console.WriteLine();
        }

        Console.ReadLine();
    }
}
C#

ここでの重要ポイント:

  • 「クラスごとの平均」は、行ごとに合計を出して科目数で割ることで求めます。
  • 二次元配列の「行」がクラス、「列」が科目という意味を持っているからこそ、 行ごとの集計が自然に書けます。

ミニ課題テンプレート:クラス別成績表

自分で値を変えて試せるひな型

最後に、クラス別成績表のミニ課題用テンプレートをまとめて示します。 このコードをベースに、点数やクラス数・科目数を変えて練習してみてください。

using System;

class Program
{
    static void Main(string[] args)
    {
        // クラス別成績表(二次元配列)
        // 行:クラス(0: A, 1: B, 2: C)
        // 列:科目(0: 国語, 1: 数学, 2: 英語)
        int[,] scores = new int[,]
        {
            { 80, 75, 90 }, // クラスA
            { 70, 85, 88 }, // クラスB
            { 90, 80, 95 }  // クラスC
        };

        // クラス名
        string[] classNames = { "クラスA", "クラスB", "クラスC" };

        // 科目名
        string[] subjectNames = { "国語", "数学", "英語" };

        int classCount = scores.GetLength(0);   // 行数(クラス数)
        int subjectCount = scores.GetLength(1); // 列数(科目数)

        // 見出し行(科目名)
        Console.Write("        ");
        for (int s = 0; s < subjectCount; s++)
        {
            Console.Write($"{subjectNames[s],6}");
        }
        Console.WriteLine();

        // 各クラスの成績と平均を表示
        for (int c = 0; c < classCount; c++)
        {
            Console.Write($"{classNames[c],6} ");

            int sum = 0;

            for (int s = 0; s < subjectCount; s++)
            {
                int score = scores[c, s];
                Console.Write($"{score,6}");
                sum += score;
            }

            double average = (double)sum / subjectCount;
            Console.Write($"  平均:{average:F1}");

            Console.WriteLine();
        }

        Console.ReadLine();
    }
}
C#

Day 22 ミニ課題のまとめ

このミニ課題では、

  • 二次元配列で「クラス × 科目」の成績表を表現する
  • 行と列に意味を持たせて設計する
  • 成績表をきれいに表示し、クラスごとの平均点を計算する

という流れで、二次元配列を実際のデータ表現に使う感覚を身につけました。

二次元配列は、

「表形式のデータをコードで扱う」

ための強力な道具です。

ぜひ、

  • クラス数や科目数を増やしてみる
  • 科目名を変えてみる(理科・社会など)
  • クラスごとの最高点・最低点も計算してみる

といったアレンジを加えながら、 二次元配列を使った「データ表現」の練習を続けてみてください。

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