[英]I executed following code with macro
我执行了以下代码
# 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
我的问题是,即使if(i>j)
语句为false
后,为什么也会执行#define
宏?
您需要将宏包装在花括号中以使其起作用:
#define swap(a,b) {temp=a; a=b; b=temp;}
您的宏扩展为以下内容
if( i > j)
temp=a;
a=b;
b=temp;
正确的解决方案是使用std :: swap ,它是一个模板函数。 模板功能永远不会遇到此类问题
像这样重写宏:
#define swap(a, b) do { int temp = (a); (a) = (b); (b) = temp; } while (0)
请注意,这里我在复合语句中声明了temp
,如果您必须处理不同的(更大)类型,则可以像在其他范围内声明temp
变量。
在该宏中需要一个作用域:
# define swap(a,b) do { temp=a; a=b; b=temp; } while(0)
注意:do / while用作表达式时避免了陷阱。
但是无论如何,这个宏都是垃圾。 它要求在外部声明变量temp,这首先导致混乱。
在C ++中,只需使用std :: swap。
在您的宏中添加大括号有助于确定代码范围。 当您编写不带花括号的宏时,它将以这种方式扩展。
if( i > j)
{
temp=a;
}
a=b;
b=temp;
但是,当您添加如下括号时:-
#define swap(a,b) {temp=a; a=b; b=temp;}
然后您的代码将按照您的期望执行
为大括号添加括号。 它会工作。
# define swap(a,b) { temp=a; a=b; b=temp;}
如果在代码中插入宏定义,则代替
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.