Unix C プログラミング入門資料(高崎金久)   5.配列変数と繰り返し処理 目次 1.今回のテーマについて 2.配列の宣言や要素の参照 3.プログラムの例 4.プログラムの解説 -------------------------------------------------------------------------- 1.今回のテーマについて 配列は同じ型の変数を複数並べて番号で参照できるようにしたものです.C言語で は直線的(1次元的)に並ぶ配列だけでなく2次元,3次元,など高次元的な配列 も使えるようになっています.これらは線形代数におけるベクトル,行列,テンソ ルの概念に相当しますが,配列が用いられるのはこのような線形代数的な問題に限 りません.例えば,画像データは画像を構成する大量の画素(ピクセル)からなる わけですが,そのようなデータを蓄えるためにも配列が欠かせません.また,C言 語では文字列を文字型配列として扱います. 配列を用いるプログラムでは整数変数で要素を参照しながら同じ処理を繰り返すこ とが多いのですが,そのような場合にもちいられるのが for 文という繰り返し構 文です.この節では配列を通じて for 文の使い方についても学びます. 2.配列の宣言や要素の参照 プログラム例に進む前に,配列変数の宣言や要素の参照についての一般的事項をま とめておきます. 1)1次元配列の場合 配列も単一の変数と同様に宣言をしてから用います.宣言の仕方は配列の要素の型 によらず同じで,次のような形式をとります. *1次元配列の宣言の一般的形式* type name[size]; ここで type -- 配列の要素のデータ型 name -- 配列名 size -- 配列の長さ 宣言は他の同じ型の変数や配列と一緒にまとめて行えます. *例* double x,y,z[10],w[20]; /* 倍精度実数変数 x, y と長さ10の配列 z, 長さ20の配列 w を宣言 */ 配列の要素は配列名を name とするとき name[0], name[1], ..., というように各 括弧で添え字番号を囲んだもので参照できます.注意すべきはCシェルの配列と違 って要素番号は0から始まるということです.配列の要素は単一の変数とまったく 同じように扱えます. *例* double z[10]; ... ... z[0] = sin(PI/10.0); z[1] = sin(2*PI/10.0); ... ... ... printf("z[2] = %lf\n", z[2]); ... ... 厄介なことに,最初に宣言した添え字範囲を超えて要素を参照する(たとえば上の 例でz[10] を参照する)プログラムを作っても,コンパイラーはそのままコンパイ ルしてしまいます.そしで実行時に異常が起きます.これはよくあるミスなので注 意してください. 宣言時に初期化を行う(つまり各要素に一定の値を設定しておく)には次のように します. *1次元配列の宣言と初期化の一般的形式* type name[] = { data0, data1, ..., dataN }; こうすると name[0] = data0; name[1] = data1; ... と代入したのと同じことになります.なお,ここで配列の要素数を空欄のままにし ていますが,これでも構いません.データ数が多かったりあとで変更する可能性が ある場合は,このようにコンパイラーに数えさせる方が間違いがありません. 2)多次元配列の場合 *多次元配列の宣言の一般的形式* type name2[size1][size2]; /* 2次元配列の場合 */ type name3[size1][size2][size3]; /* 3次元配列の場合 */ 4次元以上も(あまり使わないが)同様に宣言できます.ここで [size1],... は そこに現われる添え字の動く範囲の大きさを指定しています.[size]の場合は1次 元と同様に 0, ..., size-1 が添え字の範囲です. 要素の参照は name2[i][j], name3[i][j][k], ... というように参照します. 2次元配列は要するに行列のようなもので, name2[0][0] name2[0][1] name2[0][2] ... name2[1][0] name2[1][1] name2[1][2] ... ... ... ... と並んでいるとみなせばよいわけです.3次元の場合は空間的に配置している イメージになります.ただし,メモリーの上では name2[0][0] ... name2[0][size2-1] name2[1][0] ... name2[1][size2-1] ... のように直線的に並んでいます. 多次元配列の初期化は { } を入れ子にします.2次元の場合だけ例を掲げておき ます. *2次元配列の初期化の例* int a[5][5] = { {0,1,2,3,4}, {5,6,7,8,9}, {10,11,12,13,14}, {15,16,17,18,19}, {20,21,22,23,34} }; C言語ではプログラムの書き方はかなり自由なので,このように行列のイメージが 見えるように書くことができます.内側の括弧のあとのコンマを忘れないように注 意してください. 3.プログラム例 次の例はパスカルの3角形の関係を利用して2項係数を求めて表示するものです. (本来の2項係数は C(n-m,m) に相当することに注意.) 1:/******************************************************************* 2: 組み合わせ数 C(n,m) = (n+m)(n+m-1)...(m+1) / m! を計算して表示する. 3: 計算には漸化式 C(n,m) = C(n-1,m) + C(n,m-1) を利用する. 4: *******************************************************************/ 5:#include 6:#define COLUMN 10 7:#define ROW 15 8: 9:int main(void) 10:{ 11: long C[ROW][COLUMN]; 12: int i,j; 13: 14: for (j=0; j