運算符基本概念
1.對于含有多個運算符的復雜表達式來說,要想理解它的含義首先要理解運算級、結合律、以及運算對象的求值順序。
2.重載運算符:當運算符作用于類類型的運算對象時,用戶可以自定義其含義。在使用重載運算符時,其包括運算對象的類型和返回值的類型都是由該運算符定義的;但是運算對象的個數、運算符的優先級和結合律都是無法改變的。
3.C++中左值右值的含義不像C語言中那么簡單,做一個歸納:當一個對象被用作右值的時候用的是對象的值(內容);當對象被用作左值的時候,用的是對象的身份(在內存中的位置)。有幾個熟悉的運算符是要用到左值的:賦值運算符、取地址符、某些解引用運算符及遞增遞減運算符和下標運算符。
4.使用decltype關鍵字時左值和右值也有所不同。若表達式求值結果是一個左值,將得當引用類型。
5.對于那些沒有指定執行順序的運算符來說,如果表達式指向并修改了同一個對象,將會引發錯誤并產生未定義的行為。運算對象的求值順序與優先級和結合律無關。有四種運算符明確規定了求值順序:(&&)、(||)、(?:)、(,)。
6.處理復合表達式的兩個經驗:
①.拿不準時最好用括號讓表達式組合關系符合程序邏輯要求。
②.如果改變了某個運算對象的值,在表達式的其他地方不要再使用這個運算對象。(重要例外:當改變運算對象的子表達式本身就是另一個子表達式的運算對象時除外)
運算符
1.算數運算符的運算對象和求值結果都是右值。在表達式求值之前,小整數類型的運算對象被提升成較大的整數類型,所有運算對象最終會轉換成同一類型。
2.取余運算的運算對象必須是整數類型,且m%(-n)與m%n等價。
3.關系運算符作用于指針類型,邏輯運算符作用于任意能轉換成布爾值的類型。
4.對邏輯與和邏輯或運算符來說,當且僅當左側運算對象無法確定表達式的結果時才會計算右側對象的值,這種策略稱為短路求值。
5.賦值運算符的左側對象必須是一個可修改的左值,賦值運算的結果是它的左側運算對象并且是一個左值,且結果類型是左側運算對象的類型。
6.因為賦值運算符的優先級低于關系運算符的優先級,所以在條件語句中賦值部分通常應該加上括號。
7.養成使用前置遞增遞減運算符的習慣,這樣不僅不需要擔心性能的問題,而且更重要的是寫出的代碼會更符合編程的初衷。
8.因為遞增遞減運算符會改變運算對象的值,所以要提防在復合表達式中錯用這兩個運算符。
9.當條件運算符的兩個表達式都是左值或者能轉換成同一種左值類型時運算結果為左值,否則運算的結果是右值。
10.條件運算符可以嵌套。
11.條件運算符的優先級非常低,因此當一條長表達式中嵌套了條件運算子表達式時通常要在它兩端加上括號。
12.位運算符作用于整數類型的運算對象,并把運算對象看成二進制位的集合。
13.關于符號位如何處理沒有明確規定,所以強烈建議僅將位運算符用于處理無符號類型。
14.對位運算符來說如果運算對象是小整型,則它的值會被提升。
15.靈活運用位運算符可以達到意想不到的效果,例如可以用char存儲32個數據。
16.sizeof運算符有兩種形式:sizeof (type) 和 sizeof exPR。
17.sizeof并不實際計算其運算對象的值,在sizeof中解引用一個無效指針仍然是一種安全的行為,因為指針實際上并沒有被真正使用。
18.對string和vector對象執行sizeof運算只返回該類型固定的大小,不會計算對象中的元素占用了多少空間。
類型轉換
1.隱式轉換:
①.算數轉換,其中注意整數的提升和無符號類型的運算對象
②.數組轉換成指針
③.指針轉換,包括整數常量0或字面值nullptr轉換成任意指針類型、指向任意非常量的指針轉換成void*以及指向任意對象的指針能轉換成const void*
④.轉換成布爾類型
⑤.轉換成常量
⑥.類類型定義的轉換
2.顯示轉換(命名的強制):
①.dynamic_cast
②.static_cast:當需要把一個較大的算數類型賦給較小類型或對于編譯器無法自動執行的類型轉換非常有用,當將void*類型指針強制轉換為原來類型時,必須確保轉換后所得的類型就是指針所指的類型
③.const_cast:只能改變運算對象的底層const
④.reinterpret_cast:盡量不要使用
盡量避免使用強制類型轉換
新聞熱點
疑難解答
圖片精選