今天臘月二十九啦,無心上班,專注划水.然后就在那里翻帖子消磨時光.
看到了這樣一個問題,有人提問為什么 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=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 ->換值完成
記錄一下自己愚蠢的一天.文章中有錯誤之處希望大佬們不吝賜教,感謝