基础知识 | 每日一面(71)
- 2020 年 4 月 2 日
- 筆記

古代的剑客们与
对手相逢时,无
论对手多么强大,
明知不敌,也要亮出自己的剑!
读者:我试图用 ANSI “字符串化” 预处理操作符 # 向信息中插入符号
常量的值, 但它字符串化的总是宏的名字而不是它的值。
小林;你可以用下面这样的两步方法迫使宏既字符串化又扩展:
#define Str(x) #x
#define Xstr(x) Str(x)
#define OP plus
char *opname = Xstr(OP);
这段代码把 opname 置为 “plus” 而不是 “OP”。在使用符号粘接操作符 ## 连接两个宏的值 (而不是名字) 时也要采用同样的“迂回战术”。
读者:警告信息 “warning: macro replacement within a string lit-eral” 是什么意思?
小林:有些 ANSI 前的编译器/预处理器把下面这样的宏
#define TRACE(var, fmt) printf("TRACE: var = fmtn", var)
解释为
TRACE(i, %d);
这样的调用会被扩展为
printf("TRACE: i = %dn", i);
换言之, 字符串常量内部也作了宏参数扩展。K&R 和标准 C 都没有定义这样的宏扩展。当你希望把宏参数转成字符串时,你可以使用新的预处理操作符 # 和字符串常量连接:
#define TRACE(var, fmt)
printf("TRACE: " #var " = " #fmt "n", var)
有时候,正是那些意想不到之人,成就了无人能成之事。
——图灵