如何用java实现两个变量值的互换!

摘要:
1.通过第三方变量实现两个变量的交换:2.通过两个现有变量之间的加法或减法实现两个参数的交换:当两个变量无限连接到int值范围并且加法超过int值范围时,此方法不适用。3.指针地址操作实际上是整数操作。例如,可以减去两个地址以得到一个整数,该整数表示内存中两个变量的存储位置之间分隔了多少字节;地址和一个整数相加,即“a+10”表示最后10个a类数据单元的地址,a作为基地址。因此

1、通过第三方变量实现两个变量的交换:

        如何用java实现两个变量值的互换!第1张

2、通过已有的两个变量之间的加或减实现:

        如何用java实现两个变量值的互换!第2张

这种方法对于两个都是无限接进int取值范围,而相加超出int取值范围的情况不适用。

3. 指针地址操作
因为对地址的操作实际上进行的是整数运算,比如:两个地址相减得到一个整数,表示两个变量在内存中的储存位置隔了多少个字节;地址和一个整数相加即“a+10”表示以a为基地址的在a后10个a类数据单元的地址。所以理论上可以通过和算术算法类似的运算来完成地址的交换,从而达到交换变量的目的。即:
int *a,*b; //假设
*a=new int(10);
*b=new int(20); //&a=0x00001000h,&b=0x00001200h
a=(int*)(b-a); //&a=0x00000200h,&b=0x00001200h
b=(int*)(b-a); //&a=0x00000200h,&b=0x00001000h
a=(int*)(b+int(a)); //&a=0x00001200h,&b=0x00001000h
通过以上运算a、b的地址真的已经完成了交换,且a指向了原先b指向的值,b指向原先a指向的值了吗?上面的代码可以通过编译,但是执行结果却令人匪夷所思!原因何在?
首先必须了解,操作系统把内存分为几个区域:系统代码/数据区、应用程序代码/数据区、堆栈区、全局数据区等等。在编译源程序时,常量、全局变量等都放入全局数据区,局部变量、动态变量则放入堆栈区。这样当算法执行到“a=(int*)(b-a)”时,a的值并不是0x00000200h,而是要加上变量a所在内存区的基地址,实际的结果是:0x008f0200h,其中0x008f即为基地址,0200即为a在该内存区的位移。它是由编译器自动添加的。因此导致以后的地址计算均不正确,使得a,b指向所在区的其他内存单元。再次,地址运算不能出现负数,即当a的地址大于b的地址时,b-a<0,系统自动采用补码的形式表示负的位移,由此会产生错误,导致与前面同样的结果。
有办法解决吗?当然!以下是改进的算法:
if(a<b)
{
a=(int*)(b-a);
b=(int*)(b-(int(a)&0x0000ffff));
a=(int*)(b+(int(a)&0x0000ffff));
}
else
{
b=(int*)(a-b);
a=(int*)(a-(int(b)&0x0000ffff));
b=(int*)(a+(int(b)&0x0000ffff));
}
算法做的最大改进就是采用位运算中的与运算“int(a)&0x0000ffff”,因为地址中高16位为段地址,后16位为位移地址,将它和0x0000ffff进行与运算后,段地址被屏蔽,只保留位移地址。这样就原始算法吻合,从而得到正确的结果。
此算法同样没有使用第三变量就完成了值的交换,与算术算法比较它显得不好理解,但是它有它的优点即在交换很大的数据类型时,它的执行速度比算术算法快。因为它交换的时地址,而变量值在内存中是没有移动过的。(以下称为地址算法)

4、通过异或实现(异或符号为^)

*******************************************************************************************************

关于^:

     异或的运算法则,相当于不带进位的二进制加法。二进制下用1表示真,0表示假,则异或的运算法则为:0异或0=0,1异或0=1,0异或1=1,1异或1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。

第一个数符号第二个数结果
0^00
0^11
1^01
1^10

如:

num1 = 5,对应的二进制为(101); num2 = 7,对应的二进制为(111);

num1=num1^num2=2; 即二的平方位1^1=0,二的一次方位0^1=1,二的0次方位1^1=0;得到(010)即为2。

num2 = num1 ^ num2=5 ;相当于num2=num1^num2^num2;二的平方位1^1^1=1(此处无论num2的二的平方位是0还是1,异或运算后都为0,故得到的肯定与原num1的二的平方位相同,同理其他位置全部也都是原num1的数);二的一次方位0^1^1=0;二的0次方位1^1^1=1.;得到(101)即为5.

num1 = num1^num2=7; 相当于num1 = num1^num2^num1^num2^num2=num2=7.

此方法同样实现了两个数互换。

*******************************************************************************************************    如何用java实现两个变量值的互换!第3张

由于^符号是不进位的,所以即使两个都无限接进int取值范围的数。通过^运算,也不会超过int取值范围。 

免责声明:文章转载自《如何用java实现两个变量值的互换!》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Spring整合Hessian访问远程服务zabbix 在linux上安装以及一些配置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

JS中一道关于this和闭包的题

this和闭包的一道练习题 var num = 20; var obj = { num: 30, fn: (function (num){ this.num *= 3; num += 15; var num = 45; return function(){...

JavaScript学习笔记及知识点整理_1

一.js的基础部分 1.==和===的区别:==在判断是否相等的时候会进行类型转换,有时会得到非常奇怪的结果,因此一般情况下都是用===判断是否相等2.strict模式:在js中,如果一个变量没有用var进行声明,那么这个变量将会变成全局变量.采用strict模式声明后,如果该变量没有用var声明,那么将会报错!采用strict模式的方法是在js的第一行加...

postman-变量/环境/过滤等

之前虽然自己也有用postman来测试api,但都只是最简单输入url,发送,查看结果,大部分时候跟使用浏览器差不多,偶然在简书首页看到一篇 API开发神器-Postman , 深感还是得对自己使用的工具多琢磨一下,兴许你就发现了宝贝,大大加快开发测试速度了; 这里没有打算写全面的教程,只对我之前没了解的环境设置/变量使用以及对返回结果进行过滤等操作进行记...

jsp、freemarker、velocity对比

在java领域。表现层技术主要有三种:jsp、freemarker、velocity。 jsp是大家最熟悉的技术长处:1、功能强大,能够写java代码2、支持jsp标签(jsp tag)3、支持表达式语言(el)4、官方标准。用户群广。丰富的第三方jsp标签库5、性能良好。jsp编译成class文件运行。有非常好的性能表现缺点:jsp没有明显缺点,非要挑点...

C语言探索之旅 | 第一部分第五课:变量的世界(二),变量声明

作者 谢恩铭,公众号「程序员联盟」。 转载请注明出处。 原文:https://www.jianshu.com/p/8db33987cb49 《C语言探索之旅》全系列 内容简介 变量是什么? 给变量起个名字 变量的类型 声明变量 const 关键字 第一部分第六课预告 1. 变量是什么? 上一课我们学习的是 C语言探索之旅 | 第一部分第四课:变量...

(原创)CheckTool:CRC校验、累加和校验、异或和校验专业校验工具V1.1

功能升级说明:V1.1版本在V1.0版本上对用户输错情况下予以提示加强,同时新增32位CRC校验功能。 下面是CheckToolV1.1的主界面: 用户输入正常时的界面: 用户输入出错的界面提醒: 功能介绍: 1、自动操作:当用户输入十六进制数据后,CheckTool会自动计算各种校验值,省去了再次点击“计算”的烦恼,哈哈,是不是很贴心噢!...