当前位置: 首页 > news >正文

C语言自动生成宏定义枚举类型和字符串

#include <stdio.h>// 定义错误枚举
#define ERROR_LIST(e) \e(SUCCESS)        \e(FAILURE)        \e(NOT_FOUND)      \e(TIMEOUT)// 使用宏生成枚举
#define GENERATE_ENUM(ENUM) ENUM,
typedef enum {ERROR_LIST(GENERATE_ENUM)
} ErrorCode;// 使用宏生成字符串数组
#define GENERATE_STRING(STRING) #STRING,
const char* ErrorStrings[] = {ERROR_LIST(GENERATE_STRING)
};// 测试
int main() {for (int i = 0; i < sizeof(ErrorStrings) / sizeof(ErrorStrings[0]); i++) {printf("Error %d: %s\n", i, ErrorStrings[i]);}return 0;
}

代码解释:
ERROR_LIST:宏定义,用于列举所有错误码。
GENERATE_ENUM:宏定义,用于生成枚举值。
GENERATE_STRING:宏定义,用于将枚举值转换为字符串。
ErrorStrings:通过宏展开生成的字符串数组,数组中的每个元素对应一个错误码的字符串表示。

输出:

Error 0: SUCCESS
Error 1: FAILURE
Error 2: NOT_FOUND
Error 3: TIMEOUT

宏展开过程
宏 #define GENERATE_ENUM(ENUM) ENUM, 的详细解析
这个宏定义用于生成枚举值,并在每个枚举值后面加上一个逗号。
ENUM:是宏的参数,代表传递给宏的一个标识符(通常是枚举值的名字)。
ENUM,:这是宏展开后的内容。它表示将传递给宏的 ENUM 参数保留原样,然后在后面加上一个逗号 ,。

当预处理器处理这个宏时,会将 ERROR_LIST(GENERATE_ENUM) 展开为:

typedef enum {SUCCESS,FAILURE,NOT_FOUND,TIMEOUT,
} ErrorCode;

如上所示,ERROR_LIST(GENERATE_ENUM) 会依次替换为:

GENERATE_ENUM(SUCCESS) → SUCCESS,
GENERATE_ENUM(FAILURE) → FAILURE,
GENERATE_ENUM(NOT_FOUND) → NOT_FOUND,
GENERATE_ENUM(TIMEOUT) → TIMEOUT,

末尾逗号的问题
在标准 C 和 C++ 中,枚举类型的最后一个值后面可以带逗号,也可以不带逗号。也就是说,下面两种写法都是合法的:

typedef enum {SUCCESS,FAILURE,NOT_FOUND,TIMEOUT,  // 这种情况是合法的
} ErrorCode;
typedef enum {SUCCESS,FAILURE,NOT_FOUND,TIMEOUT // 这种情况也是合法的
} ErrorCode;

在预处理展开后,最后一个枚举值 TIMEOUT 后面也会带有逗号。这在 C/C++ 中是合法的,因为编译器允许最后一个枚举项后面跟随一个逗号。

为什么宏这样设计?
简化代码:通过这种设计,代码生成的逻辑变得更加一致,每个枚举值后面都会自动加上一个逗号,省去了在 ERROR_LIST 内部手动加逗号的麻烦。
方便添加/移除元素:如果未来需要在 ERROR_LIST 中添加或移除枚举值,不用担心逗号的问题,因为每个宏展开后的项都是独立的,最后一项的逗号不会引起语法错误。

http://www.lryc.cn/news/429389.html

相关文章:

  • C#单例模式
  • 10-使用sentinel流控
  • redis AOF机制
  • Day 21代码|随想录| 二叉树完结撒花,今日刷题669.修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.吧二叉搜索树转换为累加树
  • cmake教程一
  • 3D场景标注标签信息,three.js CSS 2D渲染器CSS2DRenderer、CSS 3D渲染器CSS3DRenderer(结合react)
  • C++参悟-单例模式
  • 【题解】—— LeetCode一周小结32
  • 详解线索分层的目的、维度与创新实践
  • 于8月21号的回顾
  • Abstract Class抽象类
  • webrtc ns 降噪之粉红噪声参数推导
  • IO进程线程8月21日
  • Web安全:SqlMap工具
  • 用手机写一本电子书
  • 【网络编程】基于UDP的TFTP文件传输
  • Vue 3 + Pinia 实现网页刷新功能
  • DVWA综合靶场漏洞讲解
  • 实现Bezier样条曲线
  • MySQL中的EXPLAIN的详解
  • LearnOpenGL——SSAO学习笔记
  • [C语言]-基础知识点梳理-文件管理
  • pcdn闲置带宽被动收入必看教程。第五讲:光猫更换和基础设置
  • 工业数据采集网关简介-天拓四方
  • Java 调整字符串,验证码生成
  • 【专题】全球商用服务机器人市场研究(2023)报告合集PDF分享(附原数据表)
  • SQL UA注入 (injection 第十八关)
  • 初阶数据结构之计数排序
  • 【开端】记一次诡异的接口排查过程
  • jenkins最佳实践(二):Pipeline流水线部署springCloud微服务项目