note - tips - c macro multi-level expansion

note - tips - c macro multi-level expansion

经常看到一个宏嵌套另一个宏的做法,却没深入了解过原因,正好抽空整理了一下,顺带记录。

c 语言宏定义多级展开

在预编译阶段展开宏定义,如果为多级宏定义,则一次只展开当前的宏,但涉及到 “#” 和 “##” 时不会展开,举例如下:

#define VERSION_DECAL		10
#define PREFIX_HEX			0x
#define TO_HEX(prefix, a)	(prefix##a)
#define VERSION				TO_HEX(PREFIX_HEX, VERSION_DECAL)
  1. VERSION -> TO_HEX(PREFIX_HEX, VERSION_DECAL);
  2. TO_HEX(PREFIX_HEX, VERSION_DECAL) -> (PREFIX_HEX##VERSION_DECAL);
  3. 导致输出 “PREFIX_HEXVERSION_DECAL” 错误。

此时可在 #define TO_HEX(prefix, a) (prefix##a)之间加一层中间宏先展开再连接,例如:

#define VERSION_DECAL		10
#define PREFIX_HEX			0x
#define _TO_HEX(prefix, a)	(prefix##a)
#define TO_HEX(prefix, a)	_TO_HEX(prefix, a)
#define VERSION				TO_HEX(PREFIX_HEX, VERSION_DECAL)
  1. VERSION -> TO_HEX(PREFIX_HEX, VERSION_DECAL);
  2. TO_HEX(PREFIX_HEX, VERSION_DECAL) -> _TO_HEX(0x, 10);
  3. _TO_HEX(0x, 10) -> (prefix##a)
  4. 导致输出 “0x10” 。

c 语言宏定义 tips

宏定义展开不会替换 “” 中间部分,即#define TO_STRING(a) "a"此时不管TO_STRING(a)中的 a 是什么,最终都会替换为 “a”;
需要通过宏转为字符串,则需用到 “#”,如#define TO_STRING(a) #a,此时可将对应的a转为字符串,但同样涉及到多级展开,此时 TO_STRING(a) 中必须为要转为的字符串,而不能是另一层宏,否则可参考上述添加中间宏先展开再连接。

问题(未解决,待续。。。)

按每次展开一级的理论,以下 demo 应该输出 “TO_HEX(PREFIX_HEX, VERSION_DECAL)”,但实际可以输出 “0x10”。

#include <stdio.h>

#define VERSION_DECAL		10
#define PREFIX_HEX			0x
#define _TO_HEX(prefix, a)	(prefix##a)
#define TO_HEX(prefix, a)	_TO_HEX(prefix, a)
#define VERSION				TO_HEX(PREFIX_HEX, VERSION_DECAL)

#define _TO_STRING(a)	#a
#define TO_STRING(a)	_TO_STRING(a)

int main()
{
   /*  Write C code in this online editor and run it. */
   printf("Hello, World! %s \n", TO_STRING(VERSION));
   
   return 0;
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值