解释以下c程序的输出

时间:2014-01-29 18:38:35

标签: c

以下程序

#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语句不会被执行。那么,有人可以解释一下我得到这个输出的原因吗?

4 个答案:

答案 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)

虽然只使用括号,省略dowhile (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;

我更喜欢'括号'方法,因为它更好地说明了范围。