X-Macros基于嵌套宏的属性以及在其他宏内定义宏的能力。从某种意义上说,X-Macros可以创建一个可自我维护且相互依赖的代码,因此它是一种非常强大的预处理器技术。当程序某个部分的更改导致另一部分的更改时,则称该代码是相互依赖的。
句法:
X宏应用程序包含两个部分:
- 列表元素的定义:
#define VARIABLES \ X(value1, 1) \ . . . \ X(valueN, N)
- 扩展列表以生成声明或语句的片段:
#define X(name) int name; VARIABLES #undef X
该列表由一个宏或头文件(名为VARIABLES)定义,该文件本身不生成任何代码,而仅由一系列调用宏(通常称为“ X”)与元素的数据组成。每次对VARIABLES进行扩展时,都会在X的定义之前加上list元素的语法。调用VARIABLES会为列表中的每个元素扩展X。
实现方式:
- 示例1:以下代码说明了X-Macros的工作方式:
#include
// Defines four variables. #define VARIABLES \ X(value1, 1) \ X(value2, 2) \ X(value3, 3) \ X(value4, 4) // driver program. int main(void) { // Declaration of every variable // is done through macro. #define X(value, a) char value[10]; VARIABLES #undef X // String values are accepted // for all variables. #define X(value, a) scanf("\n%s", value); VARIABLES #undef X // Values are printed. #define X(value, a) printf("%d) %s\n", a, value); VARIABLES #undef X return 0; } 输出:1) geeks 2) for 3) geeks 4) geeksforgeeks
在上面的代码中,在宏“变量”中添加一个或多个变量将导致其自动声明,扫描以及打印。这个简单的示例清除了X-Macros的工作和功能。扩展后,上面的代码将类似于以下代码:
#include
int main(void) { char value1[10]; char value2[10]; char value3[10]; char value4[10]; scanf("\n%s", value1); scanf("\n%s", value2); scanf("\n%s", value3); scanf("\n%s", value4); printf("%d) %s\n", 1, value1); printf("%d) %s\n", 2, value2); printf("%d) %s\n", 3, value3); printf("%d) %s\n", 4, value4); return 0; } 输出:1) geeks 2) for 3) geeks 4) geeksforgeeks
尽管上面的代码只是解释了X-Macros的功能,但是这种用法很少见,不建议使用,因为它会使代码的可读性降低。一个更实际的例子是枚举或跳转表。
- 示例2:以下代码说明了X-Macros与枚举的工作方式:
#include
// Defining a macro // with the values of colors. #define COLORS \ X(RED) \ X(BLACK) \ X(WHITE) \ X(BLUE) // Creating an enum of colors // by macro expansion. enum colors { #define X(value) value, COLORS #undef X }; // A utility that takes the enum value // and returns corresponding string value char* toString(enum colors value) { switch (value) { #define X(color) \ case color: \ return #color; COLORS #undef X } } // driver program. int main(void) { enum colors color = WHITE; printf("%s", toString(color)); return 0; } 输出:WHITE
在上面的代码中,从COLORS宏中添加或删除任何常量将自动反映在enum以及toString()函数的定义中。这就是为什么使用X-Macros生成自维护代码的原因。宏扩展后,上面的代码将类似于以下代码:
#include
// Creating an enum of colors. enum colors { RED, BLACK, WHITE, BLUE }; /*A utility that takes the enum value and returns corresponding string value*/ char* toString(enum colors value) { switch (value) { case RED: return "RED"; case BLACK: return "BLACK"; case WHITE: return "WHITE"; case BLUE: return "BLUE"; } } // driver program. int main(void) { enum colors color = WHITE; printf("%s", toString(color)); return 0; } 输出:WHITE
X-Macros的优点
- X-Macros通过创建单独的头文件以实现可维护性和可读性而被广泛用于操作系统开发中
- 帮助轻松维护复杂的编程
- 它可以创建一个自我维护且相互依赖的代码
X-Macros的缺点
- 代码变得不那么可读
- 代码复杂易懂
- 通常仅用于内部编程,例如OS编程。
参考: https : //en.wikipedia.org/wiki/X_Macro
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。