为什么枚举在 C 中有名称?

Why enums have names in C?

举个例子:

#include <stdio.h>


enum fruit  {APPLE, ORANGE, BANANA};
enum planet {EARTH, MARS, NEPTUNE};


void foo(enum fruit f)
{
    printf("%ld", f);
}


int main()
{
    enum planet p = MARS;

    foo(p); /* compiler doesn't complain */

    return 0;
}

如果代码可以编译,enum 有名字有什么意义?
这是我的 gcc 命令行:

gcc file.c -ansi -Wall -Wextra

据我所知,在 C99 中,enum 的 "tag"(您所说的名称,例如 fruit)是可选的。

所以

enum { BLACK, RED, GREEN, BLUE, YELLOW, WHITE };

可以接受(而且非常有用)

你甚至可以给出整数常数

enum { RFCHTTP =2068, RFCSMTP= 821 };

这是一种比

更现代的方式
#define RFCHTTP 2068
#define RFCSMTP 821

(特别是,当您使用调试信息进行编译时,调试器知道这样的 enum 值)

但在 C 中 enum 大多是整数值。在 C++ 中情况有所不同。

关于使用 %ld 格式控制转换 printfenum 参数可能是一些 undefined behavior (so you should be scared)。可能 gcc -Wall -Wextra 会警告你。

顺便说一句,GCC has many options. Read its chapter on Invoking GCC

我建议(在 2017 年)编码 C99 or C11,而不是旧的 1989 ANSI C。

即使您的代码可以编译,以下代码也不会

enum fruit *f = 0;
enum planet *p = f;

因为 enum fruitenum planet 是两个不同的不相关类型。

您在代码示例中观察到的仅仅是值上下文中两个枚举类型之间的隐式转换。您可以使用完全相同的方式将 double 值隐式转换为 int 类型。但是,我希望您不会以此为结论,认为没有理由区分 doubleint

如果你问 "Why do we have implicit conversions between unrelated enum types?" 你的问题会更有道理 "Why do we have implicit conversions between unrelated enum types?" 至于具有独特名称的枚举类型......有充分的理由。