预处理器如何处理宏中的括号参数



我有一个宏:

#define FBOX(x) [NSNumber numberWithFloat:x]

我听说宏是由预处理器处理的,在这种方式中,来源将被宏文本替换,但是当我从来没有真正地将括号扔到混合物中时,这对我来说是没有意义的说FBOX(x)。我说的是FBOX(1.0f)。那么,预处理器在宏中如何处理参数?

如何处理参数?

那么,预处理器在宏中如何处理参数?

本质上是宏替换是字符串替换,但它是语言意识

语言意识部分是宏和宏参数的替换文本必须在(objective-)c( )中为整个令牌;您不能在没有关闭的情况下包括开场的双引号。但是,这种意识停止了令牌的级别,您可以定义宏,并通过宏观参数,这是代码不完整的宏,甚至是无效的代码块 - 只要单个令牌有效。

作为语言意识的一部分,在预处理过程中也删除了评论和额外的空间。

字符串替换部分是宏"呼叫"仅由构成其定义的文本(单个令牌)替换,并且定义中的每种使用参数都被替换为呼叫中的参数文本。这一切都发生在之前的编译器分析代码的语法。

所以在您的示例中:

#define FBOX(x) [NSNumber numberWithFloat:x]

然后"呼叫":

... FBOX(1.0f) ...

由:

取代
... [NSNumber numberWithFloat:1.0f] ...

编译器分析您的代码语法之前。

要看到宏正在被象征化,我们可以将您的宏重新定义为:

#define FBOX(x) [NSNumber numberWithFloat:x.0f]

然后尝试:

... FBOX(1) ...

成功替换了宏,但是在分析语法时,编译器会产生错误,因为结果文本看起来像:

... [nsnumber numberWithFloat:1 .0f] ...

其中 1&.0f两个令牌,而不是一个浮点数。因此,编译器期望在1之后使用],并将报告错误。

在xcode中,如果您选择产品:执行操作:预处理代码Xcode将在预处理后向您显示文件的结果。

它只是用1.0f替换x,因此:

NSNumber *n = FBOX(1.0f);

变为:

NSNumber *n = [NSNumber numberWithFloat:1.0f];

然后将其提交给编译器。

给定:

#define FBOX(x) [NSNumber numberWithFloat:x]

使用 FBOX(1.0f)将替换为:

[NSNumber numberWithFloat:1.0f]

在某种程度上,它类似于编写一种方法...

- (void)foo:(NSObject*)bar {
    // do stuff with bar
}

您不一定将名为bar的变量传递到该方法中。您只是传递一个变量。然后,该方法的主体将变量用于该方法的任何操作,只是当您编写它时,您将其称为bar,因为您必须有某种名称。

最新更新