名前空間
変種
操作

列挙型

From cppreference.com
< c‎ | language

列挙型とは、その値が基底型(後述)の値であるような、独立したであり、明示的に名前が付けられた定数(列挙子定数)の値を含みます。

目次

[編集] 構文

列挙型は、宣言文法における型指定子として、以下の列挙子指定子を使用して宣言されます。

enum attr-spec-seq (任意) identifier (任意) { enumerator-list } (1)
enum attr-spec-seq (任意) identifier (任意) : type { enumerator-list } (2) (C23以降)
1) 基底型が固定されていない列挙型を宣言します。
2) 基底型がtypeに固定された列挙型を宣言します。

ここで、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)属性の任意のリスト。
  • enumの後に現れる場合、列挙型全体に適用されます。
  • enumeration-constantの後に現れる場合、enumeratorに適用されます。

構造体または共用体と同様に、列挙型とその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配列のサイズ)でいつでも使用できます。

列挙子リスト内の各列挙子定数の処理中、その列挙子定数の型は次のようになります。

  • 同じ列挙子定数の再宣言である場合、以前に宣言された型。
  • 基底型が固定された列挙型の場合、その列挙型。
  • 列挙子リストに以前の列挙子定数がなく、明示的な=と整数定数式の定義がない場合、int
  • 明示的に=で指定され、整数定数式の値がintで表現可能な場合、int
  • 明示的に=で指定され、整数定数式の値がintで表現不可能である場合、その整数定数式の型。
  • 前の列挙子定数の値に1を加えた値の型。そのような整数定数式が、前の列挙子定数に1を加えることでオーバーフローまたはラップアラウンドする場合、型は次のいずれかになります。
    • 前の列挙子定数に1を加えた値を表現できる、適切にサイズの符号付き整数型(ビット精度指定の符号付き整数型を除く)。
    • 前の列挙子定数に1を加えた値を表現できる、適切にサイズの符号なし整数型(ビット精度指定の符号なし整数型を除く)。

前の列挙子定数が符号付き整数型の場合、符号付き整数型が選択されます。前の列挙子定数が符号なし整数型の場合、符号なし整数型が選択されます。上記で説明した、新しい値を表現できる適切なサイズの整数型が存在しない場合、その列挙型はそのすべての値を表現できる型を持ちません。

(C23以降)
enum color { RED, GREEN, BLUE } r = RED;
switch(r)
{
case RED:
    puts("red");
    break;
case GREEN:
    puts("green");
    break;
case BLUE:
    puts("blue");
    break;
}

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以降)

基底型が固定されていない列挙型が完了したときの列挙メンバの型は、次のようになります。

  • 列挙のすべての値がintで表現可能な場合、int
  • 列挙型。
(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
}

[編集]

#include <stdio.h>
 
int main(void)
{
    enum TV { FOX = 11, CNN = 25, ESPN = 15, HBO = 22, MAX = 30, NBC = 32 };
 
    printf("List of cable stations:\n");
    printf(" FOX: \t%2d\n", FOX);
    printf(" HBO: \t%2d\n", HBO);
    printf(" MAX: \t%2d\n", MAX);
}

出力

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 列挙子指定子

[編集] キーワード

enum

[編集] 関連項目

C++ドキュメント列挙型宣言
English 日本語 中文(简体) 中文(繁體)