12. その他の型(2/4)
12.3 列挙型
列挙型とは列挙定数と呼ぶ識別子によって定義された整数値の集合を使用するためのものです。
例えば、図12-2のint型変数numberに設定できる値は、int型の値であればどのような値も可能です。int型を4バイト長とすると-2147483648〜2147483647の範囲の値となります。
これに対して、図12-2の列挙型の例では、列挙定数としてZERO、ONE、TWOの3つの値を宣言しておき、これを利用して、列挙変数numberを宣言しています。この場合の列挙変数numberに設定できる値はZERO、ONE、TWOのどれか1つになります。これ以外の値を設定しようとするとコンパイルエラーになります。
この様に、列挙型は列挙定数として宣言した値以外を参照・代入出来ませんので、コーディングミスをコンパイルの段階で発見できますし、列挙定数を理解しやすい適切な名前にしておけば、理解しやすいプログラムになる可能性があります。
なお、列挙定数はint型の値ですので、int型の定数として取り扱うことも可能です。
12.3.1 形式
構造体、共用体、列挙型はよく似ていますので、宣言の形式も似ています。相違点は型指定子としてenumを指定します。
※ 列挙型名の宣言
enum 列挙型名 {列挙定数1 = 値, 列挙定数2 = 値, …};
※ 列挙変数の宣言
enum 列挙型名 列挙変数名 = 列挙定数;
※ 列挙型名の宣言と列挙変数の宣言を同時に行う
enum 列挙型名 {列挙定数1 = 値, 列挙定数2 = 値, …} 列挙変数名 = 列挙定数;
※ メンバーの参照・更新
列挙変数名 = 列挙定数;
- enum
- 列挙型を宣言するための型指定子です。
- 列挙型名
- 任意の列挙型名を宣言します。列挙型名は自由につけることが出来ます。列挙型名の宣言と列挙型変数の宣言を同時に行う場合は列挙型名は省略できます。
- 列挙定数 = 値
- 列挙定数を宣言します。値を指定しないと直前に指定した列挙定数に1を加えた値になります。なお、最初の列挙定数に値を指定しないと0を指定したことになります。指定できる値はint型の範囲の整数値です。
- 列挙型変数名
- 列挙型名を指定して、列挙変数を宣言します。初期値として列挙定数を指定することもできます。
12.3.2 例題
肥満度を計算して正常・異常を判定して結果を出力します。判定結果を表す定数を列挙型で宣言しています。
#include <stdio.h>
/* 肥満の状態を表すフラグ */
enum judge_type
{
BMI_NORMAL, /* 正常 */
BMI_UNDER, /* 低い */
BMI_OVER, /* 高い */
BMI_ERROR /* 判定不可 */
};
/* 肥満度データを格納する構造体 */
struct bmi_type
{
int number; /* 番号 */
double weight; /* 体重 */
double height; /* 身長 */
double bmi; /* 肥満度 */
enum judge_type judge; /* 肥満状態 */
};
int main(void)
{
struct bmi_type bmi_data;
int return_code = 0;
/* CalcBmiEx関数のプロトタイプ宣言 */
void CalcBmiEx(struct bmi_type *Bmi);
printf("肥満度(BMI)の計算を行います\n");
printf("体重(kg)と身長(cm)を入力してください ==> ");
scanf("%lf%lf", &bmi_data.weight, &bmi_data.height);
CalcBmiEx(&bmi_data);
printf("肥満度は%.2fです。", bmi_data.bmi);
switch(bmi_data.judge)
{
case BMI_NORMAL:
printf("正常です。\n");
break;
case BMI_UNDER:
printf("低すぎます。\n");
break;
case BMI_OVER:
printf("高すぎます。\n");
break;
default:
printf("判定出来ません。\n");
return_code = 1;
}
return return_code;
}
/* 体重と身長を元に肥満度(BMI)の計算を行い、正常かどうかの判定を行う*/
void CalcBmiEx(struct bmi_type *pBmi)
{
double height;
/* 体重と身長の値をチェック */
if (pBmi->weight > 0.0 && pBmi->height > 0.0)
{
/* 身長をセンチメートルからメートルに変換 */
height = pBmi->height / 100.0;
/* 肥満度(BMI) = 体重(kg) / 身長(m) / 身長(m) */
pBmi->bmi = pBmi->weight / height / height;
/* 肥満度が18.5〜25.5の範囲であれば正常 */
if(pBmi->bmi >= 18.5 && pBmi->bmi <= 25.0)
{
pBmi->judge = BMI_NORMAL; /* 正常 */
}
else
{
if(pBmi->bmi > 25.0)
{
pBmi->judge = BMI_OVER; /* 高い */
}
else
{
pBmi->judge = BMI_UNDER; /* 低い */
}
}
}
else
{
pBmi->bmi = 0.0;
pBmi->judge = BMI_ERROR;
}
return;
}
$ ./ex12_2.prg
肥満度(BMI)の計算を行います
体重(kg)と身長(cm)を入力してください ==> 67.5 188
肥満度は19.10です。正常です。
$
$ ./ex12_2.prg
肥満度(BMI)の計算を行います
体重(kg)と身長(cm)を入力してください ==> 67.5 159.5
肥満度は26.53です。高すぎます。
$
$ ./ex12_2.prg
肥満度(BMI)の計算を行います
体重(kg)と身長(cm)を入力してください ==> 67.5 -159.5
肥満度は0.00です。判定出来ません。
$
- 3〜9行目
- 肥満の状態を表す値を列挙型名judge_typeとして宣言します。列挙定数としてはBMI_NORMAL、BMI_UNDER、BMI_OVER、BMI_ERRORを宣言していますが、値を明示的に指定していませんので、値はそれぞれ、0、1、2、3となります。
- 17行目
- bmi_type構造体のメンバーとしてjudge_type型のjudge列挙変数を宣言します。この列挙変数の取りうる値は上記の列挙定数のみです。
- 31行目
- CalcBmiEx関数を呼び出します。引数はbmi_data構造体変数のアドレスです。この結果、bmi_data構造体変数にはCalcBmiEx関数で求めた肥満度情報が格納されます。
- 35〜37行目
- 肥満度が正常の時の処理です。
- 38〜40行目
- 肥満度が低すぎる時の処理です。
- 41〜43行目
- 肥満度が高すぎる時の処理です。
- 53行目
- 以降、CalcBmiEx関数の定義です。引数はbmi_type構造体変数のアドレスで、返り値はありません。
- 67行目
- 肥満度が正常の時の処理です。
- 73行目
- 肥満度が高すぎる時の処理です。
- 77行目
- 肥満度が低すぎる時の処理です。
- 84行目
- 肥満度の計算が出来なかった時の処理です。