How to define an enumerated type (enum) in C?
我不确定使用C枚举的正确语法是什么。我有以下代码:
1 2 | enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; |
但这不会编译,错误如下:
1 2 | error: conflicting types for ‘strategy’ error: previous declaration of ‘strategy’ was here |
号
我做错什么了?
值得指出的是,你不需要一个
1 2 | enum strategy { RANDOM, IMMEDIATE, SEARCH }; enum strategy my_strategy = IMMEDIATE; |
这是一个风格问题,你是否喜欢
两种方法都有各自的利弊。其中一个更为复杂,但是将类型标识符保存到标记命名空间中,这样它们就不会与普通标识符冲突(想想
声明枚举变量的过程如下:
1 2 | enum strategy {RANDOM, IMMEDIATE, SEARCH}; enum strategy my_strategy = IMMEDIATE; |
但是,可以使用
1 2 | typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy my_strategy = IMMEDIATE; |
号
最好有一个命名约定来区分类型和变量:
1 2 | typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type; strategy_type my_strategy = IMMEDIATE; |
您试图声明
1 2 3 4 5 6 7 8 9 10 | #include <stdio.h> enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE; int main(int argc, char** argv){ printf("strategy: %d ", strategy); return 0; } |
如果第二行不是上述行,则改为:
1 2 3 4 | ... enum { RANDOM, IMMEDIATE, SEARCH } strategy; strategy = IMMEDIATE; ... |
。
从警告中,你很容易看到你的错误:
1 2 3 4 | enums.c:5:1: warning: data definition has no type or storage class [enabled by default] enums.c:5:1: warning: type defaults to ‘int’ in declaration of ‘strategy’ [-Wimplicit-int] enums.c:5:1: error: conflicting types for ‘strategy’ enums.c:4:36: note: previous declaration of ‘strategy’ was here |
号
因此,编译器使用
但是,如果您将赋值放在
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h> enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE; int main(int argc, char** argv){ strategy=SEARCH; printf("strategy: %d ", strategy); return 0; } |
号
当你说
1 | enum {RANDOM, IMMEDIATE, SEARCH} strategy; |
。
您创建了一个名为"Strategy"的单实例变量,它是一个无名称枚举。这不是一件非常有用的事情-您需要一个typedef:
1 2 | typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType; StrategyType strategy = IMMEDIATE; |
如前所述,您的代码没有任何问题。你确定你没有做过
1 2 3 | int strategy; ... enum {RANDOM, IMMEDIATE, SEARCH} strategy; |
。
错误消息指向哪些行?当它说"以前的战略宣言在这里"时,"这里"是什么?它显示了什么?
@在他发表的对问题的评论中,透皮斯汀是对的。问题中发布的代码段是有效的,没有错误。您所犯的错误一定是因为C源文件的任何其他位置的其他语法错误。
1 2 3 4 5 6 7 |
这将输出
这也将有效:
1 2 3 4 5 6 7 8 |
号
并将输出与以前相同的结果。
如果您这样做:
1 2 | enum {a,b,c}; enum {a,b,c}; |
您将有一个错误,但如果您这样做:
1 2 | enum alfa{a,b,c}; enum alfa; |
。
你不会有任何错误。
您可以这样做:
1 2 | enum {a,b,c}; int aa=a; |
1 | enum {a,b,c} aa= a; |
。
具有相同的效果(即,
您也可以这样做:
1 2 | enum {a,b,c} aa= a; aa= 7; |
。
由于不能使用
1 2 3 | enum tag1 {a,b,c}; enum tag1 var1= a; enum tag1 var2= b; |
使用
1 2 3 | typedef enum {a,b,c} Tag1; Tag1 var1= a; Tag1 var2= b; |
。
您还可以拥有:
1 2 3 | typedef enum tag1{a,b,c}Tag1; Tag1 var1= a; enum tag1 var2= b; |
最后要说的是,既然我们在讨论定义的符号常量,那么在使用
1 | enum {A,B,C}; |
。
而不是
1 | enum {A,B,C}; |
。
值得一提的是,在C++中,你可以使用"EnUM"来定义一个新类型,而不需要一个TyWIFF语句。
1 2 3 | enum Strategy {RANDOM, IMMEDIATE, SEARCH}; ... Strategy myStrategy = IMMEDIATE; |
。
我觉得这种方法更友好。
[编辑-澄清C++状态-我原来有这个,然后删除它!]
声明似乎有点混乱。
当
1 | enum strategy {RANDOM, IMMEDIATE, SEARCH}; |
号
您正在创建一个名为
1 2 | enum strategy {RANDOM, IMMEDIATE, SEARCH}; strategy a; |
号
同时,以下内容是有效的
1 2 3 4 5 | enum strategy {RANDOM, IMMEDIATE, SEARCH}; enum strategy queen = RANDOM; enum strategy king = SEARCH; enum strategy pawn[100]; |
号
当
所以现在,你可以做一些像
1 2 | enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = RANDOM; |
号
但是,您不能声明任何其他类型的
1 2 | enum {RANDOM, IMMEDIATE, SEARCH} strategy; enum strategy a = RANDOM; |
号
您也可以将这两个定义结合起来
1 2 3 4 5 | enum strategy {RANDOM, IMMEDIATE, SEARCH} a, b; a = RANDOM; b = SEARCH; enum strategy c = IMMEDIATE; |
号
如前所述,
1 | typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy; |
号
现在,您已经告诉编译器,
1 | strategy x = RANDOM; |
号
您还可以将typedef与枚举名称组合以获取
1 | typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy; |
除了可以互换使用
1 2 3 4 | typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy; enum strategyName a = RANDOM; strategy b = SEARCH; |
。
我最喜欢和唯一使用的建筑总是:
1 2 3 4 5 6 7 8 9 | typedef enum MyBestEnum { /* good enough */ GOOD = 0, /* even better */ BETTER, /* divine */ BEST }; |
我相信这会消除你的问题。从我的观点来看,使用新类型是正确的选择。
如果声明枚举的名称,则不会发生错误。
如果没有声明,您必须使用
1 2 | enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; |
。
它不会显示错误…
TARC的回答是最好的。
枚举的大部分讨论都是一个误区。
比较此代码段:
1 2 3 4 5 | int strategy; strategy = 1; void some_function(void) { } |
哪个给了
1 2 | error C2501: 'strategy' : missing storage-class or type specifiers error C2086: 'strategy' : redefinition |
号
它编译起来没有问题。
1 2 3 4 5 | int strategy; void some_function(void) { strategy = 1; } |
变量
他使用枚举随机、立即、搜索而不是int,这一事实只与它使无法超越它的人感到困惑的程度有关。问题中的重新定义错误消息表明,这是作者所做的错误。
所以现在您应该能够理解为什么下面的第一个示例是错误的,而其他三个示例是正确的。
例1。错了!
1 2 3 4 5 | enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; void some_function(void) { } |
。
例2。正确的。
1 2 3 4 | enum {RANDOM, IMMEDIATE, SEARCH} strategy = IMMEDIATE; void some_function(void) { } |
例3。正确的。
1 2 3 4 5 | enum {RANDOM, IMMEDIATE, SEARCH} strategy; void some_function(void) { strategy = IMMEDIATE; } |
。
例4。正确的。
1 2 3 4 5 | void some_function(void) { enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; } |
。
如果你有一个正常工作的程序,你应该能够将这些代码片段粘贴到你的程序中,并且看到有些代码是编译的,而有些则不是。
我尝试使用gcc,并根据我的需要,不得不使用最后一个选项,以无错误编译。
typedef枚举状态a=0,b=1,c=2状态;
1 2 3 4 5 6 7 8 9 10 11 12 13 |
号