如何在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 stat
和stat
函数:这些都不冲突),并立即看到它是一个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};
定义了三个符号常量( a
, b
和c
),它们分别是值为0
和2
整数,但是当我们使用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;
除了现在可以互换使用strategy
和enum 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; }
如果你有一个工作程序,你应该能够将这些代码片段粘贴到你的程序中,看看有些编译,有些则不能。