变量值的交换方法总结

 
变量值的交换方法总结
2008年05月09日 星期五 下午 04:47

编程中肯定会常常用到swap这个函数,他的意思就是交换两个变量的数值,但是这个过程手动实现也很容易,总结了一下,大致有5种实现。

主函数:
main()
{ int a,b;
a=10; b=30;
swap(&a,&b);
printf("%d %d\n",a,b);
}
方法一:
通过临时变量实现,也是最常见的方法:

void swap(int a ,int b)
{int t;
t=a;
a=b;
b=t;
}

t是核心内容,作为临时变量进行交换。这种算法易于理解,但需要一个临时变量。

方法二:
算术运算,就是通过普通的+和-运算来实现:

void swap(int a ,int b)
{
a=b-a; //a=20;b=30
b=b-a; //a=20;b=10
a=b+a; //a=30;b=10
}

证明:把a、b看做数轴上的点,围绕两点间的距离来进行计算。第一句“a=b-a”求出ab两点的距离,并且将其保存在a中;第二句“b=b-a”求出a到原点的距离(b到原点的距离与ab两点距离之差),并且将其保存在b中;第三句“a=b+a”求出b到原点的距离(a到原点距离与ab两点距离之和),并且将其保存在a中。完成交换。
此算法与方法一相比,多了三个计算的过程,但是没有借助临时变量。

方法三:
指针地址操作,因为对地址的操作实际上进行的是整数运算,比如:两个地址相减得到一个整数,表示两个变量在内存中的储存位置隔了多少个字节;地址和一个整数相加即“a+10”表示以a为基地址的在a后10个a类数据单元的地址,所以理论上可以通过和算术算法类似的运算来完成地址的交换,从而达到交换变量的目的:

void swap(int a ,int b)
{
if(a<b)
{
a=(int*)(b-a);
b=(int*)(b-(int(a)&0x0000ffff));
a=(int*)(b+(int(a)&0x0000ffff));
}
else
{
b=(int*)(a-b);
a=(int*)(a-(int(b)&0x0000ffff));
b=(int*)(a+(int(b)&0x0000ffff));
}

这里采用位运算中的与运算“int(a)&0x0000ffff”,因为地址中高16位为段地址,后16位为位移地址,将它和0x0000ffff进行与运算后,段地址被屏蔽,只保留位移地址。这样可以避免由系统自动采用补码的形式表示负的位移所产生的错误,需要说明一下就是一般我们写的0x00000100h之类的地址并不是其变量所在的真实地址,而是要加上变量所在内存区的基地址,例如前面的变量的实际地址可能是0x008f0100h,其中0x008f即为基地址.它是由编译器自动添加的。
此算法同样没有使用第三变量就完成了值的交换,与算术算法比较它显得不好理解,但是它有它的优点即在交换很大的数据类型时,它的执行速度比算法一快。因为它交换的时地址,而变量值在内存中是没有移动过的。

方法四:
通过异或运算也能实现变量的交换,这也许是最为神奇的:

void swap(int a ,int b)
{
a=a^b;
b=a^b;
a=a^b;
}

证明:a1=a0^b0; b1=b0^a1=b0^(a0^b0)=a0^b0^b0=a0; a2=a1^b1=(a0^b0)^a0=b0^a0^a0=b0;
此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变。

方法五:
堆栈实现,很普通的栈操作就行,写法很多,这里通过asm实现:

void swap(int a ,int b)
{
__asm{
push a;
push b;
pop a;
pop b;
}
}

这种方法可能在值大的情况下会有溢出的情况,所以不推荐。
另外还会出现一些技巧性的操作来实现,但还是应用以上的方法,只是形式有些变动,例如使用逗号表达式:a=(a = a+b, b = a-b, a-b);

http://hi.baidu.com/superwyh


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值