本文记录了不使用中间变量交换2个变量的value,很多的网络留言说是直接异或运算就可以了,而且效率很高,是真的吗?

这里简单的说一下我的环境:Win7 32位,Qt creator 5.4.1 编译器MinGW4.9.2 32bit 调试器:GNU GDB 7.8


关于这个问题,网络上面有很多的解释,3种方法,我这里给比较一下各自的优缺点,然后简单分析一下汇编代码,分析代码如下:

#include <stdio.h>
void swap1(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
}
void swap2(int &a,int &b)
{
a += b;
b = a - b;
a -= b;
}
void swap3(int &a,int &b)
{
a ^= b;//使用异或运算符
b ^= a;
a ^= b;
}
//这是第三种的缺点,不能交换float
/*void swap3float(float &a,float &b)
{
a ^= b;//使用异或运算符
b ^= a;
a ^= b;
}*/ void swap3char(char &a,char &b)
{
a ^= b;//使用异或运算符
b ^= a;
a ^= b;
} int main(void)
{
int a1 =,b1 =;
int a2 =,b2 =;
int a3 =,b3 =;
int a = ,b=;
swap1(a1,b1);
swap2(a2,b2);
swap3(a3,b3);
printf("a1 = %d,b1 = %d\n",a1,b1);
printf("a2 = %d,b2 = %d\n",a2,b2);
printf("a3 = %d,b3 = %d\n",a3,b3); swap2(a,b);
printf("a = %d,b = %d\n",a,b); // float a4=1.25,b4=2.51;
// swap3float(a4,b4);
// printf("a4 = %f,b4 = %f\n",a4,b4); char a5 = 'a',b5 = 'b';
swap3char(a5,b5);
printf("a5 = %c,b5 = %c\n",a5,b5);
return ;
}
/*
* 三种交换方式,第一种属于教科书的方式,属于低级的
* 第二种,加减运算时,可能会导致数据的溢出
* 第三种方法最优。(但是float类型的不能交换)
*/ /*
a1 = 2,b1 = 1
a2 = 4,b2 = 3
a3 = 6,b3 = 5
a = 1,b = 2147483647
a5 = b,b5 = a
Press <RETURN> to close this window... */

通过上面的代码展示,你会发现,啊,原来最高效的运算是异或运算啊。定论别下的太早。看完下面的汇编,我想你心里就有数了。你不必知道汇编的语句,你只要会数代码的行数就OK了。


方法1,号称最笨的方法。汇编代码如下:


方法2,使用+-运算解决,汇编如下:


方法3,直接异或运算,汇编代码如下:


小结:

在我没有查看汇编代码以前,我也轻易了相信了网络上的留言,甚至某些书籍。在我写博客以前,我还在相信方法3是最高效的,因为它的思维最接近机器的运算的思维。我还在他人的面前显摆过自己。但是,现在,我明白了,只有代码会说实话。swap2和swap3的有效汇编代码都在21行,而swap1的只有14行,相互差距7行代码,当然了,如果你的变量开销很大的话,那么swap3是很好的,swap2也不错,就是注意一下运算的时候不要溢出就可以了。当然了,算法的好坏,都是相对了,要看具体的环境情况。现在我想说,遇到什么知识,能自己测试的,可以测试一下,实践是检验真理的唯一标准。


修改日期20150601:

昨天睡的时候又在想这个问题,谁让咱是强迫症呢,觉得自己的想法太简单了,没有用时间来测试一下。今天看到1楼BYSF-XF的评论,更加让我下定决心用时间来测试一下了。测试的结果更是让我意外。我的环境已经在前面补充出来了。

首先是1楼的源码测试,结果如下,测试次数:0x7FFFFFFF:

从结果中,在我的环境上看到:使用swap4异或的效率确实不怎么好。我的机器和我的人一样笨笨的,接下来次数小一点吧,如下:

我使用了一个const常量来控制次数,这么多次,记得把下面的for循环也修改了。可以看到测试数据还是swap4异或很不理想。


修改日期20150602:

今天得到1楼BYSF-XF的测试反馈,测试结果在3楼,我把结果移植到这里了。从下面的结果看,不同的编译器,会产生不同的效果。而且debug和release的区别更是显著,这主要是因为debug是调试用的,编译器没有对程序进行优化处理,而release是发布版本,编译器对程序都做了优化处理,使程序更快更小,所以最后产生0的结果,也就不意外了。

好了,本人只是闲的没事儿,喜欢纠结。如果您有什么好的发现,还请留言讨论,一起探索。有时候存有一颗质疑的心,还是会发现新东西的。


