6. 2次元配列
 6.1 1次元配列と2次元配列
 前に,配列変数についての説明で,2科目の試験点数を扱う例を示しましたが,2次元配列の説明の前に,ここで.再度,紹介します.


 プログラム例 6.1.1  実行結果
#include <stdio.h>
void main(void){
  int eigo[5]  = { 90, 75, 80, 65, 70};
  int sugaku[5]= { 60, 30, 65, 90, 75};
  int ngakusei = 5;
  int i;

  printf("i  英語  数学\n");
  for(i = 0; i < ngakusei; i++){
    printf("%2d %4d %4d\n",i,eigo[i],sugaku[i]);
  }
}
  i  英語  数学
  0    90    60
  1    75    30
  2    80    65
  3    65    90
  4    70    75  


 上記のプログラムでは,2科目それぞれに,別々の配列変数を割り当てていますが,次のプログラム例では,2科目分の変数を 1つの配列変数にまとめて書いてあります.ただし,配列変数名の要素を指定する[ ]の数が2個に増えています.このように配列変数の個々の要素を指定するのに2つの添字が必要な配列を2次元配列と呼びます.
 2次元配列に対し,これまでに登場した[ ]が1つ,すなわち,添字が1つの配列を1次元配列と呼びます.もちろん,3次元,...その他の配列も宣言し使用することができますが,このようなプログラムは,作成の途中で頭が混乱するかもしれませんね.
 次のプログラムをながめ,2次元配列の理解を試みてください.


 プログラム例 6.1.2  実行結果
#include <stdio.h>
void main(void){
  /*2次元配列kamokuを宣言*/
  int tensu[2][5] ;
  int ngakusei = 5;
  int i, j;

  /*英語の点数を記憶させる*/ 
  tensu[0][0]=90;   tensu[0][1]=75;
  tensu[0][2]=80;   tensu[0][3]=65;
  tensu[0][4]=70;

  printf("英語の点数の表示\n");
  i=0;
  for(j = 0; j < ngakusei; j++){
    printf("%4d\n", tensu[0][j]);
  }

  /*数学の点数を記憶させる*/ 
  tensu[1][0]=60;   tensu[1][1]=30;
  tensu[1][2]=65;   tensu[1][3]=90;
  tensu[1][4]=75;

  printf("数学の点数の表示\n");
  i=1;
  for(j = 0; j < ngakusei; j++){
    printf("%4d\n", tensu[i][j]);
  }
}
英語の点数の表示
  90
  75
  80
  65
  70
数学の点数の表示
  60
  30
  65
  90
  75

 プログラム例6.1.2を見ればわかると思いますが,2次元配列を宣言すると,配列変数には,次のようにメモリーが割り当てられます.
       int tensu[2][5];
  メモリー
 
 
tensu[0][0]    90
tensu[0][1]    75
tensu[0][2]    80
tensu[0][3]    65
tensu[0][4]    70
tensu[1][0]    60
tensu[1][1]    30
tensu[1][2]    65
tensu[1][3]    90
tensu[1][4]    75





 2次元配列の各要素は,メモリー中で
    tensu[0][0],tensu[0][1],tensu[0][2],tensu[0][3],...,tensu[1][0],tensu[1][1],tensu[1][2],tensu[1][3],...
のように連続して並べられます.また,要素間には,隙間はできません.
 後で,ポインター変数というのが登場しますが,それを使いこなすには,配列変数領域での各要素の並び方を知っていることが必要になります.






 6.2 2次元配列と2重ループ
 2次元配列中に記憶されたデータを使って各種の計算や処理を行う場合,2重ループを使って,配列要素を指定します.
プログラム例の場合,全ての配列要素の記憶内容を表示するために,次のように2重ループを使っています.

    for(i = 0; i < nkamoku; i++){
      for(j = 0; j < ngakusei; j++){
        printf("%4d %4d %4d\n",i,j,tensu[i][j]);
      }
    }

 このプログラムの場合,外側の i のループで科目を指定し,内側の jのループで学生を指定しています.もちろん,外側のiのループが1回ループするたびに内側のjのループはngakusei回ループすることになります.このように,ループの内側にループがあるような構造を,ループのネストと呼びます




 プログラム例 6.2.1  実行結果
#include <stdio.h>
void main(void){
  /*2次元配列kamokuを宣言*/
  int tensu[2][5] ;
  int nkamoku = 2, ngakusei = 5;
  int i, j;

  /*英語の点数を記憶させる*/ 
  tensu[0][0]=90;   tensu[0][1]=75;
  tensu[0][2]=80;   tensu[0][3]=65;
  tensu[0][4]=70;

  /*数学の点数を記憶させる*/ 
  tensu[1][0]=60;   tensu[1][1]=30;
  tensu[1][2]=65;   tensu[1][3]=90;
  tensu[1][4]=75;

  /*2重ループを使って要素を指定する*/
  printf("   i     j kamoku[i][j]\n" );
  for(i = 0; i < nkamoku; i++){
    for(j = 0; j < ngakusei; j++){
      printf("%4d %4d %4d\n",i,j,tensu[i][j]);
    }
  }
}
   i    j   tensu[i][j]
   0    0     90
   0    1     75
   0    2     80
   0    3     65
   0    4     70
   1    0     60
   1    1     30
   1    2     65
   1    3     90
   1    4     75








 6.3 2次元配列の宣言時の初期化
 2次元配列も,1次元配列と同様,変数宣言時に値を代入(初期化)することができます.
配列宣言時に,次のように書けば,
  int tensu[2][5] ={ 90, 75, 80, 65, 70, 60, 30, 65, 90, 75};
{ }中に並んだ順に要素,tensu[0][0],tensu[0][1],...,tensu[0][4],tensu[1][0],tensu[1][1],...,tensu[1][4]に代入されます.

 通常は,プログラム例のように,わかりやすく次のような書き方をします.
  int tensu[2][5] ={{ 90, 75, 80, 65, 70},{ 60, 30, 65, 90, 75}};
このような書き方をすれば,内側の最初の{ }中の数値がtensu[0][0],...,tensu[0][4]に代入され,2番目の{ }中の数値がtensu[1][0],...,tensu[1][4]に代入されることになります.



 プログラム例 6.3.1  実行結果
#include <stdio.h>
void main(void){
  /*2次元配列kamokuを宣言,同時に初期化*/
  int tensu[2][5] ={{ 90, 75, 80, 65, 70},
                    { 60, 30, 65, 90, 75}};
  int nkamoku = 2, ngakusei = 5;
  int i, j;

  /*2重ループを使って要素を指定する*/
  printf("   i     j kamoku[i][j]\n" );
  for(i = 0; i < nkamoku; i++){
    for(j = 0; j < ngakusei; j++){
      printf("%4d %4d %4d\n",i,j,tensu[i][j]);
    }
  }
}
   i    j   tensu[i][j]
   0    0     90
   0    1     75
   0    2     80
   0    3     65
   0    4     70
   1    0     60
   1    1     30
   1    2     65
   1    3     90
   1    4     75