c#记两个变量进行值交换

  • A+
所属分类:.NET技术
摘要

  今天腊月二十九啦,无心上班,专注划水.然后就在那里翻帖子消磨时光.  看到了这样一个问题,有人提问为什么   a=b+(b=a)*0 

  今天腊月二十九啦,无心上班,专注划水.然后就在那里翻帖子消磨时光.

  看到了这样一个问题,有人提问为什么   a=b+(b=a)*0 

  ???

  第一眼看上去,我也有点蒙,仔细推敲了一下,嗯~的确是交换了值

  先把这个等式为什么能交换值先搁置一下,先来总结一下目前我所知道的

两个变量进行值交换有哪些方式?

 


 

  第一种方式也是最常用的方式:通过中间变量

    int a = 1;     int b = 2;      int temp = a;     a = b;     b = temp;

 

  第二种方式:通过数学运算

    int a = 1;     int b = 2;      a = a + b;     b = a - b;     a = a - b;

 

  

  第三种方式:异或运算

  int a = 1;   int b = 2;    a = a ^ b;          //第一步     001  a值为1     第二步     011   a值为3       第三步     011  a值为3   b = a ^ b;          //异或操作   010  b值为2     异或操作    010   b值为2       异或操作    001  b值为1   a = a ^ b;          //得到       011  值为3      得到       001   值为1       得到       010   值为2                        //这时候a的值为3             这时候b的值为1                这时候a的值为1
  

  这样三步异步操作就完成了换值操作 这也是目前我所知的,不借助中间变量,速度最快的换值,因为异或的运算是位运算,二进制运算

  

  第四种方式在C# 7.0 中可以使用元组(Tuple)类

    int a = 1;     int b = 2;      (a, b) = (b, a)

  这种方式以我的理解 他就像是 new 一个新对象 然后把新对象赋值给旧对象

  像这样 

    public class ClassDemo         {             private int a;             private int b;              public int A { get => a; set => a = value; }             public int B { get => b; set => b = value; }             public override string ToString()             {                 return "A的值为" + A + "  B的值为" + B;             }         }

 static void Main(string[] args)         {              ClassDemo oldOBj = new ClassDemo() { A = 1, B = 2 };             Console.WriteLine("旧对象: " + oldOBj.ToString());              ClassDemo newObj = new ClassDemo() { A = 2, B = 1 };             oldOBj = newObj;              Console.WriteLine("旧对象: " + oldOBj.ToString());             Console.ReadLine();         }

  如果实在不明白(a, b) = (b, a)  这行代码到底什么意思,来看一下反编译之后他是什么样子

  这里用IL Spy反编译一下这个控制台程序,如图:

  c#记两个变量进行值交换

  可以看到(a, b) = (b, a)这个操作多出来了两个变量

  所以说利用元组的这个特性去做值交换时,虽然目的可以达到,但是浪费资源
  
 好了,总结到此为止,上我今天最开始的问题,为什么  a=b+(b=a)*0   能达到交换值的操作?


 

  来分析一下:

  这个能交换值当然是因为优先级啦 我们还是先假设 

  a=1,b=2;

  首先,肯定要先算等式右边的,右有又加号,有括号,有乘号, 有等号 那优先级肯定是括号 -> 乘号 -> 然后加号 最后赋值

  我看到第一眼是这样推理的

   (b=a)先执行 此时b=1  ->   等式右边就是  1+0   ->   然后给a赋值   ->   则结果时a=1,b=1

  运行一下代码,结果:

c#记两个变量进行值交换

  所以我说我第一眼看去有点懵,这是什么操作,Why???

 后来,仔细推敲了一下,被自己的愚蠢逗笑了,原来是受到了我亲爱的小学老师先乘除后加减的影响,第一眼看上去就先算乘除去了,实际应该这样推理:

  等式右边分两部分b和(b=a)*0做加法  ->  从左往右计算a=2+(b=a)*0  ->  右半部分(b=a)先执行 此时b=1  ->   等式右边就是  2+0   ->   然后给a赋值   ->   则结果时a=2,b=1  ->换值完成

  

  记录一下自己愚蠢的一天.文章中有错误之处希望大佬们不吝赐教,感谢