C语言宏#和##

C语言宏#和##

 

一、基本用途


#用于将宏定义中的参数转换为字符串。
例:存在宏#define TO_STRING(x) #x
则TO_STRING(hello)展开为"hello"

 

##用于拼接Token。
例:存在宏#define DECLARE_HANDLER(x) x##_handler
则DECLARE_HANDLER(foo)展开为foo_handler

 

二、打印出展开后的宏


#define TO_STRING(x) #x
#define MACRO_TO_STRING(macro) TO_STRING(macro)
宏MACRO_TO_STRING将宏转换为字符串

 

例:

#define FOO_1(n) int a##n;

cout << MACRO_TO_STRING(FOO_1(1)) << endl;


将输出int a1;

 

三、宏参数替换中的#和##


Unicode下文件名的宏定义如下:
#define WIDEN2(x) L##x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)

 

为什么不直接定义#define __WFILE__ WIDEN2(__FILE__)呢?这篇博文也是为此而生。
先来看看展开的结果:
将MACRO_TO_STRING(__WFILE__)打印出来结果为
L"D:\\TestMacro\\test.cpp"

 

如果定义#define __WFILE__ WIDEN2(__FILE__)
将MACRO_TO_STRING(__WFILE__)打印出来结果为
L__LINE__

 

从结果可以看到__LINE__并没有展开。

 

四、宏参数替换标准


C99标准中6.10.3.1
6.10.3.1 Argument substitution
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.

 

当宏参数替换遇到#或##时,宏参数不会被宏定义替换。


#define WIDEN2(x) L##x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)


替换过程如下:
__WFILE__
WIDEN(__FILE__)
WIDEN2("D:\\TestMacro\\test.cpp")
L"D:\\TestMacro\\test.cpp"

 

而定义#define __WFILE__ WIDEN2(__FILE__)的替换过程如下:
__WFILE__
WIDEN2(__FILE__)
L__FILE__

  

WIDEN2宏定义替换参数遇到##,将该参数作为一般token处理,即使参数是个宏,也不替换该宏。
要展开的话,就需要增加一步中间操作,上例中的WIDEN(x)就是中间操作。


同理,上面的MACRO_TO_STRING打印宏定义的宏也是使用了TO_STRING作为了中间步骤。
MACRO_TO_STRING(__WFILE__)
TO_STRING(L"D:\\TestMacro\\test.cpp")
"L"D:\\TestMacro\\test.cpp""


参考资料:
1.《C语言参考手册(原书第5版)》, Samuel P.Harbison / Guy L.Steele , 机械工业出版社
2. C99标准 ISO/IEC 9899:1999 (E)

 

转载于:https://www.cnblogs.com/shokey520/p/3745013.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值