当您看到如下行:
#define IX(i,j) ((i)+(N+2)*(j))
相当于:
int IX(int i, int j) {
return ((i)+(N+2)*(j));
}
您如何知道退货类型等?
答案 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)会产生不良副作用,但这就是智能使用的地方。