第5章:表達式

轉載請註明原文出處:http://blog.csdn.net/roddick621

以下的知識點全部都是來自於C++ Primer 第四版,如果需要詳細瞭解的話,可以查看原版的書籍。


表達式由一個或多個操作數(operand)通過操作符(operator)組合而成,而每個表達式都會產生一個結果(result)。C++提供了一元操作符(unary operator),二元操作符(binary operator)和三元操作符(ternary operator)


1.算術操作符:

優先級越高越在前
操作數 功   能 用   法
+ 一元正號 + expr
- 一元負號 - expr
* 乘法 expr * expr
/ 除法 expr / expr
% 求餘 expr % expr
+ 加法 expr + expr
- 減法 expr - expr

2.關係操作符和邏輯操作符。

以下操作符都產生bool值
操作符 功  能 用   法
! 邏輯非 ! expr
< 小於 expr < expr
<= 小於等於 expr <= expr
> 大於 expr > expr
>= 大於等於 expr >= expr
== 等於 expr == expr
!= 不等 expr  != expr
&& 邏輯與 expr && expr
|| 邏輯或 expr || expr
不應該串聯使用關係操作符。


3.位操作符。

位操作符使用整型的操作數。它會講整數操作數視爲二進制位的集合,爲每一位提供檢驗和設置的功能。另外,這類操作符還可以用bitset類型的操作數。

位操作符
操作符 功  能 用  法
~ 位求反 ~ expr
<< 左移 expr1 << expr2
>> 右移 expr1 >> expr2
& 位與 expr1 & expr2
^ 位異或 expr1 ^ expr2
| 位或 expr1 | expr2

位操作符操縱的整數的類型可以是有符號的,也可以是無符號的。如果操作數是負數,則位操作符如何處理其操作數的符號依賴於機器。

左移操作符(<<)在右邊插入0以補充空位。

右移操作符(<<)如果其操作數是符號的數,則從左邊開始插入0;如果操作數是有符號數,則插入符號位的副本或者0值。

以爲操作的右操作數不可以是負數,而且必須是嚴格小於左操作數的值,否則,操作的效果未定義。


4.賦值操作符。

賦值操作符的左操作數必須是非const的左值。賦值表達式的值是左操作數的值,其結果的類型爲左操作數的類型。通常,賦值操作講其右操作數的值賦給左操作數,然而當左右操作數的類型不同時,該操作實現的類型轉換可能會修改被賦的值。

  1. 複製操作的右結合性
  2. 賦值操作具有低優先級
  3. 複合賦值操作符


5.自增和自減操作符

自增(++)和自減(--)提供了前置和後置兩種形式。

1.後置操作符返回未加1的值。(使用完變來那個的當前值,然後再加1)。

2.單個表達式中組合使用解引用和自增操作。

vector<int>::iterator iter=ivec.begin();
while (iter != ivec.end())
    cout << *iter++ <<endl;
//*iter++等效於*(iter++)。子表達式iter++是iter加1,然後返回iter原值的副本作爲該表達式的結果,因爲這裏姐操作*的操作數是iter未加1前的副本。

6.箭頭操作符。

可用箭頭操作符(->)來獲取類類型對象的成員。但是調用該操作符的必須是一個指向類類型對象的指針。


7.條件操作符。

條件操作符是C++中唯一的三元操作符。語法格式爲: cond ? expr1 : expr2 ;

避免條件操作符的深度嵌套

在輸出表達式中使用條件操作符。條件才操作符的優先級向當低,因爲最好嚴格的使用圓括號把條件操作符括起來。


8.sizeof操作符

sizeof操作符的作用是返回一個對象或類型名的長度,返回值的類型爲size_t。使用sizeof的結果部分地依賴所涉及的類型:

  • 對char類型或值爲char類型的表達式做sizeof操作保證得1。
  • 對引用類型做sizeof操作返回存放次類型對象所需的內存大小空間。
  • 對指針做sizeof操作將返回指針所需的內存大小。
  • 對數組做sizeof操作等效於將對其元素類型做sizeof操作的結果乘上數組元素的個數。

9.逗號操作符

逗號表達式是一組由逗號分隔的表達式,這些表達式從左向右計算。逗號表達式的結果是其最右表達式的值。


10.符合表達式的值

含有兩個或更多操作符的表達式成爲符合表達式,操作數和操作符的結合方式決定了整個表達式的值。結合方式取決於

1.優先級

2.結合性

3.求值順序


11.new和delete表達式

動態創建對象時,只需指定其數據類型,而不必爲對象命名,new表達式返回的指向新創建對象的指針。

1.動態創建對象的初始化

int *pi = new int(1024) // pi指向地址中存的值是1024

C++使用直接初始化語法規則初始化動態創建的對象。如果是提供了初值,new表達式分配到所需的內存後,用給定的初值初始化內存空間。

