使用异或运算交换两个任意类型变量

这篇文章中将使用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个字节.

 

posted on 2014-10-21 14:08  叶飞影  阅读(2667)  评论(8编辑  收藏  举报