这些枚举在C中有什么区别?

iLo*_*nix 3 c enums struct typedef

新来的C所以我在这里感到困惑.

我有三个不同的枚举

enum Space{STAR = 6, PLANET, SUN =3, EARTH =5, PLUTO};

typedef enum {STAR = 6, PLANET, SUN =3, EARTH =5, PLUTO}System;

typedef enum Space{STAR = 6, PLANET, SUN =3, EARTH =5, PLUTO}System;
Run Code Online (Sandbox Code Playgroud)

这三者之间到底有什么区别?

我知道它们是一组有序的变量,类型为int,因此PLANET = 7,PLUTO = 6等.

但香港专业教育学院尝试打印这些价值观,但看起来它们都是一样的.

printf("%d", PLANET);
Run Code Online (Sandbox Code Playgroud)

Ste*_*mit 7

这可能看起来很奇怪或令人困惑,但是:结构,联合和枚举最终可能在C中有两个(或更多)不同的名称.

第一个,在某种意义上,更基本的名称通常称为"标签".这是你的第一个例子中的名字:

enum Space {STAR = 6, PLANET, SUN = 3, EARTH = 5, PLUTO};
Run Code Online (Sandbox Code Playgroud)

我们创建了一个新的枚举(实际上是一个新类型),描述了5个枚举常量,并且我们给它标记了名称" Space".

标签名称不是全局的 - 单词" Space"不足以唯一标识我们创建的这种新类型.如果我们要声明一个可以保存此新枚举类型值的变量,我们必须在执行此enum操作时重复该关键字:

enum Space spacevar;
Run Code Online (Sandbox Code Playgroud)

如果我们试着说

Space spacevar;
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨,因为Space它不是类型名称,它只是一个标记名称.

(它有点像美国地理中的"华盛顿"这个名字.它是指太平洋西北地区的华盛顿州,还是华盛顿特区?我们总是需要更多的信息,一个额外的词或缩写,确定.)

然后我们来到typedef.typedef会创建一个新的类型名称(对于现有类型).typedef可以"包含"大量信息.如果我们说

typedef int myint;
Run Code Online (Sandbox Code Playgroud)

然后myint只是一个同义词int.但如果我们说

typedef int *intptr;
Run Code Online (Sandbox Code Playgroud)

然后intptr意味着"指向int",它"包含" *; 我们可以稍后说

intptr p1, p2;
Run Code Online (Sandbox Code Playgroud)

我们得到两个指针.同样,如果我们说

typedef enum Space System;
Run Code Online (Sandbox Code Playgroud)

然后System是一个新的类型名称,意思是" enum Space",它"包含"关键字enum.稍后我们可以声明枚举类型的另一个变量

System spacevar2;
Run Code Online (Sandbox Code Playgroud)

这与之相同

enum Space spacevar2;
Run Code Online (Sandbox Code Playgroud)

除了当我们System用来声明spacevar2变量时,我们不必重复那个enum关键字.

所以现在我们可以回到你的第二个和第三个例子.你的第三个例子,

typedef enum Space {STAR = 6, PLANET, SUN = 3, EARTH = 5, PLUTO} System;
Run Code Online (Sandbox Code Playgroud)

在同一行上同时声明标记名称Space和类型名称System.就像你说的那样

enum Space {STAR = 6, PLANET, SUN = 3, EARTH = 5, PLUTO} System;
typedef enum Space System;
Run Code Online (Sandbox Code Playgroud)

在两条线上.

然后你的第二个例子

typedef enum {STAR = 6, PLANET, SUN = 3, EARTH = 5, PLUTO} System;
Run Code Online (Sandbox Code Playgroud)

创建相同的新的类型,但它给它只有一个类型的名称,而不是一个标签名.这为您提供了一个枚举类型,您只能使用类型名称形式声明新变量:

System spacevar3;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,你不能说

enum ??? spacevar3
Run Code Online (Sandbox Code Playgroud)

因为您尚未声明可以在???现场进行的标记名称.

但最后,无论您使用哪种形式以及如何声明枚举变量,都可以以相同的方式使用它们.你可以说

spaceval = STAR;
Run Code Online (Sandbox Code Playgroud)

spaceval2 = PLANET;
Run Code Online (Sandbox Code Playgroud)

spaceval3 = SUN;
Run Code Online (Sandbox Code Playgroud)

根据您用于定义变量的名称(标记名称或类型名称),使用变量没有任何不同的方法.