列挙型
列挙型とは、その値が基底型(後述)の値であるような、独立した型であり、明示的に名前が付けられた定数(列挙子定数)の値を含みます。
目次 |
[編集] 構文
列挙型は、宣言文法における型指定子として、以下の列挙子指定子を使用して宣言されます。
enum attr-spec-seq (任意) identifier (任意) { enumerator-list } |
(1) | ||||||||
enum attr-spec-seq (任意) identifier (任意) : type { enumerator-list } |
(2) | (C23以降) | |||||||
ここで、enumerator-listは、カンマ区切りのリスト(末尾のカンマも許可される)(C99以降)であり、各要素はenumeratorです。各enumeratorは次の形式をとります。
| enumeration-constant attr-spec-seq (任意) | (1) | ||||||||
enumeration-constant attr-spec-seq (任意) = constant-expression |
(2) | ||||||||
ここで、
| identifier, enumeration-constant | - | この宣言によって導入される識別子。 |
| 定数式 | - | 整数定数式。 値はint型として表現可能であること。(C23まで) 列挙型に固定基底型がある場合、typeの値として表現可能であること。(C23以降) |
| attr-spec-seq | - | (C23)属性の任意のリスト。
|
構造体または共用体と同様に、列挙型とその1つ以上の列挙子定数を導入する宣言は、その型またはそれから派生した型の1つ以上のオブジェクトを宣言することもできます。
enum color { RED, GREEN, BLUE } c = RED, *cp = &c; // introduces the type enum color // the integer constants RED, GREEN, BLUE // the object c of type enum color // the object cp of type pointer to enum color
[編集] 説明
列挙子指定子の本体に現れる各enumeration-constantは、外部スコープの整数定数(int型(C23まで))となり、整数定数が必要な場所(例: caseラベルや非VLA配列のサイズ)でいつでも使用できます。
|
列挙子リスト内の各列挙子定数の処理中、その列挙子定数の型は次のようになります。
前の列挙子定数が符号付き整数型の場合、符号付き整数型が選択されます。前の列挙子定数が符号なし整数型の場合、符号なし整数型が選択されます。上記で説明した、新しい値を表現できる適切なサイズの整数型が存在しない場合、その列挙型はそのすべての値を表現できる型を持ちません。 |
(C23以降) |
enumeration-constantの後に= constant-expressionが続く場合、その値はその定数式の値です。enumeration-constantの後に= constant-expressionが続かない場合、その値は同じ列挙内の前の列挙子の値より1大きい値です。最初の列挙子(= constant-expressionを使用しない場合)の値はゼロです。
enum Foo { A, B, C = 10, D, E = 1, F, G = F + C }; // A=0, B=1, C=10, D=11, E=1, F=2, G=12
使用される場合、identifier自体は、タグの名前空間における列挙型の名前となり、キーワードenumの使用が必要になります(通常の名前空間にtypedefされない限り)。
enum color { RED, GREEN, BLUE }; enum color r = RED; // OK // color x = GREEN; // Error: color is not in ordinary name space typedef enum color color_t; color_t x = GREEN; // OK
基底型が固定されていない各列挙型は、互換性のある型であり、次のいずれかに互換性があります。char、符号付き整数型、または符号なし整数型(boolおよびビット精度指定の整数型を除く(C23以降))。どの型が任意の列挙型と互換性があるかは実装定義ですが、いずれにしても、その列挙のすべての列挙子値を表現できる必要があります。基底型が固定されたすべての列挙について、列挙型は列挙の基底型と互換性があります。(C23以降)
|
基底型が固定されていない列挙型が完了したときの列挙メンバの型は、次のようになります。
|
(C23以降) |
| すべての列挙型は基底型を持ちます。基底型は、enum-type-specifierを使用して明示的に指定でき、その固定基底型となります。明示的に指定されない場合、基底型は列挙の互換性のある型であり、符号付きまたは符号なし整数型、あるいはcharのいずれかです。 | (C23以降) |
列挙型は整数型であり、他の整数型が使用できる場所であればどこでも使用できます。これには、暗黙の変換や算術演算子が含まれます。
enum { ONE = 1, TWO } e; long n = ONE; // promotion double d = ONE; // conversion e = 1.2; // conversion, e is now ONE e = e + 1; // e is now TWO
[編集] 注記
構造体または共用体とは異なり、C言語には前方宣言された列挙型はありません。
enum Color; // Error: no forward-declarations for enums in C enum Color { RED, GREEN, BLUE };
列挙型は、#defineよりも便利で構造化された方法で名前付き定数を宣言することを可能にします。デバッガで可視であり、スコープ規則に従い、型システムに参加します。
#define TEN 10 struct S { int x : TEN; }; // OK
or
enum { TEN = 10 }; struct S { int x : TEN; }; // also OK
C23以降、constexprが同様の目的で使用できます。
constexpr int TEN = 10; struct S { int x : TEN; }; // also OK
さらに、C言語では構造体または共用体はスコープを確立しないため、列挙型とその列挙子定数は、前者メンバー仕様で導入でき、そのスコープは前者と同じです。
struct Element { int z; enum State { SOLID, LIQUID, GAS, PLASMA } state; } oxygen = { 8, GAS }; // type enum State and its enumeration constants stay visible here, e.g. void foo(void) { enum State e = LIQUID; // OK printf("%d %d %d ", e, oxygen.state, PLASMA); // prints 1 2 3 }
[編集] 例
出力
List of cable stations: FOX: 11 HBO: 22 MAX: 30
[編集] 参考文献
- C23標準 (ISO/IEC 9899:2024)
- 6.2.5/21 型 (p: 39)
- 6.7.2.2 列挙子指定子 (p: 107-112)
- C17標準 (ISO/IEC 9899:2018)
- 6.2.5/16 型 (p: 32)
- 6.7.2.2 列挙子指定子 (p: 84-85)
- C11標準 (ISO/IEC 9899:2011)
- 6.2.5/16 型 (p: 41)
- 6.7.2.2 列挙子指定子 (p: 117-118)
- C99標準 (ISO/IEC 9899:1999)
- 6.2.5/16 型 (p: 35)
- 6.7.2.2 列挙子指定子 (p: 105-106)
- C89/C90標準 (ISO/IEC 9899:1990)
- 3.1.2.5 型
- 3.5.2.2 列挙子指定子
[編集] キーワード
[編集] 関連項目
| C++ドキュメント (列挙型宣言)
|