如果要交換兩個變量的值,一段典型的代碼如下:
void swap(type& a, type& b)
{
type temp = a;
a = b;
b = temp;
}
如果要求不藉助於臨時變量,則可能有如下代碼:
void swap(type& a, type& b)
{
a = a + b;
b = a - b;
a = a - b;
}
上面這段代碼是比較危險的,有數值溢出的危險。
如果交換的數值是整形,則可以有如下可用代碼:
void swap(int& a, int& b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
如果交換的兩個值是單精度浮點數,則交換代碼如下:
void swap(float& a, float& b)
{
(*(unsigned int*)(&a)) = (*(unsigned int*)(&a)) ^ (*(unsigned int*)(&b));
(*(unsigned int*)(&b)) = (*(unsigned int*)(&a)) ^ (*(unsigned int*)(&b));
(*(unsigned int*)(&a)) = (*(unsigned int*)(&a)) ^ (*(unsigned int*)(&b));
}
編譯器可能會默認地把float型轉換爲double型,所以建議用宏實現兩個變量的值的交換:
#define US(x) (*(usigned*)(&x))
#define swap(a,b) \
US(a) = US(a) ^ US(b), \
US(b) = US(a) ^ US(b), \
US(a) = US(a) ^ US(b)
如果是雙精度浮點數,則可以用下面的的函數:
void swap(double& a, double& b)
{
(*(unsigned long long*)(&a)) = (*(unsigned long long*)(&a)) ^ (*(unsigned long long*)(&b));
(*(unsigned long long*)(&b)) = (*(unsigned long long*)(&a)) ^ (*(unsigned long long*)(&b));
(*(unsigned long long*)(&a)) = (*(unsigned long long*)(&a)) ^ (*(unsigned long long*)(&b));
}
以上函數以C的方式實現的,分別處理每種情況。一下代碼是C++形式的代碼,藉助於STL的偏特化特性:
#include <iostream>
using namespace std;
template <int N>
struct traits //根據字節數得到類型
{
typedef void TYPE;
};
template <>
struct traits<sizeof(float)> //模板特化
{
typedef unsigned TYPE;
};
template<>
struct traits<sizeof(double)> //模板特化
{
typedef unsigned long long TYPE;
};
template <typename T>
typename traits<sizeof(T)>::TYPE &Ref(T &x) //把變量x按另一種類型解釋,並返回引用
{
return reinterpret_cast<typename traits<sizeof(T)>::TYPE&>(x);
}
template <typename T>
void myswap(T &a, T &b) //類型轉換
{
Ref(a) = Ref(a) ^ Ref(b);
Ref(b) = Ref(a) ^ Ref(b);
Ref(a) = Ref(a) ^ Ref(b);
}
以上代碼很簡潔,一個函數就實現了不藉助於臨時變量而交換兩個變量的值的功能。STL功能可謂法力廣大,但是個人不屑,謂之奇技淫巧而已,感覺其已墮入魔道了。
不借助臨時變量交換兩個變量的值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
顯示dos命令ping和tracert等輸出結果中的ip對應的地域名稱
企鹅
2020-07-06 21:15:10
opensuse12.2的gdb不能自動加載.gdbinit的解決方法
企鹅
2020-07-06 21:15:10
數組是否應該初始化?
企鹅
2020-02-24 22:33:09
C語言運算時的參數符號自動轉換
企鹅
2020-02-24 22:33:09