Linux講座にようこそ。このページは「C言語プログラミング入門 - 第7章.たくさんのデータを処理するための配列」です。

C言語プログラミング入門

7. たくさんのデータを処理するための配列(3/3)

7.4 2次元配列

2次元配列
【図7-3】2次元配列

今まで説明した配列は1次元配列と呼ばれるもので、表計算ソフトに例えると「行」に相当します。2次元配列になると、「列」が加わり、行と列で構成する配列ということになります。3次元以上の配列もありますが、使われることは少ないと思いますので、ここでは主に2次元配列に付いて説明します。

2次元配列を取り扱うには1つの要素に対して、行と列に対応する添字が必要です。2次元配列の場合、列に対応する添字の方が先に変化するようにメモリ上に配置されます。(一般に、次元数の多い方から先に変化するように配置されます)

2次元配列で複数の文字列を取り扱うこともできます。その場合、1つの文字列が1つの行になります。文字列の最後にヌル文字が必要なことは1次元配列の場合と同じです。

7.4.1 形式

2次元配列の宣言は配列名の次に「行の要素数」と「列の要素数」をそれぞれ大括弧([と])で括って指定します。

初期値を指定する場合は初期値全体を中括弧({と})で括って、その中に行単位に中括弧で括って指定します。なお、行および、初期値は,(コンマ)で区切ります。

要素の内容を参照する場合も「行の添字」と「列の添字」をそれぞれ大括弧([と])で括って指定します。

※ 宣言時に初期値を指定しない場合
型名 配列名[行の要素数][列の要素数];

※ 宣言時に初期値を指定する場合
型名 配列名[行の要素数][列の要素数] = {{初期値1, 初期値2, … 初期値n}, {初期値1, 初期値2, … 初期値n}, …};
型名 配列名[行の要素数][列の要素数] = {{1行目の文字列}, {2行目の文字列}, … {n行目の文字列}};

※ 参照
配列名[行の添字][列の添字];

初期値を指定する場合、各行の初期値の数は必ずしも一致させる必要はありません。つまり、行ごとに初期値の数が異なっていても良いということになります。このため、列数は単純には決まりませんので、初期値を指定した場合でも列の要素数は省略できませんので注意してください。

例1:int ar1[][4] = {{1, 2, 3, 4}, {5, 6, 7}, {8, 9}}; ← 行の要素数は省略可能です

次の例では、最初の初期値の「hello」がヌル文字を含めて6文字と一番長いので、列の要素数は最低6必要です。

例2:int ar2[][6] = {{"hello"}, {"hi"}, {"bye"}};

7.4.2 例題

例題1

メートル単位の長さを入力するとインチ、フィート、ヤード、尺、寸の長さに変換した値を出力します。どの単位の長さに変換するかはメニューで選択します。

  1. #include <stdio.h>
  2. int main()
  3. {
  4.     double  coefficient[] = {39.370,           /* インチ */
  5.                             3.280,             /* フィート */
  6.                             1.093,             /* ヤード */
  7.                             3.300,             /* 尺 */
  8.                             33.000};           /* 寸 */
  9.     char    unit_name[][20] = {{"インチ"},
  10.                               {"フィート"},
  11.                               {"ヤード"},
  12.                               {"尺"},
  13.                               {"寸"}};
  14.     double  length;
  15.     int     number;
  16.  
  17.     printf("長さの変換を行います\n");
  18.     printf("変換する長さを入力してください(単位はメートル) ==> ");
  19.     scanf("%lf", &length);
  20.  
  21.     printf("1. インチ\n");
  22.     printf("2. フィート\n");
  23.     printf("3. ヤード\n");
  24.     printf("4. 尺\n");
  25.     printf("5. 寸\n");
  26.     printf("変換する単位の番号を入力してください ==> ");
  27.     scanf("%d", &number);
  28.  
  29.     if (number >= 1 && number <= 5)
  30.     {
  31.         printf("%.2fメートルは%.3f%sです\n",
  32.             length,                            /* 入力した値(変換する長さ) */
  33.             length * coefficient[number - 1],   /* 指定された長さの単位に変換 */
  34.             unit_name[number - 1]);             /* 変換した長さの単位 */
  35.     }
  36.     else
  37.     {
  38.         printf("番号が不当です\n");
  39.     }
  40.  
  41.     return 0;
  42. }
