17.1 编写一个函数,不用临时变量,直接交换两函数。
解法:
方法一:这个是经典面试题,也相当直接。我们将用a0表示a的初值,b0表示b的初始值,用diff表示a0-b0的值。
让我们将a>b的情形绘制在数轴上。
首先,将a设为diff,即上面数轴的右边那一段。然后,b加上diff(并将结果保存在b中),就看得到a0.至此,我们得到b=a0和a=diff。最后,只需将b设为a0-diff,也就是b-a。
方法二:我们还可以用位操作实现类似的解法,这种解法的优点在于它适用的数据类型更多,不仅限于整数。
C++实现代码:
#include<iostream> using namespace std; void swap(int a,int b) { a=a-b; b=a+b; a=b-a; cout<<a<<" "<<b<<endl; } void swap1(int a,int b) { a=a^b; b=a^b; a=a^b; cout<<a<<" "<<b<<endl; } int main() { int a=1; int b=2; swap(a,b); swap1(a,b); cout<<a<<" "<<b<<endl; }
以上的swap函数,尤其是第2个实现,简洁美观高效,乃居家旅行必备良品。但是, 使用它们之前一定要想一想,你的程序中,是否有可能会让swap中的两个形参引用同一变量。 如果是,那么上述两个swap函数都将出问题。有人说,谁那么无聊去swap同一个变量。 那可不好说,比如你在操作一个数组中的元素,然后用到了以下语句:
swap(a[i], a[j]); // i==j时,出问题
你并没有注意到swap会去操作同一变量,可是当i等于j时,就相当于你这么干了。 然后呢,上面两个实现执行完第一条语句后,操作的那个内存中的数就变成0了。 后面的语句不会起到什么实际作用。
所以如果程序中有可能让swap函数去操作同一变量,就老老实实用最朴素的版本:
void swap(int &a, int &b){ int t = a; a = b; b = t; }