第 13 講:運(yùn)算符(五):復(fù)合賦值運(yùn)算符
復(fù)合賦值運(yùn)算符針對(duì)于需要兩個(gè)數(shù)值才能操作的運(yùn)算符才有。比如說 +
、-
、%
、>>
等等。這些運(yùn)算符都可以使用復(fù)合賦值運(yùn)算符來簡(jiǎn)化調(diào)用:a =?
a?op?b
可以簡(jiǎn)化成 a op= b
。其中的 op
是一個(gè)運(yùn)算符號(hào)。
Part 1 經(jīng)典的 a = a + 1 問題
入門初學(xué)賦值語(yǔ)句的時(shí)候,經(jīng)常會(huì)看不懂 a = a + 1
類似的賦值過程。等號(hào)左側(cè)的變量表示賦值方,右側(cè)是表達(dá)式,是一個(gè)結(jié)果。等號(hào)的左右兩側(cè)雖然都有 a
,但是實(shí)際上右側(cè)的 a
只起到了取值的作用,而左側(cè)的 a
起到的則是一個(gè)代號(hào),表示賦值結(jié)果要到 a
變量里來,而不是賦值給別的變量上去。
正是因?yàn)槿绱?,所有左右兩?cè)可以完全使用同一個(gè)變量來賦值。a = a + 1
實(shí)際上就是把 a
原始的結(jié)果增大一個(gè)單位之后,將結(jié)果重新賦值給 a
的過程。這樣理解的話,顯然在語(yǔ)法語(yǔ)義上、邏輯上都是完全說得通的,也不產(chǎn)生錯(cuò)誤。
Part 2 復(fù)合賦值運(yùn)算符的簡(jiǎn)化過程
實(shí)際上,前文給的 a = a + 1
可以使用復(fù)合賦值運(yùn)算符來簡(jiǎn)化使用:a += 1
。復(fù)合賦值運(yùn)算符的類似模式還有很多,比如說 a = a >> 3
可以改寫成 a >>= 3
、a = a * 5
可以改寫成 a *= 5
、a = a % (b * 7)
可以改成 a %= b * 7
等等。
所以說,語(yǔ)法上基本上不用多說。稍微注意一下的是,只有如下的符號(hào)才有復(fù)合賦值運(yùn)算符的配套寫法。
數(shù)值加法運(yùn)算、字符串拼接運(yùn)算
+
減法運(yùn)算
-
乘法運(yùn)算
*
除法運(yùn)算
/
取模運(yùn)算
%
貪婪邏輯且運(yùn)算、位與運(yùn)算
&
貪婪邏輯或運(yùn)算、位或運(yùn)算
|
邏輯異或運(yùn)算、位異或運(yùn)算
^
位左移運(yùn)算
<<
位右移運(yùn)算
>>
就這么一些?;旧隙加校瑢?duì)吧。不過,&&
和 ||
就沒有。比如說 a = a && b
就不能寫成,因?yàn)?C# 本身是沒有這種復(fù)合賦值的。a &&= b
Part 3 怎么理解復(fù)合賦值運(yùn)算
從人類的角度來說,復(fù)合賦值運(yùn)算并不單單是一種簡(jiǎn)化寫法。為了簡(jiǎn)化理解,我們沒有必要從代碼簡(jiǎn)化這個(gè)層面去繞一下。
思考一下,我們將數(shù)值本身增大(或者縮?。?,然后賦值回去,可以怎么理解呢?是的,累計(jì)。比如說 a += 3
就可以理解成“a
再增大 3 個(gè)單位”;a *= 5
表示“a
擴(kuò)大 5 倍”。所以,它是一種累計(jì)的過程。這么理解就輕松一些了:從原有數(shù)據(jù)的基礎(chǔ)上修改得到的新數(shù)值。
Part 4 a = a + 1
、a += 1
和 a++
有啥區(qū)別?
下面我們來說一下,a = a + 1
、a += 1
和 a++
三者的區(qū)別。
實(shí)質(zhì)上,三者沒有語(yǔ)義上的區(qū)別(它們都是增大一個(gè)單位),如果 a++
直接寫成語(yǔ)句的話(即 a++;
這樣的,當(dāng)然也可以包含 ++a;
這樣的東西,它倆之前說過是沒區(qū)別的),那么 a++
、a = a + 1
和 a += 1
三者都可以拿來比較。
不過說實(shí)在的,你完全可以認(rèn)為,a++
是 a += 1
的簡(jiǎn)寫,a += 1
又是 a = a + 1
的簡(jiǎn)寫。而從性能分析上講,它們依舊沒有區(qū)別。但我們更建議使用具體化格式來代替廣泛化格式。通用寫法可以涵蓋更多的格式,但它可能在處理過程之中和具體化的寫法要復(fù)雜一點(diǎn)。當(dāng)然,從書寫上,簡(jiǎn)單的更香一些,不是嗎?
Part 5 串聯(lián)賦值
賦值運(yùn)算符和 ++
、--
運(yùn)算符具有相同的功效。除了本身的行為以外,它自身(整個(gè)表達(dá)式)也是可以體現(xiàn)出一個(gè)數(shù)值的。舉個(gè)例子:
在第 2 行里,我們串聯(lián)了多個(gè)賦值語(yǔ)句。按照賦值的方向(從右到左)來看,這個(gè)表達(dá)式等價(jià)于 a = (b = (c = 3))
,即先將 c = 3
賦值完成后,將 c
的結(jié)果賦值給 b
;最后,又把 b
的結(jié)果賦值給 a
,以此達(dá)到串聯(lián)賦值的效果。這里 c = 3
c
賦值的結(jié)果。
這個(gè)用法還可以用于串聯(lián)復(fù)合賦值運(yùn)算。
表達(dá)式 是一個(gè)串聯(lián)賦值。按照賦值運(yùn)算符的過程,這個(gè)表達(dá)式等價(jià)于 d = (a *= (b += c))
。b
的原始數(shù)值是 2,那么 b += c
的結(jié)果就是將 b
改成 5(2 + 3);然后,整個(gè)表達(dá)式 b += c
的結(jié)果就是 5,然后帶入到 a *= ...
之中,即 a *= 5
。而 a
此時(shí)是 1,因此 a
被改成 5。接著,a *= ...
整個(gè)表達(dá)式的結(jié)果也是 5,并最后賦值給 d
,即執(zhí)行的是 d = ...
整個(gè)語(yǔ)句。
所以,d
最后是 5 這個(gè)數(shù)值。
Part 6 總結(jié)
本節(jié)我們學(xué)到了復(fù)合賦值運(yùn)算符的賦值過程,而且重新回顧了賦值的過程。另外,復(fù)合賦值和普通賦值過程都帶有一個(gè)結(jié)果,這個(gè)結(jié)果可以提供給別處使用。