C++ 原语#用C语言定义理解
我在C中定义了一个宏,如下所示:C++ 原语#用C语言定义理解,c++,c,C++,C,我在C中定义了一个宏,如下所示: #define SOME_FIELD(_A_,_B_,_C_) \ MyObj[ ## _A_ ## ].somePTR = \ (DWORD_PTR) (buff_ ## _C_ ## _C_ ## _ ## _B_ ## ); MyObj[Param1].somePTR = (DWORD_PTR) (buff_Param3Param3_Param2); 我能理解的是,对于索引A,我们得到了“somePTR”的一些值。我
#define SOME_FIELD(_A_,_B_,_C_) \
MyObj[ ## _A_ ## ].somePTR = \
(DWORD_PTR) (buff_ ## _C_ ## _C_ ## _ ## _B_ ## );
MyObj[Param1].somePTR = (DWORD_PTR) (buff_Param3Param3_Param2);
我能理解的是,对于索引A,我们得到了“somePTR”的一些值。我的问题是,什么是somePTR的#####
符号,如何计算somePTR的值
我对这样一个宏是新手,所以一个描述性的解释会很有帮助。这就是所谓的。它允许您将参数粘在一起
例如,SOME_字段(Param1、Param2、Param3)代码>按如下方式展开:
#define SOME_FIELD(_A_,_B_,_C_) \
MyObj[ ## _A_ ## ].somePTR = \
(DWORD_PTR) (buff_ ## _C_ ## _C_ ## _ ## _B_ ## );
MyObj[Param1].somePTR = (DWORD_PTR) (buff_Param3Param3_Param2);
通过使用编译器的预处理器,您可以很容易地自己尝试这一点。您通常不需要费心编写一个完全成熟的C程序,预处理器通常可以自己调用。这就是预处理器标记粘贴
它将实际的参数标记复制为字符串文字,因此请像
// preprocessor_token_pasting.cpp
#include <stdio.h>
#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
}
//预处理器\u令牌\u粘贴.cpp
#包括
#定义粘贴器(n)printf_s(“标记”#n“=%d”,标记##n)
int=9;
int main()
{
贴纸(9);
}
##是原始符号,用于创建新符号
在宏中创建名称很有用:
#define GENERIC_GETTER(f,g) (g->member_ ## f )
GENERIC\u GETTER(a,b)
将创建(b->member\u a)
(创建新符号)。如果您不使用sharp sharp,它将创建(b->member_u\a)
(不粘在一起)通常,##
操作符连接两个令牌:它需要合法的
左侧的标记和右侧的合法标记,并生成一个新的
代币在本例中,宏中的第一行
(MyObj[#A#A#A#].somePtr=\
)是
非法,并导致未定义的行为。大多数实现只是
连接字符串,然后在完成所有操作后重新排序
替换,所以它会起作用,但不能保证。到目前为止
正如我在这里所说的,这是没有必要的。在第二行,在
另一方面,您正在生成一个新令牌。如果调用宏:
SOME_FIELD(x,y,z);
它将扩展到:
MyObj[x].somePtr = (DWORD_PTR)(buff_zzy);
(我可以补充一点,像\u A\u
、\u B\u
和\u C\u
这样的符号的使用也很重要
未定义的行为。以下划线开头,后跟
大写字母在实现的名称空间中。)为什么不做一个示例并检查预处理器的输出gcc-E
等。我希望这些不是参数和宏的实际名称。。。如果是这样的话,作者需要一些同情心训练。@Dennis-这些不是真实的名字,这个宏是一个看起来可怕的宏的简化形式。你正确地指出了很多事情。谢谢你花时间解释它们。