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年以来的含蓄?