此声明:
enum fruit {
apple,
orange
};
声明了三件事:一个名为 enum fruit 的类型,以及两个名为 apple 和 orange 的枚举数。
enum fruit 实际上是一个独特的类型。它与一些实现定义的整数类型兼容;例如,enum fruit 可能与 int、char 兼容,或者甚至与 unsigned long long(如果实现选择)兼容,只要所选类型可以表示所有值。
另一方面,枚举数是int 类型的常量。事实上,有一个常见的技巧是使用裸 enum 声明来声明 int 常量而不使用预处理器:
enum { MAX = 1000 };
是的,这意味着常量apple,即使它被声明为enum fruit 定义的一部分,实际上并不是enum fruit 类型。造成这种情况的原因是历史性的。是的,将枚举数设为类型的常量可能更有意义。
在实践中,这种不一致并不重要。在大多数情况下,离散类型(即整数和枚举类型)在很大程度上是可互换的,并且隐式转换通常会做正确的事情。
enum fruit { apple, orange };
enum fruit obj; /* obj is of type enum fruit */
obj = orange; /* orange is of type int; it's
implicitly converted to enum fruit */
if (obj == orange) { /* operands are converted to a common type */
/* ... */
}
但结果是,如您所见,如果您使用与一种枚举类型相关联的常量,而您的意思是使用不同的枚举类型,编译器可能不会警告您。
获得强类型检查的一种方法是将数据包装在结构中:
enum fruit { /* ... */ };
enum color { /* ... */ };
struct fruit { enum fruit f; };
struct color { enum color c; };
struct fruit 和struct color 是不同且不兼容的类型,它们之间没有隐式(或显式)转换。缺点是您必须明确引用.f 或.c 成员。 (大多数 C 程序员只是指望他们一开始就能把事情做好——结果好坏参半。)
(typedef 不会为您提供强类型检查;尽管有名称,但它会为现有类型创建别名,而不是新类型。)
(C++中的规则有些不同。)