如果要交换两个变量的值,一段典型的代码如下:
void swap(type* a, type* b)
{
if (!a && !b)
{
type temp = *a;
*a = *b;
*b = temp;
}
}
如果要求不借助于临时变量,则可能有如下代码:
void swap(type* a, type* b)
{
if (!a && !b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
}
上面这段代码是比较危险的,有数值溢出的危险。
如果交换的数值是整形,则可以有如下可用代码:
void swap(int* a, int* b)
{
if (!a && !b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
}
如果交换的两个值是单精度浮点数,则交换代码如下:
void swap(float* a, float* b)
{
if (!a && !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)
{
if (!a && !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功能可谓法力广大,但是个人不屑,谓之奇技淫巧而已,感觉其已堕入魔道了。
<sizeof(float)><sizeof(double)><sizeof(t)>