因此,通常枚举用于将"常量整数"组声明为另一种类型,代表某种东西.例如.
enum Color {RED=0, BLUE, YELLOW};
Run Code Online (Sandbox Code Playgroud)
这很清楚.但最近我在代码中遇到了以下内容.这是嵌入式系统的编译器.
enum State {DISABLED=0, ENABLED=!DISABLED};
Run Code Online (Sandbox Code Playgroud)
它运作得很好.它表现为布尔类型.我的问题是,它(这种语法)是否符合ANSI标准?
如果它符合标准,那么为什么编译器会在内部定义像_Bool这样的布尔表示,然后在stdbool.h(对于C语言)它们:
#define bool _Bool
... // here goes definitions of true and false
Run Code Online (Sandbox Code Playgroud)
代替
enum bool {false=0, true=!false};
Run Code Online (Sandbox Code Playgroud)
哪个更干净?
是的,这符合标准.
!DISABLED是一个有效的常量表达式,它是enum值所需的全部内容.
enum State {DISABLED=0, ENABLED= (!DISABLED)};
// ^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
在DISABLED引用的位置,编译器知道它的值,因此它可以计算从它派生的表达式的值,即!DISABLED.这是一种奇特的写作方式ENABLED=1.
是的,该声明在 C 和 C++ 中都是完全有效且可移植的。
在 C 和 C++ 中,都是这样的:
enum State {DISABLED=0, ENABLED=!DISABLED};
Run Code Online (Sandbox Code Playgroud)
与此完全等效:
enum State {DISABLED=0, ENABLED=1};
Run Code Online (Sandbox Code Playgroud)
对此:
enum State {DISABLED, ENABLED};
Run Code Online (Sandbox Code Playgroud)
但出于微妙不同的原因。
在 C 中,一元!运算符生成 类型的结果int,其值为0(如果操作数不等于0)或1(如果操作数等于0)。!x相当于x == 0. (任何非零值在用作条件时都被视为 true,但!and==运算符等始终产生完全0或的结果1。)枚举常量始终为 类型int;如果指定了一个值,则int根据需要将其转换为。
(C 在 1999 年标准中添加了类型_Bool,但所有产生逻辑“布尔”值的运算符仍然产生类型的结果int。)
在 C++ 中,一元运算符的结果的!类型为bool。结果是falseor ,true其中 C 的!运算符将分别产生0or 1。与 C 中一样,如果指定了一个值,则会根据需要进行转换;值bool和分别false转换true为0和。1
在 C 中,枚举常量始终为 类型int。在 C++ 中,它们是枚举类型,在本例中是enum State。
在同一类型声明中引用较早的枚举常量是合法的。每个枚举常量在声明后变得可见。
至于类似的事情:
enum bool { false = 0, true = !false );
Run Code Online (Sandbox Code Playgroud)
比
enum bool { false = 0, true = 1 };
Run Code Online (Sandbox Code Playgroud)
(在 C 中;在 C++ 中这是非法的),我谨表示不同意。1对于任何熟悉 C 语言的人来说,该常量都是非常清楚的。将其重写为!false没有任何帮助。事实上,当<stdbool.h>不可用时(现在很少见),我使用过:
typedef enum { false, true } bool;
Run Code Online (Sandbox Code Playgroud)
false恕我直言,和true将被赋予正确值的事实是非常明显的。
至于为什么C99没有使用enum这样的定义,我怀疑是因为每个枚举类型都与某些实现定义的整数类型兼容。(对于 gcc,通常是unsigned int或int。)委员会希望_Bool成为一种转换等级低于任何其他整数类型的独特类型。(而且他们无法bool在不破坏现有代码的情况下创建关键字。)