如何在C中定义枚举类型(enum)?

如何在C中定义枚举类型(enum)?,c,enums,C,Enums,我不确定使用C枚举的正确语法是什么。我有以下代码: enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; 但这不会编译,出现以下错误: error: conflicting types for ‘strategy’ error: previous declaration of ‘strategy’ was here 我做错了什么?声明枚举变量的方式如下: enum strategy {RANDOM, IMMEDIAT

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

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
但这不会编译,出现以下错误:

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

我做错了什么?

声明枚举变量的方式如下:

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;
当你说

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
您创建一个名为“strategy”的无名枚举实例变量。这不是一件非常有用的事情-您需要一个typedef:

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

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

enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;
我发现这种方法更加友好


<> > [编辑-澄清C++状态-我最初有这个,然后删除它!] < /p> 如写的,代码没有错。你确定你没有做过类似的事情吗

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

错误消息指向哪些行?当它说“以前的‘战略’宣言在这里”时,“这里”是什么?它表明了什么

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

enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;
你是否喜欢
typedef
,这是一个风格问题。如果没有它,如果要引用枚举类型,则需要使用
enum策略
。有了它,你就可以说
策略


这两种方式都有其利弊。一个更冗长,但将类型标识符保留在标记名称空间中,这样它们就不会与普通标识符冲突(想想
struct stat
stat
函数:它们也不会冲突),并且您可以立即看到它是一个类型。另一个较短,但将类型标识符引入普通名称空间

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

如果未声明,则必须使用
typedef

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

它不会显示错误…

您试图声明
策略两次,这就是为什么会出现上述错误。以下工作无任何投诉(使用
gcc-ansi-pedantic-Wall
编译):

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

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
的变量进行声明,该变量的默认类型为
int
,但之前已经有一个使用此名称的变量声明

但是,如果将赋值放在
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;
}
#包括
枚举{随机,立即,搜索}策略=立即;
int main(int argc,字符**argv){
策略=搜索;
printf(“策略:%d\n”,策略);
返回0;
}

@ThoAppelsin在对所贴问题的评论中是正确的。问题中发布的代码片段是有效的,没有错误。您的错误一定是因为c源文件的任何其他位置存在其他错误语法<代码>枚举{a,b,c}
定义了三个符号常量(
a
b
c
),它们分别是值为
0
1
2
的整数,但当我们使用
enum
时,这是因为我们通常不关心特定的整数值,我们更关心符号常量名称的含义。 这意味着您可以:

#include <stdio.h>
enum {a,b,c};
int main(){
  printf("%d\n",b);
  return 0;
}
并将输出与以前相同的结果

如果您这样做:

enum {a,b,c};
enum {a,b,c};
enum alfa{a,b,c};
enum alfa;
您将有一个错误,但如果您这样做:

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;
enum {a,b,c} aa= a;
aa= 7;
并且将具有相同的效果(即,
aa
是具有
0
值的
int

您也可以这样做:

enum {a,b,c} aa= a;
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
可以避免您每次编写
enum 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};

这份声明似乎有点混乱

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
策略
出现在
{RANDOM,IMMEDIATE,SEARCH}
之前时,如下所示

enum strategy {RANDOM, IMMEDIATE, SEARCH};
您正在创建一个名为
enum strategy
的新类型。但是,在声明变量时,需要使用
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
声明为该类型的变量

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

int strategy;
...
enum {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}
策略一致。因此,现在您可以自由使用
策略
作为变量类型。您不再需要键入
枚举策略
。以下内容现在有效

strategy x = RANDOM;

您还可以将Typedef与enum name组合以获得

typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;
没有多少优势
int strategy;
void some_function(void) 
{
    strategy = 1;   
}
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
void some_function(void) 
{
}
enum {RANDOM, IMMEDIATE, SEARCH} strategy = IMMEDIATE;
void some_function(void) 
{
}
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
void some_function(void) 
{
    strategy = IMMEDIATE;
}
void some_function(void) 
{
    enum {RANDOM, IMMEDIATE, SEARCH} strategy;
    strategy = IMMEDIATE;
}
typedef enum MyBestEnum
{
    /* good enough */
    GOOD = 0,
    /* even better */
    BETTER,
    /* divine */
    BEST
};
enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;
typedef enum bool {false, true} bool;

