#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
printf("h(f(1,2))-> %s, g(f(1,2))-> %s\n", h(f(1,2)), g(f(1,2)));
先上答案:
h(f(1,2))-> 12, g(f(1,2))-> f(1,2)
也许你跟我一样,满脑子的“为什么“?
#
是将内容字符串化##
是连接字符串例1:
#include
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
int main(void) {
message_for(Carole, Debra);
return 0;
}
输出结果是:
Carole and Debra: We love you!
例2:
#include
#define tokenpaster(n) printf ("token" #n " = %d", token##n)
int main(void) {
int token34 = 40;
tokenpaster(34);
return 0;
}
输出结果是:
token34 = 40
tokenpaster(34);
这个通过预处理后就变成了printf ("token34 = %d", token34)
看到这里,我想大家已经理解#
和##
是什么意思了。
h(f(1,2))
和g(f(1,2))
的结果是不一样的?这就要看宏替换的规则是什么了。After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
#
或##
这样的东西,否则就将这些parameter替换到底;#
或 ##
处理完),预处理器还会对整个宏剩下的继续处理,因为这个function-like macro会替换出一些新东西,例如h( f(1,2) )
--> g(12)
,g(12)
--> "12"
。h(f(1,2))
:h(f(1,2))
预处理先找到h
这个function-like macrof(1,2)
替换成12
,即得到g(12)
12
g(f(1,2))
:g(f(1,2))
预处理先找到g
这个function-like macro#
了,即得到#f(1,2)
#f(1,2)
变成了字符串f(1,2)
了,因为预处理遇到#
不会继续了。 #define ABC"abc"
#define _STR(x) #x
#define STR(x) _STR(x)
char * pc1 = _STR(ABC);
char * pc2 = STR(ABC);
printf("pc1:%s\n",pc1);
printf("pc2:%s\n",pc2);
会输出什么结果?其实不难理解,按照上面的套路可以得到(实际输出的结果):
pc1:ABC
pc2:"abc"
但需要注意的是,这个"abc"
是把双引号""
都打印出来的哦。或者,可以通过gcc -E
来看看预编译后的结果:
# 3 "macro.c"
int main(void)
{
# 14 "macro.c"
char * pc1 = "ABC";
char * pc2 = "\"abc\"";
# ... ...
别着急疑惑,继续往下看(在上面例子基础上加点料,看完你会更疑惑):
char * pc3 = STR(_STR(ABC));
char * pc4 = STR(STR(ABC));
printf("pc3:%s\n",pc3);
printf("pc4:%s\n",pc4);
你觉得它会输出什么结果?答案是:
pc3:"ABC"
pc4:"\"abc\""
不仅""
出来了,就连\
都输出来了。哈哈,你品,你细品!
END