# define swap(a,b) temp=a; a=b; b=temp;
main( )
{
int i, j, temp;
i=5;
j=10;
temp=0;
if( i > j)
swap( i, j );
printf( "%d %d %d", i, j, temp);
}
执行上面的代码后,我得到了意想不到的输出,我没有得到这背后的确切逻辑。所以请帮助我。
输出上述代码:
10 0 0
答案 0 :(得分:8)
宏swap
不是C函数,而是预处理器在宏调用的位置插入宏,因此代码如下所示:
if( i > j)
temp=i; i=j; j=temp;;
重新格式化代码后
if( i > j)
temp=i;
i=j;
j=temp;
;
如果条件为真,则仅完成对temp
的分配,其他两个分配始终 无条件地完成。
这可以通过两种方式解决:将宏调用放在语句块中:
if( i > j)
{
swap( i, j );
}
或使宏体成为块:
#define swap(a,b) do { temp=(a); (a)=(b); (b)=temp; } while (0)
将多语句宏放在do { ... } while (0)
语句中的约定是因为否则你得到一个空语句(就像你现在一样,见上文),这可能会在扩展宏时引起问题,例如if else
声明。
答案 1 :(得分:0)
if( i > j)
{
swap( i, j );
}
如果您的要求是i
和j
i>j
,请按照上面的代码进行操作。在这里使用宏不是一个好主意
void func(int *i,int *j)
{
int t;
t = *i;
*i = *j;
*j = t;
}
并致电
if(i>j)
func(&i,&j);
答案 2 :(得分:0)
你需要用do ... while(0)包装宏,如下所示:
#define swap(a,b) do { temp=a; a=b; b=temp; } while(0)
因此," if"会对整个宏产生影响。
答案 3 :(得分:0)
只有宏的第一个语句(即temp=a;
)在if(i > j)
条件内。这就是为什么你没有得到你期望的。
您应该使用{}包围任何多语句宏以避免此问题。
#define swap(a,b) {temp=a; a=b; b=temp;}
这也允许您在宏内部声明temp
,因为它有自己的本地作用域,但这限制了数据类型。