有时候我经常看到一些这样的代码:
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位是一样的:
结果:
从中可以看出不管如何赋值,enum都是4字节的。
但51不同:
结果:从图可以看出所enum内容占位数是2字节,标识符为1字节,然后,我发现了一个特殊的现象:
代码:
现象:代码:
现象:这一长串可能你看不懂,其实就是我想看一下标识符附一个超过一个字节数看能否正常输出,结果是不加判断条件是不可以的,越界了是0x100,输出是000,但加了一个判断条件时就可以正常输出256(后面第一个判断不用管,程序的bug它恒小于0xff,我原本是想看看枚举数据能否大于一个字节,但是这种判断方法不行,因为标识符那个也会大于0xff,如图:
)
然后,超出范围不好查看,我在qt上也试过,不好输出。(有大佬教教我吗)
2.与宏定义的区别:
枚举数据类型的作用范围有限,和普通变量一样,在函数内部只能作用于内部,在其它文件中需要申明。
其中函数内部的代码如下:(其它文件的可以自己动手实践)
函数。
本文参考资料链接:
http://c.biancheng.net/view/2034.html
https://www.runoob.com/cprogramming/c-enum.html
https://baike.baidu.com/item/ENUM/10934073?fr=aladdin
最后,希望这个对大家有帮助,如有错误,大家可以指出来,教教我