枚举名称的用途是啥?
Posted
技术标签:
【中文标题】枚举名称的用途是啥?【英文标题】:What purpose does the enum name serve?枚举名称的用途是什么? 【发布时间】:2013-04-15 06:14:55 【问题描述】: 枚举是“命名的常量集合”:enum MyType_e A, B, C;
这些常量在枚举的父范围内声明,即如果枚举在文件范围内声明,并且未命名,则相当于一系列例如#define A 0
语句
枚举常量的底层类型总是int
,即int var = A
是完全合法的,虽然var
不是MyType_e
类型
那么枚举 name 的用途是什么?
编辑 根据下面的 cmets,我对枚举的理解似乎存在很大缺陷。 枚举与#define 语句无关。 Enums are resolved at compile time,并且是类型化的。
【问题讨论】:
您能指出您从中获得这些想法的 C 标准部分吗? C 没有名称空间(至少在我认为您在这里所指的意义上),枚举的底层类型也不总是 int。还是来自较新的 C 标准? @Anonymous:C99 标准的 6.7.2.2/3 表示“枚举器列表中的标识符被声明为类型为int
... 的常量”。不过,这有点令人困惑,因为它后来继续说,“每个枚举类型都应与char
、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的...... ." 所以常量本身是int
,但enum
类型本身可能不是。通过“命名空间”,我认为 Vorac 的意思是“范围”。
@jamesdlin,匿名:我将问题修改为不那么不正确。枚举的依赖于实现的类型对我来说是新闻。很有趣。
"这些常量...父作用域...并且未命名,是等价的。" “是”应该是“如果”吗?什么是未命名的范围?我认为问题是关于 C++ 而不是 C 中的枚举,并且将“命名空间”更正为“范围”是一个错误。
另外,我不明白枚举等同于一系列#define
语句的意义。这个问题有很多赞成票,但它包含根本错误的假设。
【参考方案1】:
使用enum
类型传达意图。
假设您有一个将enum
常量作为参数的函数。
void foo(enum MyType_e e);
是关于什么是有效输入的自我记录,但是:
void foo(int e);
不是。此外,如果您尝试为 enum
类型传递不兼容的值,编译器可能会发出警告。来自 ISO C99 规范的附录 I(“常见警告”):
一个实现可能会在许多情况下产生警告......以下是一些更常见的情况。
[...]
为枚举类型的对象赋予值,而不是通过分配作为该类型成员的枚举常量、具有相同类型的枚举变量或返回相同值的函数的值枚举类型 (6.7.2.2)。
如果您在 enum
类型上使用 switch
但忽略处理其所有常量并且没有 default
大小写,某些编译器(例如 gcc)甚至可能会生成警告。
【讨论】:
我不喜欢用无用的 cmets 把答案弄得一团糟,但这确实是一个很好的答案,我不知道你能做到这一点。不过,有趣的是,如果您尝试为枚举类型传递不兼容的值,编译器将如何“发出警告”。当然这只会在编译器视图之外的运行时知道? @DeanP 当我写“如果您尝试为enum
类型传递不兼容的值时,编译器可能会发出警告”,我的意思是可以静态确定为对 enum
无效的值.例如,如果您有 enum MyEnum a, b, c ; void foo(enum MyEnum e);
并尝试使用 foo(100)
调用它,那显然是错误的,如果使用 int
参数声明函数,您将不会收到任何编译时警告。【参考方案2】:
虽然你可以完美地说
int var = A
变种
enum mytype var = A
出于文档原因更好。
【讨论】:
当函数的参数类型为enum mytype
时,将1 分配给声明为enum mytype var
的var
或传递1 怎么样?
@AlexeyFrunze 没有什么能阻止你这样做。
你至少可以得到一个有用的警告。【参考方案3】:
上面的答案是好的和正确的,我只想补充一点,某些调试器能够在悬停或监视枚举类型变量时显示枚举名称。这确实有助于清晰,尤其是当枚举用于状态机实现中的状态时。
【讨论】:
以上是关于枚举名称的用途是啥?的主要内容,如果未能解决你的问题,请参考以下文章