//this is the same as 
enum bool {false, true};
typedef enum bool bool;

//or
enum bool {false, true};
typedef unsigned int bool;

//remember though, bool is an alias for _Bool if you include stdbool.h. 
//and casting to a bool is the same as the !! operator 
+--------------+-----+-----+-----+
|   enum bool  | a=1 |b='a'| c=3 |  
+--------------+-----+-----+-----+
| unsigned int | int | int | int |  
+--------------+-----+-----+-----+

+--------------+-----+-----+-----+
|   enum bool  | a=1 | b=-2| c=3 |  
+--------------+-----+-----+-----+
|      int     | int | int | int |  
+--------------+-----+-----+-----+

+--------------+-----+---------------+-----+
|   enum bool  | a=1 |b=(-)0x80000000| c=2 |
+--------------+-----+---------------+-----+
| unsigned int | int |  unsigned int | int |
+--------------+-----+---------------+-----+

+--------------+-----+---------------+-----+
|   enum bool  | a=1 |b=(-)2147483648| c=2 |
+--------------+-----+---------------+-----+
| unsigned int | int |  unsigned int | int |
+--------------+-----+---------------+-----+

+-----------+-----+---------------+------+
| enum bool | a=1 |b=(-)0x80000000| c=-2 |
+-----------+-----+---------------+------+
|    long   | int |      long     |  int |
+-----------+-----+---------------+------+

+-----------+-----+---------------+------+
| enum bool | a=1 | b=2147483648  | c=-2 |
+-----------+-----+---------------+------+
|    long   | int |      long     |  int |
+-----------+-----+---------------+------+

+-----------+-----+---------------+------+
| enum bool | a=1 | b=-2147483648 | c=-2 |
+-----------+-----+---------------+------+
|    int    | int |      int      |  int |
+-----------+-----+---------------+------+

+---------------+-----+---------------+-----+
|   enum bool   | a=1 | b=99999999999 | c=1 |
+---------------+-----+---------------+-----+
| unsigned long | int | unsigned long | int |
+---------------+-----+---------------+-----+

+-----------+-----+---------------+------+
| enum bool | a=1 | b=99999999999 | c=-1 |
+-----------+-----+---------------+------+
|    long   | int |      long     |  int |
+-----------+-----+---------------+------+

#include <stdio.h>
enum c j;
enum c{f, m} p;
typedef int d;
typedef int c;
enum c j;
enum m {n} ;
int main() {
  enum c j;
  enum d{l};
  enum d q; 
  enum m y; 
  printf("%llu", j);
}
enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error
#include <iostream>
c j; //not allowed, unknown type name c before enum c{f} p; line
enum c j; //not allowed, forward declaration of enum type not allowed and variable can have an incomplete type but not when it's still a forward declaration in C++ unlike C
enum c{f, m} p;
typedef int d;
typedef int c; // not allowed in C++ as it clashes with enum c, but if just int c were used then the below usages of c j; would have to be enum c j;
[enum] c j;
enum m {n} ;
int main() {
  [enum] c j;
  enum d{l}; //not allowed in same scope as typedef but allowed here 
  d q;
  m y; //simple type specifier not allowed, need elaborated type specifier enum m to refer to enum m here
  p v; // not allowed, need enum p to refer to enum p
  std::cout << j;
}
#include <stdio.h>
enum a {l} c;
enum d {f} ;
int main() {
  c=0; // not allowed;
  c=l;
  c=(a)1;
  c=(enum a)4;
  printf("%llu", c); //4
}
#include <stdio.h>
enum class a {b} c;
int main() {
  printf("%llu", a::b<1) ; //not allowed
  printf("%llu", (int)a::b<1) ;
  printf("%llu", a::b<(a)1) ;
  printf("%llu", a::b<(enum a)1);
  printf("%llu", a::b<(enum class a)1) ; //not allowed 
  printf("%llu", b<(enum a)1); //not allowed
}
#include <stdio.h>
enum a: bool {l, w} ;
int main() {
  enum a: bool {w, l} f;
  printf("%llu", ::a::w);
}