第一类方法也是常用的方法,通过多次的数值计算来完成交换,到现在知道的有下面三种:

(1)加减法。

a = a + b;

b = a - b;

a = a - b;

该方法可以交换整型和浮点型数值的变量,但在处理浮点型的时候有可能出现精度的损失,例如对数据:

a = 3.123456

b = 1234567.000000

交换后各变量值变为:

a = 1234567.000000

b = 3.125000

很明显,原来a的值在交换给b的过程中发生了精度损失。

(2)乘除法。

a = a * b;

b = a / b;

a = a / b;

乘除法更像是加减法向乘除运算的映射,它与加减法类似:可以处理整型和浮点型变量,但在处理浮点型变量时也存在精度损失问题。而且乘除法比加减法要多一条约束:b必不为0。

可能经验上的某种直觉告诉我们:加减法和乘除法可能会溢出,而且乘除的溢出会特别严重。其实不然,采用这两种方法都不会溢出。以加减法为例,第一步的加运算可能会造成溢出,但它所造成的溢出会在后边的减运算中被溢出回来。

(3)异或法。

a ^= b;//a=a^b

b ^= a;//b=b^(a^b)=b^a^b=b^b^a=0^a=a

a ^= b;//a=(a^b)^a=a^b^a=a^a^b=0^b=b

异或法可以完成对整型变量的交换,对于浮点型变量它无法完成交换。

 

第二类方法更像是玩了一个文字游戏,此种方法采用了在代码中嵌入汇编代码的方法避免了临时变量的引入,但究其本质还是会使用额外的存储空间。此种方法可以有很多种,下边列出几种:

(1)使用xchg指令,这也是比较直观、容易想到的方法,因为xchg指令的功能就是交换源操作数和目的操作数的值,这里要使用额外寄存器来暂存变量。内嵌汇编代码如下:

_asm

{

mov eax,a

xchg b,eax

mov a,eax

}

(2)使用额外的栈。这里使用反向的出栈顺序来完成交换。内嵌代码有如下两种形式:

_asm

{

push a

push b

pop a

pop b

}

另一种形式:

_asm push a

a = b;

_asm pop a

(3)使用mov指令。这种方法使用额外寄存器来暂存一个变量的值。

_asm mov eax,a

a = b;

_asm mov b,eax

其实第二类方法并不合格,它虽然没有显式的使用临时变量,但还是会用到额外的存贮空间。不过也不能说没有必要掌握,从实用的角度看还是很“有用”的。不是有公司出过这样的面试题吗?“不使用加减法和异或法完成不使用中间变量交换两个数值型变量的值”。此时或许只好使用这种方法了。

  1. // 代码自己写的,不是转的!
  1. #include <iostream>
  2. using namespace std;
  3. void swap1(int a, int b) {
  4. b = a + b;
  5. //a^=b^=a^=b;
  6. a = b - a;
  7. b = b - a;
  8. cout << a << ' ' << b << endl;
  9. }
  10. int main() {
  11. cout << INT_MAX << endl;
  12. cout << 0x7fffffff << endl;
  13. cout << (int)0xffffffff << endl;
  14. cout << (int)0x5fffffff << endl;
  15. swap1((int)0x7fffffff, (int)0x5fffffff);
  16. return 0;
  17. }

[转][C/C++] 怎样不用中间变量temp 实现两个数交换的更多相关文章

  1. 在JS中 实现不用中间变量temp 实现两个变量值得交换

    1.使用加减法; var a=1; var b=2; a=a+b; b=a-b; a=a-b; 2.使用乘除法(乘除法更像是加减法向乘除运算的映射) var a=1; var b=2; a = a * ...

  2. 不用中间变量交换a 和b的值

    // 不用中间变量的写法 ,假如 a=13, b=8; a=a+b =21; //此时 a=21; b=8; b=a-b=13; //此时a=21; b=13; a=a-b=8; //相当于 a=21 ...

  3. 求两个数中的较大值max(a,b)。(不用if,>)

    题目:求两个数的较大值,不能使用if.>. 1.不使用if.>,还要比较大小,貌似就只能使用条件表达式: x=<表达式1>?<表达式2>:<表达式3>; ...

  4. 网络误区:不用中间变量交换2个变量的value,最高效的是异或运算.

    本文记录了不使用中间变量交换2个变量的value,很多的网络留言说是直接异或运算就可以了,而且效率很高,是真的吗? 这里简单的说一下我的环境:Win7 32位,Qt creator 5.4.1 编译器 ...

  5. 不用中间变量,交换a、b值

    如果要交换a.b之间的值,一般的做法是: tmp=a;a=b;b=tmp;这种方法不得不使用一个临时变量. 从网上学来一个方法,可以不用使用临时变量: a^=b^=a^=b; 这样计算之后,就可以交换 ...

  6. 不用中间变量交换两个数 swap(a,b);

    #include <iostream> using namespace std; int main () { ; ; cout<<"a="<<a ...

  7. C语言位操作--不用中间变量交换两数值

    1.使用加法与减法交换两数值: #define SWAP(a, b) ((&(a) == &(b)) || \ (((a) -= (b)), ((b) += (a)), ((a) = ...

  8. 不用中间变量交换a和b的值?

    a = b = a = a+b b = a-b a = a-b print(a,b) a = b = a = a^b b = b^a a = a^b print(a,b) a = b = a,b = ...

  9. java不用中间变量交换两个值

    public void changeVal(){ int a = 2; int b = 3; System.out.println("交换前 a:"+a+",b:&quo ...

随机推荐

  1. STL之优先队列(1)

    优先队列用法 在优先队列中,优先级高的元素先出队列. 标准库默认使用元素类型的<操作符来确定它们之间的优先级关系. 优先队列的第一种用法: 也是最常用的用法 priority_queue< ...

  2. Eclipse下编写的web项目部署到tomcat下

    之前都是用myeclipse编写web项目,编写好然后在myclipse上配置的tomcat下的webapps文件想项目复制到其他tomcat下就能运行了. 最近学习jquery,将eclipse编写 ...

  3. Bison

  4. 运行nodejs的blog程序遇见问题

    我是运行这个教程的代码.可以在网上找到相关视频和代码. 第一个问题,数据库中没有创建对应的表就开始运行程序.node app.js 这个错误问题大家可以去重现一下 第二个问题,我也没有看明白,但是我根 ...

  5. swift uiview弹出动画

    UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.0, ...

  6. vs2005水晶报表无法运行在X64机器上

    要下载补丁:CRRedist2005_X64.msi http://download.csdn.net/download/gcy007/7106933

  7. Linux+I2C总线分析(主要是probe的方式)

    Linux I2C 总线浅析 ㈠ Overview Linux的I2C体系结构分为3个组成部分: ·I2C核心: I2C核心提供了I2C总线驱动和设备驱动的注册.注销方法,I2C通信方法(即“algo ...

  8. 如何使用百度音乐搜索接口API

    百度有开放音乐搜索的api 比如: http://box.zhangmen.baidu.com/x?op=12&count=1&title=大约在冬季$$齐秦$$$$ http://b ...

  9. 【转】Struts1.x系列教程(5):HTML标签库

    转载地址:http://www.blogjava.net/nokiaguy/archive/2009/01/archive/2009/01/archive/2009/01/archive/2009/0 ...

  10. hibernate检索方式(HQL 检索方式,QBC 检索方式,本地 SQL 检索方式)

    hibernate有五种检索方式,这儿用 单向的一对多的映射关系 例子,这儿有后三种的方式: 导航对象图检索方式: 根据已经加载的对象导航到其他对象 OID 检索方式: 按照对象的 OID 来检索对象 ...