• 不借助临时变量交换两个变量的值


        如果要交换两个变量的值,一段典型的代码如下:
        void swap(type* a, type* b)
        {

            if (!a && !b)

            {
                  type temp = *a;
                  *a = *b;
                  *b = temp;

            }
        }
        如果要求不借助于临时变量,则可能有如下代码:
        void swap(type* a, type* b)
        {

            if (!a && !b)
            {

                *a = *a + *b;
                *b = *a - *b;
                *a = *a - *b;

            }
        }
        上面这段代码是比较危险的,有数值溢出的危险。
        如果交换的数值是整形,则可以有如下可用代码:
        void swap(int* a, int* b)
        {

            if (!a && !b)

            {
                a = a ^ b;
                b = a ^ b;
                a = a ^ b;

            }
        }
        如果交换的两个值是单精度浮点数,则交换代码如下:
        void swap(float* a, float* b)
        {

            if (!a && !b)

            {

                (*(unsigned int*)(a)) = (*(unsigned int*)(a)) ^ (*(unsigned int*)(b));
                (*(unsigned int*)(b)) = (*(unsigned int*)(a)) ^ (*(unsigned int*)(b));
                (*(unsigned int*)(a)) = (*(unsigned int*)(a)) ^ (*(unsigned int*)(b));

            }
        }
        编译器可能会默认地把float型转换为double型,所以建议用宏实现两个变量的值的交换:
        #define US(x) (*(usigned*)(&x)) 
        #define swap(a,b)           \
        US(a) = US(a) ^ US(b),   \
        US(b) = US(a) ^ US(b),   \
        US(a) = US(a) ^ US(b)
        如果是双精度浮点数,则可以用下面的的函数:
        void swap(double* a, double* b)
        {

            if (!a && !b)

            {

               (*(unsigned long long*)(a)) = (*(unsigned long long*)(a)) ^ (*(unsigned long long*)(b));
               (*(unsigned long long*)(b)) = (*(unsigned long long*)(a)) ^ (*(unsigned long long*)(b));
               (*(unsigned long long*)(a)) = (*(unsigned long long*)(a)) ^ (*(unsigned long long*)(b));

            }
        }
        以上函数以C的方式实现的,分别处理每种情况。一下代码是C++形式的代码,借助于STL的偏特化特性:
        #include <iostream>
        using namespace std;
        template <int N>
        struct traits //根据字节数得到类型
        {
            typedef void TYPE;
        };

        template <>
        struct traits<sizeof(float)> //模板特化
        {
          typedef unsigned TYPE;
        };

        template<>
        struct traits<sizeof(double)> //模板特化
        {
           typedef unsigned long long TYPE;
        };

        template <typename T>
        typename traits<sizeof(T)>::TYPE &Ref(T &x) //把变量x按另一种类型解释,并返回引用
        {
           return reinterpret_cast<typename traits<sizeof(T)>::TYPE&>(x);
        }
     
        template <typename T>
        void myswap(T &a, T &b) //类型转换
       {
          Ref(a) = Ref(a) ^ Ref(b);
            Ref(b) = Ref(a) ^ Ref(b);
          Ref(a) = Ref(a) ^ Ref(b);
       }
       以上代码很简洁,一个函数就实现了不借助于临时变量而交换两个变量的值的功能。STL功能可谓法力广大,但是个人不屑,谓之奇技淫巧而已,感觉其已堕入魔道了。
    <sizeof(float)><sizeof(double)><sizeof(t)>

  • 相关阅读:
    bzoj1101 [POI2007]Zap
    bzoj2648/2716 kdtree
    bzoj2850巧克力王国
    【bzoj1193】[HNOI2006]马步距离
    bzoj 4401 块的计数 思想+模拟+贪心
    【bzoj2751】[HAOI2012]容易题(easy) 数论,简单题
    Ubuntu分区小知识与分区方案
    Ubuntu16.04安装x11VNC远程桌面
    Ubuntu用户权限管理(chown, chmod)
    Ubuntu新建用户组
  • 原文地址:https://www.cnblogs.com/menggucaoyuan/p/2115258.html
Copyright © 2020-2023  润新知