C#: 配列
1. 1次元配列の宣言と初期化
C# の配列は、ヒープ上に格納される参照型です。配列を宣言するには、型名の後に角括弧を付け、0 から始まるインデックスを指定します。
▶ サンプル
int[] nums1 = new int[5];
int[] nums2 = new int[5] { 10, 20, 30, 40, 50 };
int[] nums3 = { 1, 2, 3, 4, 5 };
string[] names = { "Alice", "Bob", "Carol" };
Console.WriteLine(nums1[0]);
Console.WriteLine(nums2[2]);
Console.WriteLine(nums3.Length);
Console.WriteLine(names[1]);
0
30
5
Bob
警告:new int[5] は、要素が自動的にデフォルト値(int の場合は 0、string の場合は null)に初期化される配列を作成します。
2. インデックスアクセスと境界チェック
C#の配列はインデックスによってアクセスされ、ランタイムが範囲チェックを行います。範囲外のインデックスを指定すると、C言語では未定義の挙動となるのとは異なり、IndexOutOfRangeExceptionがスローされます。
▶ サンプル
int[] nums = { 10, 20, 30, 40, 50 };
nums[0] = 99;
Console.WriteLine(nums[0]);
Console.WriteLine(nums[nums.Length - 1]);
try
{
int val = nums[5];
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Index out of range!");
}
99
50
Index out of range!
ヒント:配列の長さを取得するには、C言語のように sizeof ではなく、Length プロパティを使用してください。
3. 配列クラスの一般的なメソッド
Array クラスは、ソート、逆順化、検索、コピーなどのための静的メソッドを提供しています。
▶ サンプル
int[] nums = { 5, 3, 8, 1, 9, 2 };
Array.Sort(nums);
Console.WriteLine(string.Join(", ", nums));
Array.Reverse(nums);
Console.WriteLine(string.Join(", ", nums));
int idx = Array.IndexOf(nums, 8);
Console.WriteLine(idx);
int[] copy = new int[3];
Array.Copy(nums, copy, 3);
Console.WriteLine(string.Join(", ", copy));
Array.Clear(nums, 0, 2);
Console.WriteLine(string.Join(", ", nums));
Array.Resize(ref nums, 8);
Console.WriteLine(nums.Length);
1, 2, 3, 5, 8, 9
9, 8, 5, 3, 2, 1
1
9, 8, 5
0, 0, 5, 3, 2, 1
8
ヒント:Clear は、指定された範囲内の要素を削除するのではなく、デフォルト値に設定します。Resize を使用すると、配列の長さを変更できます。
4. 多次元配列(長方形の配列)
多次元配列(長方形配列とも呼ばれる)は、すべての行の長さが同じです。宣言では、コンマを使って次元を区切ります。例えば、2次元配列の場合は int[,] となります。
▶ サンプル
int[,] matrix = new int[3, 4];
matrix[0, 0] = 1;
matrix[1, 2] = 5;
matrix[2, 3] = 9;
int[,] grid = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
Console.WriteLine(grid[0, 1]);
Console.WriteLine(grid[2, 0]);
Console.WriteLine(grid.Length);
Console.WriteLine(grid.Rank);
2
7
9
2
ヒント:Rank は次元の数を返し、Length は要素の総数(すべての次元の積)を返します。
5. ジャグド配列
不規則な配列とは、各行の長さが異なる場合がある配列の配列のことです。宣言する際は、角括弧を複数組使用します。
▶ サンプル
int[][] jagged = new int[3][];
jagged[0] = new int[] { 1, 2 };
jagged[1] = new int[] { 3, 4, 5, 6 };
jagged[2] = new int[] { 7, 8, 9 };
Console.WriteLine(jagged[0].Length);
Console.WriteLine(jagged[1][2]);
Console.WriteLine(jagged[2][0]);
int[][] scores = {
new int[] { 90, 85 },
new int[] { 78, 92, 88 },
new int[] { 95 }
};
Console.WriteLine(scores[1][1]);
2
5
7
92
警告:不規則配列は長方形配列とは異なります。int[,] はメモリ上で連続した 2 次元配列ですが、int[][] は、その要素が独立した配列からなる 1 次元配列です。
6. foreach を使った配列の反復処理
foreach ステートメントは、インデックスの手動管理を不要にすることで、配列の走査を簡略化します。これは、読み取り専用の反復処理に適しています。
▶ サンプル
string[] fruits = { "Apple", "Banana", "Orange", "Grape" };
foreach (string fruit in fruits)
{
Console.WriteLine(fruit);
}
int[,] matrix = {
{ 1, 2, 3 },
{ 4, 5, 6 }
};
foreach (int val in matrix)
{
Console.Write(val + " ");
}
Console.WriteLine();
Apple
Banana
Orange
Grape
1 2 3 4 5 6
ヒント:foreach ループ内では、配列の要素を変更することはできません。値を変更する必要がある場合は、for ループを使用してください。
7. メソッドの引数としての配列
配列は参照型であるため、メソッドに配列を渡すと、その参照が渡されます。メソッド内で配列の要素を変更すると、元の配列にも影響が及びます。
▶ サンプル
void PrintArray(int[] arr)
{
foreach (int n in arr)
{
Console.Write(n + " ");
}
Console.WriteLine();
}
void DoubleValues(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
arr[i] *= 2;
}
}
int[] nums = { 1, 2, 3, 4, 5 };
PrintArray(nums);
DoubleValues(nums);
PrintArray(nums);
int Sum(int[] arr)
{
int total = 0;
foreach (int n in arr)
{
total += n;
}
return total;
}
Console.WriteLine(Sum(nums));
1 2 3 4 5
2 4 6 8 10
30
警告:配列は参照渡しされるため、DoubleValues による変更は呼び出し元の配列に直接反映されます。
❓ よくある質問
📖 まとめ
- C#の配列は、
Type[]で宣言される参照型であり、インデックスは0から始まる Lengthは要素数を返します。実行時の境界チェックにより、範囲外のアクセスがあった場合はIndexOutOfRangeExceptionが発生します。Arrayクラスは、Sort、Reverse、IndexOf、Copy、Clear、Resizeなどの静的メソッドを提供しています。- 多次元配列
int[,]は各行の長さが等しいのに対し、ジャグド配列int[][]は各行の長さが異なる場合がある foreachは、多次元配列を含む読み取り専用の反復処理に最適です- 配列はメソッドに参照渡しされるため、メソッド内での変更は元の配列に影響を与えます
📝 練習問題
- 10個の整数からなる配列を宣言し、ループを使って1から10までの値を割り当て、その後、すべての要素を逆順で出力する
Array.Sortを使用して、文字列の配列をアルファベット順に並べ替え、その結果を出力する- 3×3の2次元整数配列を作成し、対角要素の和を計算して出力する
- 3人の生徒(それぞれ履修科目数が異なる)の成績を格納する不規則な配列を作成し、各生徒の平均点を算出する
- 配列を受け取り、その最大値を返すメソッド
int FindMax(int[] arr)を作成してください