C宏,奇怪的东西

试图在C宏中找出一些简单的东西,比如这段代码:

#include  #define MACRO(b) printf("%d\n", b*b) int main() { MACRO(4+1); } 

这段代码的输出是9,我认为它应该是25.我不知道为什么以及如何结果为9而不是25。

当你使用宏时,预处理器会逐字地替换它和它的参数,所以代码中的宏扩展看起来像

 printf("%d\n", 4+1*4.1); 

这不会为您提供您想要的结果,这也是类似函数的宏被忽视的原因之一。

您需要使用括号来确保不会发生此问题:

 #define MACRO(b) printf("%d\n", (b)*(b)) 

然后将导致以下扩展:

 printf("%d\n", (4+1)*(4.1)); 

每当您遇到与预处理器相关的问题时,几乎所有编译器都可以选择在预处理阶段之后停止,这样您就可以查看预处理源,这将帮助您解决这类问题。


还要注意另一个可能的问题是,如果作为参数传递给宏的表达式是例如具有一些副作用的函数调用,该函数将被调用两次并且副作用将发生两次,即使使用括号也是如此。

一个简单的例子,使用你的宏:

 int my_function(void) { printf("Foo\n"); return 1; } int main(void) { MACRO(my_function()); } 

上面的程序将打印两次 "Foo\n" 。 如果MACRO是一个正确的函数,对my_function的调用只会发生一次,而函数的打印输出只会发生一次。

在宏周围加上括号,以正确的顺序评估参数:

 #include  #define MACRO(b) printf("%d\n", (b)*(b)) int main() { MACRO(4+1); }