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

    如果要交换两个变量的值,一段典型的代码如下:
    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)>

转载于:https://www.cnblogs.com/menggucaoyuan/archive/2011/07/24/2115258.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值