enum

読み:イーナム
読み:イニューム
外語:enum: enumeration 英語
品詞:名詞

C/C++/JavaC#、VB.NETなどで、(数値の)列挙型。

目次

enumは、名前を付けた整数定数の集合を用意し、その集合の要素を新たな型として定義する予約語である。

Cの場合は明確な型の定義はなく単なる整数で、その型はintと区別されない。C++やJavaでは、intとは明確に異なる型として処理される。

利点

#defineで定数をマクロ定義するのに比べ、enumで定義した型を使用すると次のような利点がある。

  • コンパイラーによってはswitch文で網羅していないcaseがあると警告してくれる
  • enum型を引数にする関数に無関係な値を渡すと警告してくれる
  • デバッグ時にenum型は数値ではなくシンボルとして表示してくれる

もちろん、これはツール(コンパイラーデバッガー)の作りによる。

由来

元々はPascalで搭載されていた機能で、一部のメーカーのCコンパイラーで採用された後、ANSI Cで正式に規格に組み込まれた。

Cでは型があいまいで、値はint相当であるが、signedunsignedかは実装依存である。負数が含まれればsigned intになるとする実装もある。

Javaでは、publicstaticfinalな定数を使うことで代わりにしていたが、Java Standard Edition 5.0において、java.lang.Enum型を継承する特殊なクラスとしてenumを定義することが可能になった。

C++

Cの場合、単なる定数の列挙に過ぎず、int型との区別は曖昧であった。一方、C++では型が厳密になり、intとは明確に異なる型として処理される。

intへの代入などはCと同様問題なく行なえるが、例えばtry/catch文などにおいてenumの値をthrowしても、これをcatch(int)で捕らえることは出来ない。intではないからである。

以下は失敗する例である。

enum {
    ENUM_VER
};
try {
    throw ENUM_VAR;
}
catch (const int n) {
...
}

正常に受け取るためには、enumには識別子を付け、それを受け取る形態にせねばならない。

enum sample_enum {
    ENUM_VER
};
try {
    throw ENUM_VAR;
}
catch (const sample_enum e) {
...
}

sizeof(enum)

C/C++では、enumの要素数を得る直接的な方法はない。sizeof(enum) としても、得られるのは各要素の長さであり、おそらくは sizeof(int) と等価の値でしかない。

あまり望ましくない消極的な方法としては、

enum sample_enum {
    a,
    b,
    c,
    number
};

などとして、この number を使用するという方法がある(要素名は任意)。但し、各要素に値を代入しているような場合には、この方法では要素数を求めることができない。

Javaでは、JDK 1.5から対応した。この機能は、C/C++のenumに似た使い方ができる。

public enum Season {
    SPRING, SUMMER, FALL, WINTER
}

C/C++とは異なり、実体はクラスで、java.lang.Enum である。このため、Cのような単純なintの列挙とは異なりオブジェクトの列挙となる。

実際に使うときは、Season.SPRING のようにする。メソッドを使うときは、例えば「Season.SPRING.toString()」とすると、"SPRING" という文字列が返される。

なお、switch文で使うときは、判別式には列挙型の変数のみを記述する。つまり、例えば「case Season.SPRING:」ではなく、「case SPRING:」とだけ書けば良い。

関連する用語
C
C++
Java

コメントなどを投稿するフォームは、日本語対応時のみ表示されます


KisoDic通信用語の基礎知識検索システム WDIC Explorer Version 7.04a (27-May-2022)
Search System : Copyright © Mirai corporation
Dictionary : Copyright © WDIC Creators club