1. 程式人生 > >兩個變數的值交換的多種方法

兩個變數的值交換的多種方法

在我的部落格“函式引數的傳遞”(部落格地址:http://blog.csdn.net/wxbmelisky/article/details/50833787)一文中談到過將兩個變數的值進行交換的 swap 函式實現,它們分別是通過指標和引用並使用中間變數來實現的,這裡再把程式碼貼一下。
  • 通過指標來實現:
void swap(int *x, int *y)
{
	int t = *x;
	*x = *y;
	*y = t;
}
  • 通過引用來實現:
void swap(int &x, int &y)
{
	int t = x;
	x = y;
	y = t;
}
當然上面兩種方法是很好也是很好理解很容易想到的方法,下面再介紹兩種不需要使用中間變數的方法。


1. 使用加減運算: 先給出程式碼入下:
#include <iostream>
using namespace std;

void swap(int& a, int& b)
{
	a = a + b;
	b = a - b;
	a = a - b;
}

int main()
{
	int a = 3, b = 6;
	cout << "a = " << a << ", b = " << b << endl;
	swap(a, b);
	cout << "a = " << a << ", b = " << b << endl;
	return 0;
}
執行結果如下:
下面再來分析它為什麼能夠達到交換的目的:首先 a = a + b 使得 a 值變為 a 與 b 的和,然後 a - b 的值就變成原先 a 的值了,賦給 b 從而使得 b 的值變為原先 a 的值,再接著 a - b 是原先 a 與 b 的和減去原先 a 的值即是原先 b 的值,再賦給 a 從而使得 a 與 b 的值實現交換。 但這樣簡單的加減運算有一點不好,就是在做 a + b 和 a - b 時可能會導致資料溢位。 2. 使用按位異或運算: 同樣先給出程式碼:
#include <iostream>
using namespace std;

void swap(int& a, int& b)
{
	a ^= b;
	b ^= a;
	a ^= b;
}

int main()
{
	int a = 3, b = 6;
	cout << "a = " << a << ", b = " << b << endl;
	swap(a, b);
	cout << "a = " << a << ", b = " << b << endl;
	return 0;
}
執行結果同樣也是正確的:
下面來分析: 首先要弄明白按位異或的概念,按位異或運算子“^”是將參與運算的兩個數對應的二進位制位相異或(異或就是對應的二進位制位相同則結果為 0,對應二進位制位不同則結果為 1,即 0 ^ 0 = 0,0 ^ 1 = 1,1 ^ 0 = 1,1 ^1 = 0)。兩個相同的數進行按位異或運算後得到的數的二進位制位全是 0,而任何一個數與 0 進行按位與運算的結果都不變,再根據結合律和交換律可以得到一個很重要的規則:a ^ b ^ a = b。 由 a ^= b 得 a 的值變為了 a ^ b,再由 b ^= a 得到 b = b ^ (a ^ b) = a,從而 b 的值變為了 a 原先的值,最後由 a ^= b 得到 a = (a ^ b) ^ a = b,從而 a 的值變為了 b 原先的值。 使用按位異或運算來來實現兩個數的交換不會出現資料溢位的情況,所以推薦使用按位異或運算的方法而不使用加減運算的方法。