C语言宏定义中#define后#符号的作用及双宏定义必要性咨询
我来一步步给你拆解这个问题,都是C宏里的经典知识点:
1. #符号的作用
这个#是C预处理器里的字符串化运算符,它的功能很直接:把宏的参数转换成对应的字符串字面量。比如说你调用STRING(hello),预处理器就会把它替换成"hello";传数字STRING(123)的话,就变成"123"。
2. 只保留#define STRING(n) #n够吗?
答案是不够,尤其是当你的宏参数本身也是一个宏定义的时候,会达不到预期效果。举个例子:
#define NUM 100 #define STRING(n) #n // 调用的时候 printf("%s\n", STRING(NUM));
你猜输出是什么?不是"100",而是"NUM"!因为#运算符会直接把参数的字面名称转成字符串,不会先展开参数本身的宏定义。这就尴尬了,如果你想得到NUM对应的实际值的字符串,只靠STRING宏就做不到。
3. 为什么需要MAKESTRING这样的外层宏?
这就是为了解决上面的问题!外层宏的作用是先展开参数的宏定义,再传递给内层的字符串化宏。看同样的例子,加上外层宏:
#define NUM 100 #define STRING(n) #n #define MAKESTRING(n) STRING(n) // 调用的时候 printf("%s\n", MAKESTRING(NUM));
这次预处理器会先处理MAKESTRING(NUM):首先把参数NUM展开成100,然后再把100传给STRING宏,这时候#n就会把100转成"100",这才是我们想要的结果。
简单说就是:内层宏的#会阻止参数展开,而外层宏相当于给参数加了一层“预展开”的步骤,让参数先变成它的实际值,再被字符串化。
内容的提问来源于stack exchange,提问作者Eziz Durdyyev
相关产品推荐
相关产品推荐

