C Language
列挙型
サーチ…
備考
列挙型はenum
キーワードとオプションの識別子で構成され、その後に中括弧で囲まれた列挙子リストが続きます。
識別子はint
型です。
enumerator-listには少なくとも1つの列挙子要素があります。
列挙子は、オプションでint
型の定数式に "割り当て"られることがあります。
列挙子は定数であり、 char
、符号付き整数または符号なし整数のいずれかと互換性があります。これまでに使用されているのは実装定義です。いずれの場合でも、使用される型は、問題の列挙に対して定義されたすべての値を表すことができなければなりません。
列挙子に定数式が割り当てられておらず、それが列挙子リストの第1のエントリであれば、それは0
値をとり、そうでなければ、 列挙子リストの前のエントリの値に1を加えた値をとる。
複数の「代入」を使用すると、同じ列挙の異なる列挙子が同じ値を持つことがあります。
単純な列挙
列挙は、ユーザー定義のデータ型であり、整数定数で構成され、各整数定数には名前が付けられます。キーワードenum
は、列挙型を定義するために使用されます。
int
またはstring/ char*
かわりにenum
を使用すると、コンパイル時のチェックが増え、無効な定数が渡されるのを避けることができます。
例1
enum color{ RED, GREEN, BLUE };
void printColor(enum color chosenColor)
{
const char *color_name = "Invalid color";
switch (chosenColor)
{
case RED:
color_name = "RED";
break;
case GREEN:
color_name = "GREEN";
break;
case BLUE:
color_name = "BLUE";
break;
}
printf("%s\n", color_name);
}
main関数が次のように定義されている(たとえば):
int main(){
enum color chosenColor;
printf("Enter a number between 0 and 2");
scanf("%d", (int*)&chosenColor);
printColor(chosenColor);
return 0;
}
例2
(この例では、C99以降に標準化されている指定された初期化子を使用しています。)
enum week{ MON, TUE, WED, THU, FRI, SAT, SUN };
static const char* const dow[] = {
[MON] = "Mon", [TUE] = "Tue", [WED] = "Wed",
[THU] = "Thu", [FRI] = "Fri", [SAT] = "Sat", [SUN] = "Sun" };
void printDayOfWeek(enum week day)
{
printf("%s\n", dow[day]);
}
範囲チェックを使用した同じ例:
enum week{ DOW_INVALID = -1,
MON, TUE, WED, THU, FRI, SAT, SUN,
DOW_MAX };
static const char* const dow[] = {
[MON] = "Mon", [TUE] = "Tue", [WED] = "Wed",
[THU] = "Thu", [FRI] = "Fri", [SAT] = "Sat", [SUN] = "Sun" };
void printDayOfWeek(enum week day)
{
assert(day > DOW_INVALID && day < DOW_MAX);
printf("%s\n", dow[day]);
}
Typedef enum
列挙に名前を付けるいくつかの可能性と規則があります。 1つは、 enum
キーワードの直後にタグ名を使用することです。
enum color
{
RED,
GREEN,
BLUE
};
この列挙は、キーワードとタグで常に次のように使用する必要があります。
enum color chosenColor = RED;
enum
宣言するときにtypedef
直接使用すると、タグ名を省略してenum
キーワードなしでtypeを使用できます。
typedef enum
{
RED,
GREEN,
BLUE
} color;
color chosenColor = RED;
しかし、この後者の場合、タグ名を定義に使用していないため、 enum color
として使用することはできません。一般的な規則の1つは、 enum
キーワードの有無にかかわらず同じ名前を使用できるように、両方を使用することです。これは、 C ++と互換性があるという特別な利点があります
enum color /* as in the first example */
{
RED,
GREEN,
BLUE
};
typedef enum color color; /* also a typedef of same identifier */
color chosenColor = RED;
enum color defaultColor = BLUE;
関数:
void printColor()
{
if (chosenColor == RED)
{
printf("RED\n");
}
else if (chosenColor == GREEN)
{
printf("GREEN\n");
}
else if (chosenColor == BLUE)
{
printf("BLUE\n");
}
}
typedef
詳細についてはTypedefを参照してください。
重複値を持つ列挙型
列挙値は一意である必要はありません。
#include <stdlib.h> /* for EXIT_SUCCESS */
#include <stdio.h> /* for printf() */
enum Dupes
{
Base, /* Takes 0 */
One, /* Takes Base + 1 */
Two, /* Takes One + 1 */
Negative = -1,
AnotherZero /* Takes Negative + 1 == 0, sigh */
};
int main(void)
{
printf("Base = %d\n", Base);
printf("One = %d\n", One);
printf("Two = %d\n", Two);
printf("Negative = %d\n", Negative);
printf("AnotherZero = %d\n", AnotherZero);
return EXIT_SUCCESS;
}
サンプルは以下を印刷します:
Base = 0
One = 1
Two = 2
Negative = -1
AnotherZero = 0
typenameのない列挙定数
列挙型は、名前を付けずに宣言することもできます:
enum { buffersize = 256, };
static unsigned char buffer [buffersize] = { 0 };
これにより、この例のように配列長として使用できるint
型のコンパイル時定数を定義することができます。