宿舍有一同学在参加linux小组纳新,闲来无事时看了下他们的纳新题,其中有一道涉及到C语言下宏的嵌套运用特例,自己未曾接触过,便查了查资料,将其记录下来。
具体题目是让解释以下这段代码:
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define d(a) g(a)
int main()
{
printf("%s\n",d(f(a,b)));
printf("%s\n",g(f(a,b)));
return 0;
}
而这段代码的输出是这样的:
ab
f(a,b)
先解释一下define中#与##的作用:
#是将#后的参数变为一个字符串,例如上面的代码中的#a就是"a"。
##是将前后两个参数连接在一起,例如上面的代码中的a##b就是ab。
按照一般的嵌套顺序,大家会先展开内部参数,再展开外层函数,而这一方式明显不适用于现在这特殊情况,因为如果按照普通方式展开,两行输出都应该是ab。
那么为什么会出现上图的输出呢。
这便是#与##在嵌套中的特例。
在查询资料后,我了解到:
1、当宏中有#运算符时,参数不再被展开;
2、当宏中有##运算符时,则先展开函数,再展开里面的参数。
由此,再来分析上面的代码:
第一次输出时,d(f(a,b))中的d()并没有#与##运算符,因此按照一般规律展开即可,由此得到#ab,最终ab作为字符串输出。
第二次输出时,g(f(a,b))中的g()中含有#运算符,因此按规定,参数将不再被展开,由此得到#f(a,b),最终f(a,b)作为字符串输出。
以上便是全部内容。