2 配列

2.1 基礎

同じ型のデータが大量にあるとき配列と呼ばれるデータ構造が便利である.配列を使うときの宣言は,
	
	int hoge[100], fuga[200][200];
	double foo[300], bar[4][4][4];

のようにする.すると,次のようなひとつずつデータの格納できる要素が使えるようにな る.

2.1.0.1 配列の初期化

配列のサイズが小さい場合,宣言と同時に初期ができる.
	int hoge[3]={111,222,333};
	int fuga[2][2]={{111,222},{333,4444}};

配列よりも初期値が少ない場合には,残りはゼロに初期化される.多い場合にはエラーとなる.

2.1.0.2 配列の要素へのアクセス

配列名と添え字(インデックス)を指定する--たとえばi[3]j[25][49]--ことにより,記憶領域から値(データ)を入出力できる.
	i[3]=5;         /* 配列 i[3] に 5 を代入 */
	c=j[25][49];    /* 配列 j[25][49] の値を変数 c へ代入 */

ほとんど今まで使ってきた変数と同じである.インデックスには自然数が格納された整数 型の変数を使うことも可能である.
	for(i=0; i<=360; i++){
	    my_sin[i]=sin(M_PI*i/360.0);
	}

こうすると,my_sin[45]には $ 0.707107\cdots$が格納される.

2.2 応用

2.2.1 ファイルからのデータ読み込み

配列は大きなデータを扱うことが多い.格納するデータはファイルから読み込むことが多 い.ファイルからデータを取得するには,(1)ファイル情報を格納する変数を用意する,(2)ファ イルをオープンする,(3)ファイルからデータを読み込む,(4)ファイルをクローズすると いう一連の動作が必要である.リスト1では次のようにしている. exercise.txtというファイルを読み込んでいる.
  FILE *in_file;

  in_file = fopen("exercise.txt", "r");

  for(i=0; i<10000; i++){
    fscanf(in_file,"%d%d%d%d",
	   &data[i][0],&data[i][1],&data[i][2],&data[i][3]);
  }

  fclose(in_file);

2.2.2 関数へデータを渡す方法

配列格納されたデータは大量な場合が多い.ユーザー定義関数を利用すると分かり安プロ グラムになる.配列のデータをユーザー定義関数に渡す方法を学習した.

単純型の変数と配列では,ユーザー定義関数にデータを渡す方法は大きく異なる.

実際に,ユーザー定義関数に配列を渡す例をリスト1で見てみよう. このプログラムでは呼び出し側では配列名のみを,ユーザー定義関数では配列名と左端を 空欄とした要素数を記述している.こうすることにより,ユーザー定義関数に配列のデー タを渡すことができる.

  sum_data = cal(data);

    長いので省略


  int cal(int hoge[][4]){

    ここに関数での処理の内容を書く.

  return sum0+sum1+sum2+sum3;
}

2.3 プログラム例

それぞれについて,リスト1のプログラムを例にして説明する.この プログラムは,つぎに示すデータをファイルから読み込んで,全ての整数の合計値と各列 の平均値を計算するプログラムである.データは,10000行4列,合計4万個の整数である.


-76797  99987   53528   -43172
-34698  44783   -106207 -106631
-83424  31615   18774   -4134
78694   -886    64632   103022
-86516  -99744  -51044  -11396
90058   54995   -39364  -36610
-78969  106494  -5209   -95276
75913   32002   39260   106490
24615   -14585  -44056  97291
-77175  -42889  98034   -53226
96100   9434    50013   67420

   この辺は長いので省略

100747  -2875   37515   4509
77468   12111   76950   82072
-102787 41331   75324   -96228
-53535  -6367   65795   -62947


   1 #include <stdio.h>
   2 
   3 int cal(int hoge[][4]);                           // プロトタイプ宣言
   4 
   5 double ave0, ave1, ave2, ave3;           // 各列の平均値はグローバル変数とする
   6 
   7 //===========================================================================
   8 // main 関数
   9 //===========================================================================
  10 int main(void)
  11 {
  12   FILE *in_file;
  13   int i,data[10000][4], sum_data;
  14   
  15   in_file = fopen("/home/yamamoto/tmp/program/int_data.txt", "r");
  16 
  17   for(i=0; i<10000; i++){
  18     fscanf(in_file,"%d%d%d%d",
  19 	   &data[i][0],&data[i][1],&data[i][2],&data[i][3]);
  20   }
  21 
  22   fclose(in_file);
  23 
  24   sum_data = cal(data);
  25 
  26   printf("sum all = %d\n", sum_data);
  27   printf("average = %f\t%f\t%f\t%f\n", ave0,ave1,ave2,ave3);
  28 
  29   return 0;
  30 }
  31 
  32 //===========================================================================
  33 // データ処理のためのユーザー定義関数
  34 //===========================================================================
  35 int cal(int hoge[][4]){
  36   int i;
  37   int sum0=0, sum1=0, sum2=0, sum3=0;
  38 
  39   for(i=0; i<10000; i++){
  40     sum0+=hoge[i][0];
  41     sum1+=hoge[i][1];
  42     sum2+=hoge[i][2];
  43     sum3+=hoge[i][3];
  44   }
  45 
  46   ave0=sum0/10000.0;
  47   ave1=sum1/10000.0;
  48   ave2=sum2/10000.0;
  49   ave3=sum3/10000.0;
  50 
  51   return sum0+sum1+sum2+sum3;
  52 }



\fbox{実行結果}

sum all = -15594426
average = -612.222100   377.635000      -430.162000     -894.693500



ホームページ: Yamamoto's laboratory
著者: 山本昌志
Yamamoto Masashi
平成19年3月4日


no counter