前言:
本文一些內容是根據自己理解來寫的,沒有完全查證,不過應該也差不多了。
要想完全理解表達式,還是有很多東西要理解的,可謂博大精深。
在https://blog.csdn.net/nameofcsdn/article/details/105676294C/C++中的運算符和表達式 一文中,我已經提到了理解表達式最核心的幾個概念,編譯方式,運算符優先級,運算符結合性,還有特殊的自增自減運算符等等。
在https://blog.csdn.net/nameofcsdn/article/details/104603352運算符重載 一文中,我也提到,運算符重載不能改變運算符的優先級,結合性,以及預算對象數目。
然而,掌握了這些,依然不足以完全理解表達式的運算順序,特此補充。
首先重申一個重要概念,運算符的優先級和結合性,相當於是規定了如何添加括號,而不是規定運算順序。
比如,(a+b)*(c+d),是先計算a+b還是先計算c+d呢?這個運算順序不影響結果,但是(a=b)+(b=a)呢?這個運算順序就影響結果了。
這就是本文要討論的內容——同級表達式的運算順序,是C語言未定義的行爲,具體順序由編譯器決定。
不難發現,同級表達式的計算順序會影響結果的,有3類:
(1)func1+func2
2個函數的執行順序可能會有影響
(2)含賦值運算符的表達式
比如(a=b)+(b=a)
(3)含自增運算符++或者自減運算符--的表達式
自增自減我認爲是特殊的運算符,帶有賦值屬性,優先級又是個謎,這裏做一個單獨討論
(1)表達式中的自增自減
如果++和--的數目都不超過1,那是沒有歧義的,前綴式就是在表達式之前計算,後綴式就是在表達式之後計算,
但是有一個數目超過1,但是一個是前綴,一個是後綴,其實也是沒有歧義的。
在自增前綴、自增後綴、自減前綴、自減後綴這4個裏面,如果有一個的數量超過1,那就是未定義的行爲。
PS:有一個現象我依舊沒搞清楚,在我的編譯器中,
++--a 是合法的,++a-- 不合法,++(a--) 不合法,(++a)-- 合法,a++-- 不合法,(a++)-- 不合法
(2)函數傳參中的自增自減
比如func(a++,++a),應該是未定義的順序。
(3)cin和cout中的自增自減
int a=1;
cout<<a<<a++;
輸出:21
怎麼理解這個式子呢?
cout是一個對象,它重載了左移運算符<<,返回的是this指針指向的本身這個cout對象
因爲重載是不改變優先級和結合性的,所以上述代碼相當於
int a=1;
(cout<<a)<<(a++);
說實話,這個式子輸出21,是挺出乎我的意料的。
我猜測,這個可能是先把a++作爲參數傳進去了,再把a作爲參數傳進去了。
學海無涯啊,一個如此簡單的表達式,學編程6年了才發現自己根本不懂。