表達式由一個或多個運算對象(operand)組成缀拭,對表達式求值將得到一個結(jié)果宋列。字面值和變量是最簡單的表達式帖蔓,其結(jié)果就是字面值和變量的值。
- C++語言定義了運算符作用于內(nèi)置類型和復(fù)合類型的運算對象時所執(zhí)行的操作姑廉。當(dāng)運算符作用于類類型的運算對象時,用戶可以自行定義其含義翁涤,稱之為重載運算符桥言。IO庫的>>和<<運算符以及string對象萌踱,vector對象和迭代器使用的運算符都是重載的運算符。
- 復(fù)合表達式是指有兩個或多個運算符的表達式号阿。求復(fù)合表達式的值需要將運算符和運算對象合理地組合在一起并鸵,優(yōu)先級和結(jié)合律決定了運算對象組合的方式。也就是決定了表達式中每個運算符對應(yīng)的運算對象來自表達式的哪一部分扔涧。
- 優(yōu)先級規(guī)定了運算對象的組合方式园担,但是沒有說明運算對象按照什么順序求值。比如:
int i=f1()*f2();
int i=0;
cout<<i<<" "<<++i<<endl;
我們無法知道f1和f2之間的調(diào)用順序扰柠,同時也無法知道是先求++i的值還是先求i的值粉铐,這樣的行為是未定義的,不可預(yù)知的卤档。
- 如果改變了某個運算對象的值蝙泼,在表達式的其他地方不要再使用這個運算對象。除非改變運算對象的子表達式本身就是另外一個子表達式的運算對象劝枣。
- 進行比較運算時除非比較的對象是布爾類型汤踏,否則不要使用布爾字面值true和false作為運算對象。
- 賦值運算符滿足右結(jié)合律
- 除非必須舔腾,否則不用自增自減運算符的后置版本溪胶,因為后置版本需要將原始值存儲下來以便返回。
- 形如*pbeg++的表達式是一種被廣泛使用且有效的寫法稳诚,表示先移動指針/迭代器哗脖,再取原來指向的對象。
- 解引用運算符*的優(yōu)先級低于點運算符扳还。
- sizeof運算符(這是一個關(guān)鍵字)返回一條表達式或一個類型名字所占的字節(jié)數(shù)才避。sizeof運算符滿足右結(jié)合律,其所得的值是一個size_t類型的常量表達式氨距,運算符的運算對象有兩種形式:
- sizeof (type)
- sizeof expr
對數(shù)組執(zhí)行sizeof運算得到整個數(shù)組所占空間的大小桑逝,等價于對數(shù)組中所有元素各執(zhí)行一次sizeof運算并將所得結(jié)果求和。注意俏让,sizeof運算不會把數(shù)組轉(zhuǎn)換成指針來處理楞遏。
所以可以用數(shù)組的大小除以單個元素的大小得到數(shù)組中元素的個數(shù):
constexpr size_t sz=sizeof(ia)/sizeof(*ia);
sizeof的返回值是一個常量表達式,所以我們可以用sizeof的結(jié)果聲明數(shù)組維度首昔。
- 對于算術(shù)隱式轉(zhuǎn)換來說寡喝,可以簡單地理解為往更大的類型轉(zhuǎn)換。
- 在大多數(shù)用到數(shù)組的表達式中勒奇,數(shù)組自動轉(zhuǎn)換成指向數(shù)組首元素的指針预鬓。當(dāng)數(shù)組被用作decltype關(guān)鍵字參數(shù),或者作為取地址符(&)撬陵,sizeof及typeid等運算符的運算對象時珊皿,上述轉(zhuǎn)換不會發(fā)生网缝。
- 類類型能定義由編譯器自動執(zhí)行的轉(zhuǎn)換,比如C風(fēng)格字符串轉(zhuǎn)換成string蟋定,在條件部分讀入istream等粉臊。
- 一個命名的強制類型轉(zhuǎn)換具有以下形式:cast-name<type>(expression);
- static_cast:任何具有明確定義的類型轉(zhuǎn)換驶兜,只要不包含底層const
- const_cast: 只能改變運算對象的底層const
- reinterpret_cast:為運算對象的位模式提供重新解釋(比如把int *解釋成char *)
- 避免使用強制類型轉(zhuǎn)換
- 在早期版本的C++語言中扼仲,顯式地進行強制類型轉(zhuǎn)換包含兩種形式:
- type (expr); 函數(shù)形式的
- (type) expr; C語言風(fēng)格的