使用异或运算交换两个任意类型变量

这篇文章中将使用C语言,实现交换两个任意类型变量的功能.说到任意类型用C让人感觉很难做,如果是C++则使用模板函数就轻松搞定:

template<class T>
inline void      swap(T& t1, T& t2)
{
    T tmp;
    tmp = t1;
    t1 = t2;
    t2 = tmp;
}

先说下使用^来交换两个整数,其代码看着简单但不容易理解

a ^= b;
b ^= a;
a ^= b;

有人说这种写法很奇葩,但我要说的是,异或运算是计算机很常用的操作.搞懂这一算法是熟练掌握异或的基础.关于^交换两整数的理解方式可以按如下方式:

先将a,b当成两个布尔类型,那么a,b会有四种组合

0,0  (1)a ^= b;变成 0,0 (2)b ^= a;变成 0,0 (3)a ^= b;变成 0,0

1,0  (1)a ^= b;变成 1,0 (2)b ^= a;变成 1,1 (3)a ^= b;变成 0,1

0,1  (1)a ^= b;变成 1,1 (2)b ^= a;变成 1,0 (3)a ^= b;变成 1,0

1,1  (1)a ^= b;变成 0,1 (2)b ^= a;变成 0,1 (3)a ^= b;变成 1,1

这样三句代码执行完成后,四种组合中的数值都得到了交换.

即然位运算与BIT相邻数值无关的,那么8个BIT的char类型,16个BIT的short,以及long, long long都可以使用^来交换.

还有人认为这种异或运算只能用于整数类型的交换.实际上异或运算是针对二进制的,既然计算机所有的数据类型都是以二进制进行保存的,那么当然可以用异或运算交换任何数据类型.

最后我的解决方案如下:

 1 #define XYZ_SWAP(i, j) \   if (&i != &j) 2 { 3     switch(sizeof(i)) 4     { 5     case 1: 6         *(char*)&i ^= *(char*)&j; 7         *(char*)&j ^= *(char*)&i; 8         *(char*)&i ^= *(char*)&j; 9         break;10     case 2:11         *(short*)&i ^= *(short*)&j;12         *(short*)&j ^= *(short*)&i;13         *(short*)&i ^= *(short*)&j;14         break;15     case 4:16         *(long*)&i ^= *(long*)&j;17         *(long*)&j ^= *(long*)&i;18         *(long*)&i ^= *(long*)&j;19         break;20     case 8:21         *(long long*)&i ^= *(long long*)&j;22         *(long long*)&j ^= *(long long*)&i;23         *(long long*)&i ^= *(long long*)&j;24         break;25     default:26         for (int k = 0; k < sizeof(i); k++)27         {28             *((char*)&i + k) ^= *((char*)&j + k);29             *((char*)&j + k) ^= *((char*)&i + k);30             *((char*)&i + k) ^= *((char*)&j + k);31         }32         break;33     }34 }
35
36 void main()
37 {
38     char ca = 10;
39     char cb = 20;
40     XYZ_SWAP(ca, cb);
41
42     short sa = 10;
43     short sb = 20;
44     XYZ_SWAP(sa, sb);
45
46     int ia = 10;
47     int ib = 20;
48     XYZ_SWAP(ia, ib);
49
50     long long lla = 10;
51     long long llb = 20;
52     XYZ_SWAP(lla, llb);
53
54     float fa = 10.01f;
55     float fb = 2000.89f;
56     XYZ_SWAP(fa, fb);
57
58     double da = 10.01;
59     double db = 2000.89;
60     XYZ_SWAP(da, db);
61
62     void* pa = &da;
63     void* pb = &db;
64     XYZ_SWAP(pa, pb);
65 }

这里使用了个宏定义来实现不同类型的两个变量的交换.还有就是假设long占用4个字节.

时间: 2024-11-09 09:18:13

使用异或运算交换两个任意类型变量的相关文章

【C】辗转相除法求两个数的最大公约数,利用位运算交换两个数无须中间变量

辗转相除法,又名欧几里德算法(Euclidean algorithm)乃求两个正整数之最大公因子的算法.它是已知最古老的算法, 其可追溯至3000年前.这种算法,在中国则可以追溯至东汉出现的<九章算术>.设两数为a.b(a>b),求a和b最大公约数(a,b)的步骤如下:用a除以b,得a÷b=q......r1(0≤r1).若r1=0,则(a,b)=b:若r1≠0,则再用b除以r1,得b÷r1=q......r2 (0≤r2).若r2=0,则(a,b)=r1,若r2≠0,则继续用r1除r2

