`
mmdev
  • 浏览: 13242882 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

由教科书函数swap想到的

阅读更多
经典的Swap
几乎从远古时代至今的每一本程序设计语言的教材上, 都可以看到一个叫swap的函数, 书上这样告诉我们:(以C语言为例)
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->voidswap(int*a,int*b){
inttemp;
temp
=*a;
*a=*b;
*b=temp;
}

在时下最时尚的C#中,我们可以这样写:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->staticvoidSwap<T>(refTa,refTb)
{
Ttemp
=a;
a
=b;
b
=temp;
}

上面的C#代码和前面的C大同小异,无非只是体现了一下C#泛型的优越性. 然而有的语言则要飘逸的多,比如说python,它可以支持以下写法:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->a,b=b,a

呃,这只是一个表达式。不需要什么函数,不需要引用,最重要的是不需要麻烦临时变量

使用XOR的Swap
如果赋值运算符两边不支持多个操作数是不是就非要使用临时变量呢?那倒未必,请看下面的C代码:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->voidswap2(int*a,int*b){
*a^=*b;
*b^=*a;
*a^=*b;
}

为什么异或有这样的功能呢?其实是由以下两个性质决定的:
1.b ^ a =b ^ a (交换律)
2.a ^ a = 0 (由异或的定义)
为了说明问题,这里我们将上述的函数展开并重新标记变量:
a1 = a ^ b
b1 = b ^ a1 = b ^ (a ^ b) = a ^ (b ^ b) = a
a2 = a1 ^ b1 = a ^ b ^ a = b ^ (a ^ a) = b


我们的swap中都应该选择XOR吗?
No,看上去这种不引入临时变量的写法的确比较屌,使用XOR做置换也的确比赋值要高效,但在背后,XOR也会带来一些隐患。例如:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->inti=2;
int*a=&i;
int*b=a;
swap2(a,b);
printf(
"*a=%d,*b=%d",*a,*b);
这段代码中,我们期待的输出应该是:a = 2, b =2,因为两个同样的数经过交换应该还是一样的(=2)。但是根据先前提到的第2条规律,由于这里a,b都指向i的位置,所以这里swap2(a,b)=i^i=0;结果竟然等于“0”!。谁会想到一个小小的swap函数居然会弄丢数据。这对调试程序来说无疑增加了难度。所以代码还是写得越“老实”越好维护,正如大神Kernighan所言:

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”

Freesc
2009年7月29日

分享到:
评论

相关推荐

    交换函数2_swap_c++交换函数_

    在C++编程语言中,`swap`函数是一个非常基础且重要的工具,用于交换两个变量的值。这个功能在处理数组、容器或者需要重新排列数据顺序的场景中非常常见。本篇文章将深入探讨`swap`函数的工作原理,以及如何在C++中...

    swap交换函数

    这是交换两个数的C++函数,通过引用传参成功在函数中实现交换两个参数

    Swap函数的实现

    这种做法虽然直观,但在函数内部创建的 `temp` 只存在于函数的作用域内,因此它不会改变传递进来的实参 `x` 和 `y`。所以,这种方法实际上没有完成变量的交换,程序输出的 `x` 和 `y` 仍然是它们原来的值。 2. 通过...

    swap_1位swap电路_logisim_swap_

    一个简单的1位swap电路可能由两个异或门和一个与门组成。异或门可以用于无条件交换,但为了实现受控交换(根据c的值),需要将其中一个异或门的输入与c进行与操作。这样,只有当c为1时,异或门才会执行交换操作。 ...

    swap_state.rar_swap

    1. **交换分区管理**:`swap_state.c`可能包含了对交换分区的定义、分配、激活和去激活的函数。交换分区是在硬盘上预分配的一块空间,用于模拟额外的内存。 2. **交换空间分配**:内核如何找到合适的交换空间进行...

    C++ Swap函数有几种写法?

    在C++编程中,交换两个变量的值是一个常见的操作,`swap`函数就是用来完成这一任务的。在C++中,`swap`函数有多种不同的实现方式,每种都有其特定的适用场景和优缺点。这里我们将探讨几种常见的`swap`函数实现方法。...

    centos清理swap交换区内存

    ### CentOS清理SWAP交换区内存 #### SWAP分区机制与问题背景 在深入探讨如何清理CentOS中的SWAP交换区之前,我们先了解下SWAP的基本概念及其在系统中的作用。SWAP空间(或称为SWAP分区)是在硬盘上预留的一块区域...

    swap color.rar_dug9ab_swap_swapping与swap

    标签"dug9ab swap swapping与swap"可能代表这个压缩包内包含了与"swap"相关的代码、资源或示例,其中"swap"是关键词,可能包含交换颜色的函数或脚本。 在压缩包的子文件名"Hassan"中,我们无法直接推断具体信息,但...

    c语言函数(几乎所有的c语言函数)范例教程

    例如,你可以定义一个 `swap()` 函数来交换两个变量的值。 4. **函数指针**: C语言允许我们使用函数指针,即一个变量可以存储函数的地址。这在回调函数、排序算法(如快速排序、冒泡排序)以及实现动态策略(如...

    C语言函数范例教程大全

    C语言中的函数指针允许我们存储函数的地址,从而可以将函数作为参数传递给其他函数,或者将函数作为变量进行操作。这对于实现回调函数和策略模式等高级编程技术至关重要。 ```c typedef int (*compare)(int, int); ...

    v881开启swap教程

    v881开启swap教程,里面有详细说明!欢迎下载!

    Linux修改Swap大小.

    ### Linux 修改 Swap 大小详解 #### 一、Swap 分区概述 在 Linux 系统中,Swap 分区(或文件)充当一种辅助内存的角色。当系统的物理内存不足时,Linux 会将一部分暂时不用的数据从内存中移出并保存到 Swap 分区,...

    增大swap分区.txt 系统安装后修改swap分区

    在深入探讨如何增大swap分区之前,我们先来理解一下什么是swap分区以及它在系统中的作用。在计算机系统中,特别是Linux环境下,swap分区扮演着虚拟内存的角色。当系统的物理内存(RAM)不足时,操作系统会将一部分不...

    修改swap分区大小方法

    在Linux操作系统中,swap分区是一种特殊的分区类型,用于充当系统的虚拟内存。当物理RAM不足时,Linux会将部分数据暂时存储到swap分区中,以缓解内存压力。然而,有时在安装Linux后,可能会发现预设的swap分区大小不...

    openwrt swap启用脚本

    在深入探讨"openwrt swap启用脚本"这一主题前,我们先来了解下几个关键概念:OpenWRT、Swap以及脚本。 ### OpenWRT OpenWRT是一款基于Linux的开源固件项目,主要用于无线路由器和其他嵌入式设备。它提供了一个可...

    windows下浏览ext、swap分区

    - **使用SWAP**:在Linux系统中,SWAP分区是透明的,由内核自动管理。但在Windows下查看或操作SWAP分区,需要特定工具。 3. **Windows下浏览EXT和SWAP分区的工具** - **WinAllFS**: 这可能是一款能帮助你在...

    C++ 函数 练习题

    3. C++语言中规定函数的返回值类型是由 **D. 在定义该函数时所指定的函数类型所决定** 。这意味着函数的返回类型是在函数定义时固定的。 4. 选项 **D. 调用函数必须在一条独立的语句中完成** 的描述是不正确的。函数...

    SUSE上扩容Swap空间方法

    ### SUSE上扩容Swap空间方法详解 #### 一、引言 在Linux系统中,Swap空间作为虚拟内存的一部分,对于提升系统性能具有重要作用。当物理内存不足时,系统会将部分不常用的数据移动到Swap空间中,从而释放物理内存供...

    C++ 中的Swap函数写法汇总

    在C++编程中,`swap`函数是一种用于交换两个变量值的常见操作,它具有广泛的应用,例如在排序算法、容器操作以及数据结构的变换中。这篇文章主要探讨了`swap`函数的不同实现方法,从基本的C语言实现到C++中的模板化...

Global site tag (gtag.js) - Google Analytics