C宏和括号中参数的使用

C宏和括号中参数的使用,c,macros,c-preprocessor,parentheses,C,Macros,C Preprocessor,Parentheses,范例 我意识到这里可能没有什么显著的区别,但是为什么要在宏体的括号中包含a?它是如何改变它的?假设你有 #define Echo(a) a #define Echo(a) (a) 如果我说: #define mul(x, y) x * y 现在,如果我滑动更改宏: mul(a + 5, 6); /* a + 5 * 6 */ 请记住,不会计算参数或任何东西,只执行文本替换 编辑 有关将整个宏放在括号中的说明,请参见发布人。假设您有 #define Echo(a) a #define

范例

我意识到这里可能没有什么显著的区别,但是为什么要在宏体的括号中包含
a
?它是如何改变它的?

假设你有

#define Echo(a)  a
#define Echo(a) (a)
如果我说:

#define mul(x, y)  x * y
现在,如果我滑动更改宏:

mul(a + 5, 6); /* a + 5 * 6 */
请记住,不会计算参数或任何东西,只执行文本替换

编辑 有关将整个宏放在括号中的说明,请参见发布人。

假设您有

#define Echo(a)  a
#define Echo(a) (a)
如果我说:

#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)) */
这是好的,只要你不了解宏本身(我也不是专家:))

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

1) :

以及:

编译器将
a*b
视为例如
a==5
b==10
这样做
5*10

但是,当你说:
添加(2+a*5+b)
就像这里:

#define ADD( a, b ) a * b
你得到的
37
是因为

#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;
}
这意味着:

 2 + 5 * 5 + 10
2 + ( 5 * 5 ) + 10
这意味着:

 2 + 5 * 5 + 10
2 + ( 5 * 5 ) + 10
简而言之,这两者之间有很大的区别:

2 + 25 + 10


为了记录在案,我从这里着陆,我将尝试在这里扩展这个答案,以适合另一个

您正在询问以下方面的差异:

#define mul(x, y)  ((x) * (y))
mul(a + 5, 6); /* ((a + 5) * (6)) */
这是好的,只要你不了解宏本身(我也不是专家:))

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

1) :

以及:

编译器将
a*b
视为例如
a==5
b==10
这样做
5*10

但是,当你说:
添加(2+a*5+b)
就像这里:

#define ADD( a, b ) a * b
你得到的
37
是因为

#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;
}
这意味着:

 2 + 5 * 5 + 10
2 + ( 5 * 5 ) + 10
这意味着:

 2 + 5 * 5 + 10
2 + ( 5 * 5 ) + 10
简而言之,这两者之间有很大的区别:

2 + 25 + 10



谢谢,我只是感到困惑,因为在我正在使用的书中,他们使用它们的方式似乎是多余的。他们有一些类似于foo(bar)(bar)->的东西,它们会在这里被解析吗?你可能是指
foo(bar)(bar)->一些
,是的,它们是必要的。我想问一下,但是它是如何被解析的呢?我读了整个链接页面,仍然不知道如何被解析错误假设你有一个结构数组,出于某种原因,请执行
foo(bar+5)
。如果
foo
是一个函数,那就很好了,但是如果它是一个没有括号的宏,那么它最终会变成
bar+5->something
。类似的,如果
bar
是指向指针的指针,而你做了
foo(*bar)
,结果是
*bar->something
,这肯定是错误的,你会想要
(*bar)->一些
谢谢,我只是感到困惑,因为在我正在使用的书中,他们使用它们的方式似乎是多余的。他们有一些类似于foo(bar)(bar)->的东西,它们会在这里被解析吗?你可能是指
foo(bar)(bar)->一些
,是的,它们是必要的。我想问一下,但是它是如何被解析的呢?我读了整个链接页面,仍然不知道如何被解析错误假设你有一个结构数组,出于某种原因,请执行
foo(bar+5)
。如果
foo
是一个函数,那就很好了,但是如果它是一个没有括号的宏,那么它最终会变成
bar+5->something
。类似的,如果
bar
是一个指向指针的指针,而你做了
foo(*bar)
,结果是
*bar->something
,这肯定是错误的,你会想要
(*bar)->某个东西
这个问题可能的重复就是这个问题的重复,而不是相反,相关问题:问题的可能重复项是这个问题的重复项,而不是相反,现在是这样关闭的。相关问题:为什么在变量之前写
auto
?完全是redundant@ErikW请解释一下,在本例中使用
auto
到底有什么错误?您不需要用C编写
auto
,因为所有变量在范围中声明时都是自动的(声明为显式
静态
时除外)。这不是错误的,而是不必要的。“Erikw我不能回答你的问题,只要你不认为C中的自动使用是错误的。可能是同一个问题:为什么人们不使用主返回?”仅仅因为是隐式的吗?为什么在变量之前写
auto
?完全是redundant@ErikW请解释一下,在本例中使用
auto
到底有什么错误?您不需要用C编写
auto
,因为所有变量在范围中声明时都是自动的(声明为显式
静态
时除外)。这不是错误的,而是不必要的。“Erikw我不能回答你的问题,只要你不认为C中的自动使用是错误的。可能是同一个问题:为什么人们不使用主返回?”就因为是99年以来的含蓄?