本文介绍了以下C代码中的#和##有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的C非常生锈,我无法真正弄清这里发生的情况.

My C is very rusty and I can't really work out what is happening here.

#define V_Str(x)                    #x
#define V_FORMAT(a,b,c,d,e)         a ## . ## b ## . ## c ## . ## d ## . ## e
#define V_PROD_STR                  V_Str(V_FORMAT(13,2,99,44,0) ## 0)

#define xV_Str(x)                   V_Str(x)
#define xV_PROD_STR                 xV_Str(V_FORMAT(13,2,9,44,0) ## 0)

void Test()
{
    printf(" V_PROD_Str(...) = %s\n", V_PROD_STR);
    printf("xV_PROD_Str(...) = %s\n", xV_PROD_STR);
}

输出:

 V_PROD_Str(...) = V_FORMAT(13,2,99,44,0)0
xV_PROD_Str(...) = 13.2.9.44.00

我可以看到#x使make的内容与"x"相同,但是我很好奇##在做什么以及为什么在创建版本字符串时使用它.

I can see that the #x makes the contents of makes a literal string the same as "x", but I'm curious as to what ## is doing and why it's being used int he creation of the version string.

以后将V_PROD_Str用作RC文件中的字符串表,而根本不使用xV_PROD_Str(我出于个人理解将其添加)

The V_PROD_Str is later used as in string tables in RC files, while xV_PROD_Str is not used at all (I added it for my own understanding)

推荐答案

预处理器 ## 运算符是 token级联,并且在问题中的使用是不确定的行为.

The preprocessor ## operator is token concatenation, and the use of it in the question is Undefined Behaviour.

与stringify(#)运算符一样,串联运算符对参数的未扩展值起作用,因此,如果要将其应用于扩展参数,则需要通过另一个宏调用进行间接调用,例如使用 xV_Str(x)宏,该宏会在对内部宏的调用中扩展其参数.

Like the stringify (#) operator, the concatenate operator works on the unexpanded value of its arguments, so if you want it to apply to expanded arguments you need to indirect through another macro call, as with the xV_Str(x) macro, which expands its argument in the call to the inner macro.

令牌串联仅在结果是有效令牌时才有效.奇怪的是, 13.2.9.44.0 是有效的预处理编号.但是运算符的实际用法是)## 0 ,并且您无法将) 0 连接在一起.(您也不想这样做;其目的是将 V_FORMAT(13,2,9,44,0)的扩展值连接起来,但是您需要一个间接宏调用才能做到这一点.)

Token concatenation will only work if the result is a valid token. Oddly, 13.2.9.44.0 is a valid preprocessing number. But the actual use of the operator is ) ## 0, and you cannot concatenate ) and 0. (Nor did you want to; the intent was to concatenate the expanded value of V_FORMAT(13,2,9,44,0) but you'd need an indirect macro call to do that.)

在生成字符串的情况下,完全不需要令牌连接,因为stringify运算符不需要将其参数作为单个令牌.因此,以下应该可以正常工作:

In the case of producing strings, token concatenation is completely unnecessary, since the stringify operator does not require its argument to be a single token. So the following should work fine:

#define V_Str(x)                    #x
#define xV_Str(x)                   V_Str(x)
#define V_FORMAT(a,b,c,d,e)         a.b.c.d.e
#define V_PROD_STR                  xV_Str(V_FORMAT(13,2,99,44,0)0)

这篇关于以下C代码中的#和##有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 21:24