例子
#define Echo(a) a
#define Echo(a) (a)
我知道这里可能没有太大的区别,但是为什么你会想要在宏体内将a
放在括号中呢?这样做有什么改变吗?
例子
#define Echo(a) a
#define Echo(a) (a)
我知道这里可能没有太大的区别,但是为什么你会想要在宏体内将a
放在括号中呢?这样做有什么改变吗?
foo(bar+5)
。如果 foo
是一个函数,那么这将是完全可以的,但如果它是一个没有括号的宏,它最终会变成 bar+5->something
。如果 bar
是指向指针的指针,并且您执行 foo(*bar)
,它最终会变成 *bar->something
,这显然是错误的,您需要 (*bar)->something
。 - nos仅供参考,我从这里 如何在使用宏时修复数学错误 着陆,并尝试在此扩展此答案以适应其他内容。
您正在询问以下差异:
#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 == 5
和b == 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
有什么问题? - Michiauto
,编译器不会做出你不想要的操作,但是在 C 语言中,这种写法是 _不好的风格_,常规的风格是 从不 写 auto
。同样,在 main
函数结尾省略 return 0;
是正确的,但是也是不好的风格;常规的风格是 不要 省略它。违背常规的风格使得其他人阅读你的代码更加困难,就这一点就足以避免这样做了。 - zwolauto
意味着完全不同(并且实际上很有用),因此在C代码中编写它可能会让人们误以为它是要编译为C++;在main
函数中省略return 0;
在C99之前是UB,并且也是一个奇怪的特例,与语言的其他部分不一致。但并非所有的风格规则都有客观的理由,_你仍然应该遵守它们_。因为可读性。 - zwolauto
关键字将拥有自己的生命,就像它在C++中已经做过的那样。我坚决同意这样的观点:在过去的40年里编写的C代码不应该使用关键字auto
。即使在为C23编写的代码中,我也会谨慎使用auto
,因为可能会产生误解,这让我感到不安(而且我在工作中还在努力让我们的代码库使用C11;至少我们现在已经转向了C99)。 - undefined