swap函数 的几种实现与比较

前沿

swap函数 用于交换 a ,b 两个数。实现方法大同小异,其中不乏有好多版本,现在就其性能和可读性略作分析。不对指出还望指正。。

探讨:

其中的函数原型是:

(1) void swap(int &a,int &b);传引用

(2)void swap(int *a,int *b);传地址

下面就第二个函数原型分析,代码如下:


    #include <stdio.h>
    #include <stdlib.h>
    /**
        使用中间变量tmp
    */
    void swap(int *a,int *b)
    {
        int tmp = *a;
        *a = *b;
        *b = tmp;
    }
    /**
        使用加减法计算
    */
    void swap1(int *a,int *b)
    {
        *a = (*a) + (*b) ;
        *b = (*a) - (*b);
        *a = (*a) - (*b) ;
    }
    /**
        使用乘除法计算
    */
    void swap2(int *a,int *b)
    {
        *a = (*a)*(*b) ;
        *b = (*a) / (*b);
        *a = (*a) / (*b) ;
    }
    /**
        使用异或运算
    */
    void swap3(int *a,int *b)
    {
        *a = *a^*b;
        *b = *a^*b;
        *a = *a^*b;
        //可以这么写:
        *a^=*b^=*a^=*b;
    }
    int main(void)
    {
        int a=2,b=3;
        printf("start a:%d , b:%d\n",a,b);
        swap(&a,&b);
        printf("swap a:%d , b:%d\n",a,b);
        a=2;b=3;
        swap1(&a,&b);
        printf("swap1 a:%d , b:%d\n",a,b);
        a=2;b=3;
        swap2(&a,&b);
        printf("swap2 a:%d , b:%d\n",a,b);
        a=2;b=3;
        swap3(&a,&b);
        printf("swap3 a:%d , b:%d\n",a,b);
        return 0;
    }
    /**
    运行结果:
    start a:2 , b:3
    swap a:3 , b:2
    swap1 a:3 , b:2
    swap2 a:3 , b:2
    swap3 a:3 , b:2
    */  

实现:

这里总结了4个swap()函数的实现方法,前三个我就不详细说了,分别用了:中间变量法,加减法,乘除法。相信我不说大家也能看得懂。我主要说一下第四种方法——异或法。

这里的异或法是利用了高等数学中的知识:

对任意数 A ,B ,C

(1)A ^ 0 = A

(2)A ^ A = 0

(3)(A ^B)^C=A^(B^C)

(4)A^B = B^A

这三条常识:

我们看到函数swap3()中,我们姑且将这两个参数成为a,b

第一句 a = a^b; 咱们让 c =a^b;

第二句 b = a^b;其时就是 b = c^b =a^(b^b)=a^0=a;

第三句 a = a^b;其时就是 a = c^b =a^b^a=b^(a^a)=b^0=b;

这样就给交换过来了。。。。。

分析:

性能分析:

    (1)空间性能

    (2)时间性能

    这其实没啥说的

    空间性能上swap()浪费一个int 空间,其他没有空间开销。

    时间性能上,虽然说都是执行3条语句,但是与语句不一样,效率上 :位运算>加减>乘除 (大致上是这样,具体情况还得具体分析)

    所以swap3()技高一筹。。。。。。

稳定性:

    是不是这几个函数一定正确???呵呵。这可不一定,参数是int类型

    swap1() swap2()  你想想看。。可能造成溢出的。。

    事实的确是这样 当a =2100000001 b=2100000002

    你试一下。。呵呵。。swap() 和swap3()依然坚挺。。而swap1() ,swap2() 。。。完了。。

可读性:

    swap()当之无愧是最好的。。可读性是最好的。。

总结:

综上所述:建议大家使用swap3(异或) ,swap(中间变量)。。。
时间: 2024-11-06 23:59:32

swap函数 的几种实现与比较的相关文章

作业二、comp和swap函数

一.swap函数的代码及运行情况 1.代码 1 #include<stdio.h> 2 int main() 3 { 4 void swap(int *m,int *n); 5 int a,b; 6 int *p1,*p2; 7 scanf("%d,%d",&a,&b); 8 p1=&a; 9 p2=&b; 10 swap(p1,p2); 11 printf("%d,%d\n",*p1,*p2); 12 return 0;

