我不确定如何正确使用C语言中的枚举。我有以下代码:
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
但是这段代码无法编译,会出现以下错误:
error: conflicting types for ‘strategy’
error: previous declaration of ‘strategy’ was here
我做错了什么?
值得指出的是,您不必须使用 typedef
。您可以按照以下方式执行
enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;
关于你是否喜欢使用typedef
,这是一个风格问题。如果不使用它,当你想引用枚举类型时,需要使用enum strategy
。而通过使用typedef
,你可以直接使用strategy
来引用。
两种方法各有优缺点。第一种方法更冗长,但将类型标识符保留在标签命名空间中,避免了与普通标识符的冲突(想想struct stat
和stat
函数:它们也不会冲突),并且可以立即看出它是一个类型。第二种方法较短,但会将类型标识符带入普通命名空间。
enum
关键字。 - RichieHindleenum strategy { RANDOM, IMMEDIATE, SEARCH };
当你需要一个该枚举类型的实例时,可以使用以下代码:enum strategy myEnum;
- user3629249enum MyEnum {} useEnum;
不能正常工作?为什么需要使用 enum MyEnum variableName
?在使用Visual Studio 2015的C语言中,前面提到的代码可以正常工作,而不需要额外的输入。 - Mushy声明枚举变量的方法如下:
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 MyEnum {} myVar;
然后像下面这样使用变量 myVar
: myVar = SOMEENUMCONSTANT;
? - Mushystrategy
两次,这就是为令你收到上述错误的原因。以下代码可以正常工作(使用gcc -ansi -pedantic -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
的变量的声明,其默认类型为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;
}
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
你需要创建一个名为“strategy”的匿名枚举的单个实例变量。这样做并没有什么太大的用处 - 你需要使用typedef:
typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType;
StrategyType strategy = IMMEDIATE;
按照您的代码编写,没有任何问题。 您确定您没有做过类似于以下操作
int strategy;
...
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
这些错误消息指向哪些行?当出现“strategy的先前声明在这里”的消息时,“这里”是指什么,它显示了什么?
strategy = IMMEDIATE;
。在所有函数之外,不能在文件作用域下进行赋值操作。因此编译器尝试从错误中找到最佳解决方案,并假设他的意思是 int strategy = IMMEDIATE;
,于是就出现了冲突。 - Johannes Schaub - litb值得一提的是,在C ++中,您可以使用"enum"来定义新类型,而无需typedef语句。
enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;
我认为这种方法更加友好。
[编辑 - 澄清了 C++ 的状态 - 我最初放在里面,然后将其删除!]
typedef
,或者在变量声明中同时指定 enum
:typedef enum {RANDOM, IMMEDIATE, SEARCH} Strategy;
...
Strategy myStrategy = IMMEDIATE;
- Pavel Minaev@ThoAppelsin在他对问题的评论中是正确的。问题中发布的代码片段是有效的且没有错误。你遇到的错误可能是由于C源文件的其他位置存在不良语法所致。enum{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;
}
执行此操作将输出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
将会是值为7
的int
类型。
因为您无法使用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};
关于声明似乎有些混淆。
当strategy
位于{RANDOM, IMMEDIATE, SEARCH}
之前,如下所示:
enum strategy {RANDOM, IMMEDIATE, SEARCH};
您正在创建一个名为 enum strategy
的新类型。然而,在声明变量时,您需要使用 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}
后面时,你创建了一个匿名枚举,然后声明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
是同义词。所以现在可以自由地使用strategy
作为变量类型,不再需要输入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;
typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy
或 typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy_type
。这与 typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy
相比有什么优势吗?您是否考虑将这些内容添加到您的答案中,以便完整呢? - tjalling我的最喜欢且唯一使用的构建方式始终是:
typedef enum MyBestEnum
{
/* good enough */
GOOD = 0,
/* even better */
BETTER,
/* divine */
BEST
};
我相信这将解决你所遇到的问题。从我的角度来看,使用新类型是正确的选择。
如果声明枚举的名称,则不会出现错误。
如果没有声明,则必须使用 typedef
:
enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
strategy
具有匿名枚举类型,并将该类型声明的值之一分配给它。此外,如果我将呈现的代码包装在一个其他方面微不足道的main()
函数中,则使用gcc 4.4.7编译对我来说很好,甚至没有警告。一些答案意味着相同的事情,尽管没有那么明确地表达。 - John Bollingerstrategy = IMMEDIATE;
视为一个声明。它具有在ANSI C之前合法的形式,但在现代C中是非法的。在文件作用域中不允许赋值。 - Keith Thompsonenum strategy { ... };
定义了一个名为enum strategy
的枚举类型,其中strategy
是标签。enum { ... } strategy;
定义了一个匿名的枚举类型(没有标签)和一个名为strategy
的该类型的单一对象。这两种定义方式都是合法的,它们只是表示不同的含义。 - Keith Thompson