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

这篇文章中将使用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492825.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019与下一个十年:我们将要放弃的和将要拥抱的

来源&#xff1a;资本实验室2019年&#xff0c;是连接21世纪前两个十年的过渡一年。在金融支付和商业领域中&#xff0c;2019年也有望成为激动人心的一年。在这一年中&#xff0c;每家企业、每个人都需要对过去十年中所追求的创新进行反思&#xff0c;并决定下一个十年前进的方…

C++中虚函数、纯虚函数、普通函数三者的区别

转载自&#xff1a;https://www.cnblogs.com/cj2014/p/7692707.html 1.虚函数(impure virtual)   C的虚函数主要作用是“运行时多态”&#xff0c;父类中提供虚函数的实现&#xff0c;为子类提供默认的函数实现。 子类可以重写父类的虚函数实现子类的特殊化。 如下就是一…

麦肯锡发布调研,揭开“那些引入人工智能的企业都怎么了 ”

来源&#xff1a;亿欧智库摘要&#xff1a;根据麦肯锡的最新调研显示&#xff0c;人工智能技术普遍上得到企业接纳&#xff0c;但仍有不少企业在入门时就面临“不知道咋开门”的状况。新技术带来新问题&#xff0c;企业该如何应对&#xff1f;根据麦肯锡在全球范围内的调研&…

深度学习、图像识别的基本概念

图像识别 图像识别概念&#xff1a; 我们对图像进行一些列的处理&#xff0c;将其有用的信息提取出来&#xff0c;进行划分归类&#xff0c;这就是图像识别。 图像识别目的&#xff1a; 将景物、图像、字符等信息经过预处理&#xff0c;然后进行识别&#xff0c;让计算机具…

PHP-php.ini中文版

今天细看了下配置文件 有很多没用过的 就从网上搜了一篇 常看看 ;;;;;;;;;;;;;;;; 简介 ;;;;;;;;;;;;;;;;; 本文并非是对英文版 php.ini 的简单翻译&#xff0c;而是参考了众多资料以后&#xff0c;结合自己的理解&#xff0c;增加了许多内容&#xff0c;; 包括在原有 php.ini …

重磅!我国建成首个自动驾驶封闭高速公路测试环境

来源&#xff1a;智车科技摘要&#xff1a;根据工业和信息化部、公安部、江苏省人民政府共建“国家智能交通综合测试基地”的总体规划和建设要求&#xff0c;公安部交通管理科学研究所坚持“自动驾驶汽车产业发展与安全行驶并重”的指导思想&#xff0c;依据《中华人民共和国公…

线性运算和非线性运算

线性运算是加法和数量乘法&#xff0c;对于不同向量空间线性运算一般有不同的形式&#xff0c;它们必须满足交换律&#xff0c;结合律&#xff0c;数量加法的分配律&#xff0c;向量加法的分配律。线性是指量与量之间按比例、成直线的关系&#xff0c;在空间和时间上代表规则和…

拖延症讲:反向遍历链表

今天感觉被面试官用很简单的题目虐了。。。。“如何高效等反向遍历单链表” 一般情况下会想到一个很笨的方法&#xff1a;计算个数&#xff0c;然后再根据个数每一次将遍历的索引减一。 第二种方式就是将原链表反过来&#xff0c;再遍历。如果要求不改变原有结构&#xff0c;可…

单反相机内部光线反射原理

单反相机是照相机的一种&#xff0c;以独特的取景方式而命名。 它的全称是&#xff08;可换&#xff09;单镜头反光式取景照相机&#xff0c;&#xff08;Single Lens Reflex Camera&#xff0c;缩写为SLR camera&#xff09;一般简称为单反相机。它的含义是拍摄和取景共用用一…

面部识别技术走到十字路口?

来源&#xff1a;雷锋网摘要&#xff1a;向左走&#xff0c;还是向右走&#xff1f;近日&#xff0c;面部识别技术又遭遇“突发事件”。本周二&#xff0c;由90个倡议团体组成的小组给三巨头AAM&#xff08;亚马逊、谷歌、微软&#xff09;写信&#xff0c;要求三家公司承诺不向…

