Linux講座にようこそ。このページは「C言語プログラミング入門 - 第11章.異なる型名データをまとめて取り扱う構造体」です。

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

11. 異なる型名データをまとめて取り扱う構造体(2/2)

11.3 構造体の配列

構造体の配列
【図11-2】構造体の配列

図11-2のように構造体変数を要素として配列を作ることができます。この配列のことを当講座では「構造体の配列」と呼ぶことにします。

構造体の配列を宣言する場合も、予め、構造体型名を宣言しておく必要があります。宣言の仕方は通常の構造体の場合と同じです。

要素を操作するには添字を指定しますが、それだけですと1つの構造体(1要素)だけを指定することになりますので、構造体のメンバ一名も指定する必要があります。つまり、配列名と添字および、メンバ一名を指定することになります。

また、ポインタ変数を使って操作することもできますが、その場合もメンバ一名を指定します。

11.3.1 形式

ここでは、構造体型名の宣言は既に行われているものとします。

※ 構造体の配列の宣言
struct 構造体型名 構造体配列名[要素数];

※ メンバーの参照・更新
構造体配列名[添字].メンバー名;
構造体配列名[添字].メンバー名 = 値;
ポインタ変数名->メンバー名;
ポインタ変数名->メンバー名 = 値;

要素数や添字の指定は通常の配列と同じ要領で指定します。

11.3.2 例題

5人の方の肥満度を計算して正常・異常を判定して結果を出力すると共に、異常の人のみの値を最後に出力します。肥満度の計算とチェックを行うCalcBmiEx関数は1つのソースファイルとして作っています。

  1. /* ソースファイル名:ex11_3_1.c */
  2.  
  3. #include <stdio.h>
  4. /* 肥満度データを格納する構造体 */
  5. struct bmi_type
  6. {
  7.     int     number;    /* 番号 */
  8.     double  weight;    /* 体重 */
  9.     double  height;    /* 身長 */
  10.     double  bmi;       /* 肥満度 */
  11.     char    judge;     /* 肥満状態(正常 … 'n'、低 … 'l'、高 … 'h') */
  12. };
  13.  
  14. int main(void)
  15. {
  16.     struct bmi_type    a_bmi[5];       /* 肥満度構造体の配列 */
  17.     int                index;
  18.     int                abnormal_cnt;
  19.     int                return_code;
  20.     /* CalcBmiEx関数のプロトタイプ宣言 */
  21.     int CalcBmiEx(struct bmi_type *Bmi, int RecordNumber);
  22.  
  23.     printf("肥満度(BMI)の計算を行います\n");
  24.     for(index = 0; index < 5; ++index)
  25.     {
  26.         a_bmi[index].number = index + 1;
  27.         printf("%d. 体重(kg)と身長(cm)を入力してください ==> ", index + 1);
  28.         scanf("%lf%lf", &a_bmi[index].weight, &a_bmi[index].height);
  29.     }
  30.  
  31.     if(CalcBmiEx(a_bmi, index))
  32.     {
  33.         for(index = 0; index < 5; ++index)
  34.         {
  35.             if(a_bmi[index].bmi > 0.0)
  36.             {
  37.                 printf("\t%d番の方の肥満度は%.2fです。", a_bmi[index].number, a_bmi[index].bmi);
  38.                 switch(a_bmi[index].judge)
  39.                 {
  40.                     case 'n':
  41.                         printf("正常です。\n");
  42.                         break;
  43.                     case 'l':
  44.                         printf("低すぎます。\n");
  45.                         break;
  46.                     case 'h':
  47.                         printf("高すぎます。\n");
  48.                         break;
  49.                     default:
  50.                         printf("\n");
  51.                 }
  52.             }
  53.             else
  54.             {
  55.                 printf("\t%d番の方の肥満度は計算できませんでした\n", a_bmi[index].number);
  56.             }
  57.         }
  58.  
  59.         printf("\n肥満度が異常な方\n");
  60.         printf("番号\t体重\t身長\t肥満度\n");
  61.         abnormal_cnt = 0;
  62.         for(index = 0; index < 5; ++index)
  63.         {
  64.             if(a_bmi[index].judge != 'n')
  65.             {
  66.                 printf("%d\t%.2f\t%.2f\t%.2f\n",
  67.                     a_bmi[index].number,       /* 受付番号 */
  68.                     a_bmi[index].weight,       /* 体重 */
  69.                     a_bmi[index].height,       /* 身長 */
  70.                     a_bmi[index].bmi);         /* 肥満度 */
  71.  
  72.                 ++abnormal_cnt;
  73.             }
  74.         }
  75.  
  76.         if(abnormal_cnt > 0)
  77.         {
  78.             printf("\n肥満度が異常な方は%d人でした\n", abnormal_cnt);
  79.         }
  80.         else
  81.         {
  82.             printf("\n肥満度が異常な方はいませんでした\n");
  83.         }
  84.  
  85.         return_code = 0;
  86.     }
  87.     else
  88.     {
  89.         printf("肥満度の計算が出来ませんでした\n");
  90.         return_code = 1;
  91.     }
  92.  
  93.     return return_code;
  94. }
  1. /* ソースファイル名:ex11_3_2.c */
  2.  
  3. /* 肥満度データを格納する構造体 */
  4. struct bmi_type
  5. {
  6.     int     number;    /* 番号 */
  7.     double  weight;    /* 体重 */
  8.     double  height;    /* 身長 */
  9.     double  bmi;       /* 肥満度 */
  10.     char    judge;     /* 肥満状態(正常 … 'n'、低 … 'l'、高 … 'h') */
  11. };
  12.  
  13. int CalcBmiEx(struct bmi_type  *pBmi, int pRecordNumber)
  14. {
  15.     struct bmi_type    *p_bmi;         /* 肥満度構造体配列の要素の先頭アドレス */
  16.     int                calc_cnt;       /* 肥満度が算出できた要素の数 */
  17.     int                record_cnt;
  18.     double             height;
  19.  
  20.     p_bmi = pBmi;
  21.     calc_cnt = 0;
  22.     for(record_cnt = 1; record_cnt <= pRecordNumber; ++record_cnt)
  23.     {
  24.         /* 体重と身長の値をチェック */
  25.         if (p_bmi->weight > 0.0 && p_bmi->height > 0.0)
  26.         {
  27.             /* 身長をセンチメートルからメートルに変換 */
  28.             height = p_bmi->height / 100.0;
  29.             /* 肥満度(BMI) = 体重(kg) / 身長(m) / 身長(m) */
  30.             p_bmi->bmi = p_bmi->weight / height / height;
  31.             /* 肥満度が18.5〜25.5の範囲であれば正常 */
  32.             if(p_bmi->bmi >= 18.5 && p_bmi->bmi <= 25.0)
  33.             {
  34.                 p_bmi->judge = 'n';            /* 正常 */
  35.             }
  36.             else
  37.             {
  38.                 if(p_bmi->bmi > 25.0)
  39.                 {
  40.                     p_bmi->judge = 'h';        /* 高い */
  41.                 }
  42.                 else
  43.                 {
  44.                     p_bmi->judge = 'l';        /* 低い */
  45.                 }
  46.             }
  47.  
  48.             ++calc_cnt;
  49.         }
  50.         else
  51.         {
  52.             p_bmi->bmi = 0.0;
  53.             p_bmi->judge = ' ';
  54.         }
  55.  
  56.         ++p_bmi;
  57.     }
  58.  
  59.     return calc_cnt;
  60. }
