这篇文章中将使用C语言,实现交换两个任意类型变量的功能.说到任意类型用C让人感觉很难做,如果是C++则使用模板函数就轻松搞定:
template<class T> inline void swap(T& t1, T& t2) { T tmp; tmp = t1; t1 = t2; t2 = tmp; }
先说下使用^来交换两个整数,其代码看着简单但不容易理解
a ^= b; b ^= a; a ^= b;
有人说这种写法很奇葩,但我要说的是,异或运算是计算机很常用的操作.搞懂这一算法是熟练掌握异或的基础.关于^交换两整数的理解方式可以按如下方式:
先将a,b当成两个布尔类型,那么a,b会有四种组合
0,0 (1)a ^= b;变成 0,0 (2)b ^= a;变成 0,0 (3)a ^= b;变成 0,0
1,0 (1)a ^= b;变成 1,0 (2)b ^= a;变成 1,1 (3)a ^= b;变成 0,1
0,1 (1)a ^= b;变成 1,1 (2)b ^= a;变成 1,0 (3)a ^= b;变成 1,0
1,1 (1)a ^= b;变成 0,1 (2)b ^= a;变成 0,1 (3)a ^= b;变成 1,1
这样三句代码执行完成后,四种组合中的数值都得到了交换.
即然位运算与BIT相邻数值无关的,那么8个BIT的char类型,16个BIT的short,以及long, long long都可以使用^来交换.
还有人认为这种异或运算只能用于整数类型的交换.实际上异或运算是针对二进制的,既然计算机所有的数据类型都是以二进制进行保存的,那么当然可以用异或运算交换任何数据类型.
最后我的解决方案如下:
1 #define XYZ_SWAP(i, j) \ if (&i != &j) 2 { 3 switch(sizeof(i)) 4 { 5 case 1: 6 *(char*)&i ^= *(char*)&j; 7 *(char*)&j ^= *(char*)&i; 8 *(char*)&i ^= *(char*)&j; 9 break;10 case 2:11 *(short*)&i ^= *(short*)&j;12 *(short*)&j ^= *(short*)&i;13 *(short*)&i ^= *(short*)&j;14 break;15 case 4:16 *(long*)&i ^= *(long*)&j;17 *(long*)&j ^= *(long*)&i;18 *(long*)&i ^= *(long*)&j;19 break;20 case 8:21 *(long long*)&i ^= *(long long*)&j;22 *(long long*)&j ^= *(long long*)&i;23 *(long long*)&i ^= *(long long*)&j;24 break;25 default:26 for (int k = 0; k < sizeof(i); k++)27 {28 *((char*)&i + k) ^= *((char*)&j + k);29 *((char*)&j + k) ^= *((char*)&i + k);30 *((char*)&i + k) ^= *((char*)&j + k);31 }32 break;33 }34 } 35 36 void main() 37 { 38 char ca = 10; 39 char cb = 20; 40 XYZ_SWAP(ca, cb); 41 42 short sa = 10; 43 short sb = 20; 44 XYZ_SWAP(sa, sb); 45 46 int ia = 10; 47 int ib = 20; 48 XYZ_SWAP(ia, ib); 49 50 long long lla = 10; 51 long long llb = 20; 52 XYZ_SWAP(lla, llb); 53 54 float fa = 10.01f; 55 float fb = 2000.89f; 56 XYZ_SWAP(fa, fb); 57 58 double da = 10.01; 59 double db = 2000.89; 60 XYZ_SWAP(da, db); 61 62 void* pa = &da; 63 void* pb = &db; 64 XYZ_SWAP(pa, pb); 65 }
这里使用了个宏定义来实现不同类型的两个变量的交换.还有就是假设long占用4个字节.
时间: 2024-11-09 09:18:13