列挙体
EnumDeclaration:
enum EnumTag EnumBody
enum EnumBody
enum EnumTag : EnumBaseType EnumBody
enum : EnumBaseType EnumBody
EnumTag:
Identifier
EnumBaseType:
Type
EnumBody:
EmptyEnumBody
EnumMembersBody
EmptyEnumBody:
;
EnumMembersBody:
{ EnumMembers }
EnumMembers:
EnumMember
EnumMember ,
EnumMember , EnumMembers
EnumMember:
Identifier
Identifier = AssignExpression
Type = AssignExpression
enum宣言は、関連する整数定数の集まりを定義するのに使用されます。 これには二つの形式があります:
- EnumTag のある、名前付き列挙体
- EnumTag のない、無名列挙体
名前付き列挙体
名前付き列挙体は、 関連する整数定数の集まりを定義し、新しい型を与えるのに使用されます。 各メンバ EnumMembers は、型名 EnumTag のスコープで定義されます。 EnumTag は新しい型となり、 メンバはその型を持つようになります。
以下の例では新しい型 X が定義され、各メンバの値は X.A=0, X.B=1, X.C=2 となります:
enum X { A, B, C } // 名前付き列挙体
EnumBaseType が指定されていない場合、先頭の メンバに初期化子があれば、基底型はその初期化子の型になります。 先頭メンバにも初期化子がない場合は、 デフォルトの int が基底型となります。
名前付きenumの個々のメンバに Type 形式で型を指定することはできません。
名前付き列挙体のメンバは EnumBaseType 型に暗黙変換されますが、逆に EnumBaseType の値が名前付き列挙体の型に暗黙変換されることはありません。
各メンバの値は初期化子で指定します。 初期化子がない場合、 直前のメンバの値 + 1 となります。最初のメンバに初期化子がなかった場合は、 値は 0 となります。
EmptyEnumBody は不透明な列挙体 - メンバの不明な列挙体 - を意味します。
列挙体のデフォルト初期化値
列挙体の .init プロパティは、 先頭のメンバの値となります。 これは、この型の変数のデフォルト初期化値でもあります。
enum X { A=3, B, C }
X x; // x は 3 に初期化される
列挙体のプロパティ
これらのプロパティは名前付き列挙体にのみ存在します。
.init | 先頭のメンバの値 |
.min | 最小のメンバの値 |
.max | 最大のメンバの値 |
.sizeof | 列挙体の値を格納するメモリ領域のサイズ |
例えば:
enum X { A=3, B, C }
X.min // == X.A
X.max // == X.C
X.sizeof // int.sizeof と同じ
基底型 EnumBaseType は、.max and .min プロパティに対応するために、 比較演算が可能な型でなければなりません。
無名列挙体
もし Identifier がなければ、その列挙体は 無名列挙体 で、その EnumMembers は EnumDeclaration の存在するスコープで宣言されます。 新しい型は作られません。EnumMembers は EnumBaseType の型を持ちます。
EnumBaseType は、列挙体の元となる型です。省略された場合、個々のメンバが別々の型を持てるようになります。 各メンバの型は、以下の順に規則が適用されて決定します:
- もし指定されていれば、Type
- もし指定されていれば、AssignExpression の型
- もし存在すれば、直前の EnumMember の型
- int
enum { A, B, C } // 無名列挙体
は、int型の定数 A=0, B=1, C=2 を定義します。
列挙体には少なくとも一つのメンバが必要です。
各メンバの値は初期化子で指定します。 初期化子がない場合、 直前のメンバの値 + 1 となります。最初のメンバに初期化子がなかった場合は、 値は 0 となります。
enum { A, B = 5+7, C, D = 8+C, E }
これは全てint型の A=0, B=12, C=13, D=21, E=22 となります。
enum : long { A = 3, B }
は、全てlong型の A=3, B=4 となります。
enum : string {
A = "hello",
B = "betty",
C // エラー。"betty" に 1 は足せない
}
enum {
A = 1.2f, // A は float 型の 1.2f
B, // B は float 型の 2.2f
int C = 3, // C は int 型の 3
D // D は int 型の 4
}
記号定数 (Manifest Constant)
無名列挙体にただ1つしかメンバがない場合、{ } は省略できます:
enum i = 4; // i は int 型の 4
enum long l = 3; // l は long 型の 3
このように宣言した値は左辺値ではありません。 つまり、アドレスを取ることはできません。