黑马程序员技术交流社区

标题: 关于两变量交换值不通过第三变量的疑惑求解 [打印本页]

作者: 赵力    时间: 2012-6-10 01:13
标题: 关于两变量交换值不通过第三变量的疑惑求解
今天在论坛看了一些关于两数交换不通过第三变量的方法,不禁叹为观止,如下所示
  1. static void Main(string[] args)
  2. {
  3. int a=5,b=8;
  4. a=a+b;//第一种方法,通过数学运算
  5. b=a-b;
  6. a=a-b;
  7. Console.WriteLine("此时的a={0},b={1}",a,b);
  8. a^=b;//第二种方法,通过异或运算
  9. b^=a;
  10. a^=b;
  11. Console.WriteLine("此时的a={0},b={1}", a, b);
  12. a=b+0*(b=a);//第三种方法。
  13. Console.WriteLine("此时的a={0},b={1}", a, b);
  14. Console.ReadKey();
  15. }
复制代码
这里第一种方法很奇妙,但可以理解,个人认为第二种和第一种方法思路上有异曲同工之妙,异或运算法则中a=b^a^b;和第一种运用a=b+a-b差不多
第三种方法 论坛中也没找到解释,比较疑惑,哪位前辈给指点一下。。
我们在实际运用中一般会选择哪种方式,或者在什么环境下用哪种方式最好??




作者: 肖云    时间: 2012-6-10 01:30
这里的第一种方法有局限性,只能用于数字类型的两两交换,而对于字符类型的两两交换,还是需要用第三变量来支持.
作者: 牛景亮    时间: 2012-6-10 10:31
不错,确实很巧妙
作者: 孙玉昌    时间: 2012-6-11 15:56
个人认为第一种方法,只是没有定义第三个变量而已,其实原理仍然是通过第三者来交换。实际开发的时候,未必使用这么奇妙的方法吧,使用更容易理解的方法,最常规的方法,就可以了吧。
作者: 黑马-许泽宇    时间: 2012-6-11 17:06
其实实际运用完全没必要不适用第三方变量来交换...而且这种交换仅仅只能用于数字类型,.如果是其他类型的变量,还是需要借助于第三方变量来交换的.
作者: 赵力    时间: 2012-6-12 10:39
黑马-许泽宇 发表于 2012-6-11 17:06
其实实际运用完全没必要不适用第三方变量来交换...而且这种交换仅仅只能用于数字类型,.如果是其他类型的变 ...

哦如此 我也只是想知道下 这个第三种是怎么实现交换的? 谢谢
作者: 黑马-许泽宇    时间: 2012-6-12 12:43
赵力 发表于 2012-6-12 10:39
哦如此 我也只是想知道下 这个第三种是怎么实现交换的? 谢谢

这个方法其实我也没有见过,以我实验过几次得出的一个结论不知道对不对
a=b+0*(b=a);
这好像只是运用了一个计算机运算的特点.
因为这个式子在编译前其实是这样的.
a=b(这时的B的值是5)+0*(b=a)(由于括号的优先级,这里的B改为了10,可是前面的那个b在预编译时值为5.所以此处改变b的值并不影响前面那个b而影响这行以后的b的值,所以就会把b开始的值5赋给了a,从而交换2变量)
我的理解是这样的,如有不对,希望大家讨论讨论
作者: ren1015    时间: 2012-6-13 16:04
我的理解是在编译时,变量初始化时系统给变量a和b分配了内存空间,分别保存值,执行语句a=b+0*(b=a);时,在cpu内的堆栈中分配临时空间保存a,b的值,我猜b=a 和 a=b+……两个赋值命令的优先级是一样的,所以a=b+……中的b是b原先的值,而不是更新的值,这样,执行完命令后把堆栈的值刷新到内存
作者: 郭佳佳    时间: 2012-7-7 15:52
百度一下,会有很多解决方法。菜鸟的回答
作者: 戴水平    时间: 2012-7-8 11:22
a 和b 都是值类型的数据,第一种其实原理就像第三方变量来实现一样。第二种是将a和b的值编译器先转换成二进制了,然后进行二进制的
异或运算。第三种是利用优先级了(b=a)是b复制一份放的是a 0*(b=a)还是0,a=b(b存储的数据并没改变)+0*(b=a),就是8了。然后输出的b是改变的a,b.这也是值变量跟引用变量的区别,一个保存的是值,一个是地址,赋值的时候一个复制的是值,一个复制的是地址





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2