C语言中宏定义比较“高级”的用----#和##以及宏嵌套

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.

宏嵌套如何展开

宏嵌套的展开流程图如下
preview
其中第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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值