C语言中的枚举
枚举类型是一种独立的类型其值为其底层类型的值其中包含了显式命名的常量枚举常量的值。例如#includestdio.htypedefenum{HAL_OK0x00,HAL_ERROR0x01,HAL_BUSY0x02,HAL_TIMEOUT0x03}HAL_StatusTypeDef;intmain(){HAL_StatusTypeDef statusHAL_ERROR;printf(%d,status);return0;}运行输出底层类型枚举本质上是基于整数通常是 int实现的每个枚举常量都对应一个整数数值。枚举常量就是 HAL_OK、HAL_ERROR 这类在 enum 里定义的名字它们本质上是编译时确定的整数常量。把上例修下改变了枚举常量的值#includestdio.htypedefenum{HAL_OK0x10,HAL_ERROR0x11,HAL_BUSY0x12,HAL_TIMEOUT0x13}HAL_StatusTypeDef;intmain(){HAL_StatusTypeDef statusHAL_ERROR;printf(%d,status);return0;}运行输出不显式定义枚举常量的值#includestdio.htypedefenum{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}HAL_StatusTypeDef;intmain(){HAL_StatusTypeDef statusHAL_ERROR;printf(%d,status);return0;}运行输出不用typedef定义别名#includestdio.henumHAL_StatusTypeDef{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT};intmain(){enumHAL_StatusTypeDefstatusHAL_ERROR;printf(%d,status);return0;}运行输出定义枚举类型声明变量可以写在同一行例如#includestdio.hintmain(){enumHAL_StatusTypeDef{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}statusHAL_ERROR;printf(%d,status);return0;}运行输出出现在枚举说明符enum { … }主体中的每个枚举常量在其所在作用域中都会变成一个 int 类型的整数常量C23 标准之前并且可以在任何需要整数常量的地方使用例如case 标签或非变长数组的长度。例如#includestdio.hintmain(){enumHAL_StatusTypeDef{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}statusHAL_ERROR;printf(%d,status100);return0;}运行输出再例如#includestdio.hintmain(){enumHAL_StatusTypeDef{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}statusHAL_ERROR;switch(status){caseHAL_OK:puts(HAL_OK);break;caseHAL_ERROR:puts(HAL_ERROR);break;caseHAL_BUSY:puts(HAL_BUSY);break;caseHAL_TIMEOUT:puts(HAL_TIMEOUT);break;}return0;}运行输出如果是枚举里第一个常量且没有手动赋值类型是 int。例如#includestdio.htypedefenum{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}HAL_StatusTypeDef;intmain(){HAL_StatusTypeDef statusHAL_OK;printf(%d\n,HAL_OK);return0;}运行输出如果手动赋值了且值在 int 能表示的范围内类型是 int。例如#includestdio.htypedefenum{HAL_OK1999,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}HAL_StatusTypeDef;intmain(){HAL_StatusTypeDef statusHAL_OK;printf(%d\n,HAL_OK);return0;}运行输出如果没有手动赋值枚举常量的值是上一个常量的值 1它的类型由上一个常量的类型决定。例如#includestdio.htypedefenum{HAL_OK100,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}HAL_StatusTypeDef;intmain(){HAL_StatusTypeDef statusHAL_ERROR;printf(%d\n,HAL_ERROR);return0;}运行输出第一个枚举常量如果没跟 默认值是 0。例如#includestdio.htypedefenum{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}HAL_StatusTypeDef;intmain(){HAL_StatusTypeDef statusHAL_OK;printf(%d\n,HAL_OK);return0;}运行输出如果枚举常量后面跟了 和常量表达式那它的值就是这个表达式的值。例如#includestdio.htypedefenum{HAL_OK-1,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}HAL_StatusTypeDef;intmain(){HAL_StatusTypeDef statusHAL_OK;printf(%d\n,HAL_OK);return0;}运行输出枚举定义中的标识符会进入标签名空间因此声明变量时必须带上 enum 关键字除非用typedef 把它重定义到普通名空间就可以直接用别名声明变量。例如#includestdio.henumHAL_StatusTypeDef{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT};intmain(){//正确enumHAL_StatusTypeDefstatusHAL_OK;//错误//HAL_StatusTypeDef status2 HAL_OK;printf(%d\n,HAL_OK);return0;}运行输出再例如#includestdio.htypedefenum{HAL_OK,HAL_ERROR,HAL_BUSY,HAL_TIMEOUT}HAL_StatusTypeDef;intmain(){//正确enumHAL_StatusTypeDefstatusHAL_OK;printf(%d\n,status);//正确HAL_StatusTypeDef status2HAL_BUSY;printf(%d\n,status2);return0;}运行输出C 语言中枚举的一个关键限制不支持前向声明forward declaration和 struct/union 不一样。前向声明就是先告诉编译器 “有这么一个类型存在”但暂时不给出它的完整定义后面再补全。例如下面是错误的