2010-09-22 119 views
1

当你看到这样一行:#define是否等价于一个函数?

#define IX(i,j) ((i)+(N+2)*(j)) 

等同于:

int IX(int i, int j) { 

    return ((i)+(N+2)*(j)); 

} 

你怎么知道的返回类型等?

+0

啊谢谢你们。 – 2010-09-22 00:23:31

+0

顺便说一句,你需要阅读MACROS – 2010-09-22 02:06:15

回答

6

编译器无法看到宏 - 预处理器替换文本。

所以,当你写:

result = IX(5, 3);

编译器会看到:

result = ((5)+(N+2)*(3));

这可能对行为的影响,但它取决于你的宏。在这种情况下,不要太多(也有性能和调试方面的差异,但是我们不要在这里担心它们)。

假如,例如,你定义的宏像这样的(注二等使用变量)

#define IX(i,j) ((i)+(i+2)*(j))

并把它称为像这样:

result = IX(++i, j);

然后宏观和功能会有不同的行为。

3

#defines是预处理器命令。当代码被编译时,IX(i,j)在它发生的任何地方被它的定义替换。您可以将其视为复制粘贴操作。因为这是在编译代码时发生的,所以IX(i,j)不返回任何类型。这种缺乏类型安全既是一个特点,也是一个缺点,请谨慎使用。

3

不,它不等同。 A #define是一个宏,是一种源代码字符串替换能力。

你的IX()函数的例子有许多与执行代码有关的属性,比如说有一次编译指令,有一个地址,并且需要整数参数。

该宏需要参数,但它没有类型处理,直到尝试算术。即使如此,预处理器可以评估的任何参数都可以做一些有用的事情。或者它可以做一些意想不到的事

作为一个便利的经验法则,使用宏越多,代码越容易理解和维护。

2

是和否:它们的工作方式不同,但在此特定情况下为,如果仅使用函数签名中使用的参数类型,则效果将相同。

宏实际上只是在实际编译代码之前进行了文本替换,所以不需要类型信息;宏的使用被简单地替换为宏内容,其余部分留给编译器。

这意味着IX(i++,j--)的执行方式取决于它是函数还是宏:如果它是一个宏,则在引用时计算参数,如果它是函数,则在函数被调用时计算它们。

由于没有参数被引用两次,所有这些被执行后没有可观察到的差异,但它们仍然被区别对待。作为一个经验法则,如果你想要做的事情需要将代码放置在特定的地方,那么你可以使用宏;否则你应该使用一个函数。

0

所有的答案都是正确的。

由于在编译器将代码转换为机器指令之前宏由预处理器处理,因此他们可能会有其他人提到的有趣副作用。

我不完全赞同宏指令减少代码可理解性的说法。我认为如果他们谨慎,聪明地使用,而且证明他们是正确的,他们可以导致更易于理解的(我敢说呢?)自我记录代码。

例子:

#define MAX(N1,N2) ((N1) > (N2) ? (N1) : N2)) 
biggest = MAX(temperatureOne, temperatureTwo); 

是的,我知道,MAX(X +,Y)将有不良的副作用,但是这也正是智能应用进来

相关问题