将三个数从大到小输出

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

函数和宏的区别:

  • 宏的缺点:

  1. 不方便调试(因为预处理阶段进行了替换)
  2. 导致了代码的可读性差,可维护性差(容易误用)
  3. 没有类型安全的检查
  4. 在一个域中不能重复用,有可能会出现变量重定义的错误!
  5. 如果遇到这种情况,输出会有错误!
#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),结果输出就是正确的!


  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).
  • 宏的优点:

  1. 增强代码的复用性
  2. 提高性能
  3. 函数会有栈帧开销

猜你喜欢

转载自blog.csdn.net/qq_37941471/article/details/78485508