为什么枚举在C中有名称?
让我们以下面的例子为例:为什么枚举在C中有名称?,c,enums,c89,C,Enums,C89,让我们以下面的例子为例: #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 */
#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;
}
另外,在C99中,enum
的“标签”(您称之为名称,例如fruit
)是可选的
所以
可以接受(并且非常有用)
你甚至可以给出积分常数
enum { RFCHTTP =2068, RFCSMTP= 821 };
哪一种方式比其他方式更现代
#define RFCHTTP 2068
#define RFCSMTP 821
(特别是,当使用调试信息编译时,调试器知道此类enum
值)
但是在Cenum
中,大部分是整数值。C++中的情况不同。
关于将%ld
格式控制转换用于printf
和enum
参数,这可能是一些原因(因此您应该这样做)。可能gcc-Wall-Wextra
会警告您
顺便说一句,有很多选择。阅读它的一章
我建议(在2017年)为旧的1989 ANSI C而不是旧的ANSI C编码。即使您的代码可以编译,以下内容也不会
enum fruit *f = 0;
enum planet *p = f;
因为enum水果
和enum行星
是两种不同的不相关类型
您在代码示例中观察到的只是值上下文中两个枚举类型之间的隐式转换。以完全相同的方式,可以将double
值隐式转换为int
类型。但是,我希望,您不要利用这一点得出结论,认为没有理由区分double
和int
如果您问“为什么我们在不相关的枚举类型之间有隐式转换?”以及具有不同名称的枚举类型,您的问题将更有道理。。。这有很好的理由。不清楚你的问题是什么。但是您的代码调用了未定义的行为,任何最近的编译器/库都应该在
printf
中警告错误的转换类型说明符。为什么从main返回一个错误呢?在C语言中,枚举基本上只是符号整数常量。但是,使用错误的枚举类型在技术上是未定义的行为。请阅读您最喜欢的C语言书中有关枚举的内容。一切都在那里解释。首先使用书本和大脑,然后使用键盘编译器之所以不抱怨,不是因为函数调用正确,而是因为long
与系统上的int
大小相同,并且enum
值的类型为int
。如果添加第二个参数,并同时打印这两个参数,即使行为未定义,它们也会工作。但是如果long
大于int
,可能会得到编译器警告,并确定错误的结果..感谢您的回答,首先我使用选项-ansi
进行编译,该选项将我的代码限制为C89(参见标记)。第二个问题是:“我为什么要使用%d
说明符来打印枚举
”?原因%d
用于打印整数,枚举是整数类型,不一定是整数,使用%ld
不是更合适吗?我认为在2017年使用1989标准对于一种既有1999标准又有2011标准(两者都优于ANSI标准)的语言是不合理的,我不使用它,在我继续之前,我只是想尽可能地了解它,因为到处赞美K&R图书是没有意义的,然后告诉人们远离那个版本的CAnd请,如果可以的话,我还在等待关于说明符的问题的答案。
#define RFCHTTP 2068
#define RFCSMTP 821
enum fruit *f = 0;
enum planet *p = f;