在C语言中,使用枚举和整型变量有何不同?

6

什么是以下两个术语的区别:

enum week{Mon, Tue, Wed, Thur, Fri, Sat, Sun};
enum week day = Wed; 

enum week{Mon, Tue, Wed, Thur, Fri, Sat, Sun};
int day = Wed;

在C语言中,为什么要使用枚举类型的变量而不是普通的int类型变量呢?


1
可读性 - Alex Lop.
sizeof(enum week) 的大小可能小于 sizeof(int)。C 规范指出,枚举类型将与 char、有符号整数类型或无符号整数类型兼容。我想编译器可以使类型比 int 更宽,但由于所有枚举常量都是类型 int,因此没有必要使其比 int 更宽。 - Ian Abbott
3个回答

9

使用枚举的好处在于可以更清晰地表达你的意图,无论是对于阅读你代码的人还是编译器。例如,任何半靠谱的编译器都会警告你如果使用枚举时有不完整的 switch 案例:

switch (day) {
    case Mon: printf("Monday\n"); break;
    case Tue: printf("Tuesday\n"); break;
}

使用GCC(带有-Wall)会发出以下信息:

warning: enumeration value 'Wed' not handled in switch [-Wswitch]

7 |     switch (day) {
  |     ^~~~~~

如果day的类型是int,您将不会收到这个非常有用的警告。

2
也许值得明确指出的是:只有在省略了“default”情况时才会引发此警告,而不是在没有省略时。 - RobertS supports Monica Cellio

2
enum的标识符/常量具有int类型,因此可以将它们的值分配给int变量:

"枚举列表中的标识符被声明为具有int类型的常量,并且可以出现在任何允许使用这种类型的地方。"

C18,§6.7.7.2/3

但是,枚举的类型可能因实现而异:

"每个枚举类型都应与char、带符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,131) 但应能够表示枚举所有成员的值。"

C18,§6.7.7.2/4

因此,坚持使用enum类型可能会防止处理enum时出现任何类型问题,除了更易读之外。
另一件事是,如果它具有int类型,则很容易将另一个enum类型的常量分配给day
enum week {Mon, Tue, Wed, Thur, Fri, Sat, Sun};
enum month {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dez};

int day = Mar;

这段代码可以顺利编译。

当使用类型enum week代替day时,高级编译器可能会发出警告,并增加额外的安全层级。

enum week {Mon, Tue, Wed, Thur, Fri, Sat, Sun};
enum month {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};

enum week day = Mar;

例如,Clang 10.0会在没有任何其他标志的情况下抛出以下警告:
警告:隐式从枚举类型'enum month'转换为不同枚举类型'enum week' [-Wenum-conversion]
GCC 10.1需要使用-Wall-Wenum-conversion标志才能发出相同的警告。
此外,这篇文章涵盖了类似的问题,但我不会将其声明为重复: 此外,我还发现了这篇有趣的文章:

1
在C语言中,枚举是一种方便的方式,用于创建不一定有序的小型符号常量集。
它们不像Java或C#中那样是高级抽象。它们在内部是整数类型,并且因为C语言相信您始终知道自己在做什么,从不出错,所以当您混合使用枚举和整数类型时,它不会发生任何错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接