异或运算实现两个数的交换

通常的交换两个变量a,b的过程为 int temp; temp=a a=b; b=temp; 需借助上面的第3个临时变量temp. 采用下面的方法,对于给定两个整数a,b,下面的异或运算可以实现a,b的交换,而无需借助第3个临时变量: a = a ^ b;     b = a ^ b;     a = a ^ b; 这个交换两个变量而无需借助第3个临时变量过程,其实现主要是基于异或运算的如下性质: 1.任意一个变量X与其自身进行异或运算,结果为0,即X^X=0 2.任意一个变量X与0进行异或运算

通过异或位交换两个整型变量的一个不容易注意的细节

设变量 a = 1, b = 2, 我们要交换两个变量的值, 当用异或交换两个值的时候会有一个小问题 用位运算大概是这个样子的 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 void swap(int& a, int &b) { 6 a ^= b; 7 b ^= a; 8 a ^= b; 9 } 10 11 int main() { 12 int a = 2, b = 3; 13 cout << &qu

用异或来交换两个变量能提高速度是错误的

在进行两个变量的时候,经常会看到有些书误人子弟的推荐使用异或的方式: 方式一 { x = x ^ y; y = x ^ y; x = x ^ y; } 而不是采用临时变量实现交换: 方式二 { int temp; temp = a; a = b; b = temp; } 美其名曰:节省内存,提高运行速度. 临时变量交换的方式: 但是,真的节省了内存吗? 使用这种方式大部分时候,没有节省内存.因为,一般情况下编译器会将方式二中的临时变量优化到寄存器中,不使用堆栈. 真的提高了运行速度吗? 下边的博

为什么三次异或操作可以交换两个数

a和b是两个整数,经过以下三次异或操作,可以达到交换目的:a = a ^ b;b = a ^ b;a = a ^ b; 首先要理解,什么是^(异或)操作: 二进制两数运算结果: 0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0相同为0,不同为1 假设: a = 10 , 其二进制数为: 1010 b = 12 , 其二进制数为: 1100如果a和b交换,在二进制数看来,因为第一位和最后一位数相同,所以中间两位数只要交换一下就行了这个交换的过程,因为二制进中只有两个数

运用异或运算实现两个数不通过中间变量交换值的原理分析

或许对于像我现在这样的初学者很多都没见过这个符号 ^ 这个是个异或运算的符号,好的,我们现在开始分析它的运行原理! 异或运算的知识请点击此连接后了解 http://baike.baidu.com/view/1452266.htm 将i和j的初始值给2进制化后 分别为 10 -- 05  -- 12  -- 01 10的二进制就为1010 ----------------------------- 5 -- 1 2 -- 0 1 5的二进制就为 101 第一步: i=i^j; 好了,我们将2个数都

异或运算实现两数交换

1.异或定义 1 ⊕ 1 = 0 0 ⊕ 0 = 0 1 ⊕ 0 = 1 0 ⊕ 1 = 1 简单说就是,相同为0,不同为1. 2.C++实现方法 1 #include <iostream> 2 3 int main() 4 { 5 int a, b; 6 std::cout << "请输入要交换的两个数:"; 7 std::cin >> a >> b; 8 std::cout << "交换前:\na="

位运算交换两个变量的值

int a = 4,b = 5;//a的二进制表示 0100 b的二进制表示0101 a = a^b;// a 0001 b 0101 b = a^b;// a 0001 b 0100 a = a^b;// a 0101 b 0100 a^a = 0 一个数异或任何一个数偶数次值不变 原文地址:https://www.cnblogs.com/--lr/p/11761427.html

不借助第三个变量交换两个数值类型变量的值

原文地址:http://blog.csdn.net/web_hwg/article/details/75045689 方法一 最简单的方法是用一个临时变量 var a = 10, b = 20; var temp = a; a = b; b = temp; 方法二 让其中一个变量变成一个与a和b都有关系的值 a = a + b; b = a - b; a = a - b; 或者 a = a - b; b = a + b; a = b - a;