C++表達式(From:C++Primer)

4.1 算術運算符

*     兩個整數相除的結果是整數。如果商含有小數部分,將被截掉。

*     %該操作符只能被應用在整數類型(charshortintlong)當兩個操作數都是正數時,結果爲正。但是,如果有一個(或兩個)操作數爲負,餘數的符號則取決於機器。因此,移植性無法保證。

*     算術異常:算術表達式的計算會導致不正確或未定義的值。例如:除零、溢出。

*     標準C++頭文件limits提供了與內置類型表示有關的信息,另外C++編譯系統也提供了標準C頭文件climitscfloat,它們定義了提供類似處理的預處理宏。如何使用這些頭文件來防止溢出和下溢,參見[PLAUGER92]的第4章和第5章。

*     浮點數的算術符還涉及精度的問題:在計算機中,當它表示一個數值時,只有固定的數位可以使用。浮點數加法、乘法和減法的結果精度受到底層數據類型的固有精度的影響。

4.2 等於、關係和邏輯操作符

*     二元關係操作符(小於或等於操作符)的缺點①:左右操作數的計算順序在標準CC++都是未定義的,因此計算過程必須是與順序無關的。

*     缺點②:要判斷ivaljvalkval是否各不相同。if ( ival != jval != kval )是錯的,需要寫成如下,if ( ival != jval && ival != kval && jval != kval )

4.3 賦值操作符

*     賦值和初始化都使用=一個對象只能被初始化一次,也就是在被定義的時候,但在程序中可以被賦值多次。

*     將不同類型的表達式賦值給一個對象時,右邊表達式的類型必須與左邊被賦值對象的類型完全匹配。編譯器會試着隱式地將右操作數的類型轉換成被賦值對象的類型,如果轉換是合法的,則編譯器會悄悄地進行(如果會引起精度損失,通常會給出一個警告)。如果不可能進行隱式的類型轉換,那麼賦值操作被標記爲編譯時錯誤。

*     賦值操作符的左操作數必須是左值——必須由一個相關聯的、可寫的地址值

4.4 遞增和遞減操作符

*     使用斷言#include <cassert>assert(條件表達式)

4.5 條件操作符

*     語法格式:expr1 ? expr2 : expr3

4.6 sizeof操作符

*     sizeof的作用是返回一個對象或類型名的字節長度

       三種形式:①sizeof(type_name) sizeof(object) sizeof object

*     返回類型是size_t,這是一種與機器相關的typedef的定義。在<cstddef>中定義

*     sizeof應用在數組上,返回的是數組的字節長度,而不是數組的長度

*     sizeof在編譯時刻計算,因此被看做常量表達式

4.7 newdelete表達式

*     沒有語法能爲動態分配的數組的元素指定一個顯示的初始集合,如果是類的對象數組,如果定義了缺省構造函數,那麼每一個元素都會使用缺省構造函數初始化。

*     將同一個對象釋放一次以上是不合法的,會在運行時產生一個未定義的行爲

4.9 逗號運算符

*     從左向右計算,結果是最右邊的值

4.10 位操作符

