表達式由一個或多個運算對象(operand)組成,對表達式求值將得到一個結果。字面值和變量是最簡單的表達式,其結果就是字面值和變量的值。
- C++語言定義了運算符作用于內置類型和復合類型的運算對象時所執行的操作。當運算符作用于類類型的運算對象時,用戶可以自行定義其含義,稱之為重載運算符。IO庫的>>和<<運算符以及string對象,vector對象和迭代器使用的運算符都是重載的運算符。
- 復合表達式是指有兩個或多個運算符的表達式。求復合表達式的值需要將運算符和運算對象合理地組合在一起,優先級和結合律決定了運算對象組合的方式。也就是決定了表達式中每個運算符對應的運算對象來自表達式的哪一部分。
- 優先級規定了運算對象的組合方式,但是沒有說明運算對象按照什么順序求值。比如:
int i=f1()*f2();
int i=0;
cout<<i<<" "<<++i<<endl;
我們無法知道f1和f2之間的調用順序,同時也無法知道是先求++i的值還是先求i的值,這樣的行為是未定義的,不可預知的。
- 如果改變了某個運算對象的值,在表達式的其他地方不要再使用這個運算對象。除非改變運算對象的子表達式本身就是另外一個子表達式的運算對象。
- 進行比較運算時除非比較的對象是布爾類型,否則不要使用布爾字面值true和false作為運算對象。
- 賦值運算符滿足右結合律
- 除非必須,否則不用自增自減運算符的后置版本,因為后置版本需要將原始值存儲下來以便返回。
- 形如*pbeg++的表達式是一種被廣泛使用且有效的寫法,表示先移動指針/迭代器,再取原來指向的對象。
- 解引用運算符*的優先級低于點運算符。
- sizeof運算符(這是一個關鍵字)返回一條表達式或一個類型名字所占的字節數。sizeof運算符滿足右結合律,其所得的值是一個size_t類型的常量表達式,運算符的運算對象有兩種形式:
- sizeof (type)
- sizeof expr
對數組執行sizeof運算得到整個數組所占空間的大小,等價于對數組中所有元素各執行一次sizeof運算并將所得結果求和。注意,sizeof運算不會把數組轉換成指針來處理。
所以可以用數組的大小除以單個元素的大小得到數組中元素的個數:
constexpr size_t sz=sizeof(ia)/sizeof(*ia);
sizeof的返回值是一個常量表達式,所以我們可以用sizeof的結果聲明數組維度。
- 對于算術隱式轉換來說,可以簡單地理解為往更大的類型轉換。
- 在大多數用到數組的表達式中,數組自動轉換成指向數組首元素的指針。當數組被用作decltype關鍵字參數,或者作為取地址符(&),sizeof及typeid等運算符的運算對象時,上述轉換不會發生。
- 類類型能定義由編譯器自動執行的轉換,比如C風格字符串轉換成string,在條件部分讀入istream等。
- 一個命名的強制類型轉換具有以下形式:cast-name<type>(expression);
- static_cast:任何具有明確定義的類型轉換,只要不包含底層const
- const_cast: 只能改變運算對象的底層const
- reinterpret_cast:為運算對象的位模式提供重新解釋(比如把int *解釋成char *)
- 避免使用強制類型轉換
- 在早期版本的C++語言中,顯式地進行強制類型轉換包含兩種形式:
- type (expr); 函數形式的
- (type) expr; C語言風格的