正如我之前的许多问题所述,我正在通过K&R工作,目前正在进入预处理器.其中一个更有意思的事情 - 我之前从未尝试过的任何学习C的尝试 - 是##预处理器操作员.根据K&R的说法:
预处理器运算符
##提供了一种在宏扩展期间连接实际参数的方法.如果替换文本中##的参数与a相邻,则参数将替换为实际参数,##并删除周围的空白区域,并重新扫描结果.例如,宏paste连接其两个参数:
#define paste(front, back) front ## back所以
paste(name, 1)创建令牌name1.
如何以及为什么有人会在现实世界中使用它?它的使用的实际例子是什么,有什么需要考虑的?
我必须在C中做这样的事情.它只有在我使用char时才有效,但我需要一个字符串.我怎样才能做到这一点?
#define USER "jack" // jack or queen
#if USER == "jack"
#define USER_VS "queen"
#elif USER == "queen"
#define USER_VS "jack"
#endif
Run Code Online (Sandbox Code Playgroud) 我找到了一篇有趣的小博文,解释了如何使用行号在宏中生成(半)唯一名称:
// Do magic! Creates a unique name using the line number
#define LINE_NAME( prefix ) JOIN( prefix, __LINE__ )
#define JOIN( symbol1, symbol2 ) _DO_JOIN( symbol1, symbol2 )
#define _DO_JOIN( symbol1, symbol2 ) symbol1##symbol2
Run Code Online (Sandbox Code Playgroud)
这里有两件事让我很困惑:
LINE_NAME宏JOIN在文件中声明之后才会工作?我认为C预处理器执行了线性传递,因此需要根据依赖性来定义宏,就像C函数在使用之前需要定义一样.JOIN和_DO_JOIN宏来获得正确的结果?在宏中具有这种间接级别似乎很奇怪.我有一种感觉,这两个问题的答案是相关的,并且与C预处理器评估宏的方式有关.(但是,由于我甚至认为这个例子无效,我对宏如何工作的直觉显然已经过时了.)
特定
#define cat(x,y) x##y
Run Code Online (Sandbox Code Playgroud)
调用cat(a,1)返回a1,但cat(cat(1,2),3)未定义.但是如果我也定义了#define xcat(x,y) cat(x,y),那么结果xcat(xcat(1,2),3)就是现在123.任何人都可以详细解释为什么会这样吗?
我试图使用宏来根据类型调用适当的对象.
#define DELEGATE_FUNC(FuncName, kind, paramPtr) \
if (kind == 1) { \
return PolicyObject1.##FuncName(paramPtr); \
} \
else { \
return PolicyObject2.##FuncName(paramPtr); \
} \
return 0; \
Run Code Online (Sandbox Code Playgroud)
(PolicyObject1和PolicyObject2是两个静态对象.)现在使用宏时,例如
DELEGATE_FUNC(ProcessPreCreate,1,null_ptr);
它在VS 2015中编译得很好,但在LLVM中出错"粘贴形成了一个无效的处理令牌'.ProcessPreCreate'"
我寻找,并发现了一些帖子,并将其理解到某种程度 - 需要双层间接,例如 为什么我需要双层间接宏?
但是我无法定义那两层宏,有人可以帮忙吗?
(请不要讨论设计方面的问题)
谢谢
我正在读一本关于C编程语言的书,我发现:
#define cat(x,y) x##y
#define xcat(x,y) cat(x,y)
Run Code Online (Sandbox Code Playgroud)
调用cat(cat(1,2),3)产生错误,而调用xcat(xcat(1,2),3)产生预期结果123.
两者的工作方式有何不同?