如何在C中定义枚举types(枚举)?

我不确定使用C枚举的正确语法是什么。 我有以下代码:

enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; 

但是这不会编译,出现以下错误:

 error: conflicting types for 'strategy' error: previous declaration of 'strategy' was here 

我究竟做错了什么?

声明一个枚举variables是这样做的:

 enum strategy {RANDOM, IMMEDIATE, SEARCH}; enum strategy my_strategy = IMMEDIATE; 

但是,您可以使用typedef来缩短variables声明,如下所示:

 typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy my_strategy = IMMEDIATE; 

有一个命名约定来区分types和variables是一个好主意:

 typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type; strategy_type my_strategy = IMMEDIATE; 

值得指出的是,你不需要 typedef 。 你可以像下面这样做

 enum strategy { RANDOM, IMMEDIATE, SEARCH }; enum strategy my_strategy = IMMEDIATE; 

这是一个风格问题,你是否喜欢typedef 。 没有它,如果你想引用枚举types,你需要使用enum strategy 。 有了它,你可以说strategy

两种方式都有其优点和缺点。 一个更罗嗦,但保持types标识符到标签名称空间,他们不会与普通标识符冲突(考虑struct statstat函数:这些都不冲突),并立即看到它是一个types。 另一个更短,但是将types标识符带入普通的命名空间。

你试图两次宣布strategy ,这就是为什么你得到上述错误。 以下作品没有任何投诉(用gcc -ansi -pendantic -Wall编译):

 #include <stdio.h> enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE; int main(int argc, char** argv){ printf("strategy: %d\n", strategy); return 0; } 

如果不是上述,第二行被改为:

 ... enum { RANDOM, IMMEDIATE, SEARCH } strategy; strategy = IMMEDIATE; ... 

从警告中,你可以很容易地看到你的错误:

 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 

所以编译器把strategy = IMMEDIATE作为一个名为strategy的variables的声明,默认types为int ,但是之前已经有了一个名字variables的声明。

但是,如果您将赋值放在main()函数中,那么这将是一个有效的代码:

 #include <stdio.h> enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE; int main(int argc, char** argv){ strategy=SEARCH; printf("strategy: %d\n", strategy); return 0; } 

当你说

 enum {RANDOM, IMMEDIATE, SEARCH} strategy; 

你创build一个单一的实例variables,称为“策略”的一个无名的枚举。 这不是一个非常有用的事情 – 你需要一个typedef:

 typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType; StrategyType strategy = IMMEDIATE; 

正如所写的,你的代码没有问题。 你确定你没有做过类似的事吗?

 int strategy; ... enum {RANDOM, IMMEDIATE, SEARCH} strategy; 

错误信息指向哪条线? 当它说“先前宣布的'策略'在这里”时,“这里”是什么,它显示了什么?

@ThoAppelsin在他的评论中提出的问题是正确的。 该问题中的代码片段是有效的,没有错误。 你的错误必须是因为你的c源文件的其他地方的其他不好的语法。 enum{a,b,c}; 定义了三个符号常量( abc ),它们分别是值为02整数,但是当我们使用enum ,因为我们通常不关心具体的整数值,所以我们更关心象征常量名称。 这意味着你可以有这个:

 #include <stdio.h> enum {a,b,c}; int main(){ printf("%d\n",b); return 0; } 

这将输出1

这也是有效的:

 #include <stdio.h> enum {a,b,c}; int bb=b; int main(){ printf("%d\n",bb); return 0; } 

并会像以前一样输出。

如果你这样做:

 enum {a,b,c}; enum {a,b,c}; 

你会有一个错误,但如果你这样做:

 enum alfa{a,b,c}; enum alfa; 

你不会有任何错误。

你可以这样做:

 enum {a,b,c}; int aa=a; 

aa将是一个整数variables,值为0 。 但你也可以这样做:

 enum {a,b,c} aa= a; 

并具有相同的效果(也就是说, aa是一个0值的int )。

你也可以这样做:

 enum {a,b,c} aa= a; aa= 7; 

aa将是int与价值7

因为你不能象使用enum一样重复使用符号常量定义,如前所述,如果你想用enum声明int vars,你必须使用标签:

 enum tag1 {a,b,c}; enum tag1 var1= a; enum tag1 var2= b; 

typedef的使用是为了避免每次写入enum tag1来定义variables。 使用typedef你可以inputTag1

 typedef enum {a,b,c} Tag1; Tag1 var1= a; Tag1 var2= b; 

