zoukankan      html  css  js  c++  java
  • 无临时变量交换两变量值的方法缺陷与改进

    下面的阐述的内容只是对前辈经验的整理。

    由于早期计算机的内存容量很小,为了尽量节省空间,交换两变量值时不使用中间变量。但这可能暗藏着缺陷。

    有一个巧妙的函数 swap 是这样编写的:

    inline void swap(int &a, int &b)
    {
      a = a + b; //缺陷1: 可能产生上溢.
      b = a - b;
      a = a - b;
    }
    

    引发缺陷 1 的原因是,当 a 和 b 的值比较大,相加之和的实际值大于 int 类型所能表示的数值范围,此时产生上溢。

    当传入 swap 函数的实参来自同一变量时,将会引发另一个缺陷:

    int a = 2;
    
    // 缺陷 2: 传入同一变量, 变量结果为 0.
    swap(a, a);
    

     上面 swap 内联函数调用展开后如下:

    a = a + a;
    a = a - a;
    a = a - a;  // a 的值为 0.
    

     以此,当传入 swap 函数的实参来自同一变量时,该变量的值变为 0,得到了错误的结果。

    下面是一种改进方法:

    inline void swap(const &a, const &b)
    {
        a = a ^ b;
        b = a ^ b;
        a = a ^ b;
    }
    

    例如,a = 10110B,b = 01011B,交换过程如下:

    (1) a = a ^ b:

      a: 10110
      b: 01011
      a: 11101

    (2) b = a ^ b:

      a: 11101
      b: 01011
      b: 10110

    (3) a = a ^ b:

      a: 11101
      b: 10110
      a: 01011

    也就是:

      b = (a^b)^b = a^(b^b) = a^0 = a
      a = (a^b)^a = (a^a)^b = 0^b = b

  • 相关阅读:
    Verilog --序列检测器(采用移位寄存器实现)
    SV -- Randomization 随机化
    SV -- Interprocess Communication (IPC 线程间通信)
    SV -- Class 类
    Verilog -- 序列模三(整除3)检测器
    VSCode+C++环境搭建
    在次线性时间内计算线性递归数列
    Codefest19受虐记
    ABC135记录
    Paint.NET软件分享
  • 原文地址:https://www.cnblogs.com/wxxweb/p/2070249.html
Copyright © 2011-2022 走看看