先来段程序:
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
#define p(a) #@a
int main(int argc, char* argv[])
{
printf("%s\n", g(f(1,2)));
printf("%s\n", h(f(1,2)));
printf("%c, %d\n", p(1), p(1));
return 0;
}
输出结果
看上去有点奇怪。
##是连接操作符(我也不知道中文是啥,google到的是token-pasting operator),可以将操作符两端的标识符级联起来。
#是字符串化操作符(stringizing operator),可以将操作符后的标识符转化成字符串。
#@是字符化操作符(charizing),可以将操作符后的数据转化成字符。
来分析程序。
printf("%s\n", g(f(1,2)));
g(f(1,2)),即#f(1,2),被转化成了字符串,于是g(f(1,2))就变成了"f(1,2)"。
printf("%s\n", h(f(1,2)));
h(f(1,2)),这里需要注意一下,#跟##不一样,如果宏定义的替换部分恰好跟其他的宏定义名字一样的话,会进行展开,即调用h(a)会先对g(a)进行展开。详见http://c-faq.com/ansi/stringize.html。如此一来,h(f(1,2))会先对f(1,2)进行运算,变成12,再运行h(12),变成"12"。
printf("%c, %d\n", p(1), p(1));
p(1),1被转化成字符,为了验证,输出它的ASCII码。
#,##, #@都仅适用于宏定义,在程序中无法单独使用。
参考:http://msdn.microsoft.com/en-us/library/teas0593%28v=vs.80%29.aspx
转载于:https://blog.51cto.com/serious/844181