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 中添加或移除枚举值,不用担心逗号的问题,因为每个宏展开后的项都是独立的,最后一项的逗号不会引起语法错误。
相关文章:
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;// 使用宏生成字符串数组…...
C#单例模式
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace _3._3._6_单例模式 {public class Singleton{private static Singleton s_instance;private int _state;private Singleton(int …...
10-使用sentinel流控
本文介绍sentinel的直接流控的使用。 0、环境 jdk 1.8sentinel 1.8.2springboot 2.4.2 1、sentinel环境搭建 从官方发布的网站上下载: sentinel Jar,下载对应版本。 下载完成后,进入刚才下载的Jar文件所在的目录,执行如下命令:…...
redis AOF机制
在redis运行期间,不断将redis执行的写命令写到文件中,redis重启之后,只要将这些命令重复执行一遍就可以恢复数据。因为AOF只是将少量的写命令写入AOF文件中,因此其执行效率高于RDB,开启AOF即使Redis发生故障࿰…...
Day 21代码|随想录| 二叉树完结撒花,今日刷题669.修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.吧二叉搜索树转换为累加树
提示:DDU,供自己复习使用。欢迎大家前来讨论~ 文章目录 二叉树 Part06二、题目题目一:669.修剪二叉搜索树解题思路:递归法迭代法: 题目二: 108.将有序数组转换为二叉搜索树解题思路递归法:迭代…...
cmake教程一
1. Start 1.1 构建简单工程 cmake_minimum_required(VERSION 3.0) project(Step1) add_executable(Step1 main.cpp)设置cmake最低版本要求设置工程名字设置工程生成可执行程序 2. 声明 C Standard set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True)如果我…...
3D场景标注标签信息,three.js CSS 2D渲染器CSS2DRenderer、CSS 3D渲染器CSS3DRenderer(结合react)
如果你想用HTML元素作为标签标注三维场景中模型信息,需要考虑定位的问题。比如一个模型,在代码中你可以知道它的局部坐标或世界坐标xyz,但是你并不知道渲染后在canvas画布上位置,距离web页面顶部top和左侧的像素px值。自己写代码把…...
C++参悟-单例模式
单例模式 一、概述1. 特点2. 实现方式3. 应用场景 二、实现代码1. 静态局部变量的懒汉单例2. 加锁的懒汉式单例3. 使用 C11 中的 std::call_one 的懒汉单例4. 饿汉式单例 一、概述 这里记录一下单例模式的最常用使用,单例模式(Single Pattern࿰…...
【题解】—— LeetCode一周小结32
🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 【题解】—— 每日一道题目栏 上接:【题解】—— LeetCode一周小结31 5.不含连续1的非负整数 题目链接:600. 不含连续…...
详解线索分层的目的、维度与创新实践
线索分层是一个系统性的过程,旨在更有效地管理、跟踪和利用线索资源。这一过程可以借鉴多种策略和方法,特别是在用户运营和市场营销中。 1、线索分层的目的 线索分层的主要目的是根据线索的不同特征或成熟度,将其分类管理,以便更…...
于8月21号的回顾
傍晚的日落和逐渐深邃的夜,驱散了白天的极致闷热。倦怠和疲惫充斥着大脑,喧嚣的浮沉又在耳边轰鸣。 我不曾想到,再次打开博客已经是两年后的今天了。手指轻轻滑过鼠标,博客的页面缓缓加载,那些被时间尘封的记忆瞬间涌…...
Abstract Class抽象类
抽象类(Abstract Class)在面向对象编程中是一种特殊的类,它不能被实例化,即不能创建该类的对象。抽象类主要用于定义一组接口(即方法),这些方法的具体实现由子类来完成。抽象类通常用于表示一种…...
webrtc ns 降噪之粉红噪声参数推导
webrtc中降噪中,前50帧需要进行简单噪声估计,使用白噪声和粉红噪声模型估算。 首先我们 复习 有色噪声(包含白噪声)的一般模型: S(f) 是频率 f 处的功率谱密度。f是频率。α 是一个频谱指数,通常在1左右。…...
IO进程线程8月21日
1,思维导图 2,登录 #ifndef __LOG_H__ #define __LOG_H__ #include<myhead.h> typedef struct {char name[20];char pwd[20]; }str;int regist();int login(); #endif#include"log.h" int login() {char a[20]"\n";str p,s;…...
Web安全:SqlMap工具
一、简介 sqlmap 是一款开源的渗透测试工具,可以自动化进行SQL注入的检测、利用,并能接管数据库服务器。它具有功能强大的检测引擎,为渗透测试人员提供了许多专业的功能并且可以进行组合,其中包括数据库指纹识别、数据读取和访问底层文件系统…...
用手机写一本电子书
第1步、进入Andi.cn网站 第2步、点击登录,注册用户 第3步、点击去创作,进入创作页面 第4步、点击右下角的小笔,写一篇文章 第5步、下翻,点击提交按钮 第6步、再写一篇文章 第7步、点击栏目设计 第8步、进入栏目设计,点…...
【网络编程】基于UDP的TFTP文件传输
1)tftp协议概述 简单文件传输协议,适用于在网络上进行文件传输的一套标准协议,使用UDP传输 特点: 是应用层协议 基于UDP协议实现 数据传输模式 octet:二进制模式(常用) mail:已经不再…...
Vue 3 + Pinia 实现网页刷新功能
概述 在现代 Web 开发中,保持用户界面的动态性和响应性至关重要。当用户触发某些操作时,例如点击按钮或者完成表单提交,我们往往需要刷新页面的一部分来展示最新的数据。本文将介绍如何使用 Vue 3 和 Pinia 来实现这一功能。 技术栈 Vue 3…...
DVWA综合靶场漏洞讲解
目录 综合靶场漏洞讲解 Brute Force Low Medium High Command Injection Low Medium High File Inclusion Low,Medium,High File Upload Low Medium High SQL Injection Low Medium High SQL Injection (Blind) Low Medium High XSS(DOM&am…...
实现Bezier样条曲线
1.给出n1 个控制点pk(xk,yk,zk),这里k可取值0-n,多项式函数公式如下 获取的单个点的代码 void zmBezier::getPoint(float u, double p[3]) {int n m_count - 1;double x 0, y 0, z 0;for(int k 0; k < n; k){x m_ctrlPoints[k][0] * BEZ_k_n(n, k, u);y m_ctrlPoin…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
