zoukankan      html  css  js  c++  java
  • 使用异或运算交换两个任意类型变量

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

  • 相关阅读:
    ngRoute AngularJs自带的路由
    AngularJs $resource 高大上的数据交互
    AngularJs filter 过滤器
    eBPF监控工具bcc系列一启航
    [转载] kprobe原理解析(一)
    c++通过CMake实现debug开关
    如何使用fio模拟线上环境
    汇编学习pushl, popl
    block:cfq 学习02
    阻抗匹配详细讲解(以前的转贴)
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/4040246.html
Copyright © 2011-2022 走看看