我被困在下面的c编程中,不知道代码的概念

我被困在下面的c编程中,不知道代码的概念,c,C,在执行了上述代码之后,我得到了意想不到的输出,我没有得到背后的确切逻辑。所以请大家帮助我 上述代码的输出: # 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, t

在执行了上述代码之后,我得到了意想不到的输出,我没有得到背后的确切逻辑。所以请大家帮助我

上述代码的输出:

# 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);
}

swap
不是C函数,而是预处理器插入宏作为宏调用的位置,因此代码如下所示:

10 0 0
if(i>j)
func(&i,&j);
重新格式化后,代码将被删除

if( i > j)
temp=i; i=j; j=temp;;
如果条件为真,则仅完成对
temp
的赋值,其他两个赋值始终无条件完成

这可以通过两种方式解决:将宏调用放在语句块中:

if( i > j)
    temp=i;
i=j;
j=temp;
;
或将宏体设置为块:

if( i > j)
{
    swap( i, j );
}
将多语句宏放在
do{…}while(0)
语句中的惯例是,否则您会得到一个空语句(就像您现在所做的,请参见上文),这可能会导致在将宏作为
if else
语句的一部分展开时出现问题

#define swap(a,b) do { temp=(a); (a)=(b); (b)=temp; } while (0)
如果您的要求是交换
i
j
如果
i>j
,则按照上述代码所示进行交换。在这里使用宏不是一个好主意

if( i > j)
{
  swap( i, j );
}
打电话

void func(int *i,int *j)
{
   int t;
   t = *i;
   *i = *j;
   *j = t;
}

你需要用do…来包装你的宏。。。而(0),如下所示:

10 0 0
if(i>j)
func(&i,&j);

因此,“if”将对整个宏产生影响。

只有宏的第一条语句(即
temp=a;
)在
if(i>j)
条件内。这就是为什么你没有得到你所期望的

应该用{}包围任何多语句宏以避免此问题

#define swap(a,b) do { temp=a; a=b; b=temp;  } while(0)

这还允许您在宏中声明
temp
,因为它有自己的局部作用域(如果需要),尽管这会限制数据类型

提示:
int main()。1@user694733哇!谢谢。感谢您没有忽略
j=temp:-)实际上这里不需要do{}while(0);对于多行/多指令宏,只需使用括号{},它将在代码中展开block@Pandrei:但是你不能在调用后加分号,这很尴尬。@Pandrei不适用于
if(true)macro();else{}
@Quentin fair point…但这就是内联函数优于宏的原因之一;但那是另一回事。最好没有最后的分号,你甚至可以在限制它的作用域的块中声明
temp
,(a)=(b);(b)=temp;}而(0)
即使在这种情况下,如果你使用
交换(a++,b)之类的东西,你也会遇到问题。正如其他评论中所建议的,有充分的理由切换到内联函数。