我与ARM的那些事儿2JINLK烧录nor flash

前言 最近在研究mini2440的友善之臂&#xff0c;但是我拿着的是实验室早期买的开发板&#xff0c;在做裸机开发的过程中老是不能很好地使用最新版的minitools进行烧录&#xff0c;因而各种不爽&#xff0c;因为生成了bin文件不能很好地传到mini2440中&#xff0c;作为一个对开…

焦距及摄像机成像

焦距,本来是一个光学中的量,当一束平行光以与凸透镜的主轴穿过凸透镜时&#xff0c;在凸透镜的另一侧会被凸透镜汇聚成一点&#xff0c;这一点叫做焦点&#xff0c;焦点到凸透镜光心的距离就叫这个凸透镜的焦距。一个凸透镜的两侧各有一个焦点。 光心&#xff1a;可以把凸透镜…

基于opencv的gpu与cpu对比程序,代码来自opencv的文档中

原文链接&#xff1a; http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/gpu/gpu-basics-similarity/gpu-basics-similarity.html 代码中有错误&#xff0c;关于GpuMat OpenCV代码中没有对其进行操作符运算的重载&#xff0c;所有编译的时候有错误。对于GpuMat的运…

不只是华为/阿里/百度/小米/京东,AIoT已然成为资本与新兴企业都认可的赚钱方向...

来源&#xff1a;物联网智库整理发布摘要&#xff1a;当互联网的上半场结束之后&#xff0c;所有的互联网下半场都是重生意。随着AIoT越来越热门&#xff0c;这一概念已然成为巨头、资本以及新兴企业竞相角逐的热点。2019年注定是AIoT具有重要发展的一年&#xff0c;仅仅在刚过…

Opencv中的Laplacian(拉普拉斯算法)

下面的代码选自Opencv2.4.9源码文件opencv\sources\modules\imgproc\src文件夹下的deriv.cpp文件&#xff0c;该cpp文件中的Laplacian(…)函数源码&#xff0c;下面只显示了ksize1or3的情况&#xff0c; void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, …

机会与挑战:2019人工智能应用趋势预测

来源&#xff1a;资本实验室摘要&#xff1a;最近几天&#xff0c;印度人工智能数据分析公司Fractal Analytics宣布获得私募投资机构Apax Partners的2亿美元投资&#xff0c;估值达到了5亿美元。也是在近期&#xff0c;该公司的几位人工智能专家分别对2019年的人工智能应用趋势…

函数指针 如:void (*oper)(ChainBinTreee *p)

在C语言中&#xff0c;一个函数总是占用一段连续的内存区&#xff0c;而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量&#xff0c;使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这种指向函数的…

边缘检测中非极大值抑制简单解释

首先要明白的是: (a.) canny算子中非最大抑制(Non-maximum suppression)是回答这样一个问题: “当前的梯度值在梯度方向上是一个局部最大值吗?” 所以,要把当前位置的梯度值与梯度方向上两侧的梯度值进行比较. (b.) 梯度方向垂直于边缘方向, 这一点不要误解. - Q1: 插值…

哥德尔不完备定理”到底说了些什么?

来源&#xff1a;人机与认知实验室&#xff08;一&#xff09;【中文网上深入介绍哥德尔不完备定理的文章很少&#xff0c;我这篇文章写得很长&#xff0c;花了不少时间打磨它&#xff0c;希望能帮助到爱好数学与逻辑的人。文章把理解哥德尔不完备定理分为了五重&#xff0c;建…

背景透明文字不透明的最佳方法兼容IE(以背景黑色透明度0.5为例)

以背景黑色&#xff0c;透明度0.5举例为大家详细介绍下关于背景透明&#xff0c;文字不透明的最佳方法同时兼容IE&#xff0c;具体实现如下&#xff0c;感兴趣的朋友可以参考下哈希望对大家有所帮助以背景黑色&#xff0c;透明度0.5举例 非IE&#xff1a;background:rgba(0,0,0…