列挙型
列挙型:インデックス への移動
列挙データ型には一連の整数値に対してニーモニック識別子を提供するために使用されます。たとえば、次の宣言の場合:
enum days { sun, mon, tues, wed, thur, fri, sat } anyday;
一意の整数型、列挙型の日付、この型のさまざまな任意の日付、そして、列挙値(sun
、mon
、...)のセットが、定数の整数値と定めされます。
-b
コンパイラ スイッチは、"Treat Enums As Ints" オプションを制御します。このスイッチが使用されると、コンパイラは語全体(4 バイト int)を、列挙型(型 enum の変数)のための確保します。値の許容範囲内であるならデフォルトは ON(つまり、enums は常に int)ですが、式の中で使用される場合、値は常に int に変換されます。列挙子のリスト内で利用される識別子は、列挙子の値に基づき、暗黙的に signed char、unsigned char、int の型となります。すべての値が unsigned char または 符号なし文字 で表せる場合、それは各列挙子の型です。
C では、列挙型の変数は int 型であればいずれも値にも割り当てることができ、- 型チェックは行われません。C++ では、列挙型の変数は、その列挙子のいずれかのみに割り当てることができます。つまり、次のようになります:
anyday = mon; // OK anyday = 1; // illegal, even though mon == 1
識別子 days は、任意の列挙型タグで、それに続く型 enum days の列挙型変数の宣言で使用されます:
enum days payday, holiday; // declare two variables
C++ では、enum キーワードは省略することができます。ただし、それは days が同じスコープの別の場所で使用されていない限りです。
struct や union の宣言と同様、それ以降、この enum 型の変数を必要としない場合には、タグを省略することができます:
enum { sun, mon, tues, wed, thur, fri, sat } anyday; /* anonymous enum type */
括弧の中にリストされた列挙子はまた、列挙定数とも呼ばれます。それぞれに、固定の整数値が割り当てられます。明確な初期値がない場合、最初の列挙子 sun
が 0 に設定され、それに続く列挙子はそれより前に 1 足した数になります(mon = 1
、tues = 2
、など)。列挙定数については、「列挙定数」を参照してください。
明示的な整数初期値で、1 つまたは複数の列挙子を特定の値に設定することができます。それに続く列挙子で、初期値の指定がないものは、値が 1 ずつ大きくなります。 たとえば、次の宣言の場合:
/* Initializer expression can include previously declared enumerators */ enum coins { penny = 1, tuppence, nickel = penny + 4, dime = 10, quarter = nickel * nickel } smallchange;
tuppence は値 2 を取得し、nickel は値 5、そして quarter は値 25 となります。
この初期化子は、(int 型への拡張後)正または負の整数値となる限り、任意の式が指定可能です。 通常、列挙子の値は一意となりますが、値を重複させることもできます。
enum 型は、int 型が使用できるところであればどこでも使用可能です。
enum days { sun, mon, tues, wed, thur, fri, sat } anyday; enum days payday; typedef enum days DAYS; DAYS *daysptr; int i = tues; anyday = mon; // OK *daysptr = anyday; // OK mon = tues; // ILLEGAL: mon is a constant
列挙型タグは、構造体タグや共有体タグと同じ名前空間を共有します。 列挙子は、通常の変数識別子と同一の名前空間を共有します。
int mon = 11; { enum days { sun, mon, tues, wed, thur, fri, sat } anyday; /* enumerator mon hides outer declaration of int mon */ struct days { int i, j;}; // ILLEGAL: days duplicate tag double sat; // ILLEGAL: redefinition of sat } mon = 12; // back in int mon scope
C++ の場合、クラス内で宣言された列挙子はクラスのスコープ内に限定されます。
C++ の場合、列挙型についてのオペレータは大抵オーバーロードすることができます。しかしながら、=、[ ]、( )、-> の各演算子は、メンバ関数としてオーバーロードされなければなりません。これらを enum としてオーバーロードすることができません。前置および後置インクリメント演算子をオーバーロードする方法については、例をを参照してください。