宏#和##

#和##这两个宏在项目中见到,所以特意记录一些笔记下来,方便以后查看!

宏#

#是把其左边的参数字符串化,其实就是为其加上了"",例如:

#define _STR(x) #x   //为x加上""

std::cout<<_STR(abc);

当我们打印后,输出:abc

如果传入的是字符串:

std::cout<<_STR("abc");

那么输出的是带有引号的:"abc",因为宏只会进行替换,而#会给参数x带上双引号。

当出现宏嵌套时,就需要注意了,例如:传递给_STR()的本身就是一个宏,会发生什么问题呢?

#define _STR(x) #x   //为x加上""
#define _FILE  "C:\\test" 

std::cout<<_STR(_FILE);

像上面这样把宏_FILE传递给_STR后,打印出来的是:_FILE

这就不符合我们想要的了,明显我们想要的是"C:\\test",这种情况需要加一个中间宏,让_FILE替换成"C:\\test"后,再进行_STR替换:

#define _STR(x) #x   //为x加上""
#define STR(x) _STR(x)
#define _FILE  "C:\\test" 

std::cout<<_STR(_FILE)<<std::endl;
std::cout<<STR(_FILE)<<std::endl;

这次打印出来的是带双引号的"C:\\test",其实可以这样理解:

宏是一步步往内部进行替换的,它首先会把参数当做一个整体,如果宏的参数是一个宏,那么替换本身后,会对参数进行替换。而在第一次中当_STR替换成#_FILE后,#_FILE中的_FILE已经不再是宏,所以也就不进行替换了;而第二次有一个中间宏,STR(x)替换成的是_STR(x),x也即是_FILE还是宏,所以替换成了"C:\\test"。

_STR(_FILE)-->#_FILE-->"_FILE"

STR(_FILE)-->_STR("C:\\test")-->#"C:\\test"-->""C:\\test""

宏##

其实##这个宏还是比较的常用,在"tchar.h"头文件中宏_T的定义就用到了##:

#define _T(x)       __T(x)
#define __T(x)      L ## x

##是把参数x和##的左边部分连接起来,_T()这个宏是把const char*转化为了const wchar_t *,其实就是在字符串前面连接了" L "。

现在用宏#和宏##相结合,把几个字母转为字符串后,再通过宏##转化为宽字符串:

#define _STR(x) #x   //为x加上""
#define _WSTR(x)  L##x
std::wcout << _WSTR(_STR(abc));//

这样是编译通不过的,正如上面所说,第一层宏替换后:L_STR(abc),_STR不再是宏了,所以正确的做法是加上一个中间宏,使得_STR还是宏:

#define _STR(x) #x   //为x加上""
#define _WSTR(x)  L##x
#define WSTR(x) _WSTR(x)  //中间宏
std::wcout << WSTR(_STR(abc));//

这样就可以把abc转化成宽字符串了!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值