C语言中宏定义比较“高级”的用----#和##以及宏嵌套
#define APP_NAME "ChargingPile"
#define APP_CONFIG_FILE_PATH "/data/app/"APP_NAME"/configFile/"
#define APP_COMMON_FILE_PATH "/data/app/"APP_NAME"/commFile/"
事件起因是在同事的代码中,偶然发现宏定义可以这样去使用,这样APP_CONFIG_FILE_PATH展开为"“/data/app/”“ChargingPile”“/configFile/”",就可以灵活使用了,只需要修改第一个APP_NAME的定义。
在此的激励下,去研究了宏定义里#和##以及宏定义嵌套的用法,整理出来,作个纪念。
#的用法
"#"是将宏参数转换为字符串。不管该宏的参数是什么,都将其用双引号包裹起来形成一个字符串。
举例
#define T(x) #x
int main()
{
int temp = 10;
printf("%s\n", T(temp));
}
将打印输出字符串变量名"temp",而不是变量的值0.
##的用法
"##"被称为连接符,把宏参数与之前的token连接起来。
例如
#define T(x) x##[2]
int main()
{
int a[5] = {1, 2, 3, 4, 5};
printf("%d\n", T(a));
}
T(a)会被展开为a[2],最终打印a[2]的值,即3.
宏嵌套如何展开
宏嵌套的展开流程图如下
其中第2和第3步是或的关系,只要满足一个条件就会进入第5步。
举例说明
#include <stdio.h>
#define TO_STRING2(x) #x
#define TO_STRING1(x) #x
#define TO_STRING(x) TO_STRING1(x)
#define PARAM(x) #x
#define ADDPARAM(x) INT_##x
int main()
{
const char *str = TO_STRING(PARAM(ADDPARAM(1)));
printf("%s\n",str);
str = TO_STRING2(PARAM(ADDPARAM(1)));
printf("%s\n",str);
str = TO_STRING(TO_STRING2(PARAM(ADDPARAM(1))));
printf("%s\n",str);
return 0;
}
对于第一个宏TO_STRING(PARAM(ADDPARAM(1)))
1、最外层TO_STRING没有#或##且不是最内层,因此进入下一层
2、PARAM包含#,对当前层进行宏展开,展开为TO_STRING(“ADDPARAM(1)”)
3、此时TO_STRING变为外层,同时是最内层,展开为TO_STRING1(“ADDPARAM(1)”)
4、最终展开为"“ADDPARAM(1)”"
对于第二个宏TO_STRING2(PARAM(ADDPARAM(1)))
最外层TO_STRING2有#,直接展开为"PARAM(ADDPARAM(1))",变为一个字符串
参考文章:https://zhuanlan.zhihu.com/p/344240420