#define是否等同于函数?

时间:2010-09-22 00:09:42

标签: c

当您看到如下行:

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

相当于:

int IX(int i, int j) {

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

}

您如何知道退货类型等?

5 个答案:

答案 0 :(得分:6)

编译器永远不会看到宏 - 预处理器会替换文本。

所以,当你写:

result = IX(5, 3);

编译器会看到:

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

这可能会对行为产生影响,但这取决于您的宏。在这种情况下,没有那么多(也存在性能和调试方面的差异,但我们不要在这里担心它们。)

例如,你是这样定义了你的宏(注意第二次使用 i 变量)

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

并称之为:

result = IX(++i, j);

然后宏和函数会有不同的行为。

答案 1 :(得分:3)

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

答案 2 :(得分:3)

不,这不等同。 #define是一种宏,一种源代码字符串替换功能。

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

宏接受参数,但在尝试算术之前没有类型处理。即使这样,预处理器可以评估的任何参数都可以做一些有用的事情。或者它可以做一些意想不到的事情。

作为一个方便的经验法则,使用的宏越多,代码的可理解性和可维护性就越低。

答案 3 :(得分:2)

是和否:它们的工作方式不同,但在这种特殊情况下,如果你只使用你在函数中使用的类型的参数,效果将是相同的签名。

宏实际上只是在实际编译代码之前执行的文本替换,因此不需要类型信息;宏使用简单地用宏内容替换,其余的留给编译器。

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

由于没有参数被引用两次,因此在执行每个参数之后没有可观察到的差异,但它们仍然被区别对待。

根据经验,如果您要做的事情要求将代码放置在特定的地方,那么您可以使用宏;否则你应该使用一个函数。

答案 4 :(得分:0)

所有答案都是正确的。

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

我并不完全同意宏减少代码可理解性的说法。我认为如果他们谨慎使用,聪明地使用,并且证明是正确的,那么他们可以导致更容易理解(我敢说它吗?)自我记录代码。

示例:

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

是的,我知道MAX(x ++,y)会产生不良副作用,但这就是智能使用的地方。