Effective C++ 条款25 考虑写出一个不抛出异常的swap函数

1. swap是STL的一部分,后来成为异常安全性编程(exception-safe programming)(见条款29)的一个重要脊柱,标准库的swap函数模板定义类似以下: namespace std{ template<typename T> swap(T& lhs,T& rhs){ T temp(lhs); lhs=rhs; rhs=temp; } } 只要T类型支持拷贝构造以及拷贝赋值,标准库swap函数就会调用T的拷贝构造函数和拷贝构造操作符完成值的转换,但对于某

《Effective C++》item25:考虑写出一个不抛异常的swap函数

std::swap()是个很有用的函数,它可以用来交换两个变量的值,包括用户自定义的类型,只要类型支持copying操作,尤其是在STL中使用的很多,例如: int main(int argc, _TCHAR* argv[]) { int a[10] = {1,2,3,4,5,6,7,8,9,10}; vector<int> vec1(a, a + 4); vector<int> vec2(a + 5, a + 10); swap(vec1, vec2); for (int i =

@清晰掉 swap函数

swap函数估计是一个各种各样程序都会频繁用到的子程序,可是你知道它究竟有多少种不同的写法吗?下面我就列举我知道的几种swap函数来跟大家分享一下. (1)经典型---嫁衣法 无论是写程序还是干其他事情,一旦涉及到交换,就总是会遇到第三方.这个第三方可能是公正的监督者,也可能是一个徒为他人做嫁衣的可怜虫.在经典法的交换程序中,我们就需要有一个可怜虫来为我们提供暂时的服务.程序如下: void swap(int *a,int *b){int temp; temp=*a; *a=*b; *b=tem

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

引言 在我的上一篇博客中,讲述了swap函数. 原本swap只是STL的一部分,而后成为异常安全性编程的脊柱,以及用来处理自我赋值可能性. 一.swap函数 标准库的swap函数如下: 1 namespace std { 2 template<typename T> 3 void swap(T &a, T& b) 4 { 5 T temp(a); 6 a = b; 7 b = temp; 8 } 9 } 只要类型T支持拷贝(通过拷贝构造函数和拷贝赋值操作符完成),那么这个版本的

C++ DLL导出函数的两种方法(导出序号那种方法,别人看不到函数名)

第一种就直接导出函数名如下代码: #ifdef__cplusplus #define TEXPORT extern "c" _declspec(dllexport) #dlse #define TEXPORT _declspec(dllexport) TEXPORT BOOL FUN();//这就是要导出函数 这种方法查看DLL时能看到函数名. 第二种是就导出序号如下代码: bool _stdcall fun(); 在工程右键添加新项目点模块定义文件.DEF, 在在DEF文件里写 LI

JavaScript函数的四种存在形态

函数的四种存在形态: 1.函数形态 2.方法形态 将函数赋值给某一个对象的成员,那么就称为方法 3.构造器形态 4.上下文形态 1.函数形态: var foo = function() { alert(this); //this是window }; 2.方法形态: o = {}; o.foo = foo; //将函数foo赋值给对象o的foo属性 o.foo(); //弹出的是object,此时的this表示object var lib = { test:function() { alert(t

JavaScript笔记(二):函数只是一种对象

上一篇随笔提到JS中有两种数据类型:原始类型和对象类型,但是我们还没有提到函数.实际上函数也是一种对象,准确地说函数应该叫做函数对象.下面从对象开始说起. 1. 对象和函数 最简单的对象,是这样的: var obj = {}; 我们创建了一个空对象.说它空是因为它没有任何自定义属性,但是实际上它还是有一些默认属性的,这些属性是从它的原型对象继承来的,比如constructor.toString和valueOf等.除此之外,ECMA-262中还定义了对象的一些内置属性,这些属性对JS语言来说是不可

《Effective C 》资源管理:条款25--考虑写出一个不抛出异常的swap函数

条款25考虑写出一个不抛出异常的swap函数 条款25:考虑写出一个不抛出异常的swap函数 swap是STL中的标准函数,用于交换两个对象的数值.后来swap成为异常安全编程(exception-safe programming,条款29)的脊柱,也是实现自我赋值(条款11)的一个常见机制.swap的实现如下: namespace std{ template<typename T> void swap(T& a, T& b) { T temp(a); a=b; b=temp;