现在的位置: 首页 > 综合 > 正文

无临时变量交换两变量值的方法缺陷与改进

2013年06月10日 ⁄ 综合 ⁄ 共 599字 ⁄ 字号 评论关闭

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

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

有一个巧妙的函数 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

抱歉!评论已关闭.