列挙体とは
列挙体について理解するために、以下に示す
[様々な国の選択肢の中から選ばれた国の挨拶を表示するプログラム]
から列挙体とはどういうものなのか、そしてその使い方について学んでいきましょう。
#include <stdio.h>
enum greet { Japan, America, Korea, Invalid};
void japan(void)
{
puts("こんにちは");
}
void america(void)
{
puts("hello");
}
void korea(void)
{
puts("안녕하세요");
}
enum greet select(void)
{
int tmp;
do{
printf("0...日本 1...アメリカ 2...韓国 3...終了:");
scanf("%d", &tmp);
}while (tmp < Japan || tmp > Invalid);
return tmp;
}
int main(void)
{
enum greet selected;
do {
switch (selected = select()){
case Japan : japan(); break;
case America : america(); break;
case Korea : korea(); break;
}
}while (selected != Invalid);
return 0;
}
こんにちは
0…日本 1…アメリカ 2…韓国 3…終了:1
hello
0…日本 1…アメリカ 2…韓国 3…終了:2
안녕하세요
0…日本 1…アメリカ 2…韓国 3…終了:3
解説
列挙体とは、限られた整数値の集合を表すものです。列挙体は以下のように宣言します。
enum greet { Japan, America, Korea, Invalid };
greetを列挙体タグといい、{}内のJapan, America, Korea, Invalidを列挙定数といいます。このように宣言したとき、列挙定数には、Japanから順に、0, 1, 2, 3 と整数値が与えられます。この時、”enum greet”を列挙型といい、列挙型に変数をつけて宣言することで、その変数は列挙定数の値を取りうる変数となります。
enum greet selected;
このプログラムでは、enum greet型の変数selectedは0, 1, 2, 3の値を取りうるということになります。
ここでワンポイント
Invalidは「無効」という意味で、このプログラムでは、終了するときのための列挙定数として使用していますが、Invalidを使用せずとも同じ動きをするプログラムは作れますよね?例えばenum greet型の関数selectの中のdo-while文の条件を
//Invalidを使用しない例
do{
...
}while(tmp < Japan || tmp > Korea + 1);
とすれば実現可能です。
しかし、ここで新しい選択肢として、”China”を入れたいとき、先程の条件式を毎回書き換える必要があります。
//Invalidを使用せず列挙定数"China"を加えた例
enum greet { Japan, America, Korea, China };
...
do{
...
}while(tmp < Japan || tmp > China + 1);
しかし、Invalidを用意しておけば条件式は変更することなく、列挙体の宣言だけ変更すれば良いので、いかに有効かがわかると思います。
//Invalidを使用し列挙定数"China"を加えた例
enum greet { Japan, America, Korea, China };
...
do{
...
}while(tmp < Japan || tmp > Invalid);
補足
列挙定数の値は 列挙定数 = 整数値 という形で自由に設定することもできます。
例
enum name { Tanaka , Yamada = 3, Kato };
この時Tanakaの値は0、Yamadaの値は3、そしてKatoの値は指定されていないため、前の列挙定数(ここではYamada)に1を足した4になります。
列挙定数は同じ値でも構いません。いかの例では、TanakaとTaroの値はともに0となります。
例
enum name { Tanaka , Taro = 0 };
列挙体タグは必要でなければ省略することもできます。その時、その列挙型の変数の宣言はできなくなるので注意しましょう!
例
enum { JANUARY = 1, FEBRUARY, ..., DECEMBER};
上記の例を使用することで
#define JANUARY 1
#define FEBRUARY 2
...
と宣言したいとき、簡単に宣言する事が可能です。
C言語学習におすすめのテキストはこちら