我有一个宏:
#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
,因为您必须有某种名称。