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”的一些值。我

我在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”的一些值。我的问题是,什么是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-这些不是真实的名字,这个宏是一个看起来可怕的宏的简化形式。你正确地指出了很多事情。谢谢你花时间解释它们。