2.動態創建對象的默認初始化。

對於類類型的對象,用該類的默認構造函數初始化,而內置內省的對象則無初始化。

3.耗盡內存

4.撤銷動態創建的對象

動態創建的對象用完後,程序員必須顯式地將對象佔用的內存返回給自由存儲區。C++ 提供了delete表達式釋放指針對指向的地址空間。 eg : delete pi;

5.零指針的刪除

如果指針的值爲0,那麼在其上做delete操作是合法的。e.g. : int *pi =0; delete ip;

6.在delete之後,重設指針的值。

刪除指針後,該這真變成懸垂指針。懸垂指針指向曾經存放對象的內存,但該對象已經不存在了。

7.const對象的動態分配和回收。

const * pci = new const int(1024); //創建也初始化一個const對象。
與其他常來那個一樣,動態創建的const對象必須在創建時初始化,並且已經初始化,其值就不能再修改。對於類類型的const動態對象,如果該類提供了默認的構造函數,則此對象可隱式初始化,內置類型或爲提供默認構造函數的對象必須顯式初始化。

8.刪除const對象。

儘管程序員不可以改變const對象的值,但是可以撤銷對象本身。如同其他動態對象一樣,const動態對象也是使用刪除指針來釋放的:

delete pci; // delete a const object

12 類型轉換

如果兩個類型之間可以相互切換,則稱兩個類型相關。

有些轉換規則又編譯器自動執行的,成爲隱式類型轉換。爲了理解隱式類型轉換,我們需要知道他們在什麼時候發生,以及可能出現什麼類型的轉換。

12.1 何時發生隱式類型轉換。

編譯器在必要時將類型轉換規則應用到內置類型和類類型的對象上。

1.在混合類型的表達式中,其操作數轉換爲相同的類型

2.用做調教的表達式轉換爲bool類型

3.用以表達式初始化某個變量,或將以表達式複製給某個變量,則該表達式被轉換爲該變量的類型。


12.2 算術轉換

算術轉換保證在執行操作之前,將二元操作符的兩個操作數轉換爲同一類型,並使表達式的值也具有相同的類型。

最簡單的轉換爲整型提升:對於比int小的整型,包括char,signed char,unsigned char,short和unsigned short,如果該類型的所有值能夠包容在int內,他們就會提升爲int,否則他們將會提升爲unsigned int。如果bool值提升爲int,則false爲0,ture爲1。


12.3 其他隱式轉換

1.指針轉換:

使用數組時,大多數情況下數組都對自動轉換爲指向第一個元素的指針。C++還提供了另外兩種指針轉換:指向任意數據類型的指針都可以轉換爲void *類型;整型數值0可以轉換爲任意指針類型。

2.轉換爲bool類型:

算術值和指針值都可以轉換爲bool類型。如果指針或算術值爲0,則其bool值爲false,而其他值則爲true。

3.算術類型月bool類型的轉換:

可將算術類型轉換爲bool類型,bool類型也可以轉換爲int類型。講算術類型轉換爲bool類型,0轉換爲false,而其他值轉換爲true。將bool對象轉換爲算術類型時,true變成1,而false則爲0。

4.轉換與枚舉類型

C++自動將枚舉類型的對象和枚舉成員轉換爲整型,其轉換結果可用於任何要求使用整型數值的地方。

5.轉換爲const對象。

當使用非const對象初始化const對象的引用時,系統講非const對象轉換成const對象。此外,還可以將非const對象的地址轉換爲指向相關const類型的指針。

6.由標準庫類型定義的轉換。


12.4 顯示轉換

顯式轉換也成爲強制類型轉換(cast),包括以下列名字命名的強制類型轉換操作符:static_case , dynamic_case , const_cast 和 reinterpret_case


12.5 何時需要強制類型轉換

1.因爲要覆蓋通常的標準轉換。

2.可能存在多種轉換事,需要算則一種特定的類型轉換。


12.6 命名的強制類型轉換

格式爲case-name<type> (expression);   case-name爲以上的4個方法,type爲轉換的目標類型,expression則是被強制轉換的值。

1.dynamic_cast

dynamic_case支持運行事識別指針或引用對指向的對象。對dynamic_case的引用將在18.2節中進行。

2.const_cast

講轉換掉表達式的const性質。除了添加和刪除const特性,用const_cast符來執行其他任何類型轉換,都會引起編譯錯誤。

3.static_cast

編譯器隱式執行的任何類型轉換都可以由static_cast顯示完成。當需要將一個較大的算術類型賦值給較小的類型時,使用強制轉換非常有用。還可以通過static_cast來找回存放在void *指針中的值。

4.reinterpret_cast

reinterpret_cast通常爲操作數的位模式提供較低層次的重新解解釋。(本質上依賴於機器)





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章