怎样不用中间变量temp 实现两个数交换

<wbr><p><span style="font-size:18px"><strong>第一类方法也是常用的方法,通过多次的数值计算来完成交换,到现在知道的有下面三种:</strong></span></p> <p><span style="font-size:18px"><strong>(1)加减法。</strong></span></p> <p><span style="font-size:18px"><strong>a = a + b;</strong></span></p> <p><span style="font-size:18px"><strong>b = a - b;</strong></span></p> <p><span style="font-size:18px"><strong>a = a - b;</strong></span></p> <p><span style="font-size:18px"><strong>该方法可以交换整型和浮点型数值的变量,但在处理浮点型的时候有可能出现精度的损失,例如对数据:</strong></span></p> <p><span style="font-size:18px"><strong>a = 3.123456</strong></span></p> <p><span style="font-size:18px"><strong>b = 1234567.000000</strong></span></p> <p><span style="font-size:18px"><strong>交换后各变量值变为:</strong></span></p> <p><span style="font-size:18px"><strong>a = 1234567.000000</strong></span></p> <p><span style="font-size:18px"><strong>b = 3.125000</strong></span></p> <p><span style="font-size:18px"><strong>很明显,原来a的值在交换给b的过程中发生了精度损失。</strong></span></p> <p><span style="font-size:18px"><strong>(2)乘除法。</strong></span></p> <p><span style="font-size:18px"><strong>a = a * b;</strong></span></p> <p><span style="font-size:18px"><strong>b = a / b;</strong></span></p> <p><span style="font-size:18px"><strong>a = a / b;</strong></span></p> <p><span style="font-size:18px"><strong>乘除法更像是加减法向乘除运算的映射,它与加减法类似:可以处理整型和浮点型变量,但在处理浮点型变量时也存在精度损失问题。而且乘除法比加减法要多一条约束:b必不为0。</strong></span></p> <p><span style="font-size:18px"><strong>可能经验上的某种直觉告诉我们:加减法和乘除法可能会溢出,而且乘除的溢出会特别严重。其实不然,采用这两种方法都不会溢出。以加减法为例,第一步的加运算可能会造成溢出,但它所造成的溢出会在后边的减运算中被溢出回来。</strong></span></p> <p><span style="font-size:18px"><strong>(3)异或法。</strong></span></p> <p><span style="font-size:18px"><strong>a ^= b;//a=a^b</strong></span></p> <p><span style="font-size:18px"><strong>b ^= a;//b=b^(a^b)=b^a^b=b^b^a=0^a=a</strong></span></p> <p><span style="font-size:18px"><strong>a ^= b;//a=(a^b)^a=a^b^a=a^a^b=0^b=b</strong></span></p> <p><span style="font-size:18px"><strong>异或法可以完成对整型变量的交换,对于浮点型变量它无法完成交换。</strong></span></p> <p><span style="font-size:18px"><strong>第二类方法更像是玩了一个文字游戏,此种方法采用了在代码中嵌入汇编代码的方法避免了临时变量的引入,但究其本质还是会使用额外的存储空间。此种方法可以有很多种,下边列出几种:</strong></span></p> <p><span style="font-size:18px"><strong></strong></span></p> <p><span style="font-size:18px"><strong>(1)使用xchg指令,这也是比较直观、容易想到的方法,因为xchg指令的功能就是交换源操作数和目的操作数的值,这里要使用额外寄存器来暂存变量。内嵌汇编代码如下:</strong></span></p> <p><span style="font-size:18px"><strong>_asm</strong></span></p> <p><span style="font-size:18px"><strong>{</strong></span></p> <p><span style="font-size:18px"><strong>mov eax,a</strong></span></p> <p><span style="font-size:18px"><strong>xchg b,eax</strong></span></p> <p><span style="font-size:18px"><strong>mov a,eax</strong></span></p> <p><span style="font-size:18px"><strong>}</strong></span></p> <p><span style="font-size:18px"><strong>(2)使用额外的栈。这里使用反向的出栈顺序来完成交换。内嵌代码有如下两种形式:</strong></span></p> <p><span style="font-size:18px"><strong>_asm</strong></span></p> <p><span style="font-size:18px"><strong>{</strong></span></p> <p><span style="font-size:18px"><strong>push a</strong></span></p> <p><span style="font-size:18px"><strong>push b</strong></span></p> <p><span style="font-size:18px"><strong>pop a</strong></span></p> <p><span style="font-size:18px"><strong>pop b</strong></span></p> <p><span style="font-size:18px"><strong>}</strong></span></p> <p><span style="font-size:18px"><strong>另一种形式:</strong></span></p> <p><span style="font-size:18px"><strong>_asm push a</strong></span></p> <p><span style="font-size:18px"><strong>a = b;</strong></span></p> <p><span style="font-size:18px"><strong>_asm pop a</strong></span></p> <p><span style="font-size:18px"><strong>(3)使用mov指令。这种方法使用额外寄存器来暂存一个变量的值。</strong></span></p> <p><span style="font-size:18px"><strong>_asm mov eax,a</strong></span></p> <p><span style="font-size:18px"><strong>a = b;</strong></span></p> <p><span style="font-size:18px"><strong>_asm mov b,eax</strong></span></p> <p><span style="font-size:18px"><strong>其实第二类方法并不合格,它虽然没有显式的使用临时变量,但还是会用到额外的存贮空间。不过也不能说没有必要掌握,从实用的角度看还是很“有用”的。不是有公司出过这样的面试题吗?“不使用加减法和异或法完成不使用中间变量交换两个数值型变量的值”。此时或许只好使用这种方法了。</strong></span></p> <wbr><br></wbr></wbr>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值