$ ./ex11_3.prg
肥満度(BMI)の計算を行います
1. 体重(kg)と身長(cm)を入力してください ==> 67 188
2. 体重(kg)と身長(cm)を入力してください ==> 98 176.5
3. 体重(kg)と身長(cm)を入力してください ==> 43.2 156.5
4. 体重(kg)と身長(cm)を入力してください ==> 55.5 167.5
5. 体重(kg)と身長(cm)を入力してください ==> 75.7 166.5
        1番の方の肥満度は18.96です。正常です。
        2番の方の肥満度は31.46です。高すぎます。
        3番の方の肥満度は17.64です。低すぎます。
        4番の方の肥満度は19.78です。正常です。
        5番の方の肥満度は27.31です。高すぎます。

肥満度が異常な方
番号    体重    身長    肥満度
2       98.00   176.50  31.46
3       43.20   156.50  17.64
5       75.70   166.50  27.31

肥満度が異常な方は3人でした
$
16行目
要素数5のbmi_type構造体型名の配列(a_bmi)を宣言します。
21行目
CalcBmiEx関数の関数プロトタイプ宣言です。返り値はint型で、計算が出来たレコード(要素)数を返します。第1引数は肥満度構造体の配列で、第2引数はそのレコード(要素)数です。
26行目
肥満度構造体の配列(a_bmi)にデータを設定します。a_bmi[index].numberで、肥満度構造体の配列のindex番目の要素のnumberメンバ一の参照です。
31行目
CalcBmiEx関数を呼び出します。第1引数は肥満度構造体の配列名を指定していますので、配列の先頭アドレスを指定していることになります。なお、返り値は計算が出来たレコード数ですので、全レコードエラーの場合は0が返って来ますが、これは論理値では偽になります。