2021年11月25日
川俣晶の縁側ソフトウェアnew_C#入門・全キーワード明快解説! total 1021 count

配列とインデクサ: データをまとめて処理するぞ

Written By: 川俣 晶連絡先

この章のテーマ §

 データをまとめる基本機能となる配列を学びます。また、配列と似て非なるインデクサについても触れます。

前提知識 §

Console.Writeメソッド, Console.WriteLineメソッド,文字型と文字列型, 変数の基礎, int型, for文, new演算子

解説 §

 データを集めたものをコレクションといいます。【配列】は最も基本的なコレクションです。特定の型のデータを指定数分だけ記憶できます。

 配列の型は、通常のデータ型に[]を追加して書きます。整数の単純な配列ならint[]です。

 配列を作成するにはnew演算子を使って、new int [要素数];のように格納できるデータ数を指定して記述します。利用する時は、[]を利用して、変数名[要素番号]のように使用します。要素番号は、添え字と呼びます。添え字はC#の場合必ず0から作成時にサイズとして指定した番号マイナス1までです。添え字が違えば違う値を格納できます。

 つまり要素数10個の配列を1つ確保することは、単純変数10個を確保することとほぼ等価です。

 配列は多次元配列も可能です。たとえば将棋盤を配列で表現する場合は、横9、縦9の81個の要素を持った配列を確保したいかも知れません。その場合は2次元の多次元配列を使います。その場合は添え字がカンマ区切りで増えます。横9、縦9ならnew int[9,9];のように作成します。

 多次元配列と似て非なるものに、配列の配列があります。配列型も型なので、更にそれを配列にすることができます。この場合の型名はint[][]のようになります。この場合は配列の宣言と配列に格納する配列の作成は別々に行う必要があり、手間が増えます。その代わり、要素ごとに異なるサイズの配列を代入できます。Lengthプロパティで配列のサイズを取得できるので、サンプルソースでは個々の配列のサイズが違っていることを出力して示しています。

 配列と似て非なるものがインデクサです。インデクサを自分で書くことは希なので使い方だけ説明します。

 インデクサは、配列と似た"[]"を使う構文を使って利用します。

 インデクサを提供する典型的な例は文字列です。文字列はインデクサを使うと特定の文字を簡単に抜き出せます。たとえば、var s = "ABCDE"があるとして、s[2]はchar型の'C'となります。

罠の数々 §

  • C#の配列は作成後に要素数を変更することができない。あとから足りなくならないように数を慎重に決めて作成しよう。しかし、大きすぎる配列は無駄なメモリを消費するので、不必要な大きさを指定するのもやめておこう
  • サイズを後から変更することが重要なときは、List<T>クラスなど、他の機能を利用することを検討できる。System.Collections.Generic 名前空間には多数のクラスが揃っている
  • 配列の要素数は一度作ったら変えられないが、新しいサイズの配列を作って同じ変数に格納し、古い配列のデータを全て複写することはできる
  • 配列は簡単にメモリを大量に消費できる。だから、よりメモリ消費の少ない型を利用することは意味がある。たとえば、0から100の値を格納するためにint型の配列よりbyte型の配列を使うのは意味がある。int型は4バイト消費するがbyte型は1バイトしか消費しない

参考リンク §

配列 (C# プログラミング ガイド)

サンプルソース: array §

Console.WriteLine("1次元配列");

int[] array1 = new int [10];

for (int i = 0; i < 10; i++) array1[i] = (i+1) * (i + 1);

for (int i = 0; i < 10; i++) Console.Write($"{array1[i]} ");

Console.WriteLine();

Console.WriteLine("2次元配列");

int[,] array2 = new int[3,3];

for (int i = 0; i < 3; i++)

    for (int j = 0; j < 3; j++)

        array2[i,j] = (i+1) * (j+1);

for (int i = 0; i < 3; i++)

{

    for (int j = 0; j < 3; j++)

        Console.Write($"{array2[i, j]} ");

    Console.WriteLine();

}

Console.WriteLine("配列の配列");

int[][] arrayOfArray = new int[3][];

for (int i = 0; i < 3; i++)

    arrayOfArray[i] = new int[i];

for (int i = 0; i < 3; i++)

    Console.WriteLine($"配列[{i}]サイズ={arrayOfArray[i].Length} ");

// インデクサの利用例

string s = "Hello!";

Console.WriteLine($"{s}の4文字目は{s[3]}です。");

実行結果 §

1次元配列

1 4 9 16 25 36 49 64 81 100

2次元配列

1 2 3

2 4 6

3 6 9

配列の配列

配列[0]サイズ=0

配列[1]サイズ=1

配列[2]サイズ=2

Hello!の4文字目はlです。

リポジトリ §

https://github.com/autumn009/CSharpPrimer2

練習問題 §

 以下のプログラムの実行結果を予測してみよう。

int[] a=new int[256];a[256]=1;Console.WriteLine(a[256]);

  1. 0
  2. 1
  3. 256
  4. コンパイルエラー
  5. 例外で止まる

[[解答]]

単行本情報