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

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

正如我在前面的许多问题中提到的,我正在通过K&R进行工作,目前正在进行预处理。有一件更有趣的事情-我以前从任何一次尝试学习C时都不知道-是##预处理操作符。根据K&R:

预处理算子##提供在宏展开期间连接实际参数的方法。如果替换文本中的参数与##参数替换为实际参数,##周围的空白被移除,结果被重新扫描。例如,宏paste连接它的两个参数:

#define  paste(front, back)  front ## back

所以paste(name, 1)创建令牌name1.

为什么会有人在现实世界里用这个?它的使用有哪些实际例子,是否有需要考虑的问题?


白衣非少年
浏览 359回答 3
3回答

芜湖不芜

CrashRpt:使用#将宏多字节字符串转换为UnicodeCrashRpt(崩溃报告库)中一个有趣的用法是:#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;
打开App,查看更多内容
随时随地看视频慕课网APP