如何实现C语言X宏的自迭代扩展?避免冗余宏副本
实现C宏的N²嵌套展开(无冗余定义)
问题背景
需要通过C宏实现类似N²嵌套循环的展开效果:对宏中的每个元素,都拼接上完整的宏元素列表,同时避免重复定义原始宏数据。
原始代码示例:
#include<stdio.h> #define LETTERS\ X(A)\ X(B)\ X(C)\ X(D) #define X(L) #L int main(int nargs,char** args) { printf("%s\n",LETTERS); return 0; }
当前输出:ABCD
期望输出:AABCD BABCD CABCD DABCD
现有冗余方案需要复制LETTERS为LETTERS_COPY,不符合无冗余要求。
解决方案:基于可变参数的间接遍历宏
利用C11的__VA_OPT__特性实现通用的列表遍历,同时让每个元素触发全列表的展开,原始数据仅需定义一次:
#include<stdio.h> // 原始数据仅定义一次 #define LETTERS A,B,C,D // 通用遍历宏:对列表中每个元素执行指定操作 #define FOR_EACH(OP, LIST) _FOR_EACH(OP, LIST) #define _FOR_EACH(OP, FIRST, ...) \ OP(FIRST) \ __VA_OPT__( _FOR_EACH(OP, __VA_ARGS__) ) // 单个元素的处理逻辑:输出当前元素 + 全列表元素,末尾加空格分隔 #define PROCESS_ITEM(L) #L FOR_EACH(OUTPUT_ITEM, LETTERS) " " #define OUTPUT_ITEM(L) #L int main() { printf("%s\n", FOR_EACH(PROCESS_ITEM, LETTERS)); return 0; }
方案说明
- 无冗余数据定义:
LETTERS仅声明一次,所有展开逻辑都复用该定义 - 分层逻辑清晰:
FOR_EACH负责遍历整个元素列表,对每个元素调用PROCESS_ITEMPROCESS_ITEM处理单个元素:先输出自身,再通过FOR_EACH(OUTPUT_ITEM, LETTERS)展开完整的元素列表
- 兼容性:依赖C11的
__VA_OPT__,如果需要兼容更早的C标准,可以针对固定长度的列表编写展开宏(比如针对4个元素的硬编码遍历)
输出结果
编译运行后输出:
AABCD BABCD CABCD DABCD
(若需去掉末尾空格,可额外添加宏逻辑处理最后一个元素,或在printf中截断,此处为简化示例保留空格)
内容的提问来源于stack exchange,提问作者morrantho
相关产品推荐
相关产品推荐

