C++表達式


冰哥哥最近在刷筆試題,昨晚問了一個沒有意義,但很有意思的一個問題:

求輸出:

#include<iosteam>
int main(){
     int a=10;
     a+=a-=a++;
     std::cout<<a<<std::endl;
     return 0;  
}

C++中,只有賦值運算符和單目運算符是右結合性,其他大部分的運算符都是左結合。

后綴運算符的優先級很高,僅次於"::“作用域解析符(與->操作符屬於同一優先級,所以不能寫出a->b++這樣的表達式)

於是,上面的運算表達式可以寫成:a+=a-=(a++);進一步,a+=a-=(10) a=a+1; a=a+1在某一時刻完成。

a++會改變自身的值,進一步影響程序中其他調用a的部分。在C++中,對變量值會進行改變的表達式被稱為具有修改環境的屬性。所有帶有修改環境屬性的程序語句(包括運算表達式、函數調用等),它們修改環境的影響將在下一個順序點被執行完畢(即語言保證這些影響:寄存器的值、內存的值、cache的值等等能夠在下一次被讀取前的某時刻被完成)。

所以,要明白a+=a-=(a++)最重要的就是明確a++對其他運算符的對象:a產生的影響在什么時候完成。

C/C++語言定義(語言的參考手冊)明確定義了順序點的概念。順序點位於:
1. 每個完整表達式結束時。完整表達式包括變量初始化表達式,表達式語句,return語句的表達式,以及條件、循環和switch語句的控制表達式(for頭部有三個控制表達式);
2. 運算符 &&、||、?: 和逗號運算符的第一個運算對象計算之后;
3. 函數調用中對所有實際參數和函數名表達式(需要調用的函數也可能通過表達式描述)的求值完成之后(進入函數體之前)。

注意前面的一句話,影響的完成是在下一個順序點之前。a+=a-=()不會觸發順序點,也就是a++對a的影響是在什么時候完成的,我們不得而知。

 

——————————————————————————————————————————————————————————————————————————————————————

討論了一圈回來,我們得到的答案是此式沒有答案。是啊,在真正的編寫代碼,寫出這樣的代碼完全是找虐和找罵,沒有正確性的保障,也沒有可讀取性和效率可言。

最后在結束時,再提一個關於C++運算符的誤區:

a++ + b++

a++和b++誰先做?不是從左到右,在C++中沒有規定大多數二元運算的兩個對象的計算順序(除了&&、|| 和 ,),也沒有規定函數參數和被調函數的計算順序。

在我們日常的程序設計中,一定不能出現依賴於修改值的先后順序的語句,因為C/C++ 語言的規定告訴我們,任何依賴於特定計算順序、依賴於在順序點之間實現修改效果的表達式,其結果都沒有保證。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM