今天腊月二十九啦,无心上班,专注划水.然后就在那里翻帖子消磨时光.
看到了这样一个问题,有人提问为什么 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反编译一下这个控制台程序,如图:
可以看到(a, b) = (b, a)这个操作多出来了两个变量
来分析一下:
这个能交换值当然是因为优先级啦 我们还是先假设
a=1,b=2;
首先,肯定要先算等式右边的,右有又加号,有括号,有乘号, 有等号 那优先级肯定是括号 -> 乘号 -> 然后加号 最后赋值
我看到第一眼是这样推理的
(b=a)先执行 此时b=1 -> 等式右边就是 1+0 -> 然后给a赋值 -> 则结果时a=1,b=1
运行一下代码,结果:
所以我说我第一眼看去有点懵,这是什么操作,Why???
后来,仔细推敲了一下,被自己的愚蠢逗笑了,原来是受到了我亲爱的小学老师先乘除后加减的影响,第一眼看上去就先算乘除去了,实际应该这样推理:
等式右边分两部分b和(b=a)*0做加法 -> 从左往右计算a=2+(b=a)*0 -> 右半部分(b=a)先执行 此时b=1 -> 等式右边就是 2+0 -> 然后给a赋值 -> 则结果时a=2,b=1 ->换值完成
记录一下自己愚蠢的一天.文章中有错误之处希望大佬们不吝赐教,感谢