C语言 c枚举(typedef enum)的重要性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34323130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
The importance of c enumeration (typedef enum)
提问by Asperger
I recently saw this in an answer that was posted for me:
我最近在为我发布的答案中看到了这一点:
typedef enum
{
NO_OP,
ADDITION,
} operator_t;
int main()
{
operator_t operator = NO_OP;
}
What is typedef enum and why should we use it? I googled and found the following: http://www.programiz.com/c-programming/c-enumeration
什么是 typedef 枚举,为什么要使用它?我用谷歌搜索并发现以下内容:http: //www.programiz.com/c-programming/c-enumeration
Right now it sounds slightly too technical for me so I dont think I understand what is going on or why one would use that.
现在这对我来说听起来有点太技术了,所以我认为我不明白发生了什么或为什么人们会使用它。
Bonus (optional): What type of variable is the operator_t?
奖励(可选):operator_t 是什么类型的变量?
回答by paulsm4
It's definitely not "too technical".
The basic reason to have "enums" is to avoid "magic numbers":
Let's say you have three "states": STOP, CAUTION and GO. How do you represent them in your program?
One way is to use the string literals "STOP", "CAUTION" and "GO". But that has a lot of problems - including the fact that you can't use them in a C "switch/case" block.
Another way is to Map" them to the integer values "0", "1" and "2". This has a lot of benefits. But seeing "STOP" in your code is a lot more meaningful than seeing a "0". Using "0" in your code like that is an example of a "magic number". Magic numbers are Bad: you want to use a "meaningful name" instead.
这绝对不是“太技术化”。
拥有“枚举”的基本原因是避免“幻数”:
假设您有三个“状态”:STOP、CAUTION 和 GO。你如何在你的程序中代表他们?
一种方法是使用字符串文字“STOP”、“CAUTION”和“GO”。但这有很多问题——包括你不能在 C 的“switch/case”块中使用它们的事实。
另一种方法是将它们映射到整数值“0”、“1”和“2”。这有很多好处。但是在代码中看到“STOP”比看到“0”更有意义。像这样在代码中使用“0”是“幻数”的一个例子。幻数是不好的:你想使用“有意义的名字”来代替。
Before enums were introduced in the language, C programmers used macros:
在语言中引入枚举之前,C 程序员使用宏:
#define STOP 0
#define CAUTION 1
#define GO 2
A better, cleaner approach in modern C/C++ is to use an enum instead:
现代 C/C++ 中更好、更简洁的方法是使用枚举:
enum traffic_light_states {
STOP,
CAUTION,
GO
};
Using a "typedef" just simplifies declaring a variable of this type:
使用“typedef”只是简化了声明这种类型的变量:
typedef enum {
STOP,
CAUTION,
GO
} traffic_light_states_t ;
回答by Ryan Fitzpatrick
typedefis used to define an alternative name for an existing type. The enumcould have declared like this:
typedef用于为现有类型定义替代名称。该enum会宣布这样的:
enum operator_t
{
NO_OP,
ADDITION,
};
and then you could declare a variable of this type like so:
然后你可以像这样声明一个这种类型的变量:
enum operator_t x = NO_OP;
This is kind of verbose so you would use typedefto define a shorter alias for this type:
这有点冗长,因此您可以使用typedef此类型定义较短的别名:
typedef enum operator_t operator_t;
This defines operator_tto mean the type enum operator_tallowing you to initialize a variable like so:
这定义operator_t为enum operator_t允许您像这样初始化变量的类型:
operator_t x = NO_OP;
This syntax:
此语法:
typedef enum
{
NO_OP,
ADDITION,
} operator_t;
does the whole process in one step, so it defines an (untagged or tagless) enumtype and gives it the alias operator_t.
一步完成整个过程,因此它定义了一个(无标签或无标签)enum类型并给它别名operator_t。
Bonus: operator_tis an enumdata type; read more about it here: https://en.wikipedia.org/wiki/Enumerated_type
奖励:operator_t是一种enum数据类型;在此处阅读更多相关信息:https: //en.wikipedia.org/wiki/Enumerated_type
回答by John Bollinger
What is typedef enum and why should we use it?
什么是 typedef 枚举,为什么要使用它?
There are two different things going on there: a typedef and an enumerated type (an "enum"). A typedef is a mechanism for declaring an alternative name for a type. An enumerated type is an integer type with an associated set of symbolic constants representing the valid values of that type.
那里有两种不同的东西:typedef 和枚举类型(“enum”)。typedef 是一种为类型声明替代名称的机制。枚举类型是一个整数类型,带有一组相关联的符号常量,表示该类型的有效值。
Taking the enum first, the full form of an enum declaration consists of the enumkeyword, followed by a tag by which that particular enum will be identified, followed by the symbolic enum constants in curly brackets. By default, the enum constants correspond to consecutive integer values, starting at zero. For example:
首先以枚举为例,枚举声明的完整形式由enum关键字、后跟标识该特定枚举的标签、大括号中的符号枚举常量组成。默认情况下,枚举常量对应于从零开始的连续整数值。例如:
enum operator {
NO_OP,
ADDITION
};
As you can see, it has some similarities to a structdeclaration, and like a structdeclaration, variables of that enumerated type can be declared in the same statement:
如您所见,它与struct声明有一些相似之处,并且与struct声明一样,该枚举类型的变量可以在同一语句中声明:
enum operator {
NO_OP,
ADDITION
} op1, op2, op3;
or they can be declared later, by referencing the enum's tag:
或者它们可以稍后通过引用枚举的标签来声明:
enum operator op4, op5;
Also like a structdeclaration, the tag can be omitted, in which case the enumerated type cannot be referenced elsewhere in the source code (but any declared variables of that type are still fine):
也像struct声明一样,可以省略标记,在这种情况下,枚举类型不能在源代码的其他地方引用(但该类型的任何声明变量仍然可以):
enum {
NO_OP,
ADDITION
} op1, op2, op3;
Now we get to the typedef. As I already wrote, a typedef is a means to declare an alternative name for a type. It works by putting the typedefkeyword in front of something that would otherwise be a variable declaration; the symbol that would have been the variable name is then the alternative name for the type. For instance this ...
现在我们进入 typedef。正如我已经写过的,typedef 是一种为类型声明替代名称的方法。它的工作原理是将typedef关键字放在变量声明的前面;本来是变量名的符号就是该类型的替代名称。比如这个...
typedef unsigned long long int ull_t;
declares ull_tto be an alternative name for type unsigned long long int. The two type names can thereafter be used interchangeably (within the scope of the typedef declaration).
声明ull_t为 type 的替代名称unsigned long long int。这两个类型名称此后可以互换使用(在 typedef 声明的范围内)。
In your case, you have
在你的情况下,你有
typedef enum
{
NO_OP,
ADDITION,
} operator_t;
which declares operator_tas an alias for the tagless enumerated type given. Declaring a typedef in this way makes the enum usable elsewhere, via the typedef name, even though the enum is tagless. This is a fairly common mechanism for declaring a shorthand name for an enumerated type, and an analogous technique is common for structs, too.
它声明operator_t为给定的无标记枚举类型的别名。以这种方式声明 typedef 使枚举可以通过 typedef 名称在其他地方使用,即使枚举是无标记的。这是为枚举类型声明速记名称的一种相当常见的机制,类似的技术对于结构也很常见。
Bonus (optional): What type of variable is the operator_t?
奖励(可选):operator_t 是什么类型的变量?
As I explained, the operator_tis not a variable, it is a type. In particular, it is an enumerated type, and the symbols NO_OPand ADDITIONrepresent values of that type.
正如我所解释的,这operator_t不是一个变量,它是一个类型。特别是,它是一个枚举类型,并且符号NO_OP和ADDITION表示该类型的值。
回答by Mini Mithi
Wikipedia has a good discussion of what a typedef is
维基百科对什么是 typedef 进行了很好的讨论
typedef is a keyword in the C and C++ programming languages. The purpose of typedef is to form complex types from more-basic machine types1and assign simpler names to such combinations. They are most often used when a standard definition or declaration is cumbersome, potentially confusing, or likely to vary from one implementation to another. See this page for a detailed discussion of Typedef in Wikipedia
typedef 是 C 和 C++ 编程语言中的关键字。typedef 的目的是从更基本的机器类型1形成复杂类型,并为这些组合分配更简单的名称。当标准定义或声明很麻烦、可能令人困惑或可能因一种实现而异时,它们最常使用。 有关 Wikipedia 中 Typedef 的详细讨论,请参阅此页面
Enumerated Types allow us to create our own symbolic names for a list of related ideas.
枚举类型允许我们为相关的想法列表创建我们自己的符号名称。
Given the example you gave I'm guessing you can use enum to select which arithmetic operation to use for a particular set of variables.
鉴于您给出的示例,我猜您可以使用 enum 来选择用于特定变量集的算术运算。
The following example code should give you a good idea on what enum is useful for.
下面的示例代码应该让您对 enum 的用途有一个很好的了解。
enum ARITHMETIC_OPERATION {ADD, SUBTRACT, MULTIPLY};
int do_arithmetic_operation(int a, int b, enum ARITHMETIC_OPERATION operation){
if(operation == ADD)
return a+b;
if(operation == SUBTRACT)
return a-b;
if(operation == MULTIPLY)
return a*b;
}
If you didn't have enum, you would do something like this instead:
如果你没有枚举,你会做这样的事情:
#DEFINE ADD 0
#DEFINE SUBTRACT 1
#DEFINE MULTIPLY 2
int do_artithmetic_operation(int a, int b, int operation);
This alternative is less readable, because operation is not really an integer but a symbolic type that represents an arithmetic operation that is either ADD, MULTIPLY, or SUBTRACT.
这种替代方法的可读性较差,因为操作实际上不是整数,而是表示算术运算的符号类型,即 ADD、MULTIPLY 或 SUBTRACT。
The following links provide good discussions and sample code that uses Enum.
以下链接提供了使用 Enum 的良好讨论和示例代码。
http://www.cs.utah.edu/~germain/PPS/Topics/C_Language/enumerated_types.html
http://www.cs.utah.edu/~germain/PPS/Topics/C_Language/enumerated_types.html
http://www.cprogramming.com/tutorial/enum.html
http://www.cprogramming.com/tutorial/enum.html
http://cplus.about.com/od/introductiontoprogramming/p/enumeration.htm
http://cplus.about.com/od/introductiontoprogramming/p/enumeration.htm
回答by John Hammond
typedef and enum are two different concepts. You can rewrite the code like this:
typedef 和 enum 是两个不同的概念。你可以像这样重写代码:
enum operator
{
NO_OP,
ADDITION
};
typedef enum operator operator_t;
The first statement declares an enumeration called operator, with two values. The second statement declares that the enumeration operatoris now alsoto be known as the type operator_t.
第一条语句声明了一个名为 的枚举operator,具有两个值。第二个语句声明枚举operator现在也称为类型operator_t。
The syntax does allow to combine these two statements into one statement:
语法允许将这两个语句组合成一个语句:
typedef enum operator
{
NO_OP,
ADDITION,
} operator_t;
And finally to omit a name for the enumeration, as there is a datatype for it anyway:
最后省略枚举的名称,因为无论如何它都有一个数据类型:
typedef enum
{
NO_OP,
ADDITION,
} operator_t;
回答by Jens
Typedefs for enums, structs and unions are a complete waste. They hide important information for the questionable benefit of saving a few characters to type.
枚举、结构和联合的类型定义完全是浪费。他们隐藏了重要的信息,以节省几个字符以供输入。
Don't use them in new code.
不要在新代码中使用它们。
Technically, a typedef introduce an alias, i.e. a new name for something that already exists. This means, typedefs are notnew types. The type system will treat them just like the aliased type.
从技术上讲,typedef 引入了别名,即已存在的事物的新名称。这意味着,typedef不是新类型。类型系统会像对待别名类型一样对待它们。
The downvoters may please educate themselves by, for example, reading the wonderful Peter van der Linden book Expert C Programmingwhere the case against typedefs for enum/struct/union is made.
反对者可以通过例如阅读精彩的 Peter van der Linden 书Expert C Programming 来教育自己,其中提出了针对 enum/struct/union 的 typedef 的案例。

