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

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

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

error: conflicting types for ‘strategy’
error: previous declaration of ‘strategy’ was here

我做错了什么?


当前回答

这份声明似乎有些混乱。

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

enum strategy {RANDOM, IMMEDIATE, SEARCH};

您正在创建一个名为enum策略的新类型。但是,在声明变量时,需要使用枚举策略本身。你不能只使用策略。所以下面的内容无效。

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}后面时,您正在创建一个匿名枚举,然后将strategy声明为该类型的变量。

现在,你可以这样做

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

但是,您不能声明任何其他类型为enum {RANDOM, IMMEDIATE, SEARCH}的变量,因为您从未命名过它。所以下面的内容无效

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用于创建更短的变量声明。

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;

现在你已经告诉编译器enum {RANDOM, IMMEDIATE, SEARCH}是策略的同义词。所以现在你可以自由地使用策略作为变量类型。你不再需要输入enum 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;

其他回答

@ThoAppelsin in his comment to question posted is right. The code snippet posted in the question it is valid and with no errors. The error you have must be because other bad syntax in any other place of your c source file. enum{a,b,c}; defines three symbolic constants (a, b and c) which are integers with values 0,1 and 2 respectively, but when we use enum it is because we don't usually care about the specific integer value, we care more about the meaning of the symbolic constant name. This means you can have this:

#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是一个值为0的整型变量。但你也可以这样做:

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

和将具有相同的效果(即aa是一个值为0的int)。

你还可以这样做:

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

aa将是int,值为7。

因为你不能使用enum重复符号常量定义,就像我之前说过的,如果你想使用enum声明int变量,你必须使用标签:

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

typedef的使用是为了保证你不用每次都用枚举tag1来定义变量。使用typedef,你可以输入Tag1:

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};

声明一个枚举变量是这样的:

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

但是,你可以使用typedef来缩短变量声明,如下所示:

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

有一个命名约定来区分类型和变量是一个好主意:

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

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

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

我发现这种方法更友好。

[编辑-澄清c++状态-我原来有这个,然后删除它!]]

如果为枚举声明名称,则不会发生错误。

如果没有声明,你必须使用类型定义:

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

它不会显示错误…

我尝试了gcc,并提出了我的需要,我被迫使用最后一种选择,编译出来的错误。

类型定义enum状态{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);