如何在c语言环境中定义一个函数,让他实现交换两个整型的数值?
第一次拿到这个问题时,第一反应是这不简单吗?然后尝试写了代码如下:
1
在这段代码中,我们先把 a 的值存到 temp 中,然后把 b 的值赋给 a ,最后把 temp (也就是原来 a 的值)赋给 b ,完成交换。
<借助临时变量交换,这是最直观的方法.比如我们有两个变量 a 和 b ,要交换它们的值>
那除了此方法,我又想到了一种无需借助临时变量的方法如下:
2
这里通过先把 a 和 b 的和赋给 a ,然后利用新的 a 和原来的 b 计算得到原来的 a 并赋给 b ,最后再用新的 a 减去新的 b 得到原来的 b 赋给 a ,从而实现交换数值(只适应于整数)
然后在学长的指导下我又掌握了相对复杂一点的方法:
3
利用异或运算交换(同样只适用于整数)
对于异或
在C语言中,异或运算(用“^”符号表示)是一种位运算.
对于参与运算的两个二进制位,当这两位相异(一个是0,另一个是1)时,结果为1,当这两位相同(都是0或者都是1)时,结果为0.
例如,1 ^ 0的结果是1,0 ^ 0的结果是0,1 ^ 1的结果是0.
如果是对整数进行异或运算,会先将整数转换为二进制形式,再按位进行异或.比如,5 ^ 3,5的二进制是101,3的二进制是011,按位异或后得到110,转换回十进制就是6.
性质
- 交换律: a^b = b^a .例如, 3^5 = 5^3 ,因为异或运算只是比较对应二进制位是否相同,交换操作数不影响结果.
- 结合律: (a^b)^c=a^(b^c) .这就像加法中的结合律一,多个异或运算的顺序不影响最终结果.
- 归零律: a^a = 0 .因为相同的数二进制位完全相同,按异或运算规则,每一位都为0,所以结果为0.
- 恒等律: a^0 = a .因为0的二进制每一位都是0,与 a 进行异或运算时, a 的每一位不变,结果还是 a .
大致了解异或后我们再回到分析原题的交换方法
- 第一步 a = a ^ b ,将 a 和 b 的异或结果存储在 a 中。
- 第二步 b = a ^ b ,此时 a 是 a ^ b ,那么 a ^ b 再和原来的 b 进行异或运算,根据异或的性质 (a ^ b)^b=a^(b^b)=a^0 = a ,就得到了原来的 a 的值,并存入 b 中。
- 第三步 a = a ^ b ,此时 a 是 a ^ b , b 是原来的 a ,再进行异或运算,根据异或的性质 (a ^ b)^a=(a^a)^b = 0^b = b ,就得到了原来的 b 的值,并存入 a 中,这样我们就完成了交换。
学会异或法后学长又让我尝试一下写个函数来实现数值交换,很快我就写完了如下:
但是显然我所写的函数无法完成交换数值,我逐条调试发现问题出现在函数上面,为什么呢?我查找了一些资料,原来在函数传参过程中,存在形参和实参,形参只是对实参的一份临时拷贝,而我所写的函数只是对形参进行了修改,实际上并不影响实参的数值.
那该如何修改呢
在函数 change 内部,给 temp 赋值以及后续对 x 、 y 赋值时,应该使用指针解引用操作符 * 来访问和修改传入的实参的值,只有通过指针操作才能真正修改实参的值.所以我们在传参时也应该把a和b的地址传过去.
最终用函数解决的代码如下:
4
这里函数只用了创建临时变量的方法来交换 .
对于交换数值我学到了很多,不要小看一个简单的问题,只有把简单的题目吃透了,才有可能解决困难的题目.加油加油加油@
标签:函数,交换,数值,异或,关于,实参,运算 From: https://blog.csdn.net/2402_88950569/article/details/143854421