[C++ Primer Note3] 表示式
表示式由一個或多個運算物件(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語言風格的