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

如何对C语言宏进行拼接、求值与字符串化?

解决宏拼接后先求值再字符串化的问题

你遇到的核心问题是:#字符串化操作符不会自动展开它参数里的宏——直接用它处理拼接后的宏名(比如FOO_ONE),只会把宏名本身转成字符串,而不是先展开宏的实际值。我们可以通过两层宏嵌套的技巧来解决这个问题。

为什么你的原有写法不行?

你的CONCAT宏直接把拼接后的mac##_ONE传给STRINGIFY,但#FOO_ONE只会将标识符FOO_ONE转换成字符串"FOO_ONE",而不会先展开FOO_ONE对应的宏值12。这就是你得到FOO_ONEFOO_TWO而不是1234的原因。

正确的宏实现

#include <stdio.h>
#define FOO_ONE 12
#define FOO_TWO 34
#define BAR_ONE 56
#define BAR_TWO 78

// 基础字符串化宏:直接将参数转为字符串
#define STRINGIFY(x) #x
// 关键的中间层:先展开参数,再调用字符串化宏
#define STRINGIFY_EXPANDED(x) STRINGIFY(x)
// 拼接宏前缀和后缀,展开为实际值后字符串化,最终自动拼接
#define MAKE_MAC(mac) STRINGIFY_EXPANDED(mac ## _ONE) STRINGIFY_EXPANDED(mac ## _TWO)

int main(int argc, char *argv[]) {
    printf("FOO: " MAKE_MAC(FOO) "\n");
    printf("BAR: " MAKE_MAC(BAR) "\n");
    return 0;
}

工作原理拆解

  1. 拼接宏名:当调用MAKE_MAC(FOO)时,mac##_ONE会拼接成FOO_ONE,mac##_TWO拼接成FOO_TWO。
  2. 触发宏展开:这两个拼接结果传入STRINGIFY_EXPANDED后,宏展开规则会先将FOO_ONE展开为12,FOO_TWO展开为34。
  3. 字符串化:展开后的值再传入STRINGIFY,分别被转成字符串"12"和"34"。
  4. 自动拼接:C语言中相邻的字符串字面量会自动合并,所以"12""34"最终变成"1234",完全符合你的期望输出。

补充小知识

宏展开的优先级规则是:如果宏参数不是#或##的操作数,那么在替换到宏体之前会先被展开。STRINGIFY_EXPANDED的作用就是打破直接字符串化的限制,让拼接后的宏名先展开为实际值,再被转成字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:04:51