【发布时间】:2019-12-26 16:23:51
【问题描述】:
我正在研究enum,即C 中的关键字,用于定义枚举数列表,也称为枚举常量,编译器会为其分配有符号整数值。
Syntax:
enum identifier (optional) { enumerator-list }
我正在玩 enum 以了解编译器如何将整数分配给枚举列表中的枚举常量。
因此,当我使用enum 编写如下 3 个不同的程序时,我遇到了一些问题,这些问题都附在下面的每个程序中。
程序-1
#include <stdio.h>
#include <inttypes.h>
enum days_of_week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
int main(void) {
printf("%u %u %u %u %u %u %u\n", Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
return 0;
}
Output: 0 1 2 3 4 5 6,因为当没有为枚举常量显式分配整数时,编译器会自动根据zero-based indexing索引这些枚举常量。
程序-2
#include <stdio.h>
#include <inttypes.h>
enum days_of_week {Sunday, Monday, Tuesday = UINT16_MAX, Wednesday, Thursday, Friday, Saturday};
int main(void) {
printf("%u %u %u %u %u %u %u\n", Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
return 0;
}
Output: 0 1 65535 65536 65537 65538 65539,因为我已经将UINT16_MAX分配给Tuesday,在此之前,编译器在zero-based indexing的基础上将整数分配给枚举常量,在Tuesday之后,它根据Tuesday将整数分配给枚举常量分配给其前一个枚举常量 + 1 的整数。
程序-3
#include <stdio.h>
#include <inttypes.h>
enum days_of_week {Sunday, Monday, Tuesday = UINT32_MAX, Wednesday, Thursday, Friday, Saturday};
int main(void) {
printf("%u %u %u %u %u %u %u\n", Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
return 0;
}
编译器gcc 7.4.0 抛出一个错误,
enum_example_1.c:8:58: error: overflow in enumeration values
enum days_of_week {Sunday, Monday, Tuesday = UINT32_MAX, Wednesday, Thursday, Friday, Saturday};
-
由此得出结论,我可以分配给这些枚举常量的最大整数是
UINT16_MAX,但我有一个问题,这个值是否依赖于编译器/系统? -
编译器在哪一步将这些整数值分配给这些枚举器,我的意思是编译器是在编译时还是运行时分配这些值?
使用enum 优于宏的优点是:
- 它增加了源代码的可读性。
- 范围规则适用于
enum,但不适用于宏。 - 它会自动将有符号整数初始化为枚举器列表中的枚举器常量/标记。
除了上面列出的优点之外,使用enum 的其他优点是什么,以及在哪些用例中使用enums 优于宏?
【问题讨论】:
-
错误不是将
UINT32_MAX分配给Tuesday,而是将UINT32_MAX + 1分配给Wednesday。 -
"编译器是在编译时还是运行时分配这些值" - 编译器本身只在编译时出现,所以它决定在编译时分配什么值.
-
在您的特定编译器中,使用您的特定标志,是的。标准(see C11 p6.7.2.2)只要求“常量的类型与 char、有符号整数类型或无符号整数类型兼容”
-
在
Cenumenumcppreference 上有很好的解释/讨论。 -
@striker 不,在你的实现中最大值是
INT32_MAX,因为枚举是有符号的整数值。您应该使用%d(而不是%u)来打印分配给枚举常量的值。