使用异或运算交换两个任意类型变量
这篇文章中将使用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个字节.
转载于:https://www.cnblogs.com/WhyEngine/p/4040246.html
使用异或运算交换两个任意类型变量相关推荐
- 异或运算交换两个整数
异或运算有两个特性: 1.一个数异或本身恒等于0,如5^5恒等于0: 2.一个数异或0恒等于本身,如5^0恒等于5. 基于此,交换操作如下: a=a^b; b=b^a; a=b^a;
- 常用技巧 —— 位运算 —— 异或运算实现两个数的交换
[概述] 交换变量时,通常是借助一临时变量来赋值实现 void exchange(int a,int b) {int temp;temp=a;a=b;b=temp; } 当采用异或运算时,实现两变量交 ...
- 用异或来交换两个变量能提快速度是错误的
在进行两个变量的时候,常常会看到有些书误人子弟的推荐使用异或的方式: 方式一 { x = x ^ y; y = x ^ y; x = x ^ y; } 而不是採用暂时变量实现交换: 方式二 { i ...
- 运用异或运算实现两个数不通过中间变量交换值的原理分析
或许对于像我现在这样的初学者很多都没见过这个符号 ^ 这个是个异或运算的符号,好的,我们现在开始分析它的运行原理! 异或运算的知识请点击此连接后了解 http://baike.baidu.com/vi ...
- 位运算交换两个变量值
两个变量怎么交换值 1.通常的办法是设一个临时变量tmp,将两个值进行交换. 2.但这里有个有趣的方法是利用位运算进行交换值的操作. 首先有个原理需要知道: 若a^b=c,则c^b=a,c^a=b 可 ...
- 异或交换两个数的原理证明
算法 通过异或运算交换两个数 a ^= b b ^= a a ^= b 证明 由异或定义易得: 异或运算满足结合律, 交换律 x ^ x = 0 x ^ ...
- Python 异或运算
运算规则 0^0=0 0^1=1 1^0 = 1 1^1 = 0 将两个变量的值转化为二进制的, 再按照上边的运算规则进行 利用异或运算交换两个变量的值 方法一:利用Python特性 a = 1 b ...
- java 不用中间变量_java异或运算不使用中间变量交换两个数(Java版)详细分解...
Java的异或运算^,这个小不点"^"就是Java的异或运算符,其特性如下:真^假=真假^真=真 假^假=假 真^真=假,它却是说明了Java异或运算的基本法则,那就是:只要两个条 ...
- 你管这玩意叫异或运算?
对于底层开发来说,位运算是非常重要的一类操作.而对于位运算来说,最有意思的,应该就是异或运算(XOR)了. 提到异或运算,很多同学可能首先想到的就是一个经典的,和异或运算相关的面试问题: 给你一个包含 ...
最新文章
- Tengine高性能部署之—日志分割
- NLP的一些学习资料
- GridView 自写分页 存储过程
- php获取域名方法,PHP实现获取域名的方法小结
- 苹果新款iPad或将于下月在新总部发布
- [禅悟人生]谦虚有助于自我消融
- VUE---不连接后端的登录验证规则方法
- SQL Developer 使用问题与解决方法汇总
- 不要残渣10w+,推荐8个我平时看的公众号
- Mybatis-学习笔记(8)常用的注解
- DeepLab图像分割
- WAP PUSH解析(2)——WSP以及WBXML编码
- 已解决:如何彻底删除快压/以及彻底删除顽固的dll文件
- 李宏毅机器学习之Life Long Learning
- Cadence OrCAD Capture 原理图设计过程产生的文件总结与说明
- python圆形代码_python圆形函数
- -20dB谱宽是什么意思?
- Oracle ODBC 驱动安装及详细配置(不需安装客户端)
- python_第一节课_python基础语法
- 揭秘:香港八大钻石型男 择偶条件大公开
热门文章
- Web框架——Flask系列之Flask中的特殊变量和方法(十九)
- 十三、CSS 3新特性详解(一)——属性、结构伪类、伪元素选择器,nth-child与nth-of-type区别,2D rotate,calc函数、滤镜filter、过渡transition
- python 动态属性和特性
- LeetCode 912. 排序数组(10种排序)
- LeetCode 398. 随机数索引(概率)
- js 将图片置灰_艾叶灰千万别扔——艾叶灰的神奇功效
- python中的LEGB 规则
- Flink中的容错机制
- 遍历删除_面试难题:List 如何一边遍历,一边删除?
- 数据标准化 - scale() - Python代码