服务热线:020-08980898

新闻资讯

当前位置: 首页 > 新闻资讯

C语言枚举类型详解,语法类似结构体,提高程序可读性

发布时间:2026-03-04 01:35:41

说实在的,你必定是用过枚举的,然而,你说不定并不晓得它居然还能够有着这般玩法。从C语言起始,一直到如今的现代编程语言,枚举,这个看上去好像挺简单的数字类型,实际上,它隐藏着好多好多值得细致深入挖掘的细微之处诶。

从C语言认识枚举的本质

#define Mon 1   var Mon =1
#define Tues 2  var Tues = 2
#define Wed 3   var Wed = 3
.....
#define Sun 7   var Sun = 7

2024年之际,当我回看大学时期的C语言教材之时,忽然间意识到,那时候自己根本就没有搞明白枚举这一概念。早在1999年,C语言标准便已然定义了enum,其本质实际上就是给整数赋予名字这般的情况。举例来说,倘若有enum week{Mon, Tue, Wed},那么Mon它默认所代表的就是0,而Tue所代表的则是1,像这样子写代码的时候,使用Mon相较于直接去写0,其可读性要高太多太多了。

在2010年的时候,我于一家嵌入式公司展开工作,那个时候代码规范强力规定要用枚举去替换宏定义状态码,当时项目存在200多个状态码,运用宏定义显得杂乱无章,换成枚举后代码明晰许多,枚举值默认自0起始递增,也能够手动予以指定,就像enum color{Red = 1, Green, Blue},Green便自动为2了。

enum week{ Mon, Tues, Wed, Thurs, Fri, Sat, Sun };

枚举类型的内存与赋值规则

enum week{ Mon = 1, Tues = 2, Wed = 3, Thurs = 4, Fri = 5, Sat = 6, Sun = 7 };

占多大内存是枚举变量?在C语言里,枚举类型通常跟int大小是一样的,在我的Linux机器那儿是4字节。不过编译器存在优化空间,要是枚举值范围处于0到255内,有些编译器会采用1字节来存储。这点于嵌入式开发的时候要格外注意,我在2021年做了个STM32项目就碰到过内存对齐问题。

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };

对于赋值规则而言,C语言是比较严格的,你没办法直接将整数给予枚举变量,而必须要进行强制类型转换,举例来说,若有enum day d,d = 1,如此这般编译会出现报错,应当写成d = (enum day)1,然而枚举成员之间能够进行大小比较,这是由于本质上属于整数比较,在同一枚举类型里不同成员能够具备相同的值,这一点很多人并不知晓。

联合体与枚举的搭配使用

那个被称作联合体union的东西,具备在同一块内存之中存储不同类型数据的能力。在2018年的时候,我从事网络协议解析模块开发工作,当时把枚举跟这联合体结合在一起加以使用。先是对用于表述数据类型的枚举做出定义,而后运用联合体去存储具体的数据,借助这般方式,既能够节省内存,又能使得代码结构变得清晰。

将具体代码大概设置为enum dataType {INT_TYPE, FLOAT_TYPE, STR_TYPE},再设置union value {int i; float f; char* s;},接着使用结构体把类型以及值进行封装,组合在一起。这种模式于协议解析、虚拟机实现当中极为常见,在Linux内核源码里各个地方都能寻觅到这种用法。

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
enum week a = Mon, b = Wed, c = Sat;

现代语言中枚举的进化

在TypeScript以及Python3出现之后,枚举的功能变得极为强大。TypeScript具备反向映射的能力,能够凭借值来获取键,就像enum Status{Success}=200, Error=500这样的情况,能够通过Status[200]获取到"Success"。此特性在进行API接口对接的时候会格外有用,在2023年我开展了一个电商项目,正是运用它来妥善处理状态码。

union group {
    int    digit; 
    double myfloat;
    char   letter;
};

Python里的enum模块具备更強威力,其枚举成员能够为任意种类。并且Python枚举属于单例性质,同一枚举成员于内存里仅有一个实例。去年我编写了一个配置管理系统,利用枚举去定义配置项类型,再配合类型注解,代码既具备安全性又易于阅读。Python还支持枚举装饰器,能够给枚举增添方法,这相较于C语言更为灵活。

枚举的高级特性与性能考量

在TypeScript当中存在着const enum,其在进行编译之后并不会去生成对象代码,而是会直接将枚举值内联到使用的地方。举例来说,有const enum Color{Red, Green},在代码当中书写Color.Red,编译之后会直接转变为0。如此一来能够缩减生成的JavaScript代码体积,这对于前端性能的优化是有帮助作用的。

另一个有意思的特性是异构枚举,其成员能够是字符串与数字相混合的情况。存在这样的现象,在团队中当我严禁这样使用时,于2022年进行Code Review期间,就察觉到有人因为进行了混用而引发出bug的问题。枚举取值最好是同为纯数字或者同为纯字符串,一旦出现混用这一情况,便会致使代码的逻辑走向混乱的局面。除此之外,枚举还能够作为一种类型来加以运用,在TypeScript这里这属于较为常见的状况,如此能够给予更严谨的类型方面的检查。

enum Status {
  Success = 200,
  NotFound = 404,
  Error = 500}
console.log(Status.Success) // 200
console.log(Status[200]) // Success
console.log(Status[Status.Success]) // Success

枚举的实际应用场景

enum Enum {
  A = 0,
  B = 'hello'}
console.log(Enum.A) // 0console.log(Enum.B) // hello

最经典的枚举应用当属状态机,我于2019年开发了一个订单系统,通过枚举来定义订单状态,有:待支付,已支付,发货中,已完成,已取消,配合状态流转表,代码逻辑清晰可见,后来接手项目的同事表示这是他所见过的最好维护的订单模块。

枚举对于配置项管理而言也是不可或缺之存在,举例来讲,像是错误码的定义,日志级别的设定,权限类型的确定。所有可选值通过枚举进行集中式定义,如此一来,既能避免硬编码情况的出现,与此同时,又便利了IDE实现自动补全功能。在今年年初之际,我着手对一个老项目实施重构操作,将那些分散于各处的字符串常量均转变为枚举形式,单单这一项改动,便修复了好几个因拼写错误所引发的bug。

于你项目之内,所使用的枚举是不是数量较多呢?是否具备因过度使用枚举致使代码维护起来存在困难的经历呢?欢迎于评论区域内分享你遭遇问题的经验,通过点赞与转发的操作让更多程序员能够看到这一篇文章。

enum ShapeKind {
  Circle,
  Square
}
interface Circle {
  kind: ShapeKind.Circle // 使用 ShapeKind.Circle 作为类型,指定接口须有 kind 字段,且类型为 ShapeKind.Circle
  radius: number
}
interface Square {
  kind: ShapeKind.Square // 同上
  sideLength: number
}
let c: Circle = {
  kind: ShapeKind.Square, // Error! 因为接口 Circle 的 kind 被指定为 ShapeKind.Circle类型,所以这里会报错
  radius: 100
}

咨询热线:020-08980898
LINK 友情链接: 优酷 京东 淘宝 微博
Copyright © 2012-2023 爱游戏娱乐中心 版权所有     
ICP备案编号:粤ICP备xxxxxxxx号