如何修改C宏实现将表达式结果转为字符串?现有宏需输出"30"而非"10+20"
解决方法:让宏生成计算后的字符串"30"
咱们先搞清楚原来的宏为啥会输出"10+20":#x是预处理器的字符串化操作,它会原封不动地把传入的参数文本转成字符串,根本不会去计算10+20这个表达式——预处理器只做文本替换,不搞算术运算。
要得到"30",核心是先让10+20被计算成数值30,再把这个数值转成字符串。下面给你几种可行的方案:
方案1:针对特定场景的简单修改(不通用)
如果只需要处理10+20这一个特定表达式,直接让宏返回固定字符串就行,虽然粗暴但能解决问题:
#define TMP4(x) #x #define TMP3(x) "30" // 直接返回目标结果 const char tmp[] = TMP3(10+20); // 最终结果就是"30"
方案2:通用编译期解法(需要C23支持)
如果你的编译器支持C23标准,可以用编译期constexpr函数实现数值转字符串,这样能在编译阶段完成所有操作,完全符合你定义字符数组的需求:
#include <stddef.h> // 编译期计算整数的字符串长度 constexpr size_t int_str_len(int n) { return n == 0 ? 1 : (n < 0 ? 1 : 0) + (n / 10 ? int_str_len(n / 10) : 0) + 1; } // 编译期把整数转成字符串 constexpr void int_to_str(char* buf, int n) { if (n < 0) { *buf++ = '-'; n = -n; } if (n >= 10) { int_to_str(buf, n / 10); while (*buf) buf++; } *buf = '0' + (n % 10); *(buf + 1) = '\0'; } // 用宏包装编译期函数调用 #define TMP3(x) []() constexpr { \ char buf[int_str_len(x) + 1]; \ int_to_str(buf, x); \ return buf; \ }() const char tmp[] = TMP3(10+20); // 编译阶段直接生成"30"
方案3:运行时初始化(兼容旧标准)
如果没法用C23,也可以在运行时用sprintf完成转换,只是字符串是在程序运行后才生成的:
#include <stdio.h> char tmp[10]; sprintf(tmp, "%d", 10+20); // 运行时生成"30"
关于纯宏的通用解法
遗憾的是,标准C的预处理器只能做文本替换,根本没能力计算算术表达式,所以没有纯宏的通用解法能把任意算术表达式求值后转成字符串。如果非要用纯宏,只能针对特定的数值对写死规则,比如:
#define ADD(a,b) ADD_##a##_##b #define ADD_10_20 30 #define TMP4(x) #x #define TMP3(x) TMP4(ADD(x)) const char tmp[] = TMP3(10,20); // 结果为"30"
但这种方式扩展性极差,只能处理预先定义好的数值组合,不推荐在实际项目中使用。
内容的提问来源于stack exchange,提问作者jtfghtr
相关产品推荐
相关产品推荐