网络误区:不用中间变量交换2个变量的value,最高效的是异或运算.的更多相关文章

  1. 不用中间变量交换a 和b的值

    // 不用中间变量的写法 ,假如 a=13, b=8; a=a+b =21; //此时 a=21; b=8; b=a-b=13; //此时a=21; b=13; a=a-b=8; //相当于 a=21 ...

  2. C语言位操作--不用中间变量交换两数值

    1.使用加法与减法交换两数值: #define SWAP(a, b) ((&(a) == &(b)) || \ (((a) -= (b)), ((b) += (a)), ((a) = ...

  3. java不用中间变量交换两个值

    public void changeVal(){ int a = 2; int b = 3; System.out.println("交换前 a:"+a+",b:&quo ...

  4. 不用中间变量交换两个数 swap(a,b);

    #include <iostream> using namespace std; int main () { ; ; cout<<"a="<<a ...

  5. 不用中间变量交换a和b的值?

    a = b = a = a+b b = a-b a = a-b print(a,b) a = b = a = a^b b = b^a a = a^b print(a,b) a = b = a,b = ...

  6. 用异或运算交换两个整数实现swap函数功能

    对于异或运算有这如下说明: 1^1=0 0^0=0 1^0=1 0^1=1 简单理解就是当两个书相同时结果为0,而两个数不同时异或的结果为1 可用于两个整数的交换,而不用去引入一个中间变量 #incl ...

  7. 不用中间变量,交换a、b值

    如果要交换a.b之间的值,一般的做法是: tmp=a;a=b;b=tmp;这种方法不得不使用一个临时变量. 从网上学来一个方法,可以不用使用临时变量: a^=b^=a^=b; 这样计算之后,就可以交换 ...

  8. [转][C/C++] 怎样不用中间变量temp 实现两个数交换

    第一类方法也是常用的方法,通过多次的数值计算来完成交换,到现在知道的有下面三种: (1)加减法. a = a + b; b = a - b; a = a - b; 该方法可以交换整型和浮点型数值的变量 ...

  9. PHP中不用第三个变量交换两个变量的值

    相信大家在PHP面试或者学习中经常会遇到这个问题就是“不用第三个变量来交换两个变量的值”,今天正对这个问题来讨论一下: 第一种方法:首先会想到的 这种方法简单可行,顺利的交换了两个变量的值. 第二种方 ...

随机推荐

  1. freeCodeCamp:Chunky Monkey

    猴子吃香蕉可是掰成好几段来吃哦! 把一个数组arr按照指定的数组大小size分割成若干个数组块. 例如:chunk([1,2,3,4],2)=[[1,2],[3,4]]; chunk([1,2,3,4 ...

  2. CSS布局技巧 -- sticky属性

    在一些很长的表格中,往往需要使用表头悬浮的设计以方便用户使用,例如H5电商页面通过下滑展示大量商品列表时,顶部的导航栏需要在离开屏幕时,需要固定在屏幕顶部以方便用户筛选类别.这种效果一直以来需要通过J ...

  3. c++ 课堂作业(1)

    一.题目 Create a program that asks for the radius of a circle and prints the area of that circle, using ...

  4. Python 第三天 文件操作(2)

    文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开 文件句柄 = file('文件路径', '模式') 注:python中打开文件有两种方式,即:open(...) 和  fi ...

  5. C++基础知识易错点总结(2)

    1. 若一组待排数据有序,花费时间最多的是:快速排序,T(n)=O(n^2): 2. 有 1000 个无序的整数,希望使用最快的方式找出前 50 个最大的,最佳的选择是? 快速排序:在最理想的情况下, ...

  6. K/3 Cloud开发之旅--环境准备篇

    K/3 Cloud是金蝶软件新推出的一款产品,介绍我就不多说了,谁用谁知道啊,那么我们如果要基于它做开发需要什么环境呢 开发环境必备软件 1 操作系统Windows X86/X64 或者Windows ...

  7. MD5编码

    public class MD5 { public static String getMD5(String content) { try { MessageDigest digest = Messag ...

  8. 详解在Visual Studio中使用git版本系统[转]

    这篇教程的预期,是希望没有任何版本使用基础的新手也可以掌握,所以细节较多,不当之处,欢迎指正. 一 .安装 git 开发工具 如果要使用 git 进行版本管理,其实使用 git 命令行工具就完全足够了 ...

  9. 接口测试总结<转>

    本文主要分为两个部分: 第一部分:主要从问题出发,引入接口测试的相关内容并与前端测试进行简单对比,总结两者之前的区别与联系.但该部分只交代了怎么做和如何做?并没有解释为什么要做? 第二部分:主要介绍为 ...

  10. Word 2007 文档结构图混乱

    Word 2007在编写大型文档时经常出现文档结构图混乱的情况,经过多番检索试验,得出结论: 绝对有效的临时性解决方案:在打开word的时候左下角会有提示word自动更新文档样式,按esc键取消,然后 ...