「C/C++」C/C++预处理 之 X宏(X Macro)

在这里插入图片描述

✨博客主页
何曾参静谧的博客
📌文章专栏
「C/C++」C/C++程序设计
📚全部专栏
「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合
「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发
「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明

目录

    • X宏(X Macro)
      • 工作原理
      • 示例
      • 优点
      • 注意事项

X宏(X Macro)

X宏是一种在C和C++编程中使用的预处理技术,它允许程序员在单个位置定义一组相关的宏,然后在多个上下文中重用这些宏,而无需复制粘贴代码。这种技术特别适用于需要定义大量相关常量、枚举值、函数原型或类成员的场景。

工作原理

X宏的核心思想是将宏定义放在一个单独的文件(通常是头文件)中,并使用一个特殊的预处理指令(通常是#define后跟一个特殊的标识符,如X)来标记宏定义的开始和结束。然后,在需要这些宏的源文件中,通过包含这个头文件并重新定义X宏来生成所需的代码。

示例

假设我们有一个包含颜色名称和对应整数值的枚举,我们想要在不同的上下文中重用这些颜色定义。

colors.h(X宏定义文件):

#define COLORS_X(X) \X(RED, 1)       \X(GREEN, 2)     \X(BLUE, 3)      \// 可以继续添加更多颜色// 注意:这里没有#endif,因为这是一个独立的头文件片段

colors_enum.h(生成枚举):

#ifndef COLORS_ENUM_H
#define COLORS_ENUM_H#include "colors.h"typedef enum {
#define X(name, value) name = value,COLORS_X(X)
#undef XCOLORS_COUNT // 可选的,表示颜色总数
} Color;#endif // COLORS_ENUM_H

colors_strings.h(生成字符串数组):

#ifndef COLORS_STRINGS_H
#define COLORS_STRINGS_H#include "colors.h"#define X(name, value) #name,
const char* colorNames[] = {COLORS_X(X)
};
#undef X#endif // COLORS_STRINGS_H

main.c(使用生成的枚举和字符串数组):

#include <stdio.h>
#include "colors_enum.h"
#include "colors_strings.h"int main() {for (int i = 0; i < COLORS_COUNT; ++i) {printf("Color %d: %s\n", i, colorNames[i]);}return 0;
}

在这个例子中,COLORS_X宏在colors.h中定义了一组颜色名称和值。然后,在colors_enum.h中,我们通过重新定义X宏来生成一个枚举类型Color。在colors_strings.h中,我们再次重新定义X宏来生成一个字符串数组colorNames,其中包含每个颜色的名称。最后,在main.c中,我们包含了这些头文件并使用生成的枚举和字符串数组。

优点

  • 代码重用:通过在一个位置定义宏,并在多个上下文中重用它们,可以减少代码重复。
  • 易于维护:如果需要添加、删除或修改颜色定义,只需在colors.h中进行更改。
  • 灵活性:通过重新定义X宏,可以生成不同形式的代码(如枚举、字符串数组、函数原型等)。

注意事项

  • 命名冲突:确保X宏和任何相关的标识符(如COLORS_X)在全局命名空间中不会与其他代码冲突。
  • 可读性:虽然X宏可以提高代码的可维护性,但它们可能会降低代码的可读性,特别是对于不熟悉这种技术的程序员来说。因此,在团队项目中使用时,应确保所有成员都理解这种技术。
  • 预处理器限制:由于X宏依赖于预处理器指令,因此它们受到预处理器限制的影响(如宏展开的最大长度)。在定义大量宏时,应注意这些限制。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/58399.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF+MVVM案例实战(四)- 自定义GroupBox边框样式实现

文章目录 1、项目准备2、功能实现1、EnviromentModel.cs 代码2、GroubBoxViewModel.cs 代码实现3、ViewModelLocator.cs 依赖注入4、GroubBoxWindow.xaml 样式布局5、数据绑定3、效果展示4、资源获取1、项目准备 打开项目 Wpf_Examples,新建 GroubBoxWindow.xaml 界面、Groub…

第十六章 Vue组件化开发及组件局部/全局注册

目录 一、组件化 1.1. 组件概述 1.2. 语法高亮插件 ​编辑 1.3. 组件内部组成 1.4. 让组件支持 less 1.5. 组件注册的两种方式 二、局部注册 2.1. 使用描述 2.2. 脚手架工程变动的核心代码 2.2.1. 工程结构图 2.2.2. App.vue 2.2.3. WzxHeader.vue 2.2.4. WzxMain…

excel斜线表头

检验数据验证对象 鼠标放在检验数据 验证对象中间&#xff0c;altenter 之后空格 选中格子&#xff0c;右键单元格格式&#xff0c; 完成 如果是需要多分割&#xff0c;操作一样&#xff0c;在画斜线的时候会有区别&#xff0c;在插入里面用直线画斜线即可 在表格插入的时…

【python】OpenCV—Connected Components

文章目录 1、任务描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数6、参考 1、任务描述 基于 python opencv 的连通分量标记和分析函数&#xff0c;分割车牌中的数字、号码、分隔符 cv2.connectedComponentscv2.connectedComponentsWithStatscv2.connectedComponents…

日期选择简化版今日、本周、本月、本季度、本年

