因此,通常枚举用于将“常量整数”组声明为另一种类型,代表某种东西。例如
enum Color {RED=0, BLUE, YELLOW};
这很清楚。但最近我在代码中遇到了以下内容。这是嵌入式系统的编译器。
enum State {DISABLED=0, ENABLED=!DISABLED};
它运作得很好。它表现为布尔类型。我的问题是,它(这种语法)是否符合ANSI标准?
如果它符合标准,那么为什么编译器会在内部定义像_Bool这样的布尔表示,然后在stdbool.h
(对于C语言)它们执行:
#define bool _Bool
... // here goes definitions of true and false
而不是
enum bool {false=0, true=!false};
哪个更干净?
答案 0 :(得分:6)
是的,这是符合标准的。
!DISABLED
是一个有效的常量表达式,这是enum
值所需的全部内容。
enum State {DISABLED=0, ENABLED= (!DISABLED)};
// ^^^^^^^^^^^
在引用DISABLED
的位置,编译器知道它的值,因此它可以计算从它派生的表达式的值,即!DISABLED
。这是写ENABLED=1
的一种奇特方式。
答案 1 :(得分:3)
根据C标准(6.2.1标识符范围)
每个枚举常量的范围都在...之后开始 枚举器列表中定义枚举器的外观
同样在C ++中有效(3.3.2声明点)
5普查员的声明点紧随其后 枚举器定义。[例如:
const int x = 12;
{ enum { x = x }; }
这里,枚举器x用常量的值初始化 x,即12.-末端示例]
因此,您可以在枚举中的下一个枚举数的定义中使用已定义的枚举器。
对于C类型_Bool
,它出现在C 99中。在此标准之前,在C中使用了显式常量或枚举。
定义像这样的枚举是没有意义的
enum bool {false=0, true!=false};
因为类型_Bool
已经有两个值0和1。
答案 2 :(得分:3)
是的,声明在C和C ++中完全有效且可移植。
在C和C ++中,这个:
enum State {DISABLED=0, ENABLED=!DISABLED};
完全等同于:
enum State {DISABLED=0, ENABLED=1};
以及:
enum State {DISABLED, ENABLED};
但出于不同的原因。
在C中,一元!
运算符生成类型为int
的结果,其值为0
(如果操作数不等于0
)或{{ 1}}(如果操作数等于1
)。 0
相当于!x
。 (当用作条件时,任何非零值都被视为true,但x == 0
和!
运算符总是产生==
或0
的结果。)枚举常量始终为1
类型;如果指定了值,则在必要时将其转换为int
。
(C在1999标准中添加了类型int
,但所有逻辑上产生" boolean"值的运算符仍然会产生_Bool
类型的结果。)
在C ++中,一元int
运算符的结果是!
类型。结果为bool
或false
,其中C true
运算符将分别产生!
或0
。与在C中一样,如果指定了值,则根据需要进行转换; 1
值bool
和false
分别转换为true
和0
。
在C中,枚举常量始终为1
类型。在C ++中,它们是枚举类型,在本例中为int
。
在同一类型声明中引用较早的枚举常量是合法的。在声明之后,每个枚举常量都会变得可见。
至于:
enum State
比
更清晰enum bool { false = 0, true = !false );
(在C中;它在C ++中是非法的),我恭敬地不同意。对于熟悉C的人来说,常量enum bool { false = 0, true = 1 };
是完全清楚的。将其重写为1
是没有用的。事实上,当!false
不可用时(这些日子很少见),我已经使用过:
<stdbool.h>
typedef enum { false, true } bool;
和false
将被赋予正确的值这一事实恕我直言。
至于为什么C99没有像这样使用true
定义,我怀疑它是因为每个枚举类型都与某些实现定义的整数类型兼容。 (对于gcc,它通常是enum
或unsigned int
。)委员会希望int
是一个转换级别低于任何其他整数类型的不同类型。 (并且他们无法在不破坏现有代码的情况下使_Bool
成为关键字。)