第16章の3 enum(列挙型)

1. enumの概要

enumは列挙型と呼ばれ、int型整数値の並びに、特定の名前を与えるものです。
例えば、日曜日から土曜日までの曜日に特定の名前を与える場合、「#define」を用いると次のように宣言できます。

#define	SUN	0
#define	MON	1
#define	TUE	2
#define	WED	3
#define	THU	4
#define	FRI	5
#define	SAT	6

このマクロ定義を enum を用いると、次のように書き換える事ができます。

enum week { SUN, MON, TUE, WED, THU, FRI, SAT };

2. 列挙型の宣言

列挙型の宣言は次のようになります。

enum タグ名 { 名前, 名前, 名前, ・・・};

enum week { SUN, MON, TUE, WED, THU, FRI, SAT }; と宣言する事により、enum は 0 から順に定数に整数値を与えます。
つまり、「SUN=0, MON=1, TUE=2, WED=3, THU=4, FRI=5, SAT=6」の値が与えられます。
もし、値を指定する場合には、

enum week { SUN=10, MON=20, TUE=30, WED=40, THU=50, FRI=60, SAT=70 };

のように「=」で値を指定すれば、希望の値にすることができます。
また、列挙定数は1つ前に指定された値+1を持ちますので、

enum week { SUN=1, MON, TUE, WED, THU, FRI, SAT };

と宣言すると、「SUN=1, MON=2, TUE=3, WED=4, THU=5, FRI=6, SAT=7」の値が与えられます。

3. 列挙型の変数の宣言

列挙型を用いる変数の宣言は次のようになります。

enum タグ名 変数名;

先ほど宣言した week で変数 w を定義するには

enum week w;

のようにします。これにより、変数wは常に列挙型を扱う変数として定義され、仮に

w = 5;

などとした場合にはコンパイル時に警告メッセージを出力する処理系もあります現在は警告を発しない処理系が主流です

#include <stdio.h>

enum week { SUN, MON, TUE, WED, THU, FRI, SAT };    // 列挙型「week」の宣言

int main(void)
{
    enum week w;    // 列挙型 week で変数 w を宣言
    int a;          // 単に int型で変数 a を宣言
    
    w = MON;        // 変数 w に列挙定数 MON を代入
    a = TUE;        // 変数 a に列挙定数 TUE を代入
    
    printf("w = %d\n", w);
    printf("a = %d\n", a);
    
    w = 3;          // 変数 w に数値定数 3 を代入:コンパイル時警告の場合も
    a = 4;          // 変数 a に数値定数 4 を代入
    
    printf("w = %d\n", w);
    printf("a = %d\n", a);
    
    return 0;
}

【実行結果例】
w = 1
a = 2
w = 3
a = 4

enum についても有効範囲は考慮してください。

〇 演習問題

次の手順に従って、年月日を入力すると曜日を返却する関数を作成しなさい。
ただし、曜日の宣言には「enum」を用いること。

[メイン関数]
  1. 西暦、年、月をキーボードから入力する。
  2. 曜日取得関数を CALL して曜日を求める。
  3. 求めた曜日を表示する。
[曜日取得関数]
  • 関数名:youbi
  • 引数:
    • int y; // 西暦
    • int m; // 月
    • int d; // 日
  • 返却値:int // 曜日 0:日 1:月 2:火 3:水 4:木 5:金 6:土
  • 処理:
    1. 西暦 y年 m月 d日が何曜日であるかは、Zeller の公式により求めることができる。
      w = ( 5*y/4 - y/100 + y/400 + (26*m + 16)/10 + d ) % 7
      ただし、1月と 2月は前年の 13月・14月として計算する必要がある。 たとえば、2000年2月某日であれば「1999年14月某日」として計算しないと正しい結果が得られない。
    2. 求めた曜日を返却する。

【実行結果例】
西暦を入力しなさい 2025
月を入力しなさい 6
日を入力しなさい 4
2025年6月4日は水曜日です

水色字はキーボードからの入力

解答例

#include <stdio.h>

// 曜日の列挙型の宣言
enum week {SUN, MON, TUE, WED, THU, FRI, SAT};

// プロトタイプ宣言
enum week youbi(int y, int m, int d);

int main(void)
{
    int yy, mm, dd;
    enum week w;

    printf("西暦を入力しなさい ");
    scanf("%d", &yy);
    printf("月を入力しなさい ");
    scanf("%d", &mm);
    printf("日を入力しなさい ");
    scanf("%d", &dd);

    // 曜日の算出
    w = youbi(yy, mm, dd);

    printf("%d年%d月%d日は", yy, mm, dd);
    switch(w) {
    case SUN:
        printf("日曜日です\n");
        break;
    case MON:
        printf("月曜日です\n");
        break;
    case TUE:
        printf("火曜日です\n");
        break;
    case WED:
        printf("水曜日です\n");
        break;
    case THU:
        printf("木曜日です\n");
        break;
    case FRI:
        printf("金曜日です\n");
        break;
    case SAT:
        printf("土曜日です\n");
        break;
    default:
        printf("エラーです\n");
    }

    return 0;
}

// 曜日取得関数
enum week youbi(int y, int m, int d)
{
    int w;

    if(m == 1 || m == 2) {
        y = y - 1;
        m = m + 12;
    }
    // Zellerの公式
    w = (5 * y/4 - y/100 + y/400 + (26 * m + 16) /10 + d) % 7;

    return (enum week) w;
}

コメント