2010/11/4
關鍵字:算術表達式
零散知識點
1. 短路求值,&&和||.
2. bool字面值的true爲1,flase爲0
if (val) //正確
...
if (val == true)//錯誤
...
3. 位操作符操作signed的整型時,系統無法確保如何處理其操作數的符號位.所以強烈建議使用unsigned類型.
int n = -23;
n = n << 2; //有符號整型移位操作時可能會插入符號位的副本或0,視具體實現而定
4. 移位操作的右操作數不可以是負數,而且必須是嚴格小於左操作數位數的值.否則,操作的效果未定義.
int i = 1 << -3; //移位操作的右操作數不能爲負數,VC8下編譯警告
char c = 1 >> 9; //右操作數不能大於左操作數的最大位數,運算效果未定義,VC8下爲0
c = 1 << 9; //右操作數不能大於左操作數的最大位數,VC8下運算結果爲0
5. 建議使用bitset代替低級位操作.bitset對象不受unsigned數的位數影響,並且更容易閱讀、書寫,減少出錯的機會.
6. 不用刻意去記操作符的優先級,用()搞定,唯一的問題是不夠簡潔.
7. 前置自增和自減操作符效率高於後置的.儘量使用前置,也可以減少出錯的機會.
8. 逗號表達式的結果是最右邊表達式的值.
int j = i=0, i=5; //j爲5
sizeof
sizeof有三種語法形式
sizeof(type name)、sizeof(expr)、sizeof expr
sizeof計算結果依賴於所涉及的類型:
char *p = "123";
int i = sizeof p; //指針的大小4
i = sizeof *p; //指針所指向的對象的大小,4
i = sizeof "123"; //常量表達式的大小4,別忘了null
i = sizeof fun(); //函數返回值類型的大小
i = sizeof &fun; //函數地址的大小4
int &ref = i;
i = sizeof ref; //引用的大小即爲對象的大小4
i = sizeof char; //錯誤
i = sizeof(char); //正確1
int array[10];
i = sizeof array; //數組實際佔的內存的大小4*10
i = sizeof(*array); //數組第一個元素的大小,及元素類型的大小4
i = sizeof(array) / sizeof(*array); //數組內元素個數10
操作符計算順序
C++中規定了操作數計算順序的操作符有4個:&&、||、條件操作符(?:)、逗號操作符.其他都未定義.如果操作符順序未定,必須避免操作符的操作數涉及同一對象並改變其值的情況.
典型的陷阱:
int array[10];
int i = 0;
if (array[i++] > array[i])
//...
有兩種順序執行,視具體編譯器:
1. 先左後右.實際是array[i]與array[i+1]比較,詳細的計算順序爲
a. 計算array[i](左邊)
b. i自增
c. 計算array[i](右邊)
d. 比較左邊和右邊
2. 先右後左.實際是array[i]與array[i]比較,詳細的計算順序爲
a. 計算array[i](右邊)
b. 計算array[i](左邊)
c. i自增
d. 比較左邊和右邊
調整後的語句:
int array[10];
int i = 0;
if (array[i+1] > array[i])
//...
++i;
處理複合表達式的建議
1. 使用圓括號()控制操作符的順序和優先級
2. 如果要修改操作數的值,不要在同一語句的其他地方使用該操作數,可以用分開兩個獨立語句的方式避免.
第2條建議有個例外,如果一個子表達式修改操作數的值,結果會作用域另一個表達式,則是被允許的.例如*++iter,不過使用圓括號更好*(++iter).