Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

列挙型(enum)

関連する定数に名前を付けてまとめるデータ型です。曜日・方向・状態コードなど、限られた値のセットを整数の代わりに意味のある名前で表現でき、コードの可読性が向上します。

構文
// 列挙型を定義します(先頭から 0, 1, 2 ... の値が割り当てられます)。
enum 列挙型タグ名 {
    列挙定数1,
    列挙定数2,
    列挙定数3
};

// 値を明示的に指定できます。
enum 列挙型タグ名 {
    定数1 = 値1,
    定数2 = 値2,
    定数3      // 前の値 + 1 が割り当てられます。
};

// 列挙型変数を宣言します。
enum 列挙型タグ名 変数名;
enum 列挙型タグ名 変数名 = 列挙定数;

// typedef と組み合わせて enum を省略できます。
typedef enum { 定数1, 定数2 } 型名;
列挙型の特徴
特徴概要
デフォルト値最初の定数は0から始まり、以降は1ずつ増加します。任意の位置で値を指定すると、そこから再度連番が続きます。
内部表現列挙定数は実際には整数(int)として扱われます。整数との変換は暗黙的に行われます。
スコープC言語の列挙定数はグローバルスコープに定義されます。名前の衝突を避けるため、接頭辞を付ける慣習があります。
switch との相性列挙型の値は整数のため、switch文と組み合わせて各状態の処理を分岐させるのが一般的です。
サンプルコード
#include <stdio.h>

// 曜日を表す列挙型です(MON = 0, TUE = 1, ...)。
typedef enum {
    MON, TUE, WED, THU, FRI, SAT, SUN
} Weekday;

// 方向を表す列挙型です(ビットフラグとして使えます)。
typedef enum {
    DIR_NORTH = 0,
    DIR_EAST  = 1,
    DIR_SOUTH = 2,
    DIR_WEST  = 3
} Direction;

// エラーコードを表す列挙型です。
typedef enum {
    ERR_OK      =  0,
    ERR_NOTFOUND = -1,
    ERR_DENIED   = -2,
    ERR_TIMEOUT  = -3
} ErrorCode;

void print_weekday(Weekday day) {
    const char *names[] = {"月", "火", "水", "木", "金", "土", "日"};
    printf("曜日: %s曜日\n", names[day]);
}

const char *direction_name(Direction d) {
    switch (d) {
        case DIR_NORTH: return "北";
        case DIR_EAST:  return "東";
        case DIR_SOUTH: return "南";
        case DIR_WEST:  return "西";
        default:        return "不明";
    }
}

int main(void) {
    Weekday today = WED;
    print_weekday(today); // 『曜日: 水曜日』と出力されます。

    // 列挙型は整数として扱えます。
    printf("水曜日の値: %d\n", WED); // 『2』と出力されます。

    Direction dir = DIR_NORTH;
    printf("方向: %s\n", direction_name(dir)); // 『方向: 北』と出力されます。

    // switch と組み合わせた使い方です。
    ErrorCode err = ERR_NOTFOUND;
    switch (err) {
        case ERR_OK:       printf("成功\n"); break;
        case ERR_NOTFOUND: printf("見つかりませんでした。\n"); break; // こちらが実行されます。
        case ERR_DENIED:   printf("アクセスが拒否されました。\n"); break;
        case ERR_TIMEOUT:  printf("タイムアウトしました。\n"); break;
    }

    // 列挙型のサイズ(処理系によりますが通常 int と同じです)。
    printf("Weekday のサイズ: %zu バイト\n", sizeof(Weekday));

    return 0;
}
概要

列挙型は可読性を高めるための機能ですが、内部的には整数型です。型チェックはC言語では緩く、別の列挙型の値を誤って代入してもコンパイラは警告を出さないことがあります。列挙定数の名前はグローバルスコープに置かれるため、異なる列挙型で同じ名前を使うとコンパイルエラーになります。接頭辞(例:『DIR_』『ERR_』)で衝突を避けてください。

列挙型と『switch』を組み合わせる際、コンパイラによっては未処理の列挙定数に対して警告を出す設定があります。この警告を活用すると、定数の追加漏れを防げます。

関連する定数のグループは列挙型で、異なる型のデータをまとめる場合は『struct(構造体)』を使います。型名の別名については『typedef』も参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。