swap函数估计是一个各种各样程序都会频繁用到的子程序,可是你知道它究竟有多少种不同的写法吗?下面我就列举我知道的几种swap函数来跟大家分享一下。

(1)经典型---嫁衣法

无论是写程序还是干其他事情,一旦涉及到交换,就总是会遇到第三方。这个第三方可能是公正的监督者,也可能是一个徒为他人做嫁衣的可怜虫。在经典法的交换程序中,我们就需要有一个可怜虫来为我们提供暂时的服务。程序如下:

void swap(int *a,int *b)
{
int temp;

temp=*a;

*a=*b;

*b=temp;

}

我们看到,我必须用一个temp变量作为过渡,让他先拥有然后又再赋值给其他人。可见他也不是徒做嫁衣,而是先索取后奉献的主人公精神。哈哈,扯远了。

(2)经典型改进版---范型法
上面的那个swap函数只能交换int类型变量,如果我想交换double类型,short类型,char类型......呢?上面的程序就必须重新写,可是又不是完全推倒重来,只需要修改相应的类型变量就可以了,如果是用C++来编程,我们还可以用到NB的模板,可是C语言就没有这种特点了。唯一可以用的便是void*指针。void*指针可以视为一种通用指针,任何指针都可以转换为void*指针而不会丢失值。同理,只要我们把原先的指针变量换成void*类型不就行了。可是,你很快发现,这样不行。为什么呢?因为我们没有通用的嫁衣。C语言中的变量不可以为void类型,也就是说没有void temp; 这种古怪的东西。那怎么办呢?我们可以从底层去想两个数交换的本质。不就是相应的内存值交换嘛。我们可以联想到memcpy函数,我们可以模仿着来,写一个函数,通过传入void*指针和变量类型的字节大小,来将这两个变量相应的字节内容发生对换。程序如下:

void swap(void *a,void *b,size_t size)
{

unsigned char *p1=(unsigned char *)a;          //强制类型转换

unsigned char *p2=(unsigned char *)b;

Unsigned char temp;                         //字节型的嫁衣

while(size--)

{

temp=*p1;

*p1=*p2;

*p2=temp;

p1++;

p2++;

}

}

使用的时候可以这样调用:swap( &a,&b,sizeof(int) );
这种字节的分别交换可以通用各种类型的交换,当然,彼此之间应该是同种类型,否则会因为类型大小,字节序等一些问题发生错误。

(3)取巧型---赋值法
这个方法其实一个很取巧的方法,大家先看一下程序,看能不能看出巧在哪里:
void swap(int *a,int *b)
{
*a=*a+*b;

*b=*a-*b;

*a=*a-*b;

}
这种方法有一个好处,那就是不用消耗额外的变量空间,只需要两个变量做一些运算即可。让我们慢慢看:
首先:

我用A代表a+b

A=a+b,            这时候A的值为两者之和

接着,b=A-b, 也就是b=A-b=a+b-b=a,这时候b得到了a的值
最后,a=A-b, 因为经过上面的运算,b=a,所以a=A-b=a+b-a=b,这时候a得到了b的值。
所以,交换成功了。

(4)诡异型---逻辑运算法
如果没有仔细拿纸算一算的话,这段程序估计会晕倒很多人,让我们来看一下吧:
void swap(int *a,int *b)
{

//  *a^=*b^=*a^=*b;  这种做法达不到效果,不知道为什么

*a=*a^*b;
*b=*b^*a;
*a=*a^*b;

}
怎么样,够诡异的吧。如果我们把它拆开来看的话,其实也没那么可怕:
首先我们必须明确运算顺序,是从右至左:
*a=*a^*b;
*b=*b^*a;
*a=*a^*b;
在解释这段代码的时候,我们先普及一下逻辑运算的基础知识,^ 符号是异或符号,也就是如果两个逻辑变量各不相同,其表达式值为1,反之为0 。则有:

A^A=0

