我执行了以下代码
# 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
宏也会被执行?
答案 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;
}