为了账号安全,请及时绑定邮箱和手机立即绑定

#预处理器运算符的应用和需要考虑的问题是什么?

#预处理器运算符的应用和需要考虑的问题是什么?

C
白衣非少年 2019-07-09 13:15:48
#预处理器运算符的应用和需要考虑的问题是什么?正如我在前面的许多问题中提到的,我正在通过K&R进行工作,目前正在进行预处理。有一件更有趣的事情-我以前从任何一次尝试学习C时都不知道-是##预处理操作符。根据K&R:预处理算子##提供在宏展开期间连接实际参数的方法。如果替换文本中的参数与##参数替换为实际参数,##周围的空白被移除,结果被重新扫描。例如,宏paste连接它的两个参数:#define  paste(front, back)  front ## back所以paste(name, 1)创建令牌name1.为什么会有人在现实世界里用这个?它的使用有哪些实际例子,是否有需要考虑的问题?
查看完整描述

3 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

CrashRpt:使用#将宏多字节字符串转换为Unicode

CrashRpt(崩溃报告库)中一个有趣的用法是:

#define WIDEN2(x) L ## x#define WIDEN(x) WIDEN2(x)//Note you need a WIDEN2 so that __DATE__ will evaluate first.

在这里,他们想使用两个字节的字符串,而不是一个字节的每字符串。这看起来可能是毫无意义的,但他们这么做是有充分理由的。

 std::wstring BuildDate = std::wstring(WIDEN(__DATE__)) + L" " + WIDEN(__TIME__);

它们与返回日期和时间的字符串的另一个宏一起使用它。

L紧挨着__ DATE __会给你一个编译错误。


Windows:对通用Unicode或多字节字符串使用#

Windows使用如下所示:

#ifdef  _UNICODE    #define _T(x)      L ## x#else
    #define _T(x) x#endif

_T在代码中到处使用。


用于清洁访问器和修饰符名称的各种库:

我还在代码中看到它用于定义访问器和修饰符:

#define MYLIB_ACCESSOR(name) (Get##name)#define MYLIB_MODIFIER(name) (Set##name)

同样,您也可以在任何其他类型的聪明的名称创建中使用相同的方法。


各种库,使用它同时进行多个变量声明:

#define CREATE_3_VARS(name) name##1, name##2, name##3int CREATE_3_VARS(myInts);myInts1 = 13;myInts2 = 19;myInts3 = 77;


查看完整回答
反对 回复 2019-07-09
  • 3 回答
  • 0 关注
  • 358 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信