我用宏执行了以下代码

时间:2014-02-25 13:18:45

标签: c++ c macros

我执行了以下代码

# define swap(a,b) temp=a; a=b; b=temp;
#include<stdio.h>
#include<conio.h>
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

我的问题是,即使在#define语句为if(i>j)后,false宏也会被执行?

6 个答案:

答案 0 :(得分:6)

您需要将宏包装成花括号以使其工作:

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

您的宏已扩展为以下

if( i > j)
  temp=a; 
a=b; 
b=temp;

正确的解决方案是使用std::swap,这是一个模板函数。你永远不会遇到模板函数的这类问题

答案 1 :(得分:3)

像这样重写你的宏:

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

请注意,我在复合语句中声明temp,如果必须处理不同(较大)的类型,则可以像在其他范围内一样声明temp变量。

答案 2 :(得分:1)

您需要该宏中的范围:

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

注意:do / while如果用作表达式,则可以避免陷阱。

但无论如何,那个宏是垃圾。它需要在外部声明的变量temp,这首先导致混淆。

在C ++中,只需使用std :: swap。

答案 3 :(得分:1)

向宏添加大括号有助于确定代码范围。 当您编写没有大括号的宏时,它将以这种方式扩展。

    if( i > j)
{
      temp=a; 
}
    a=b; 
    b=temp;

但是当你添加这样的大括号时: -

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

然后您的代码将按照您的期望执行

答案 4 :(得分:0)

为宏添加大括号。它会起作用。

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

答案 5 :(得分:0)

如果要在代码中插入宏定义,而不是

  if( i > j)
    swap( i, j );

你会得到

  if( i > j)
    temp=i; i=j; j=temp;

如果要正确格式化此代码,将会更清楚

  if( i > j) 
    temp=i; 

  i=j; 
  j=temp;

所以在现实中if语句没有被执行。

然而,执行if语句后面的两个语句。

因此j被分配给i而i变为等于10而temp被分配给j并且j变为等于0,

你得到了这个结果。:)

如果您不想要此结果,则应将宏定义括在大括号中。例如

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

然而,将变量temp定义为局部变量会更好。例如

# define swap(a,b) { int temp=a; a=b; b=temp; }

C++中,您可以使用标准模板函数std::swap。问题是C没有引用。通常用C引用代替指针。所以函数看起来像

void swap( int *a, int *b )
{
   int temp = *a;
   *a = *b;
   *b = temp;
} 

在主要内容中,您可以将此功能称为

swap( &i, &j );

C99中,您可以将此功能定义为内联

inline void swap( int *a, int *b )
{
   int temp = *a;
   *a = *b;
   *b = temp;
}