此声明:
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++的规则略有不同。)
所有冰雹苹果/ LLVM。我相信这3个编译器几乎涵盖了所有主要的操作系统(iOS,Android,Microsoft,OSX),但是还有其他有趣的更新。我相信以前的帖子提到icc,但我没有访问。 – 2015-02-12 17:57:02