目录
方法一:创建中间变量法:
方法二:算数加减法:
方法三:使用“位操作符”来实现变量的交换:
最后的总结:
交换两个变量的值是我们在编程的时候常常需要去做的事情,那么如何做到两个变量值的交换呢?这里给教大家介绍三种方法:
方法一:创建中间变量法:
第一个方法是我们最为经典的创建中间变量的方法,几乎没有任何的缺陷和不足,适用范围广泛。话不多说,直接上代码和运行截图:
方法二:算数加减法:
你要交换a,b两个变量的值,你可以先把a+b的值给变量a或者变量b两者当中的任意一个,假设我们就赋值给a, 然后我们将a-b赋值给b(注意这个时候的a的值已经是a+b了),再将a-b的值赋值给a(这个时候的a==a+b,b==a)如此便实现了两个变量值的交换。我们来看代码和运行截图:这是个很不错的交换两个变量值的方法,几乎适用于所有类型,甚至这个方法呢不需要去设置中间变量!但是当a和b的值比较大的时候,a+b的值超过了a,b的数据类型所能表示的最大数值。这种交换变量值的方法就会出现bug,可能会有交换不成功的情况出现。我们可以来做两个测试实例: 测试用例(一)
测试用例(二)
说明一下,int类型的数据所能表示的最大的数值是2^31-1=2147483647;
float类型的数据所能表示的最大的数值大概是3.0e48左右;
两个测试用例中的a+b的值都超过了两个各自数据类型所能表示的最大数,你也发现我们的测试用例(二)出现了问题,但是测试用例(一)却啥问题也没有。。。嗯,难道2147483647不是int类型数据的极限吗?实则不然,你可以在自己的ide上测试一下,2147483647+1的值赋值给一个int类型变量的时候,这个变量的值就会等于-2147483648,而这个负数正是int类型数据所能表示的最小值的大小!
实际上这个问题和我们int类型和float类型在计算机中的存储方式是密切相关,正是整数和小数在计算机中各自独特的存储方式导致当前我们程序运行的不同的结果,大家都知道整数在计算机中是以二进制的补码的形式进行存储的,那小数呢?这个问题则相对来说比较复杂,如果大家感兴趣的话我们会放在后面的博客《数据在计算机中的的存储方式》当中和大家详细去探讨一个整数,或者一个小数在计算机内部到底是如何存储的,而现在大家只需要记住两句话:
- 对于一个int类型的数据: INT_MAX+1==INT_MIN,具有回溯的特性;
- 对于一个float类型的数据:FLOAT_MAX+1!=FLOAT_MIN,不具有回溯的特性。
int数据类型的这种可以回溯的特性,导致了最后我们才能够交换成功!
float数据类型的不可回溯性,导致最后我们交换的时候出现了bug。
温馨提示:INT_MAX和FLOAT_MAX在C语言标准库中是没有定义的,这是作者在文中为了便于阐述而使用的特定的标识符,分别用于表示int类型的最大数和float类型的最大数。仅针对此博客,望星空听星雨对此拥有最终解释权。
那么同样的用例用方法一来实现,能不能成功交换成功呢?在理论上,方法一只要初始值不越界,后期的交换过程中也不会出现问题的,我们来测试一下:
嗯,确实没有问题的哦,毕竟是最为经典的方法嘛!
方法三:使用“位操作符”来实现变量的交换:
考虑部分读者可能不太清楚C语言中“位操作符”的运算规则,这里首先就给大家简单去列举一下这些操作符的使用吧(位操作符都是针对整数在计算机中存储的二进制进行操作的,而整数在计算机中是以补码的形式进行存储的):
&(按位“与”) | 对应二进制位上,有0则为0,同时为1才为1; |
|(按位“或”) | 对应二进制位上,有1则为1,同时为0才为0; |
^(按位“异或”) | 对应二进制位上,相同为0,相异为1; |
我们这里主要再给大家去介绍这个按位“异或”,由按位“异或”的运算规则不难得出两个重要的异或算式:如果定义了一个整数a;则 a^a=0, a^0=a.即:
- 一个整数对它本身进行异或会得到0;
- 一个整数对0进行异或会得到这个整数本身;
- 同时值得我们注意的是,位运算符本身满足满足交换律。
基于以上三点的阐述,我们可以写出以下用于交换两个变量值的方法:
当然最后再给大家反复申明一下,这种方法只适用于两个整数之间变量值的交换!
最后的总结:
总体来说,这些方法都是我们在交换两个变量值的时候一些不错的选择,最后将这些方法的优缺点都给总结如下了,方便大家写程序时能根据需求更快更准确地做出选择:
- 方法一适用于几乎所有数据类型,需要设置中间变量,不需要考虑数据值的越界问题;
- 方法二适用于几乎所有数据类型,不需要设置中间变量,需要考虑数据值的越界问题;
- 方法三只适用于int类型的数据类型,不需要设置中间变量,不需要考虑数据值的越界问题。