基礎
基本概念
- C++定義了:一元運算符和二元運算符
- 除此之外,還定義了作用於三個運算對象的三元運算符
- 函數調用也是一種特殊的運算符
(1)組合運算符和運算對象
- 首先要理解==優先級、結合律以及運算對象的求值順序==
(2)運算對象轉換
(3)重載運算符
(4)左值和右值
- 當一個對象被用作右值時,用的是對象的值
- 當一個對象被用作左值時,用的是對象的身份(內存中的未知)
優先級與結合律
- 括號無視優先級與結合律
- 優先級與結合律有
求值順序
(1)有4種運算符明確規定了求值順序
- (&&)、(||)、(?:)、(,)
算術運算符
一元運算符的級別最高,然後是乘除法,最低是加減法
計算結果溢出將導致不可預知的後果
取模(%)運算只支持整數類型
- 在除法運算中,兩個運算對象的符號相同則商爲正數,否則爲負;C++11新標準規定,商一律向0取整(不管正負,直接切除小數部分)
邏輯和關係運算符
- 關係運算符作用於算術類型或指針類型
- 邏輯運算符作用於任何能轉換成布爾的類型
(1)與和或運算符
- 注意“與”運算符的左側想檢測原則,右側不一定會檢測
(2)非運算符
(3)關係運算符
- 滿足左結合律,所以,只要關係運算符兩側的數據類型會馬上轉變爲布爾值,不能再進行連續比較了
(4)相等性測試和布爾字面值
賦值運算符
- 賦值運算符的左右兩個運算對象類型不同,則==右側運算對象將轉換成左側運算對象==
- C++11允許用花括號來初始化列表
- 轉換成左側運算對象時,所佔的空間不能大於目標類型空間
(1)賦值運算滿足右結合律
- 靠右的賦值運算符會先完成結合
(2)賦值運算符的優先級較低
- 在條件語句中,通常爲賦值運算符部分加上括號
(3)切勿混淆相等運算符和賦值運算符
(4)複合賦值運算符
- += -= %= 等等,只執行一次求值,省去了求值拷貝的賦值
遞增和遞減運算符
除非必須,否則不用遞增運算符的後置版本
(1)在一條語句中混用解引用和遞增運算符
auto pbeg=v.begin();
while (pbeg!=v.end()&&*pbeg>=0)
cout<<*pbeg++<<endl;
- 此時,由於後置遞增運算符的優先級高於解引用運算符,所以pebg++ 等價於 (pebg++)
- 由於將會返回未增加的副本,所以能夠實現,顯示第一個值,然後向後移動
(2)運算對象可按任意順序求值
= 不要將遞增運算同時符放在賦值運算符的右邊和左邊
成員運算訪問符
- 點運算符和箭頭運算符都可以用來訪問成員
- 其中,點運算符獲取類對象的一個成員
- 箭頭運算符,表達式 ptr->mem 等價於 (*ptr).mem
string s1="a string",*p=&s1;
auto n=s1.size(); //運行string對象s1的size成員
n=(*p).size(); //運行p所指對象的size成員
n=p->size(); //等價於(*p).size()
條件運算符
- 條件運算符(?:)的使用形式:
cond?expr1:expr2
(1) 嵌套的條件運算符
(2) 在輸出表達式中使用條件運算符
- 最好在cond表達式處加上括號,因爲條件運算符的優先級很低
位運算符
- 位運算符提供檢查和設置二進制位的功能
(1)移位運算符( >> 或 << )
unsigned char bits=0233;
bits<<8;
(2)位求反運算符(~)
unsigned char bits=0227;
~bits;
(3)位與、位或、位異或
(4)使用位運算符
- ==第138頁==實例
(5)移位運算符
- (<<)移位運算符比的優先級:低於算術運算符、高於關係運算符、賦值運算符、條件運算符
sizeof運算符
- 對char或者類型爲ichar的表達式執行sizeof運算,結果得1
- 對引用類型執行sizoof運算得被引用對象所佔空間的大小
- 對指針執行sizeof運算得到指針本身的所佔空間的大小
- 對解引用指針執行sizeof運算得到指針指向的對象所佔空間的大小,指針不需有效
逗號運算符
- 對於逗號運算符來說,首先對左側的表達式求值,然後將求值結果丟棄掉。逗號運算符真正的結果是右側表達式的值。如果右側運算對象是左值,那麼最終的求值結果也是左值
類型轉換
算術轉換
- 整型提升
- 無符號類型的運算對象
- 理解算數轉換
其他隱式類型轉換
- 數組轉換成指針
- 指針的轉換
- 整數值0或者字面值nullptr能轉換成任意指針類型
- 指向任意非常量的指針能轉換成void
- 指向任意對象的指針能轉換成const void*
- 轉換成布爾類型
- 轉換成常量
int i;
const int &j=i; //非常量轉換成const int的引用
const int *p=&i; //非常量的地址轉換成const的地址
int &r=j,*q=p; //錯誤,不允許const轉換成非常量
- 類類型定義的轉換
顯式轉換
- 命名的強制類型轉換,形式:
cast-name<type>(expression)
- 其中,cast-name是:static_cast、dynamic_cast、const_cast、reinterpret_cast
(1)static_cast
double slope=static_cast<double>(j) / i;
void* p=&d;
double *dp=static_cast<double*>(p);
(2)const_cast
- 只能改變運算對象的底層const
const char *pc;
char *p=const_cast<char*>(pc);
(3)reinterpret_cast
- 爲運算對象的位模式提供較低層次上的重新解釋
int *ip;
char 8pc=reinterpret_cast<char*>(ip);
- 舊的強制類型轉換
- type(expr); //函數形式的強制類型轉換
- (type)expr; //C語言風格的強制類型轉換