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

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

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

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

posted @   Atypiape  阅读(418)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示