A^1=~A
A^0=A
A^B^C=A^(B^C)=B^(A^C)

首先,A=a^b;

接着,b=b^A=b^a^b=a^0=a,这时候b获得了a的值。
最后,a=A^b=a^b^a=b^0=b,这时候a获得了b的值。

@清晰掉 swap函数的更多相关文章

  1. 从Swap函数谈加法溢出问题

    1.      初始题目 面试题:). 这个题目太经典,也太简单,有很多人都会不假思索结出答案: //Code 1 void Swap(int* a, int* b) { *a = *a + *b; ...

  2. 关于swap函数传值的问题

    #include <stdio.h> void swap(int * p3,int * p4); int main() {  int a = 9;  int b = 8;  int * p ...

  3. 自己写一个swap函数交换任意两个相同类型元素的值 对空指针的使用 字节大小的判断(二)了解原理

    验证的代码: #include <stdio.h> int main(){ char c = 'z'; ) + (c << ) + () + 'a'; printf(" ...

  4. swap函数的四种写法

    swap 函数的四种写法 (1)经典型 --- 嫁衣法 void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } ( ...

  5. c++ swap 函数

    转载地址 1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T ...

  6. [转]谈谈C++中的swap函数

    1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T c(a) ...

  7. [Effective C++ --025]考虑写出一个不抛异常的swap函数

    引言 在我的上一篇博客中,讲述了swap函数. 原本swap只是STL的一部分,而后成为异常安全性编程的脊柱,以及用来处理自我赋值可能性. 一.swap函数 标准库的swap函数如下: namespa ...

  8. [020]转--C++ swap函数

    原文来自:http://www.cnblogs.com/xloogson/p/3360847.html 1.C++最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符 template < ...

  9. EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数

    记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...

随机推荐

  1. php多域名单站点路由

    能够使多域名但是只有一个站点的小站,通过路由访问到各个指定目录 <?php //域名跳转路由 //默认跳转 $default = "http://www.stanwind.com/in ...

  2. vue城市选择组件

    适用于vue的城市选择组件 仓库地址 基本功能: 支持全选.反选以及全部清空. 支持按拼音筛选. 勾选省份将会勾选省份下所有城市. 返回数据可灵活处理. 安装 npm install cn-regio ...

  3. VeryNginx中文文档

    VeryNginx VeryNginx 是一个功能强大而对人类友好的 Nginx 扩展程序. 提示 v0.2` 版本之后,控制台入口被移动到了 `/verynginx/index.html 中文控制台 ...

  4. 用C#控制台编写 推箱子之类的 坐标移动----之二维坐标

     //首先用枚举 列出方向  上,下,左,右(枚举的最后一位数后不用符号  否则会报错)        public enum dro    {       up = 1,        down = ...

  5. git使用以及对应sourceTree

    git上面的几条指令 (1)要想把A合并到B分支上,就需要先切换到B分支上,然后在合并A分支,执行指令: git checkout B // 这是切换到B分支上 git merge A // 这是将A ...

  6. npm学习(三)之如何安装本地包、更新本地安装的包、卸载本地安装的包

    如何安装本地包 有两种方式用来安装 npm 包:本地安装和全局安装.至于选择哪种方式来安装,取决于我们如何使用这个包. 如果你自己的模块依赖于某个包,并通过 Node.js 的 require 加载, ...

  7. java学习笔记(5)多线程

    一.简介(过段时间再写,多线程难度有点大) --------------------------------------- 1.进程:运行时的概念,运行的应用程序 2.线程:应用程序内部并发执行的代码 ...

  8. 将div的内容生成清晰的PDF、高清PDF

    //需要引入html2canvas.js.jquery.js文件 html: <button type="button" class="btn btn-primar ...

  9. 81. Search in Rotated Sorted Array II (JAVA)

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  10. Linux文件读写笔记

    读文件: #include <stdio.h> #include <stdlib.h> #include <unistd.h> //linux下面的头文件 #inc ...