【问题标题】:C macros and use of arguments in parenthesesC 宏和括号中参数的使用
【发布时间】:2011-11-03 10:19:38
【问题描述】:

例子

#define Echo(a)  a
#define Echo(a) (a)

我意识到这里可能没有显着差异,但是为什么您要在宏主体内的括号内包含a?它是如何改变它的?

【问题讨论】:

标签: c macros c-preprocessor parentheses


【解决方案1】:

假设你有

#define mul(x, y)  x * y

如果我说:

mul(a + 5, 6); /* a + 5 * 6 */

现在如果我稍微改变一下宏:

#define mul(x, y)  ((x) * (y))
mul(a + 5, 6); /* ((a + 5) * (6)) */

请记住,不会对参数进行评估或任何其他操作,只会执行文本替换。

编辑

有关将整个宏放在括号中的说明,请参阅Nate C-K 发布的the link

【讨论】:

  • 谢谢,我只是很困惑,因为在我正在使用的书中,他们使用它们的方式似乎是多余的。他们有类似 foo(bar) (bar)-> 的东西,他们会在这里需要吗?
  • 你的意思可能是foo(bar) (bar)->something,是的,它们是必要的。
  • 不好意思问一下,那里的情况怎么样?
  • 我阅读了整个链接页面,但仍然不明白它是如何被解析错误的
  • 假设您有一个结构数组,并且您出于某种原因使用foo(bar+5)。如果foo 是一个函数,那将是非常好的,但如果它是一个没有括号的宏,它将以bar+5->something 结束。类似的,如果 bar 是指向指针的指针,而您执行 foo(*bar) 最终结果为 *bar->something ,这肯定是错误的,您会想要 (*bar)->something
【解决方案2】:

为了记录,我从这里How to fix mathematical errors while using macros 登陆,我会尝试在这里扩展这个答案以适应另一个。

你问的是关于以下方面的区别:

#define Echo( a )  a
#define Echo( a ) ( a )

只要你不理解它自己的宏就可以了(我也不是专家:))。

首先你已经(可能)知道有运算符优先级,所以这两个程序有很大的不同:

1):

#include <stdio.h>
#define ADD( a , b ) a + b

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD (  2 + a ,  2 + b );
    printf( "%d", c );
    return 0;
}

输出:

19

和:

#include <stdio.h>
#define ADD( a , b ) ( a ) + ( b )

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( a , b );
    printf( "%d", c );
    return 0;
}

输出:

15

现在让+ 替换为*

#define ADD( a, b ) a * b

编译器将a * b 视为例如a == 5b == 10 处理5 * 10

但是,当你说: ADD ( 2 + a * 5 + b ) 喜欢这里:

#include <stdio.h>
#define ADD( a , b ) ( a ) * ( b )

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( 2 + a , 5 + b );
    printf( "%d", c );
    return 0;
}

你得到105,因为涉及到运算符优先级并处理

2 + b * 5 + a

作为

( 2 + 5 ) * ( 5 + 10 )

这是

( 7 ) * ( 15 ) == 105

但是当你这样做时:

#include <stdio.h>
#define ADD( a, b ) a * b

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( 2 + a , 5 + b );
    printf( "%d", c );
    return 0;
}

你得到37是因为

 2 + 5 * 5 + 10

意思是:

2 + ( 5 * 5 ) + 10

意思是:

2 + 25 + 10

简短的回答,有很大的区别:

#define ADD( a , b ) a * b

#define ADD( a , b ) ( a ) * ( a )

【讨论】:

  • 变量前为什么要写auto?这是完全多余的
  • @ErikW 请解释一下你在这个例子中使用auto到底有什么问题?
  • 您永远不需要在 C 中编写 auto,因为所有变量在范围内声明时都是自动的(除非声明为显式 static)。这没有错,但没有必要。
  • @ErikW 只要您不认为在 C 中使用 auto 是错误的,我就无法回答您的问题。
  • 可能是同一个问题:为什么人们不在 main 中使用 return?就因为是99以来隐含的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
相关资源
最近更新 更多