你会写几种swap函数?
 
     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. C++ Swap函数有几种写法?

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/104344435 S ...

  2. 利用swap函数的三种写法

    简述: 本节记录一下两个数据进行交换的三种写法. 其中第三中可算有点趣味. A.手写swap 利用我们自己写的swap函数,利用引用来交换. #include<iostream> usin ...

  3. PHP两个匿名函数传递性,PHP让人不知道的匿名函数的几种写法(附代码)

    PHP让人不知道的匿名函数的几种写法 通用的写法: 1.传统写法 function timer () { echo "hello world"; } SwooleTimer::ti ...

  4. 【v-on】一个元素绑定多个事件以及一个事件绑定多个函数的两种写法

    本文代码主要讲述了v-on绑定事件函数传参,一个元素绑定多个事件的两种写法,一个事件绑定多个函数的两种写法,修饰符的使用. <!DOCTYPE html> <html lang=&q ...

  5. JavaScript 普通函数的三种写法

    第一种写法:不常用 //创建一个函数对象,较少使用//可以将要封装的代码以字符串的形式传递给构造函数var fun = new Function("console.log('hello,这是 ...

  6. php函数几种写法,PHP让人不知道的匿名函数的几种写法(附代码)

    PHP让人不知道的匿名函数的几种写法 通用的写法: 1.传统写法 function timer () { echo "hello world"; } SwooleTimer::ti ...

  7. 技术点:connect函数的几种写法及连接方式

    技术点:connect函数的几种写法及连接方式 沭osTT 0.077 2020.07.21 09:38:09 字数 2,494 阅读 2,336 前言 conncet函数是QT中信号和槽机制的实现函 ...

  8. javascript函数的三种写法

    在JS中函数的三种写法 [0401] 在js中函数有三种写法,这里我简单列举一下. 第一种: 第二种: 第三种: 对于以上三种函数的调用方法,这里可以简单的理解一下,第一种是最常见的函数写法,第三种是 ...

  9. JavaScript函数的几种写法

    几种常见写法 1. 常规写法: 最常规的写法 // 函数的定义 function foo(){alert('常规写法'); }// 函数的调用 foo() 2. 匿名函数写法 给一个变量赋值为一个函数 ...

最新文章

  1. 微服务系列(五):事件驱动的数据管理
  2. IOS纯手写代码支持旋屏
  3. react学习系列之ajax
  4. 可视化Spring开发插件 Spring IDE
  5. java元婴期(24)----java进阶(mybatis(3)---动态sql(重点))
  6. (43)内存装载驱动
  7. JavaScript prototype
  8. (\w+)\s*, \s*(\w+)
  9. [转]JS部分通用函数
  10. 线性表之简介及顺序表
  11. Response JSON数据返回
  12. 五校联考R1 Day2T2 矩阵matrix(容斥)
  13. Deepin 20.1 安装nvidia显卡驱动 爬坑
  14. 微软云服务Azure所有产品简介
  15. 《Think Python》练习 4-1:本章示例代码栈图、停止点偏离思考
  16. Office2016使用HP打印机只能打印一次再打印就假死怎么办?
  17. Android SDK 2.1 下载与安装教程
  18. 大型网站seo布局怎么做
  19. 今天你代言了吗?WPS版“陈欧体”引热议
  20. 这10个小技巧,让你的Python数据分析加速50%!

热门文章

  1. 网页验证码显示在输入框input上的方法
  2. 活动报名 | 中科院信工所陈恺:人工智能安全攻防对抗
  3. 亚马逊中关于店铺广告设定的介绍
  4. 【分享】关闭科学上网后网络连接故障
  5. opencv之Mat的定义
  6. JVM内存模型JVM内存模型
  7. async-excel整合站内信通知用户体验感满满
  8. android支持gif图片格式,Android 支持Gif动态图 的imagview
  9. 8月9日个人训练小结
  10. Windows用户管理、文件权限、本地策略、组策略说明