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

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

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

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

我做错了什么?


当前回答

你尝试两次声明策略,这就是为什么你会得到上面的错误。以下工作没有任何抱怨(编译gcc -ansi - petic -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来声明一个默认类型为int的名为strategy的变量,但之前已经声明了一个具有此名称的变量。

然而,如果你把赋值放在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 strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;

这是一个风格问题,你是否喜欢typedef。如果没有它,如果要引用枚举类型,则需要使用枚举策略。有了它,你可以说策略。

两种方法都有优缺点。一种方法比较冗长,但将类型标识符保留在标记名称空间中,在那里它们不会与普通标识符冲突(想想struct stat和stat函数:它们也不冲突),并且在那里您立即看到它是一个类型。另一个较短,但将类型标识符引入普通名称空间。

这份声明似乎有些混乱。

如下所示,当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;

我尝试了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);

Tarc的答案是最好的。

全会的许多讨论都是在转移话题。

比较以下代码片段:-

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

变量策略需要在声明中或在函数中设置。您不能在全局范围内编写任意软件——特别是赋值软件。

他使用enum {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;
}

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

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

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

我发现这种方法更友好。

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