C++ Primer 第四章筆記
Chapter 4 Expressions
4.1 基礎
4.1.1 基本概念
左值和右值
一個左值表示式的求職結果是一個物件或者一個函式,然而以常量物件為代表的某些左值實際上不能作為賦值語句的左側運算物件。當一個物件用作右值的時候,用的是物件的值(內容);當物件被用作左值的時候,用的是物件的身份(在記憶體中的位置)。
4.1.3 求值順序
對於某些沒有執行順序的運算子來說,如果表示式指向並修改了同一個物件,將會引發錯誤併產生未定義的行為,例如,<< 運算子沒有明確規定何時以及如何對運算物件求值,因此下面的輸出表達式是未定義的:
int i = 0;
cout << i << " " << ++i << endl; // undefined
因為程式是未定義的,所以我們無法推斷它的行為。
4.2 算術運算子
int i = 1024;
int k = -i; // i is -1024
bool b = true;
bool b2 = -b; // b2 is true!
布林值不應該參與運算,-b 就是一個很好的例子。
對大多數運算來說,布林型別的運算物件被提升為 int 型別。如上所示,不二變數 b 的值為真,參與運算時將被提升為整數值 1,對它求負後的結果為 -1。將 -1 再轉換為布林值並將其作為 b2 的初始值,顯然這個初始值不等於 0,轉換成布林值後應該為 -1。所以,b2 為真!
當計算的結果超出該型別所能表示的範圍時就會產生溢位。該值會發生環繞,如:
short short_value = 32767; // max value if shorts are 16 bits
short_value += 1; // this calculation overflows
cout << "short_value: " << short_value << endl;
// short_value: -32768
4.8 位運算子
位運算子作用於整數型別的運算物件,並把運算物件看成是二進位制的集合。位運算子提供檢查和設定二進位制位的功能。如果運算物件是帶符號的且它的值是負的,那麼位運算子如何處理運算物件的 “符號位” 依賴於機器。而且,此時的左移操作可能會改變符號位的值,因此是一種未定義的行為。
移位運算子
<< 運算子和 >> 運算子的內建含義是對其運算物件執行基於二進位制位的移動操作,首先令左側運算物件的內容按照右側運算物件的要求移動指定位數,然後經過移動的(可能還進行了提升)左側運算物件的拷貝作為求值結果。其中,右側運算物件一定不能為負,而且值必須嚴格小於結果的位數,否則將會產生未定義的行為。二進位制或者向左移(<<)或者向右移(>>),移出邊界之外的位就被捨棄掉了。
位求反運算子
將運算物件逐位求反後生成一個新值,將 1 置為 0、將 0 置為 1。
位與、位或、位異或運算子
在兩個運算物件上執行相應的邏輯操作:
4.9 sizeof 運算子
sizeof 運算子返回一條表示式或一個型別名字所佔的位元組數。sizeof 運算子滿足右結合律,其所得的值是一個 size_t 型別的常量表達式:
sizeof 運算子的結果部分地依賴於其作用的型別: