我有一个像这样的宏:
#define FBOX(x) [NSNumber numberWithFloat:x]
我听说过这些宏会由预处理器处理,其中source将被宏文本替换,但是当括号被抛入混合中时,这对我来说没有意义,因为我实际上从未说FBOX(x)
。我说FBOX(1.0f)
之类的东西。那么预处理器如何完全处理宏中的参数呢?
答案 0 :(得分:2)
那么预处理器究竟是如何处理宏中的参数的呢?
基本宏替换是字符串替换,但它是语言识别。
语言识别部分是宏的替换文本和宏的参数必须是(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 :(得分:0)
它只是将x
替换为1.0f
,因此:
NSNumber *n = FBOX(1.0f);
变为:
NSNumber *n = [NSNumber numberWithFloat:1.0f];
然后将其呈现给编译器。
答案 2 :(得分:0)
假设:
#define FBOX(x) [NSNumber numberWithFloat:x]
使用FBOX(1.0f)
将替换为:
[NSNumber numberWithFloat:1.0f]
在某种程度上,它类似于编写方法......
- (void)foo:(NSObject*)bar {
// do stuff with bar
}
您不一定要将名为bar
的变量传递给方法。你只是传入一个变量。然后该方法的主体将该变量用于该方法所做的任何事情,只是在您编写它时,您将其称为bar
,因为您必须为它添加某种名称。