你也可以有:

 typedef enum tag1{a,b,c}Tag1; Tag1 var1= a; enum tag1 var2= b; 

最后要说的是,由于我们正在讨论定义的符号常量,所以在使用enum时最好使用大写字母,例如:

 enum {A,B,C}; 

代替

 enum {a,b,c}; 

值得一提的是, 在C ++中,你可以使用“enum”来定义一个新的types,而不需要typedef语句。

 enum Strategy {RANDOM, IMMEDIATE, SEARCH}; ... Strategy myStrategy = IMMEDIATE; 

我觉得这种方法更友好。

[编辑 – 澄清C ++状态 – 我原来是这样的,然后删除它!]

宣言似乎有一个混乱。

strategy出现在{RANDOM, IMMEDIATE, SEARCH}之前{RANDOM, IMMEDIATE, SEARCH}如下所示,

 enum strategy {RANDOM, IMMEDIATE, SEARCH}; 

您正在创build一个名为enum strategy的新types。 但是,在声明variables时,您需要使用enum strategy本身。 你不能只使用strategy 。 所以以下是无效的。

 enum strategy {RANDOM, IMMEDIATE, SEARCH}; strategy a; 

而下面是有效的

 enum strategy {RANDOM, IMMEDIATE, SEARCH}; enum strategy queen = RANDOM; enum strategy king = SEARCH; enum strategy pawn[100]; 

strategy出现在{RANDOM, IMMEDIATE, SEARCH}后面时,您将创build一个匿名枚举,然后声明strategy为该types的variables。

所以现在,你可以做类似的事情

 enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = RANDOM; 

但是,您不能声明任何types为enum {RANDOM, IMMEDIATE, SEARCH}其他variables,因为您从来没有将其命名。 所以以下是无效的

 enum {RANDOM, IMMEDIATE, SEARCH} strategy; enum strategy a = RANDOM; 

你也可以把这两个定义结合起来

 enum strategy {RANDOM, IMMEDIATE, SEARCH} a, b; a = RANDOM; b = SEARCH; enum strategy c = IMMEDIATE; 

如前所述的Typedef用于创build较短的variables声明。

 typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy; 

现在你已经告诉编译器enum {RANDOM, IMMEDIATE, SEARCH}是与strategy同步的。 所以现在你可以随意使用strategy作为variablestypes。 你不需要再inputenum strategy 。 以下是现在有效

 strategy x = RANDOM; 

你也可以结合Typedef和枚举名来获得

 typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy; 

除了现在可以互换使用strategyenum strategyName之外,使用这种方法没有多大优势。

 typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy; enum strategyName a = RANDOM; strategy b = SEARCH; 

如果您声明枚举的名称将不会发生错误。

如果没有声明,你必须使用typedef

 enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; 

它不会显示错误…

我尝试了与海湾合作委员会,并拿出我的需要,我被迫使用最后一个select,编译出错误。

typedef枚举状态 {a = 0,b = 1,c = 2} 状态 ;

 typedef enum state {a = 0, b = 1, c = 2} state; typedef enum state old; // New type, alias of the state type. typedef enum state new; // New type, alias of the state type. new now = a; old before = b; printf("State now = %d \n", now); printf("Sate before = %d \n\n", before); 

Tarc的答案是最好的。

很多enum讨论是一个红色的鲱鱼。

比较这段代码片段: –

 int strategy; strategy = 1; void some_function(void) { } 

这使

 error C2501: 'strategy' : missing storage-class or type specifiers error C2086: 'strategy' : redefinition 

用这个编译没问题的那个。

 int strategy; void some_function(void) { strategy = 1; } 

他使用枚举{RANDOM,IMMEDIATE,SEARCH}而不是int的事实只是与它使人们看不到的东西相混淆。 问题中的重新定义错误信息表明,这是作者做错了什么。

所以现在你应该能够明白为什么下面的第一个例子是错的,其他三个都没问题。

例子1.错误!

 enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; void some_function(void) { } 

例2.右。

 enum {RANDOM, IMMEDIATE, SEARCH} strategy = IMMEDIATE; void some_function(void) { } 

例3.右。

 enum {RANDOM, IMMEDIATE, SEARCH} strategy; void some_function(void) { strategy = IMMEDIATE; } 

例4.右。

 void some_function(void) { enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; } 

如果你有一个工作程序,你应该能够将这些代码片段粘贴到你的程序中,看看有些编译,有些则不能。