当前位置:网站首页>enum in c language

enum in c language

2022-08-09 11:03:00 XV_

今天说说C语言中的枚举。

参考:Enumeration (or enum) in C

1 定义

定义一个枚举类型很容易:

enum aa {
     a1, a2, a3 };

这里

  • enum是关键字
  • aa是枚举变量,也就是我们自定义类型
  • a1,a2,a3是枚举成员

然后怎么使用呢?

首先,它就像结构体struct和联合体union那样,是一个自定义的数据类型,用它定义变量,也是一样的:

enum aa abc; 	// 定义变量
enum aa *en_p; 	// 定义指针

是的,它跟基本数据类型以及结构体等特殊数据类型一样,都可以定义变量和定义指针

所以,和int一样,如果仅仅定义,而没有赋值和使用,编译后它就没了,变量定义本身不占地方,赋值了才占地方。

另外,和struct一样,它只是一个结构,这个结构是C语言层级的声明,编译后不存在这个结构的,汇编层级没有的。

所以,下面我们先说说,变量的赋值

2 变量的赋值

枚举类型的赋值其实是比较复杂的,先说最常用的。

2.1 默认值

enum aa {
     a1, a2, a3 };

对于上述枚举类型,它的a1 a2 a3, 在默认情况下,会被赋值为

a1 = 0;
a2 = 1;
a3 = 2;

2.2 赋初值

enum aa {
     a1 = 1, a2 = 3, a3 = 5 };

可以对其任意赋初值,这样,三个枚举成员的值就对应了你指定的值了。

我们看看多种情况:

情况1:全都赋初值

enum aa {
     a1 = 1, a2 = 3, a3 = 5 };

情况2:有重复的初值

这种情况的完全可以的。

enum aa {
     a1 = 1, a2 = 1, a3 = 5 };

情况3:部分赋初值,部分不赋值

enum aa {
     a1 = 1, a2, a3 };

对于此时,a2 = 2 a3 = 3,也就是说,后面没有赋值的,是默认根据前面赋值的累加的

enum aa {
     a1 = 1, a2, a3, a4 = 10, a5, a6 };

那这种情况呢?

  • 根据a1累加:a2 = 2 a3 = 3 a4 = 4
  • 根据a4累加:a5 = 11 a6 = 12

赋值范围

与int类型赋值范围一样!赋值-1什么的也可以,与int类型的范围一样的。

2.3 变量赋值

其实就是定义一个变量,然后给它赋值,这里不一样的是,枚举成员本身,就代表值

enum aa {
     a1 = 1, a2, a3, a4 = 10, a5, a6 };
enum aa abc = a2;

这个时候,abc = 2a2就代表数值2.

从其他角度理解,enum aa abc = a2;的含义就是

int a2 = 2;
int abc = a2;

就是这么个意思。

2.4 指针赋值

enum aa abc = a2;  
enum aa *enu_p = &abc;
printf("%d\n", *enu_p);		

没啥好说的,跟基本数据类型指针待遇一样的。

3 谈谈枚举成员

3.1 作用范围

首先,结构体本身

enum aa {
     a1 = 1, a2, a3, a4 = 10, a5, a6 };

它的作用范围,跟struct一样,跟int也一样,{ } 里面就是局部变量,在最外面就是全局变量,对于aa这个自定义类型标识符,也是一样的,不多说了。

比较需要注意的是,枚举成员也是标识符

3.2 枚举成员也是标识符

我们上面的例子,a1,a2,a6这些,在其作用域内,也是标识符,也就是相当于你定义了一个int a1;一样,在作用域内不能重复定义了!并且,这个标识符本身代表了一个int值。

int main(){
    
	enum aa {
     a1 = 1, a2, a3, a4 = 10, a5, a6 };
	int a1; // error!重定义了!上面定义过a1了!
	enum bb {
    a2,a4}; // error!
}

4 enum与int

enum中的枚举成员,都是int类型的变量,也代表int类型的值,值的范围也是int的范围。

5 enum与#define

5.1 共同点

下面两段代码基本来说是等价的:

#define Working 0
#define Failed 1
#define Freezed 2
enum state  {
    Working, Failed, Freezed};

5.2 enum的优势

#define是全局的,而enum则是与基本数据类型一样,范围非常灵活。

5.3 #define的优势

enum只能定义int类型值,define什么都可以等价,任何值,以及函数,都可以。

6 enum的大小(size)

6.1 变量的大小

注意:讨论enum结构本身大小没必要,因为其变量,就是这个结构的实例化,这一点和struct一样的!

enum aa {
     a1 = 10, a2, a3 };
enum aa abc = a2;
printf("size = %d\n", sizeof(enum aa)); // 4 
printf("size = %d\n", sizeof(abc));		// 4

试一下就知到了,都是4字节。这俩肯定相等,一个是模板,一个是实例

为什么是4呢?

因为enum这里面的值,其实就是int类型的,那不就是4吗!然后这个枚举变量,值只能有一个吧,那就占一个4字节空间足够了。

像struct那是可以有多个值,所以每个变量都占空间,这个就没必要,一堆里面选一个就可以了。

另外就是,不要试图获取枚举成员的地址,因为它有没有用上场都不一定呢,它只是C语言层级的一个值而已,不一定被分配

在这里插入图片描述

好吧,没人这么闲的没事干。

7 奇奇怪怪

enum aa abc = 100;
printf("***%d\n", abc); // 100

这种情况下,就真的当int用了,其实也没啥,反正编译器允许,不过一般没人这么干。

8 最后,说说真正常用的地方

说实话,说了这么多,基本都很少用得到!常用的地方也就固定套路,内些野路子你看看就好。

就比如你定义个月份什么,星期什么的。

#include<stdio.h>
  
enum year{
    Jan, Feb, Mar, Apr, May, Jun, Jul, 
          Aug, Sep, Oct, Nov, Dec};
  
int main()
{
    
   int i;
   for (i=Jan; i<=Dec; i++)      
      printf("%d ", i);
        
   return 0;
}

另外还有就是,编译原理中的,词法分析器的单词表,需要把编号和名称对应起来,enum是天然适合的结构,使用struct嵌套enum和其他,就很完美很方便。

原网站

版权声明
本文为[XV_]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_42929607/article/details/116003843