$ ./ex07_5.prg
長さの変換を行います
変換する長さを入力してください(単位はメートル) ==> 2
1. インチ
2. フィート
3. ヤード
4. 尺
5. 寸
変換する単位の番号を入力してください ==> 3
2.00メートルは2.186ヤードです
$
4〜8行目
メートル単位の長さを変換するための係数を格納した配列です。インチ、フィート、ヤード、尺、寸の順番です。
9〜13行目
変換する長さの単位名(文字列)を格納した配列です。格納の順番は上記配列と対応させます。
19行目
変換する長さを入力します。
27行目
入力した長さの変換番号(変換する長さの単位)を入力します。
31〜34行目
入力した値、変換結果、変換した長さの単位を出力します。変換した長さの単位はunit_name配列の「number - 1」が示す行全体ですので「unit_name[number - 1]」と指定します。

例題2

5人の方の肥満度を計算して正常・異常を判定して結果を出力すると共に、異常の人のみの値を最後に出力します。正常は18.5〜52.0の範囲で、それ以外を異常とします。

体重と身長を入力しますが、体重はキログラム、身長はセンチメートル単位で入力します。

  1. #include <stdio.h>
  2. int main()
  3. {
  4.     int     number;
  5.     int     index1;
  6.     int     index2;
  7.     double  weight;
  8.     double  height;
  9.     double  bmi;
  10.     double  alert_table[5][3];         /* 番号、体重、身長を格納 */
  11.  
  12.     printf("肥満度(BMI)の計算を行います\n");
  13.     index1 = 0;
  14.  
  15.     for(number = 1; number <= 5; ++number)
  16.     {
  17.         printf("%d. 体重(kg)と身長(cm)を入力してください ==> ", number);
  18.         scanf("%lf%lf", &weight, &height);
  19.         height = height / 100.0;       /* センチメートルをメートルに変換 */
  20.         /* 肥満度(BMI) = 体重(kg) / 身長(m) / 身長(m) */
  21.         bmi = weight / height / height;
  22.         printf("\t%d番の方の肥満度は%.2fです。", number, bmi);
  23.  
  24.         if(bmi >= 18.5 && bmi <= 25.0)
  25.         {
  26.             printf("正常です。\n");
  27.         }
  28.         else
  29.         {
  30.             printf("異常です。\n");
  31.  
  32.             /* 異常な人のデータを格納 */
  33.             alert_table[index1][0] = (double)number;   /* 番号 */
  34.             alert_table[index1][1] = weight;           /* 体重 */
  35.             alert_table[index1][2] = height;           /* 身長 */
  36.             ++index1;
  37.         }
  38.     }
  39.  
  40.     if(index1 > 0)
  41.     {
  42.         printf("\n肥満度が異常な方\n");
  43.         printf("番号\t体重\t身長\t肥満度\n");
  44.         for(index2 = 0; index2 < index1; ++index2)
  45.         {
  46.             printf("%d\t%.2f\t%.2f\t%.2f\n",
  47.                 (int)alert_table[index2][0],           /* 番号 */
  48.                 alert_table[index2][1],                /* 体重 */
  49.                 alert_table[index2][2],                /* 身長 */
  50.                 alert_table[index2][1] / alert_table[index2][2] / alert_table[index2][2]);     /* 肥満度 */
  51.         }
  52.     }
  53.     else
  54.     {
  55.         printf("\n肥満度が異常な方はいませんでした\n");
  56.     }
  57.  
  58.     return 0;
  59. }
$ ./ex07_6.prg
肥満度(BMI)の計算を行います
1. 体重(kg)と身長(cm)を入力してください ==> 67 188
        1番の方の肥満度は18.96です。正常です。
2. 体重(kg)と身長(cm)を入力してください ==> 98 176
        2番の方の肥満度は31.64です。異常です。
3. 体重(kg)と身長(cm)を入力してください ==> 43 156
        3番の方の肥満度は17.67です。異常です。
4. 体重(kg)と身長(cm)を入力してください ==> 55 167
        4番の方の肥満度は19.72です。正常です。
5. 体重(kg)と身長(cm)を入力してください ==> 75 166
        5番の方の肥満度は27.22です。異常です。

肥満度が異常な方
番号    体重    身長    肥満度
2       98.00   1.76    31.64
3       43.00   1.56    17.67
5       75.00   1.66    27.22
$
10行目
肥満度が異常だった人のデータ(番号、体重、身長)のみを格納しておくための2次元配列です。
24行目
肥満度が正常かどうかを判定します。
33〜35行目
肥満度が異常だった場合、alert_table配列に入力データを格納(番号、体重、身長)します。
46〜50行目
alert_table配列に格納されているデータを出力します。