解释
#:“字符串化”,把#后面的参数变为 字符串
##:连接,把##前面和后面的参数连接在一起
举例
#include <stdio.h>
// 转字符串的宏定义
#define STR(s) #s
// 连接的宏定义
#define CON(a,b) (a##_love_##b)
int main()
{
printf("After STR: %s\n",STR(Hello));
printf("After CON: %s\n",CON(I,you));
return 0;
}
-
被展开成为:
printf("After STR: %s\n","Hello");
printf("After CON: %s\n",I_love_you);
-
输出(这里其实是有个小坑的)
After STR: Hello
After CON: I_love_you (编译会报错)
问题(小坑)
但是第二句编译会报错,它只是进行连接,像是没有定义一样,举个例子:
// 正确:
int a = 10;
printf("%d",a);
// 错误:
printf("%d",b);
CON(I,you)
这里只是进行了宏的展开和替换并完成连接,完成后就是:printf("After CON: %s\n",I_love_you);
有没有发现了,就像是你凭空调用一个变量I_love_you
,所以是不通过的。
解决
所以这里就需要想办法了,我可以多加一层中间转换宏,把所有的宏参数在这一层进行全部展开,那么就可以正常使用得到我们想要的答案了。
#include <stdio.h>
// 转字符串的宏定义
#define _STR(s) #s
#define STR(s) _STR(s)
// 连接的宏定义
#define _CON(a,b) a##_love_##b
// 正确
#define CON(a,b) STR(_CON(a,b))
// 错误
//#define CON(a,b) _STR(_CON(a,b))
int main()
{
printf("After CON: %s\n",CON(I,you));
return 0;
}
这里转化如下:
CON(I,you) -> STR(_CON(I,you)) -> _STR(I_love_you) > "I_love_you"
这里第二步往第三步 转换有点绕,可以多看看
下面是实际跑的代码,注意看下我圈出来那里和CON输出结果,根据上面推一下。
正确版:
错误版: