本文介绍了在宏中使用#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请解释代码

#include <stdio.h>
#define A(a,b) a##b
#define B(a) #a
#define C(a) B(a)

main()
{
 printf("%s\n",C(A(1,2)));
 printf("%s\n",B(A(1,2)));
}

输出

A(1,2)

我不明白,第一个printf的计算结果如何为12?它不是与第二个相似,因为C宏只是B宏的包装器?

I don't understand, how the first printf evaluates to 12?Isn't it similar to the second, as C macro is simply a wrapper to B macro?

推荐答案

此处的困惑来自一个简单的规则.

The confusion here comes from a simple rule.

在评估宏时,预处理程序首先解析传递给宏的参数中的宏.但是,在特殊情况下,如果参数是#的右边或与 ## 相邻,则它不会解析此类参数中的宏.这是规则.

When evaluating a macro the pre-processor first resolves the macros in the arguments passed to the macro. However, as a special case, if an argument is right of # or adjacent to ##, it doesn't resolve macros within such arguments. Such are the rules.

您的第一种情况

C(A(1,2))

预处理器首先应用 C(a)宏,该宏定义为 B(a).没有 ### 与定义中的参数相邻(在 B(a) 中根本没有),因此 pre-processor必须解析参数中的宏:

The pre-processor first applies the C(a) macro, which is defined as B(a). There's no # or ## adjacent to the argument in the definition (none of them in B(a) at all), thus the pre-processor must resolve macros in the argument:

A(1,2)

A(a,b)的定义是 a ## b ,其结果为 12 .

The definition of A(a,b) is a##b which evaluates into 12.

在对 C(a)宏的参数中的宏进行求值后,C宏变为:

After the macros in the arguments of the C(a) macro are evaluated, the C macro becomes:

C(12)

预处理器现在解析 C(a)宏,根据其定义,该宏变为

The pre-processor now resolves the C(a) macro, which according to its definition becomes

B(12)

完成此操作后,预处理器将再次评估结果中的宏并应用 B(a)宏,因此结果变为

Once this is done, the pre-processor evaluates macros inside the result once again and applies the B(a) macro, so the result becomes

"12"

您的第二种情况

B(A(1,2))

类似于第一种情况,预处理器首先应用 B(a)宏.但是这一次,宏的定义使得该参数以#开头.因此,应用特殊规则并且评估参数内的宏.因此,结果立即变为:

Similar to the first case, the pre-processor first applies the B(a) macro. But this time, the definition of the macro is such that the argument is preceded by #. Therefore, the special rule applies and macros inside the argument are not evaluated. Therefore, the result immediately becomes:

"A(1,2)"

预处理器再次遍历结果,试图找到更多要扩展的宏,但是现在所有内容都在字符串的一部分,并且宏不会在字符串内扩展.所以最终结果是:

The preprocessor goes over the result again trying to find more macros to expand, but now everything is a part of the string, and macros don't get expanded within strings. So the final result is:

"A(1,2)"

这篇关于在宏中使用#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 19:56