一次配列を駆使すれば、どんな複数のデータでも扱えます。
例えば、3つクラス1組、2組、3組があり、それぞれ25人の学生がいて、それぞれの点数を記憶して、
データを管理したい場合を考えてみます。
そのための配列を ten の名前で用意する場合、3クラス×25人=75 より、
int ten[75] と記憶域を用意すればサイズ的に足ります。
変数 n_kumi に、2組の2を記憶し、
変数 n_gaku に10番目学生の意味で 10を記憶し、
これを利用して、その人に100点数を記憶したい場合、次のように記憶すると決めて使うことになります
ten[(n_kumi-1)*25 + n_gaku-1]=100;
つまり、1組で1番目の人は、 ten[0] に記憶することになり、
つまり、2組で1番目の人は、 ten[25] に記憶することになり、
つまり、3組で1番目の人は、 ten[50] に記憶することになります。
さてこのような場合、
配列で配列を作ると表現が簡単になります。その宣言は次のようになります。
int ten[3][25];
これは、『 int型が[25]個並ぶ領域 』の配列を3個用意する配列で、2次配列とよばれます。
この宣言は、
[3]個の要素を持つ配列で、各要素を 『 [25]個のint型が並ぶ領域 』 に指示するものですが、その記憶域を
割り当てるメモリのイメージは、次のように、『 int型が[25]個並ぶ領域 』を連続して3個並べた形になります。
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ このイメージは、□の1つがint型要素で、右側にある程、そのアドレスが大きくなるメモリ空間です
n_kumi に、2組の2を記憶し、
n_gaku に10番目学生の意味で10を記憶し、
これを利用して、その人に100点数を記憶したい場合、次のように記憶すると決めて使うことになります
ten[n_kumi-1][n_gaku-1]=100;
つまり、1組で1番目の人は、 ten[0][0] に記憶することになり、
つまり、2組で1番目の人は、 ten[1][0] に記憶(上記□の所です)することになり、
つまり、3組で1番目の人は、 ten[2][0] に記憶することになります。
このように、int型で宣言した2次配列なので、[]演算子を2つ使った ten[2][0] の表現で、
(int)型記憶域になります。
そして、この2次配列名に、[]演算を一つだけ使った ten[2]の表現は、
(int)型記憶域を指し示すポインタで、
それは(int *)型になります。それは、アドレス演算子&を使った(&ten[2][0])と同じです。
そして、配列名 ten の表現は、
(int)型記憶域が25個並んだところを指し示すポインタで、
その型は(int (*)[25])型という表現になります。
2次配列も1次配列と同様に、添え字をどのように使うかを決めて、使います。
『1月から 12月を0から11の添え字に使って、それぞれの月の日数を各要素へ記憶する』と決めてプログラミングしました。
それを2つ並べた2次配列の例で、2月は、months[0][1]の28と、閏年の場合につかう months[1][1]の29があります。
char months[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },/* 通常の年間月のデータ */ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } /* 閏年の年間月のデータ */ };
2次配列を初期化する場合、一つの配列構造を { と } で囲むので、
それを { } の中で並べた表現になります。
この時、最初の [2] の中の2だけ省略可能で、その場合は、中で並べた { } の数で要素数が決まります。
その並べる対象となる [12] の12は、省略した表記ができません。(省略するとエラーです。)
なお、配列名 months の表現は、
(char)型記憶域が12個並んだところを指し示すポインタで、
その型は(char (*)[12])型という表現になります。
そして、months[0]や、months[1]の表現は、(char *)型です。
ですから、char *mp = months[1];と管理でき、
この時 mp[0]からmp[11]で、閏年の1月から12月の日数データを処理するプログラムが作れます。
char の2次配列では、次のように文字列を並べた初期化が可能です。
char a[][5] = { "ab", "x", "1234" };
この場合、aの配列のメモリーイメージは次のようになります。
a[0][0] | a[0][1] | a[0][2] | a[0][3] | a[0][4] | a[1][0] | a[1][1] | a[1][2] | a[1][3] | a[1][4] | a[2][0] | a[2][1] | a[2][2] | a[2][3] | a[2][4] |
'a' | 'b' | '\0' | '\0' | '\0' | 'x' | '\0' | '\0' | '\0' | '\0' | '1' | '2' | '3' | '4' | '\0' |
なおこのイメージで、a[1][0]
の文字から始まる文字列をputsで表示する場合は、
puts( a[1] )または、puts( & a[1][0] )で、できます。