C 语言中的枚举


2021年8月23日, Learn eTutorial
2365

在本教程中,您将学习到关于另一种用户自定义数据类型——C 语言中的枚举数据类型的所有知识。您将通过简单的示例理解在 C 语言中使用枚举的必要性及其基本事实。

C 语言中的枚举数据类型是什么?

让我们从理解“enumeration”(枚举)这个词的字面意思开始。枚举是指逐一提及事物列表的过程。在编程世界中,枚举数据类型是一种用户自定义的数据类型,它包含一组命名的值。这些命名的值被称为枚举成员。关键字“enum”用于定义枚举数据类型,就像 struct 和 union 一样。

语法

定义的原型是
 


enum flag { int_const1,int_const2, . . . . . , int_const n };
 

这里我们定义了一个名为 flag 的枚举,它包含 n 个整数常量。默认情况下,编译器为 int_const1 设置的值是 0,为 int_const2 设置的值是 1,依此类推。

让我们看一个例子


enum Status{unmarried, married ,divorced};

如何声明枚举数据类型?

就像我们为其他用户数据类型所做的一样,我们也可以用两种不同的格式为这个用户自定义的枚举数据类型创建一个变量。

  1. 在枚举器定义期间

    
    enum flag { int_const1,int_const2, . . . . . , int_const n } Var;
    
    

    示例

    
    enum Status{unmarried, married ,divorced} S;
    
    
  2. 在 main() 函数内部使用 enum 关键字

    声明枚举器的另一种方法是在 main 函数内部使用 enum 关键字来声明它,就像我们对结构体和联合体所做的那样。原型是

    
    enum flag Var;  // inside main function
    
    

    下面是演示枚举声明的示例。

    
    enum Status{unmarried, married ,divorced};
    
    int main()
    
    {
      enum Status S;
    }
    
    

在这两种情况下,S 都是我们为枚举 Status 声明的变量。这意味着变量 S 可以包含 unmarriedmarrieddivorced 这些值中的任意一个。

ENUM 的自动赋值

关于枚举的一个有趣事实是它会自动为其枚举成员赋值。更清楚地说,当没有明确给元素赋值时,编译器会自动按 0, 1, 2, ...n 的顺序为成员赋默认值。


#include<stdio.h>

enum Status{unmarried, married ,divorced};

int main()

{
  enum Status S;
  S = married;
  printf("INTEGRAL CONSTANT OF MARRIED :%d",S);

  return 0;
}
 

输出


INTEGRAL CONSTANT OF MARRIED :1

因此,在我们的例子中,编译器将 unmarried 赋值为 0,married 赋值为 1,divorced 赋值为 2。因此输出为 1。

如何初始化枚举数据类型?

然而,如果需要,用户可以更改默认值,并在声明时为枚举元素设置新值。枚举类型的初始化如下


enum Status{unmarried = 3, married= 6 ,divorced = 5};
 

示例:如何初始化枚举数据类型?


#include<stdio.h>

enum Status{unmarried =3, married=6 ,divorced=5};

int main()

{
  enum Status S;
  S = married;
  printf("INTEGRAL CONSTANT OF DIVORCED :%d",S);

  return 0;
}
 

输出


INTEGRAL CONSTANT OF DIVORCED :5

在这个例子中,我们已经明确地为枚举元素赋值,因此它会输出相应的值。

让我们深入探讨一些关于枚举元素初始化的有趣事实。

1. 可以将相同的值初始化给多个元素

在上面的例子中,我们为每个元素分配了不同的值,所以出现了一个问题:是否可以为多个枚举元素分配相同的值。通过查看下面的程序,您将得到答案。


#include<stdio.h>

enum Signal{Green = 1, Orange = 0, Red = 0};

int main()

{
  enum Signal S;
  printf("%d %d %d",Green, Orange, Red);

  return 0;
}
 

输出


1 0 0

在上面的代码中,Orange 和 Red 都被赋值为 '0'。所以我们可以得出结论,在 C 语言中,多个枚举名称可以有相同的值。

2. 赋值的顺序无关紧要

在枚举数据类型中,赋值的顺序不是一个大问题。Enum 在赋值方面提供了更好的灵活性,因此用户可以为某些元素赋值,而让其他元素保持未赋值状态。未赋值的元素将取前一个元素的值加一。

这是示例


#include<stdio.h>

enum Rainbow{Violet= 22, Indigo , Blue = 2,Green = 7, Yellow,Orange,Red =18 };

int main()

{
  enum Rainbow R;
  printf("Violet = %d \nIndigo = %d \nBlue=%d\nGreen = %d\nYellow= %d\nOrange= %d\nRed = %d",Violet , Indigo, Blue,Green,Yellow, Orange, Red);

  return 0;
}

 

输出


Violet = 22
Indigo = 23
Blue=2
Green = 7
Yellow= 8
Orange= 9
Red = 18

在上面的例子中,indigo、Yellow 和 Orange 是未赋值的值,它们会跟随其前一个元素的值。Indigo 跟随 Violet 的值,所以它被自动赋值为 23 (22+1)。类似地,yellow 和 orange 跟随 Green 的值,即 7,因此分别被设置为 8 和 9。

3. 赋的值必须是整型常量

到目前为止,我们在所有示例中看到,赋给枚举元素的值都是整型常量,并且它们都工作得很好。如果我们赋一个非整型常量的值会怎样呢?


#include<stdio.h>

enum Rainbow{Violet= 22.55, Indigo , Blue = 2,Green = 7, Yellow,Orange,Red =18 };

int main()

{
  enum Rainbow R;
  printf("Violet = %d \nIndigo = %d \nBlue=%d\nGreen = %d\nYellow= %d\nOrange= %d\nRed = %d",Violet , Indigo, Blue,Green,Yellow, Orange, Red);

  return 0;
}

 

输出

error: enumerator value for 'Violet' is not an integer constant|

我们稍微修改了前面的例子,为枚举值提供了一个非整数值。这里 Violet 被赋值为 '22.55',这是一个非整数值,因此如上所示,输出是错误。

因此,从这个结果我们可以得出结论,枚举数据类型是类型受限的,只会接受整型常量作为其元素,并且值的范围必须在可能的最小整数值和最大整数值之间。

枚举和作用域规则

枚举器遵循作用域规则,即每个枚举器必须是唯一的。每个枚举器中的枚举常量必须是唯一的,如果两个不同的枚举器有相同的枚举常量,那么程序将会出错。

这是示例


#include<stdio.h>

enum color{Green, Yellow,Blue };
enum signal{Green,Orange ,Red};

int main()

{
  enum color C;
  enum signal S;

}

 

输出


error: redeclaration of enumerator 'Green'|

ENUM 与 #DEFINE 的对比

ENUM #DEFINE

语法


enum Signal { Green , Orange, Red};
 

语法


#define Green 0
#define Orange 1
#define Red 2
 
Enum 是一种用户自定义的数据类型,它为一个整型常量赋予名称 #define 是一个宏预处理器指令,它用一个值替换一个标记。
Enum 由编译器执行 #define 由预处理器执行,对编译器不可见
Enum 是类型受限的,即 enum 的类型始终是 signed int。 #define 可以是任何类型。
Enum 遵循作用域规则 #define 不遵循作用域规则
Enum 提供自动赋值。 #define 提供显式赋值。