das*_*ght 36
就可读性而言,枚举比宏更好,因为相关值被组合在一起.另外,enum定义一个新类型,因此程序的读者可以更容易地确定可以传递给相应参数的内容.
相比
#define UNKNOWN 0
#define SUNDAY 1
#define MONDAY 2
#define TUESDAY 3
...
#define SATURDAY 7
Run Code Online (Sandbox Code Playgroud)
至
typedef enum {
UNKNOWN
, SUNDAY
, MONDAY
, TUESDAY
, ...
, SATURDAY
} Weekday;
Run Code Online (Sandbox Code Playgroud)
阅读这样的代码要容易得多
void calendar_set_weekday(Weekday wd);
Run Code Online (Sandbox Code Playgroud)
比这个
void calendar_set_weekday(int wd);
Run Code Online (Sandbox Code Playgroud)
因为你知道哪些常数可以通过.
Zif*_*ion 19
宏是预处理器的事情,编译后的代码不知道您创建的标识符.在代码到达编译器之前,它们已经被预处理器替换.枚举是编译时实体,编译后的代码保留有关该符号的完整信息,该信息在调试器(和其他工具)中可用.
喜欢枚举(当你可以).
Kaz*_*Kaz 11
在C中,最好使用枚举来实际枚举:当某个变量可以包含多个值中的一个时,可以给出名称.枚举的一个优点是编译器可以执行超出语言要求的某些检查,例如枚举类型上的switch语句不会丢失其中一种情况.枚举标识符也传播到调试信息中.在调试器中,您可以将标识符名称视为枚举变量的值,而不仅仅是数值.
枚举可以仅用于创建整数类型的符号常量的副作用.例如:
enum { buffer_size = 4096 }; /* we don't care about the type */
Run Code Online (Sandbox Code Playgroud)
这种做法并没有那么广泛.首先,buffer_size它将用作整数而不是枚举类型.调试器将不会呈现4096到buffer_size,因为该值将不被表示为枚举类型.如果你申报一些,char array[max_buffer_size];那么sizeof array就不会显示为buffer_size.在这种情况下,枚举常量在编译时消失,因此它也可能是一个宏.并且存在缺点,例如无法控制其确切类型.(在某些情况下,翻译的预处理阶段的输出被捕获为文本可能会有一些小优势.宏将变为4096,而buffer_size将保持为buffer_size).
预处理器符号让我们这样做:
#define buffer_size 0L /* buffer_size is a long int */
Run Code Online (Sandbox Code Playgroud)
请注意,由C的各种值<limits.h>就像UINT_MAX是预定义和不枚举符号,具有充分的理由,因为这些标识符需要有一个精确确定的类型.预处理器符号的另一个优点是我们可以测试它的存在,甚至根据它的值做出决定:
#if ULONG_MAX > UINT_MAX
/* unsigned long is wider than unsigned int */
#endif
Run Code Online (Sandbox Code Playgroud)
当然,我们也可以测试枚举常量,但不能以我们可以根据结果更改全局声明的方式.
枚举也不适用于位掩码:
enum modem_control { mc_dsr = 0x1, mc_dtr = 0x2, mc_rts = 0x4, ... }
Run Code Online (Sandbox Code Playgroud)
它只是没有意义,因为当值与按位OR组合时,它们会产生一个超出类型的值.这样的代码也会引起头疼,如果它被移植到C++,它有(更多)类型安全的枚举.
请注意,宏和枚举之间存在一些差异,这些属性中的任何一个都可能使它们(un)适合作为特定常量.
sizeof(int).对于小值数组(最多可以说CHAR_MAX),您可能需要一个char foo[]而不是一个enum foo[]数组.enum funny_number { PI=3.14, E=2.71 }.实际上,差别不大。它们同样可以用作程序中的常量。有些人可能出于风格原因更喜欢其中一种,但我想不出任何技术原因来选择其中一种。
一个区别是宏允许您控制相关常量的整数类型。但 anenum将使用int.
#define X 100L
enum { Y = 100L };
printf("%ld\n", X);
printf("%d\n", Y); /* Y has int type */
Run Code Online (Sandbox Code Playgroud)