function 未来之窗_时间_现在() {let date new Date(),year date.getFullYear(), //获取完整的年份(4位)month date.getMonth() 1, //获取当前月份(0-11,0代表1月)strDate date.getDate() // 获取当前日(1-31),小时 date.getHours(),分钟 date.getMinutes();if (month &…

基于安卓Android的健康饮食系统APP(源码+文档+部署+讲解)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 会持续一直更新下去 有问必答 一键收藏关注不迷路 源码获取&#xff1a;https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwdjf1d 提取码: jf1d &#…

【Unity基础】初识UI Toolkit - 编辑器UI

&#xff08;本文所需图片在文章上面的资源中&#xff0c;点击“立即下载”。&#xff09; 本文介绍了如何通过UI工具包&#xff08;UI Toolkit&#xff09;来创建一个编辑器UI。 一、创建项目 1. 打开Unity创建一个空项目&#xff08;任意模板&#xff09;&#xff0c;这里我…

【网络】传输层协议TCP

目录 四位首部长度 序号 捎带应答 标记位 超时重传机制 连接管理机制&#xff08;RST标记位&#xff09; 三次握手及四次挥手的原因 TCP的全称是传输控制协议&#xff08;Transmission Control Protocol&#xff09;&#xff0c;也就是说&#xff0c;对于放到TCP发送缓冲…

docker基础篇(尚硅谷)

学习链接 docker1️⃣基础篇&#xff08;零基小白&#xff09; - 语雀文档 (即本篇) Docker与微服务实战&#xff08;基础篇&#xff09; Docker与微服务实战&#xff08;高级篇&#xff09;- 【上】 Docker与微服务实战&#xff08;高级篇&#xff09;- 【下】 文章目录 学习…

Spark RDD

概念 RDD是一种抽象&#xff0c;是Spark对于分布式数据集的抽象&#xff0c;它用于囊括所有内存中和磁盘中的分布式数据实体 RDD 与 数组对比 对比项数组RDD概念类型数据结构实体数据模型抽象数据跨度单机进程内跨进程、跨计算节点数据构成数组元素数据分片(Partitions)数据…

OmicsTools软件和R语言分析环境安装配置答疑汇总最新版

OmicsTools软件和R语言分析环境安装配置答疑汇总 前言提示 我开发了一款本地电脑无限使用的零代码生信数据分析作图神器电脑软件OmicsTools&#xff0c;欢迎大家使用进行生物医学科研数据分析和作图&#xff0c;不需要学编程写代码&#xff0c;分析次数没有限制&#xff0c;可…

java web调试时清理当前网址的缓存

java web调试时清理当前网址的缓存 背景 开发后端接口的时候&#xff0c;出现页面已经重新部署启动。但页面报错404的问题。询问前端同学后&#xff0c;发现是因为没有清理页面缓存导致的。特别在此记录。 清理页面缓存 操作方式 chrome浏览器 F12 > 应用 > 存储 &g…

分布式 ID 生成策略(二)

在上一篇文章&#xff0c;分布式 ID 生成策略&#xff08;一&#xff09;&#xff0c;我们讨论了基于数据库的 ID 池策略&#xff0c;今天来看另一种实现&#xff0c;基于雪花算法的分布式 ID 生成策略。 如图所示&#xff0c;我们用 41 位时间戳 12 位机器 ID 10 位序列号&a…

解决edge浏览器无法同步问题

有时候电脑没带&#xff0c;但是浏览器没有同步很烦恼。chrome浏览器的同步很及时在多设备之间能很好使用。但是edge浏览器同步没反应。 在这里插入图片描述 解决方法&#xff1a; 一、进入edge浏览器点击图像会显示未同步。点击“管理个人资料”&#xff0c;进入后点击同步&…

【机器学习】14. 集成学习 ensemble: bagging, boosting, 随机森林 random forest

集成学习 ensemble: bagging, boosting, 随机森林 random forest 1. Ensemble 整体认知2. 使用Ensemble的原因3. 构建Ensemble 的方法4. Bagging&#xff08;bootstrap aggregation&#xff09;特点 5. BoostingAdaBoost整体算法思路 6. 比较7. 随机森林 1. Ensemble 整体认知 …

记录一次更新idea

一、官网下载安装包&#xff0c;拿所需版本 二、链接下载&#xff0c; 逐行仔细读readme.txt 三、执行script(unstall<->install)vbs、-javaagent:更改时记得

低代码平台如何通过AI赋能,实现更智能的业务自动化?

引言 随着数字化转型的加速推进&#xff0c;企业在日常运营中面临的业务复杂性与日俱增。如何快速响应市场需求&#xff0c;优化流程&#xff0c;并降低开发成本&#xff0c;成为各行业共同关注的核心问题。低代码平台作为一种能够快速构建应用程序的工具&#xff0c;因其可视化…

实现企业微信打卡月报与简道云的高效集成

实现企业微信打卡月报与简道云的高效集成 企业微信打卡月报同步到简道云 在企业管理中&#xff0c;员工的考勤数据是至关重要的一环。为了实现高效的数据管理和分析&#xff0c;我们需要将企业微信的打卡月报数据集成到简道云平台。本文将分享一个具体的技术案例&#xff0c;展…

【Redis】常见基本全局命令

一、Redis俩大核心命令 由于Redis是以键值对的形式进行数据存取&#xff0c;自然就离不开不断的存储和获取&#xff0c;而其所对应的命令则是set和get&#xff0c;如此说来二者为Redis的核心基础命令也不为过。 作用&#xff1a;用于存储Stirng类型的数据 返回&#xff1a;当…

GPT避坑指南:如何辨别逆向、AZ、OpenAI官转

市面上有些说自己是官转&#xff0c;一刀只需要1块甚至几毛钱&#xff0c;并声称官方倍率的&#xff0c;很大可能就是使用的是 逆向或Azure。 如何鉴别逆向 逆向的种类很多&#xff0c;主要分为3类 逆向不知名A| 镜像站或偷的 key。成本约等于0&#xff0c;调用聊天数据可能在…