You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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;
}

方案说明

  1. 无冗余数据定义:LETTERS仅声明一次,所有展开逻辑都复用该定义
  2. 分层逻辑清晰:
    • FOR_EACH负责遍历整个元素列表,对每个元素调用PROCESS_ITEM
    • PROCESS_ITEM处理单个元素:先输出自身,再通过FOR_EACH(OUTPUT_ITEM, LETTERS)展开完整的元素列表
  3. 兼容性:依赖C11的__VA_OPT__,如果需要兼容更早的C标准,可以针对固定长度的列表编写展开宏(比如针对4个元素的硬编码遍历)

输出结果

编译运行后输出:

AABCD BABCD CABCD DABCD 

(若需去掉末尾空格,可额外添加宏逻辑处理最后一个元素,或在printf中截断,此处为简化示例保留空格)


内容的提问来源于stack exchange,提问作者morrantho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 00:41:12