更新時(shí)間:2020年03月31日17時(shí)29分 來源:傳智播客 瀏覽次數(shù):
最近在知乎上看到一個(gè)c/c++運(yùn)算符連寫的問題,引發(fā)了諸多網(wǎng)友的討論,具體內(nèi)容如下圖:
乍一看,這句代碼很長,確實(shí)有些讓人糊涂,尤其是學(xué)習(xí)過python的同學(xué),對此寫法不太理解,今天我們一起來說一說。推薦了解傳智播客C++工程師培訓(xùn)課程。
優(yōu)先級
在c語言的表達(dá)式中,如果存在多個(gè)運(yùn)算符的時(shí)候,需要考慮數(shù)據(jù)的優(yōu)先級和結(jié)合方向的問題,例如:x = a + b * c -d在這個(gè)例子中,c語言的處理流程是:
1)先做乘法b*c,
2) 然后先做加法,后做減法
3)最后將計(jì)算結(jié)果賦值給x
我們驗(yàn)證一下:
1 + 2 *3 -4,結(jié)果為3,驗(yàn)證成功!
通過這個(gè)例子,我們可以總結(jié)如下:對于表達(dá)式
a op1 b op2 c ,它的運(yùn)行邏輯有兩種可能性:
1) 如果op1優(yōu)先級高于op2,則為:(a op1 b) op2 c
2) 如果op2優(yōu)先級高于op1,則為:a op1 (b op2 c)
如果op1與op2優(yōu)先級相同,則取決于結(jié)合方向。所謂結(jié)合方向指的是“從左至右”或“從右至左”。
結(jié)合方向
關(guān)于結(jié)合方向,我們一起來探討一下,還是剛剛的例子:x = a+b *c -d,這里面有二元運(yùn)算和賦值運(yùn)算,在c語言中:
· 賦值運(yùn)算的結(jié)合方向?yàn)椋簭挠抑磷?/p>
· 二元運(yùn)算符的結(jié)合方向?yàn)椋簭淖笾劣?/p>
我們假設(shè) b*c 的值為m,則,
· a + m -d 可以翻譯為 (a + m) -d,,結(jié)合方向是從左至右
· x = a + m -d 可以翻譯為: x = (a + m -d),結(jié)合方向是從右至左
在C/C++中,所有的運(yùn)算符都有明確的優(yōu)先級和結(jié)合方向定義,具體如下:
問題解答
鋪墊好了知識點(diǎn),我們回歸到最初網(wǎng)友的問題上,x +=5 ==4,
由于==號的優(yōu)先級大于+=號,所以這句代碼的邏輯可以解讀為:
1) x += (5 ==4)
2)即先判斷 5 == 4是否成立,此時(shí)不成立,返回false,即返回0
3)然后再計(jì)算x+=0,所以最終結(jié)果為0。
使用代碼驗(yàn)證一下:
執(zhí)行結(jié)果:
可以看到,輸出的結(jié)果依然為10,說明x添加的值為0,得到驗(yàn)證。
接下來,我們修改一下代碼,讓兩個(gè)數(shù)字比較值返回true,再次驗(yàn)證一下結(jié)果,如下圖:
執(zhí)行結(jié)果:
進(jìn)一步思考
對于這種x +=5 ==4表達(dá)式的編碼風(fēng)格,我們在開發(fā)中是不建議的,這樣寫雖然高效簡潔、正確運(yùn)行、看起來很酷,但是存在一個(gè)風(fēng)險(xiǎn),即需要人進(jìn)一步確認(rèn)這種表達(dá)式是否就是開發(fā)人員的真正意圖。我們在公司開發(fā)的時(shí)候,通常是很多同事協(xié)同開發(fā),當(dāng)同事看到這類代碼的時(shí)候,會產(chǎn)生懷疑,從而增加彼此的溝通成本。我們在編碼的時(shí),盡量不要讓人產(chǎn)生歧義,如果一定想要寫這種風(fēng)格的代碼,我建議加上括號,即:x +=(5 == 4),這樣語義更加明確,從而也避免造成同事因揣摩代碼而帶來的苦惱。
當(dāng)然,深刻的理解語法是我們必須要做到的,這種代碼常見于面試題中,對于考察面試者對語法的理解程度是個(gè)不錯的選擇。
猜你喜歡
C++學(xué)科之零基礎(chǔ)視頻教程
北京校區(qū)