Objective c 预处理器如何处理宏中的插入参数?

Objective c 预处理器如何处理宏中的插入参数?,objective-c,macros,Objective C,Macros,我有这样一个宏: #define FBOX(x) [NSNumber numberWithFloat:x] 我听说预处理器处理宏的方式是将源代码替换为宏文本,但当在混合中插入括号时,这对我来说没有意义,因为我从来没有说过FBOX(x)。我说的是类似于FBOX(1.0f)。那么,预处理器究竟如何处理宏中的参数呢?它只是将x替换为1.0f,因此: NSNumber *n = FBOX(1.0f); 变成: NSNumber *n = [NSNumber numberWithFloat:1.0f]

我有这样一个宏:

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

我听说预处理器处理宏的方式是将源代码替换为宏文本,但当在混合中插入括号时,这对我来说没有意义,因为我从来没有说过
FBOX(x)
。我说的是类似于FBOX(1.0f)。那么,预处理器究竟如何处理宏中的参数呢?

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

NSNumber *n = FBOX(1.0f);
变成:

NSNumber *n = [NSNumber numberWithFloat:1.0f];
然后将其呈现给编译器。

给定:

#define FBOX(x) [NSNumber numberWithFloat:x]
使用
FBOX(1.0f)
将替换为:

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

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

- (void)foo:(NSObject*)bar {
    // do stuff with bar
}
您不一定要将名为
bar
的变量传递到方法中。您只是传入了一个变量。然后,方法的主体将变量用于该方法所做的任何事情,只是当您编写它时,您将它称为
bar
,因为您必须为它命名

那么,预处理器究竟如何处理宏中的参数呢

宏替换本质上是字符串替换,但它是语言感知的

语言感知部分是宏的替换文本和宏的参数必须是(Objective-)C(++)中的完整标记;比如说,你不能包括一个开头的双引号而没有结尾的引号。然而,这种意识停留在标记级别,您可以定义宏并传递宏参数,这些宏参数是不完整的代码块,甚至是无效的代码块,只要单个标记有效

作为语言意识的一部分,注释和额外的空白也会在预处理过程中被删除

字符串替换部分是,宏“call”只被组成其定义的文本(单个标记)替换,定义中参数的每次使用都被调用中参数的文本替换。这一切都发生在编译器分析代码语法之前

在你的例子中:

#define FBOX(x) [NSNumber numberWithFloat:x]
然后是“呼叫”:

替换为:

[NSNumber numberWithFloat:1.0f]
... [NSNumber numberWithFloat:1.0f] ...
在编译器分析代码语法之前

要查看宏正在标记化,我们可以将您的宏重新定义为:

#define FBOX(x) [NSNumber numberWithFloat:x.0f]
然后尝试:

... FBOX(1) ...
宏被成功替换,但编译器在分析语法时产生错误,因为结果文本如下所示:

。。。[NSNumber numberWithFloat:1.0f]

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


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

有什么混淆?你说的是对的
FBOX(1.0f)
被翻译成
[NSNumber numberWithFloat:1.0f]
BTW-这种宏现在已经过时了。使用新的文本装箱语法。示例:
[someArray addObject:@1.0]
[someArray addObject:@(SomePrimitiveNumbertTypeVariable)]
@rmaddy NSNumber也可以保存
BOOL
@YES
@NO
有效吗?或者我应该使用
@1
@0
?@nhgrif Yes,
@Yes
@NO
是有效的,基本上用bool:
替换
NSNumber Number。