C语言中的enum

有时候我经常看到一些这样的代码:

typedef enum
{ 
  GPIO_OType_pp = 0x00,
  GPIO_OType_od = 0x01
}GPIOOType_typeDef;

我们都知道enum是枚举数据类型,那么它具体有什么用呢?(typedef 先不管,以后我可能单独写一篇关于它的)我们先来看一段代码(实验平台是qt,下面截图的代码除了51全在下面):

#include <stdio.h>
//#include <cs.h>
#define char1 0x01
#define char2 0x02
#define char3 (unsigned char)0x03
#define char4 (unsigned short)0x04

enum day
{
    saturday=7,
    sunday,
    monday,
    tuesday,
    wednesday,
    thursday,
    friday
} workday;

//enum恒为数据为四位
enum chara
{
    chara1=(unsigned char)0x01,
    chara2=(unsigned char)0x02,
    chara3=(unsigned char)0x04,
    chara4=(unsigned char)0x08
};

enum charb
{
    charb1=(unsigned char)0x01,
    charb2=(unsigned char)0x02,
    charb3=(unsigned char)0x04,
    charb4=(unsigned char)0x08
}charbx;

enum
{
    charx1=0x01,
    charx2=chara2,
    charx3=chara3,
    charx4=charb4
};

enum
{
    charc1=0x01,
    charc2=charx2,
    charc3=chara3,
    charc4=charb4
}charcx;


//enum chard chard1=0x01,chard2=0x02,chard3=chara4,chard4=charb4;
//enum chard chard1,chard2,chard3,chard4;
//enum weekday a,b,c;

enum anum
{
    anum1,
    anum2,
    anum3,
    anum4=9,
    anum5,
    anum6
}anumx;

void show(void)
{
    enum day
    {
        saturday,
        sunday,
        monday,
        tuesday,
        wednesday,
        thursday,
        friday
    } workday;
    
    int a = 1;
    enum day weekend;
    //weekend = ( enum day ) a;  //类型转换
    weekend = a; //错误
    printf("weekend:%d",weekend);
    printf("\nshow friday=%d",friday);
}

int main()
{
    enum chara charax1,charax2,charax3,charax4,charax5,charax6;
    int int1=1;
    unsigned int uint1=1;
    char charx1=1;
    //        int *p;
    //        p=&charax3;
    //        *p=19;
    //        printf("*p=%d\n"
    //               "charax3=%d\n\n",*p,charax3);
    //    charax6=0x100000000;
    //    printf("%lld\n\n",charax6);
    
    charax5=charx1;
    charax1=chara1;
    charax2=1;
    charax3=int1;
    charax4=uint1;
    //    chara1=0;
    
    printf("chara1=%d\n"
           "chara2=%d\n"
           "chara3=%d\n"
           "chara4=%d\n\n"
           ,chara1,chara2,chara3,chara4);
    
    printf("charb1=%d\n"
           "charb2=%d\n"
           "charb3=%d\n"
           "charb4=%d\n\n"
           ,charb1,charb2,charb3,charb4);
    
    printf("charx1=%d\n"
           "charx2=%d\n"
           "charx3=%d\n"
           "charx4=%d\n\n"
           ,charx1,charx2,charx3,charx1);
    
    printf("charc1=%d\n"
           "charc2=%d\n"
           "charc3=%d\n"
           "charc4=%d\n\n"
           ,charc1,charc2,charc3,charc4);
    
    printf("anum1到anum6分别是:\n"
           "anum1=%d\n"
           "anum2=%d\n"
           "anum3=%d\n"
           "anum4=%d\n"
           "anum5=%d\n"
           "anum6=%d\n\n"
           ,anum1,anum2,anum3,anum4,anum5,anum6);
    
    printf("charax1=%d\n"
           "charax2=%d\n"
           "charax3=%d\n"
           "charax4=%d\n"
           "charax5=%d\n\n"
           ,charax1,charax2,charax3,charax4,charax5);
    
    printf("默认宏定义字节数:%d\n"
           "char型宏定义字节数:%d\n"
           "short宏定义字节数:%d\n\n"
           ,sizeof(char1),sizeof(char3),sizeof(char4));
    
    printf("enum内数据所占字节数:%d\n",sizeof(charc1));
    printf("charax5所占字节数:%d\n"
           "charx1所占字节数:%d\n"
           "标识符所占字节:%d\n\n"
           ,sizeof(charax5),sizeof(charx1),sizeof(charax1));
    
    show();
    
    printf("\nmain friday=%d",friday);
    
    return 0;
}

