【问题标题】:C macro, something weirdC宏,奇怪的东西
【发布时间】:2015-11-08 12:09:58
【问题描述】:

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

#include <stdio.h> 
#define MACRO(b)  printf("%d\n", b*b)

int main()
{
    MACRO(4+1); 
}

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

【问题讨论】:

  • ^^^ 编译器不在乎你的想法。

标签: c


【解决方案1】:

当您使用宏时,预处理器会逐字替换它及其参数,因此代码中的宏扩展看起来像

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

那不会为你提供你想要的结果,这也是类函数宏被看不起的原因之一。

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

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

while 将导致以下扩展:

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 的调用只会发生一次,并且该函数的打印输出只会发生一次。

【讨论】:

  • 为了防止副作用,使用:#define MACRO(b) do{int t=(b);printf("%d\n",t);}while(0)
  • ..eh..应该是#define MACRO(b) do{int t=(b);printf("%d\n",t*t);}while(0)
【解决方案2】:

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

#include <stdio.h> 
#define MACRO(b)  printf("%d\n", (b)*(b))

int main()
{
    MACRO(4+1); 
}

【讨论】:

    猜你喜欢
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2013-04-15
    相关资源
    最近更新 更多