一、使用中间变量

void swap(int &a, int &b){//注意这里一定要是引用形参或指针,传值(int a)是错误的
    int tmp=a;
    a=b;
    b=tmp;
}

void swap1(int *a,int *b){//a,b指向地址的内容作了交换
    int tmp=*a;
    *a=*b;
    *b=tmp;
}

为什么非引用形参void swap_0(int  a,int  b)是错误的??

     编译器总是要为函数的非引用形参生成一个拷贝假设是_a, _b,如果函数体内的程序修改了_a,_b的内容,就导致参数a的内容作相应的修改。但a,b是局部变量,不会影响到主函数中原数p,q,当swap生命周期结束时,a,b也就消失了,不会传递给p,q。

二、不使用中间变量,最简单的方法是最安全的方法,下面的算法多少有问题:

(1)异或法。

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

如果交换的变量是自己,结果是0;(经过测试)

void swap3(int &a, int &b){
    a=a^b;
    b=b^a; //b=a^b;也对
    a=a^b;
}

int a=1;
int &b=a;
swap3(a,b);//结果为0

 

 

(2)加减法。

void mySwap_1(float &a,float &b){
    a=a+b;
    b=a-b;
    a=a-b;
}

 

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

a = 3.123456

b = 1234567.000000

交换后各变量值变为:

a = 1234567.000000

b = 3.125000

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

(3)乘除法。

a = a * b;

b = a / b;

a = a / b;

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

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

 ***********错误的方法**********************************************************************************

 

 

posted on 2014-05-28 19:34  zhangxh_Doris  阅读(556)  评论(0编辑  收藏  举报