以下程序
#include <stdio.h>
# define swap(a,b) temp=a; a=b; b=temp;
int main( )
{
int i, j, temp;
i=5;
j=10;
temp=0;
if( i > j)
swap ( i, j );
printf ( "%d %d %d", i, j, temp);
return 0;
}
我得到了这个输出,我用不同的编译器进行了测试:
10 0 0
据我所知,如果j为5且我已经10,那么输出就会被交换掉。但是,在这个特定的程序中,if语句不会被执行。那么,有人可以解释一下我得到这个输出的原因吗?
答案 0 :(得分:4)
您需要用括号包装宏swap
。
if (i > j)
{
swap(i, j);
}
不要忘记宏只是预处理器执行的复制粘贴操作,导致以下结果:
temp = i;
i = j;
j = temp;
如果你不包装它,你最终得到:
if (i > j)
temp = i;
i = j;
j = temp;
我认为这不是你想要的......:)
答案 1 :(得分:1)
正如其他人所说,您的swap
宏会产生三个语句,只有第一个语句成为if
语句的一部分。
编写这样一个宏的惯用方法是:
#define swap(a, b) \
do { temp = a; a = b; b = temp; } while (0)
虽然只使用括号,省略do
和while (0)
可能会起作用,但在以下情况下会失败:
if (something)
swap(a, b);
else
something
在此代码中,作者将swap
视为普通函数调用,而不知道应该省略分号。预处理后,这将扩展为:
if (something)
{ temp = a; a = b; b = temp; }
;
else
something
这会导致编译错误,因为else
不会紧跟if
之后的单个语句。使用do … while (0)
表单会产生代码,使swap(a, b);
只是一个语句,并且可以在任何可以使用该表单的正常函数调用的地方使用。
答案 2 :(得分:0)
扩展宏后,您的代码看起来像
if( i > j)
temp=i;
i=j;
j=temp;
这不是你所期望的:
if( i > j)
{
temp=a;
a=b;
b=temp;
}
答案 3 :(得分:0)
As an alternative to wrapping the macro in brackets...
#define swap(a,b) {temp=a; a=b; b=temp;}
You could also replace the semicolons to ensure the macro expands to a single statement...
#define swap(a,b) temp=a, a=b, b=temp;
我更喜欢'括号'方法,因为它更好地说明了范围。