代码可能有点长,我拆开来分析。

1.定义:
enum是计算机编程语言中的一种数据类型。枚举类型:在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等。如果把这些量说明为整型,字符型或其它类型显然是不妥当的。为此,C语言提供了一种称为“枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。(摘自百度百科)
简而言之,就是将描述一个对象的同一方面的内容集中写一起,并将其数字化。比如将描述颜色红、橙、黄、绿、青、蓝、紫…的写一起并为其赋值,当我们描述颜色时就直接用红、橙…等名称就行。

2.实际用途:
1.方便了解我们自己定义了什么东西去描述一个对象的那个方面。
2.判断描述一个对象时,描述内容是否合法。
实现方法:#define is_y([描述内容]) ( ( [描述内容]&[合法内容1] ) | ( [描述内容]&[合法内容2] ) )
当合法时:is_y([描述内容])=1,否则is_y([描述内容])=0。

3.定义形式:

经过我查找资料和实践,能编译通过有四种分别是:
①.enum [自定义的枚举类型名称] {[枚举值表]};
②.enum [自定义的枚举类型名称] {[枚举值表]} [枚举类型变量标识符(类似int a;中的a)];
③.enum {[枚举值表]} [枚举类型变量标识符(类似int a;中的a)];
④.enum {[枚举值表]}
那它们之间有什么区别呢?
①和②中的[自定义的枚举类型名称]相当于自己创造了一种新类型,我们可以向代码中的(enum chara charax1)一样定义一个新的变量,而②的话还直接定义了一个变量。
③和④的话就没有[自定义的枚举类型名称]这一选项,也就意味着不能去定义一个新变量。
在正常用的时候我们并不需要一个[自定义的枚举类型名称]去定义一个新类型,也用不到定义一个[枚举类型变量标识符(类似int a;中的a)]的变量标识符。
但是,我觉得可以定义其中的一个,这样放变我们通过编辑器查找定义这一类型的地方,当然也可以随便写一个在其中的一个变量,然后跳转。我个人习惯③这一方法。
(百度百科还有这一种,但我用不了,会报错,我怀疑少打了一个大括号,或者是其他语言的定义形式,有大佬知道吗在这里插入图片描述

4.注意事项:
1.枚举数据范围:
我试验了三种平台,分别为16位的51单片机,qt下的x86和x64,也就是32位和64位系统,其中32位和64位是一样的:
其中charax是定义char型变量,如下图

结果:

从中可以看出不管如何赋值,enum都是4字节的。
但51不同:


结果:从图可以看出所enum内容占位数是2字节,标识符为1字节,然后,我发现了一个特殊的现象:
代码:

现象:
在这里插入图片描述代码:

现象:
这一长串可能你看不懂,其实就是我想看一下标识符附一个超过一个字节数看能否正常输出,结果是不加判断条件是不可以的,越界了是0x100,输出是000,但加了一个判断条件时就可以正常输出256(后面第一个判断不用管,程序的bug它恒小于0xff,我原本是想看看枚举数据能否大于一个字节,但是这种判断方法不行,因为标识符那个也会大于0xff,如图:

然后,超出范围不好查看,我在qt上也试过,不好输出。(有大佬教教我吗)
2.与宏定义的区别:
枚举数据类型的作用范围有限,和普通变量一样,在函数内部只能作用于内部,在其它文件中需要申明。
其中函数内部的代码如下:(其它文件的可以自己动手实践)

![](https://img-blog.csdnimg.cn/ddd5e45d16984e27802867c35c3f7cd4.png#pic_center

现象:

3.与普通int之类的区别:
无法在其它位置给元素赋值,很像用const修饰的变量,不能直接修改它好像也可以用指针去修改:
4.然后菜鸟教程中有一个错误,好像那个不是错误:
这个我代码里有,就是show()函数。

本文参考资料链接:
http://c.biancheng.net/view/2034.html
https://www.runoob.com/cprogramming/c-enum.html
https://baike.baidu.com/item/ENUM/10934073?fr=aladdin

最后,希望这个对大家有帮助,如有错误,大家可以指出来,教教我


版权声明:本文为ldl666999原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。