#include <stdio.h>
//利用宏实现两个数的交换
//#define Swap(a,b) \
// do{ \
// a = a^b; \
// b = a^b; \
// a = a^b; \
// }while(0);//位运算符(不用考虑越界问题)
//函数实现两个数的交换
void Swap(int* a,int* b)
{
//int tmp;
//tmp = *a;
//*a = *b;
//*b = tmp;//使用中间变量
*a = *a+*b;
*b = *a-*b;
*a = *a-*b;//考虑值越界
}
void test()
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
printf("a b c :%d %d %d\n",a,b,c);
//将a b c按照从大到小排列顺序
if(a < b)
{
Swap(&a,&b);
}
if(a < c)
{
Swap(&a,&c);
}
if(b < c)
{
Swap(&b,&c);
}
printf("a b c从大到小:%d %d %d\n",a,b,c);
}
int main()
{
test();
return 0;
}
这里实现两个值的交换采用了两种方法。(宏和函数)
-
值交换
1.不使用中间变量
1>不考虑值的越界
a = a+b;
b = a-b;
a = a-b;
2>考虑值的越界
a = a^b;
b = a^b;
a = a^b;
2.使用中间变量
int tmp;
tmp = a;
a = b;
b = tmp;
函数和宏的区别:
-
宏的缺点:
- 不方便调试(因为预处理阶段进行了替换)
- 导致了代码的可读性差,可维护性差(容易误用)
- 没有类型安全的检查
- 在一个域中不能重复用,有可能会出现变量重定义的错误!
- 如果遇到这种情况,输出会有错误!
#include <stdio.h>
//利用宏实现两个数的交换
#define Swap(a,b) \
a = a^b; \
b = a^b; \
a = a^b;
int main()
{
int a = 10;
int b = 20;
if(0)
Swap(a,b);
printf("a b:%d %d\n",a,b);
return 0;
}
而如果if(0)换成if(1),结果输出就是正确的!
- 如果遇到下面这种情况,程序会崩溃!
#include <iostream>
using namespace std;
#define NEW_ARRAY(ptr,type,n) \
ptr = (type*)operator new(sizeof(type)*n+4); \
*((int*)ptr) = n; \
ptr = (type*)((char*)ptr+4); \
for(size_t i = 0;i < n;++i) \
new(ptr+i)type;
class AA
{
public:
AA()
{
cout<<"AA()"<<endl;
}
~AA()
{
cout<<"~AA()"<<endl;
}
};
void test2()
{
AA* p1 = NULL;
if(0)
NEW_ARRAY(p1,AA,10);
}
int main()
{
test2();
return 0;
}
假如 test2()改成:
void test2()
{
AA* p1 = NULL;
if(1)
NEW_ARRAY(p1,AA,10);
}
这个输出就会调用10次构造函数。
所以这就是宏的缺陷!避免上下文能够正确匹配,如果要使用宏,一定要加上do{}while(0).
-
宏的优点:
- 增强代码的复用性
- 提高性能
- 函数会有栈帧开销