枚举
枚举类型是一种独特的类型,其值为其底层类型(见下文)的值,包括显式命名的常量(枚举常量)的值。
目录 |
[编辑] 语法
枚举类型在声明语法中,使用以下枚举说明符作为类型说明符进行声明:
enum 属性说明符序列 (可选) 标识符 (可选) { 枚举器列表 } |
(1) | ||||||||
enum 属性说明符序列 (可选) 标识符 (可选) : 类型 { 枚举器列表 } |
(2) | (自 C23 起) | |||||||
其中枚举器列表是一个逗号分隔的列表(允许尾随逗号)(C99 起),每个枚举器的形式为:
枚举常量 属性说明符序列 (可选) | (1) | ||||||||
枚举常量 属性说明符序列 (可选) = 常量表达式 |
(2) | ||||||||
其中
标识符,枚举常量 | - | 由该声明引入的标识符 |
常量表达式 | - | 整数常量表达式 其值可表示为int类型的值(C23 前)。如果枚举具有固定底层类型,则表示为类型的值(C23 起) |
属性说明序列 | - | (C23)属性的可选列表,
|
与结构体或联合体一样,引入枚举类型和一个或多个枚举常量的声明也可以声明该类型或其派生类型的一个或多个对象。
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
[编辑] 解释
出现在枚举说明符体中的每个枚举常量都成为封闭作用域中的整型常量,其类型为int(C23 前),并且可以在需要整型常量时使用(例如,作为case标签或非VLA数组大小)。
在处理枚举器列表中的每个枚举常量时,枚举常量的类型应为:
如果正在添加的上一个枚举常量是有符号整数类型,则选择有符号整数类型。如果上一个枚举常量是无符号整数类型,则选择无符号整数类型。如果没有上述适当大小的整数类型可以表示新值,则该枚举没有能够表示其所有值的类型。 |
(自 C23 起) |
如果枚举常量后跟= 常量表达式,则其值为该常量表达式的值。如果枚举常量后没有跟= 常量表达式,则其值为同一枚举中前一个枚举器值加1。第一个枚举器(如果它不使用= 常量表达式)的值为零。
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
如果使用标识符本身,它将成为标签命名空间中枚举类型的名称,并且需要使用关键字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
每个没有固定底层类型(C23 起)的枚举类型与以下之一兼容: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
[编辑] 注意
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
或
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++ 文档,关于枚举声明
|