Enumerations
一个 枚举类型 是一种独立的 类型 ,其值是其 底层类型 (见下文)的值,包含显式命名的常量( 枚举常量 )的值。
目录 |
语法
枚举类型通过以下 枚举说明符 作为 声明语法 中的 类型说明符 进行声明:
enum
attr-spec-seq
(可选)
identifier
(可选)
{
enumerator-list
}
|
(1) | ||||||||
enum
attr-spec-seq
(可选)
identifier
(可选)
:
type
{
enumerator-list
}
|
(2) | (自 C23 起) | |||||||
其中 enumerator-list 是一个逗号分隔的列表 (允许尾随逗号) (since C99) ,每个元素的形式为:
| 枚举常量 属性说明符序列 (可选) | (1) | ||||||||
枚举常量
属性说明符序列
(可选)
=
常量表达式
|
(2) | ||||||||
其中
| identifier , enumeration-constant | - | 通过此声明引入的标识符 |
| constant-expression | - | 整型常量表达式 其值可表示为 int 类型的值 (C23前) 。 若枚举具有固定底层类型,其值可表示为 type 类型的值 (C23起) |
| attr-spec-seq | - |
(C23)
可选的
属性
列表,
|
与 struct 或 union 类似,引入枚举类型及一个或多个枚举常量的声明,也可以声明该类型或派生自该类型的一个或多个对象。
enum color { RED, GREEN, BLUE } c = RED, *cp = &c; // 引入枚举类型 enum color // 整型常量 RED, GREEN, BLUE // 类型为 enum color 的对象 c // 类型为指向 enum color 指针的对象 cp
说明
每个出现在枚举说明符主体中的 枚举常量 都会成为封闭作用域中的 整数常量 其类型为 int (C23前) ,可在需要整数常量的场合使用(例如作为case标签或非VLA数组的大小)。
|
在处理枚举器列表中的每个枚举常量时,枚举常量的类型应为:
如果要相加的前一个枚举常量是有符号整数类型,则选择有符号整数类型。如果前一个枚举常量是无符号整数类型,则选择无符号整数类型。如果不存在能够表示新值的上述合适大小的整数类型,则该枚举没有能够表示其所有值的类型。 |
(since C23) |
如果 枚举常量 后跟 = 常量表达式 ,其值即为该常量表达式的值。如果 枚举常量 后未跟随 = 常量表达式 ,其值等于同一枚举中前一个枚举器的值加一。首个枚举器(若未使用 = 常量表达式 )的值为零。
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; // 正确 // color x = GREEN; // 错误:color不在普通命名空间中 typedef enum color color_t; color_t x = GREEN; // 正确
每个 无固定底层类型的 (C23起) 枚举类型都与以下类型之一 兼容 : char 、有符号整数类型或无符号整数类型 (不包括 bool 和位精确整数类型) (C23起) 。具体哪种类型与给定枚举类型兼容由实现定义,但无论选择何种类型,都必须能够表示该枚举的所有枚举值。 对于所有具有固定底层类型的枚举,其枚举类型与枚举的底层类型兼容。 (C23起)
|
对于无固定底层类型的枚举类型,其枚举成员类型在定义完成时为:
|
(since C23) |
| 所有枚举类型均具有底层类型。可通过枚举类型说明符显式指定底层类型,此时该类型即为固定底层类型。若未显式指定,则底层类型为该枚举的兼容类型——可能是有符号或无符号整数类型,或 char 类型。 | (since C23) |
枚举类型是整数类型,因此可以用于其他整数类型适用的任何场景,包括 隐式转换 和 算术运算符 。
enum { ONE = 1, TWO } e; long n = ONE; // 整型提升 double d = ONE; // 类型转换 e = 1.2; // 类型转换,e 当前值为 ONE e = e + 1; // e 当前值为 TWO
注释
enum Color; // 错误:C语言中枚举不支持前向声明 enum Color { RED, GREEN, BLUE };
枚举允许以比 #define 更便捷和结构化的方式声明命名常量;它们在调试器中可见,遵循作用域规则,并参与类型系统。
#define TEN 10 struct S { int x : TEN; }; // 正确
或
enum { TEN = 10 }; struct S { int x : TEN; }; // 同样有效
自 C23 起, constexpr 可用于实现相同目的:
constexpr int TEN = 10; struct S { int x : TEN; }; // 同样有效
此外,由于 结构体 或 联合体 在C语言中不会建立独立作用域,枚举类型及其枚举常量可以在结构体/联合体的成员声明中定义,且其作用域与所属结构体/联合体相同。
struct Element { int z; enum State { SOLID, LIQUID, GAS, PLASMA } state; } oxygen = { 8, GAS }; // 枚举类型 State 及其枚举常量在此处保持可见,例如: void foo(void) { enum State e = LIQUID; // 正确 printf("%d %d %d ", e, oxygen.state, PLASMA); // 输出 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 类型(页码:41)
-
- 6.7.2.2 枚举说明符(页码:117-118)
- C99标准(ISO/IEC 9899:1999):
-
- 6.2.5/16 类型(第35页)
-
- 6.7.2.2 枚举说明符(第105-106页)
- C89/C90 标准 (ISO/IEC 9899:1990):
-
- 3.1.2.5 类型
-
- 3.5.2.2 枚举说明符
关键词
参见
|
C++ 文档
关于
枚举声明
|