zoukankan      html  css  js  c++  java
  • [转][C/C++] 怎样不用中间变量temp 实现两个数交换

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

    (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

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

    [cpp] view plaincopy
     
    1. // 代码自己写的,不是转的!  
    [cpp] view plaincopy
     
    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.   
    9.     cout << a << ' ' << b << endl;  
    10. }  
    11. int main() {  
    12.     cout << INT_MAX << endl;  
    13.     cout << 0x7fffffff << endl;  
    14.     cout << (int)0xffffffff << endl;  
    15.     cout << (int)0x5fffffff << endl;  
    16.     swap1((int)0x7fffffff, (int)0x5fffffff);  
    17.     return 0;  
    18. }  
  • 相关阅读:
    Docker篇章1:Docker介绍
    flask-restful结合vue自定义错误类型
    9.Go语言-函数
    8.Go语言-流程控制
    7.Go语言-结构体
    6.Go语言-指针
    5.Go语言-map类型
    计算机组成原理笔记2-数制、字符、校验码、定点数、浮点数、算术逻辑单元
    计算机组成原理笔记1--基础概念丶性能指标
    计算机网络笔记2--物理层
  • 原文地址:https://www.cnblogs.com/hehexiaoxia/p/5062769.html
Copyright © 2011-2022 走看看