*     如果一個對象被用作一組位或位域的離散集合,稱此對象爲位向量(bitvector

*     位向量是用來記錄一組項目或條件的是/否信息的緊縮方法

*     編譯器中,類型聲明的限定修飾符,如constvolatile,有時就存儲在位向量中

*     iostream庫用位向量表示格式狀態,例如:輸出的整數是以十進制、十六進制等

*     支持位向量的兩種方式:

       ①使用內置整值來表示位向量,典型使用unsigned int

       ②標準庫bitset類,支持位向量的類抽象

建議使用標準庫的類抽象

*     用整值數據類型作爲位向量時,類型可以是有符號的,也可以是無符號的,強烈建議使      用無符號類型。因爲大多數的位操作中,符號位的處理是未定義的,因此在不同的實現    中符號位的處理可能會不同。在一個實現下可行的程序,在另一個實現有可能會失敗。

*     按位非操作符(~):翻轉操作數的每一位,每個1被設置爲0,而每個0被設置爲1

*     移位操作符(<<>>):將其左邊操作數的位向左或向右移動某些位。操作數中移到外    面的位被丟棄。左移操作符(<<)從右邊開始用0補空位。如果操作數是無符號數,則是右移操作符(>>)從左邊開始插入0,否則的話,它或者插入符號位的拷貝,或者插入0,具體由實現定義。

*     按位與(&):如果兩個操作數都含1,則結果是1。否則是0

*     按位異或(^):在每個位所在處,如果兩個操作數只有一個含有1,則結果該位爲1,否則爲0

*     按位或(|):如果兩個操作數有一個或者兩個含有1,則結果爲1,否則爲0.

*     通過使用常數1移位,再進行位操作來設置或取消某個位的值。

4.11 bitset操作

*     要使用bitset類,必須包含相關的頭文件。#include <bitset>

*     bitset三種聲明方式:

-      缺省定義中,只需簡單地指明位向量的長度。例如:bitset<32> bitvec;缺省情況,所有位都被初始化爲0

-      傳遞一個無符號參數。例如:bitset<32> bitvec2(0xffff);

-      傳遞一個代表01的字符串。例如:string bitval(“1010”); bitset<32> bitvec4(bitval);

*     轉換爲字符串:bitvec3.to_string();

*     轉換爲unsigned longto_ulong();

4.12 優先級

*     優先級順序:

       -      ::(全局域)、::(類域)、::(名字空間域)

       -      .(成員選擇)

       -      ->(成員選擇)

       -      [](下標)

       -      ()(函數調用)()(構造函數)

       -      ++(後置遞增)

       -      --(後置遞減)

       -      C++類型轉換

       -      ++/--(前置遞增、遞減)

       -      ~/!/-/+(按位非、邏輯非、一元減、一元加)

       -      *(解引用)

       -      &(取地址)

       -      ()(類型轉換)

       -      */%+-

       -      << >>

       -      比較 <<=>>===!=

       -      &^(異或)、|(按位或)、&&(邏輯與)、||(邏輯或)、

       -      ?:(條件運算符)、=(賦值)、複合賦值(*=/=

       -      throw

       -      ,(逗號運算符)

4.13 類型轉換

*     C++並不是把不同類型的值加在一起,而是提供一組算術轉換,以便在執行算術運算之前,將兩個操作數轉換成共同的類型。

*     轉換規則:小類型總是被提升成大類型,以防止精度丟失。這些轉換由編譯器自動完成,無需程序員介入----稱爲隱式類型轉換

*     doubleint的轉換不支持舍入,需要編寫程序來實現。

4.13_1 隱式類型轉換

*     C++定義了一組內置類型對象之間的標準轉換,在必要時它們被編譯器隱式地應用到對象上。隱式類型轉換髮生在下列這些典型的情況:

-      在混合類型的算術表達式中。這種情況下,最寬的數據類型成爲目標轉換類型稱爲算術轉換

-      用一種類型的表達式賦值給另一種類型的對象,這種情況,目標轉換類型是被賦值對象的類型

-      把表達式傳遞給一個函數調用,表達式的類型與形式參數的類型不相同。這種情況,目標轉換類型是形式參數的類型

-      從一個函數返回一個表達式,表達式的類型與返回類型不相同。這種情況下,目標轉換類型是函數的返回類型

4.13_2 算術轉換

*     算術轉換保證了二元操作符(如加法或乘法)的兩個操作數被提升爲共同的類型,然後再用它表示結果的類型。

*     爲了防止精度丟失,如果必要的話,類型總是被提升爲較寬的類型

*     所有含有小於整型的有序類型的算術表達式。在計算之前,其類型都會轉換成整型。對於比int小的整型,包括:charsigned charunsgined charshortunsgined short,如果類型的所有可能的值都能包容在int內,它們就會被提升爲int型,否則它們將被提升爲unsgined int

*     long類型的一般轉換有一個例外:如果一個操作數是long類型,另一個是unsigned int類型,只有機器上的long類型足夠長以便能夠存放unsigned int的所有值時,unsigned int纔會轉換爲long,否則兩個操作數都被提升爲unsigned long

4.13_3 顯示轉換

*     也被成爲強制類型轉換(cast

*     static_castdynamic_castconst_castreinterpret_cast

*     const_cast,去掉表達式的常量性(以及volatile對象的volatile性)

*     static_cast,類似於C風格的強制轉換。無條件轉換、靜態類型轉換。編譯器隱式執行的任何類型轉換都可以由static_cast完成。用於:

       -      基類和子類之間的轉換

       -      基本數據類型轉換

       -      把空指針轉換成目標類型的指針

       -      把任何類型的表達式轉換成void類型

       -      static_cast不能去掉constvolatile屬性

*     reinterpret_cast----轉換爲不同類型(不安全)時候使用。例如:

       double dval = 0.123;int *pi = reinterpret_cast<int*>(&dval);

4.13_4 舊式強制類型轉換

*     只有當爲C語言或標準C++之前的編譯器編寫代碼的時候用這個語法

*     兩種形式:

       -      type(expr)     // C++強制轉換符號

       -      (type)expr     // C強制轉換符號

*     對舊式強制轉換符號的支持是爲了對“在標準C++之前寫的程序”保持向後兼容性,以及提供與C語言兼容的符號

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