日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++primer 第 4 章 表达式 4.7条件运算符 4.8位运算符 4.9 sizeof运算符 4.10逗号运算符 4.11类型转换 4 . 1 2 运算符优先级表

發(fā)布時間:2023/12/13 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++primer 第 4 章 表达式 4.7条件运算符 4.8位运算符 4.9 sizeof运算符 4.10逗号运算符 4.11类型转换 4 . 1 2 运算符优先级表 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

4.7條件運算符

  • 條件運算符(?:)允許我們把簡單的if else邏輯嵌入到單個表達式當(dāng)中,條件運算符按照如下形式使用:
  • cond ? expr1 : expr2;其中cond是判斷條件的表達式,而expr1和expr2是兩個類型相同或可能轉(zhuǎn)換為某個公共類型的表達式。條件運算符的執(zhí)行過程是:首先求cond的值,如果條件為真對expr1求值并返回該值,否則對expr2求值并返回該值。舉個例子,我們可以使用條件運算符判斷成績是否合格:
  • string finalgrade = (grade<60) ?"fail" : "pass”;
  • 條件部分判斷成績是否小于60。如果小于,表達式的結(jié)果是"fail",否則結(jié)果是"pass"。有點類似于邏輯與運算符和邏輯或運算符(&&和||),條件運算符只對expr1和expr2中的一個求值。
  • 當(dāng)條件運算符的兩個表達式都是左值或者能轉(zhuǎn)換成同一種左值類型時,運算的結(jié)果是左值;否則運算的結(jié)果是右值。

嵌套條件運算符

  • 允許在條件運算符的內(nèi)部嵌套另外一個條件運算符。也就是說,條件表達式可以作為另外一個條件運算符的cond或expr
  • 舉個例子,使用一對嵌套的條件運算符可以將成績分成三檔:優(yōu)秀(highpass)>合格(pass)和不合格(fail):
  • finalgrade=(grade>90)?"highpassn:(grade<60)?“fail":"pass";
  • 第一個條件檢查成績是否在90分以上,如果是,執(zhí)行符號?后面的表達式,得到"highpass";如果否,執(zhí)行符號:后面的分支。這個分支本身又是一個條件表達式,它檢查成績是否在60分以下,如果是,得到"fail";否則得到"pass"。
  • 條件運算符滿足右結(jié)合律,意味著運算對象(一般)按照從右向左的順序組合。因此在上面的代碼中,靠右邊的條件運算(比較成績是否小于60)構(gòu)成了靠左邊的條件運算的:分支。
  • 隨著條件運算嵌套層數(shù)的增加,代碼的可讀性急劇下降.因此,條件運算的嵌套最好別超過兩到三層

4.8位運算符

  • 位運算符作用于整數(shù)類型的運算對象,并把運算對象看成是二進制位的集合。位運算符提供檢查和設(shè)置二進制位的功能,如17.2節(jié)(第640頁)將要介紹的,一種名為bitset的標準庫類型也可以表示任意大小的二進制位集合,所以位運算符同樣能用于bitset類型.

  • 一般來說,如果運算對象是''小整型”,則它的值會被自動提升(參見4.11.1節(jié),第142頁)成較大的整數(shù)類型。運算對象可以是帶符號的,也可以是無符號的。如果運算對象是帶符號的且它的值為負,那么位運算符如何處理運算對象的“符號位”依賴于機器。而且,此時的左移操作可能會改變符號位的值,因此是一種未定義的行為。
  • 關(guān)于符號位如何處理沒有明確的規(guī)定,所以強烈建議僅將位運算符用于處理無符號類型。

移位運算符

  • 之前在處理輸入和輸出操作時,我們已經(jīng)使用過標準IO庫定義的<<運算符和>>運算符的重載版本。這兩種運算符的內(nèi)置含義是對其運算對象執(zhí)行基于二進制位的移動操作,首先令左側(cè)運算對象的內(nèi)容按照右側(cè)運算對象的要求移動指定位數(shù),然后將經(jīng)過移動的(可能還進行了提升)左側(cè)運算對象的拷貝作為求值結(jié)果。其中,右側(cè)的運算對象一定不能為負,而且值必須嚴格小于結(jié)果的位數(shù),否則就會產(chǎn)生未定義的行為。二進制位或者向左移(?)或者向右移(?),移出邊界之外的位就被舍棄掉了:

  • 左移運算符(<<)在右側(cè)插入值為0的二進制位。右移運算符(>>)的行為則依賴于其左側(cè)運算對象的類型:如果該運算對象是無符號類型,在左側(cè)插入值為0的二進制位:
  • 如果該運算對象是帶符號類型,在左側(cè)插入符號位的副本或值為0的二進制位,如何選擇要視具體環(huán)境而定。

位求反運算符

  • 位求反運算符( ~) 將運算對象逐位求反后生成一個新值,將 1 置為0、將 0 置為1:
  • char類型的運算對象首先提升成int類型,提升時運算對象原來的位保持不變,往高位(highorderposition)添加0即可。因此在本例中,首先將bits提升成int類型,增加24個高位0,隨后將提升后的值逐位求反。

位與、位或、位異或運算符

  • 與(&)、或(|)、異或(^)運算符在兩個運算對象上逐位執(zhí)行相應(yīng)的邏輯操作:

  • 對于位與運算符(&)來說,如果兩個運算對象的對應(yīng)位置都是1則運算結(jié)果中該位為1,否則為0。對于位或運算符(|)來說,如果兩個運算對象的對應(yīng)位置至少有一個為1則運算結(jié)果中該位為1,否則為0。對于位異或運算符(^)來說,如果兩個運算對象的對應(yīng)位置有且只有一個為1則運算結(jié)果中該位為1,否則為0

移位運算符(又叫10運算符)滿足左結(jié)合律

  • 盡管很多程序員從未直接用過位運算符,但是幾乎所有人都用過它們的重載版本來進行10操作。重載運算符的優(yōu)先級和結(jié)合律都與它的內(nèi)置版本一樣,因此即使程序員用不到移位運算符的內(nèi)置含義,也仍然有必要理解其優(yōu)先級和結(jié)合律。
  • 因為移位運算符滿足左結(jié)合律,所以表達式

4.9 sizeof運算符

  • sizeof運算符返回一條表達式或一個類型名字所占的字節(jié)數(shù)。sizeof運算符滿足右結(jié)合律,其所得的值是一個size_t類型(參見3.5.2節(jié),第 103頁)的常量表達式(參 見2.4.4節(jié),第 58頁)。運算符的運算對象有兩種形式:
  • sizeof (type)
  • sizeof expr

  • 這些例子中最有趣的一個是sizeof *p。首先,因為sizeof滿足右結(jié)合律并且與*運算符的優(yōu)先級一樣,所以表達式按照從右向左的順序組合。也就是說,它等價于sizeof(*p)
  • 其次,因為sizeof不會實際求運算對象的值,所以即使p是一個無效(即未初始化)的指針(參見2.3.2節(jié),第47頁)也不會有什么影響。在sizeof的運算對象中解引用一個無效指針仍然是一種安全的行為,因為指針實際上并沒有被真正使用。
  • sizeof不需要真的解引用指針也能知道它所指對象的類型。新標準允許我們使用作用域運算符來獲取類成員的大小。通常情況下只有通過類的對象才能訪問到類的成員,但是sizeof運算符無須我們提供一個具體的對象,因為要想知道類成員的大小無須真的獲取該成員。
  • sizeof運算符的結(jié)果部分地依賴于其作用的類型:
  • 對char或者類型為char的表達式執(zhí)行sizeof運算,結(jié)果得1。
  • 對引用類型執(zhí)行sizeof運算得到被引用對象所占空間的大小。
  • 對指針執(zhí)行sizeof運算得到指針本身所占空間的大小。
  • 對解引用指針執(zhí)行sizeof運算得到指針指向的對象所占空間的大小,指針不需有效。
  • 對數(shù)組執(zhí)行sizeof運算得到整個數(shù)組所占空間的大小,等價于對數(shù)組中所有的元素各執(zhí)行一次sizeof運算并將所得結(jié)果求和。注意,sizeof運算不會把數(shù)組轉(zhuǎn)換成指針來處理。
  • 對string對象或vector對象執(zhí)行sizeof運算只返回該類型固定部分的大小,不會計算對象中的元素占用了多少空間。
  • 因為執(zhí)行sizeof運算能得到整個數(shù)組的大小,所以可以用數(shù)組的大小除以單個元素的大小得到數(shù)組中元素的個數(shù):

?

4.10逗號運算符

  • 逗號運算符含有兩個運算對象,按照從左向右的順序依次求值。和邏輯與、邏輯或以及條件運算符一樣,逗號運算符也規(guī)定了運算對象求值的順序。
  • 對于逗號運算符來說,首先對左側(cè)的表達式求值,然后將求值結(jié)果丟棄掉。逗號運算符真正的結(jié)果是右側(cè)表達式的值。如果右側(cè)運算對象是左值,那么最終的求值結(jié)果也是左值。
  • 逗號運算符經(jīng)常被用在for循環(huán)當(dāng)中:

?

4.11類型轉(zhuǎn)換

  • 在C++語言中,某些類型之間有關(guān)聯(lián)。如果兩種類型有關(guān)聯(lián),那么當(dāng)程序需要其中一種類型的運算對象時,可以用另一種關(guān)聯(lián)類型的對象或值來替代。換句話說,如果兩種類
  • 型可以相互轉(zhuǎn)換(conversion),那么它們就是關(guān)聯(lián)的。舉個例子,考慮下面這條表達式,它的目的是將ival初始化為6:
  • int ival = 3.541 + 3; / / 編譯器可能會警告該運算損失了精度
  • 加法的兩個運算對象類型不同:3.541的類型是double,3的類型是int。C++語言不會直接將兩個不同類型的值相加,而是先根據(jù)類型轉(zhuǎn)換規(guī)則設(shè)法將運算對象的類型統(tǒng)一后再求值。上述的類型轉(zhuǎn)換是自動執(zhí)行的,無須程序員的介入,有時甚至不需要程序員了解。因此,它們被稱作隱式轉(zhuǎn)換(implicitconversion)。算術(shù)類型之間的隱式轉(zhuǎn)換被設(shè)計得盡可能避免損失精度。很多時候,如果表達式中既有整數(shù)類型的運算對象也有浮點數(shù)類型的運算對象,整型會轉(zhuǎn)換成浮點型。在上面的例子中,3轉(zhuǎn)換成double類型,然后執(zhí)行浮點數(shù)加法,所得結(jié)果的類型是double。接下來就要完成初始化的任務(wù)了。在初始化過程中,因為被初始化的對象的類型無法改變,所以初始值被轉(zhuǎn)換成該對象的類型。仍以這個例子說明,加法運算得到的double類型的結(jié)果轉(zhuǎn)換成int類型的值,這個值被用來初始化ival。由double向int轉(zhuǎn)換時忽略掉了小數(shù)部分,上面的表達式中,數(shù)值6被賦給了ival。

何時發(fā)生隱式類型轉(zhuǎn)換

  • 在下面這些情況下,編譯器會自動地轉(zhuǎn)換運算對象的類型:
  • 在大多數(shù)表達式中,比int類型小的整型值首先提升為較大的整數(shù)類型。
  • 在條件中,非布爾值轉(zhuǎn)換成布爾類型。
  • 初始化過程中,初始值轉(zhuǎn)換成變量的類型;在賦值語句中,右側(cè)運算對象轉(zhuǎn)換成左側(cè)運算對象的類型。
  • 如果算術(shù)運算或關(guān)系運算的運算對象有多種類型,需要轉(zhuǎn)換成同一種類型。
  • 如第6章將要介紹的,函數(shù)調(diào)用時也會發(fā)生類型轉(zhuǎn)換。

4.11.1算術(shù)轉(zhuǎn)換

  • 算術(shù)轉(zhuǎn)換(arithmeticconversion)的含義是把一種算術(shù)類型轉(zhuǎn)換成另外一種算術(shù)類型,這一點在2.1.2節(jié)(第32頁)中已有介紹。算術(shù)轉(zhuǎn)換的規(guī)則定義了一套類型轉(zhuǎn)換的層次,其中運算符的運算對象將轉(zhuǎn)換成最寬的類型。例如,如果一個運算對象的類型是long double,那么不論另外一個運算對象的類型是什么都會轉(zhuǎn)換成long double。還有一種更普遍的情況,當(dāng)表達式中既有浮點類型也有整數(shù)類型時,整數(shù)值將轉(zhuǎn)換成相應(yīng)的浮點類型。

整型提升

  • 整型提升 ,負責(zé)把小整數(shù)類型轉(zhuǎn)換成較大的整數(shù)類型。對于bool、char、signedchar、unsignedchar、short和unsignedshort等類型來說,只要它們所有可能的值都能存在int里,它們就會提升成int類型;否則,提升成unsigned int類型。就如我們所熟知的,布爾值false提升成0、true提升成1。較大的char類型(wchar_t、charl6_t、char32_t)提升成int、unsignedint、long、unsigned long、long long和unsigned long long中最小的一種類型,前提是轉(zhuǎn)換后的類型要能容納原類型所有可能的值。

無符號類型的運算對象

  • 如果某個運算符的運算對象類型不一致,這些運算對象將轉(zhuǎn)換成同一種類型。但是如果某個運算對象的類型是無符號類型,那么轉(zhuǎn)換的結(jié)果就要依賴于機器中各個整數(shù)類型的相對大小了。像往常一樣,首先執(zhí)行整型提升。如果結(jié)果的類型匹配,無須進行進一步的轉(zhuǎn)換。如果兩個(提升后的)運算對象的類型要么都是帶符號的、要么都是無符號的,則小類型的運算對象轉(zhuǎn)換成較大的類型。
  • 如果一個運算對象是無符號類型、另外一個運算對象是帶符號類型,而且其中的無符號類型不小于帶符號類型,那么帶符號的運算對象轉(zhuǎn)換成無符號的。例如,假設(shè)兩個類型分別是unsigned int和int,則int類型的運算對象轉(zhuǎn)換成unsigned int類型。需要注意的是,如果int型的值恰好為負值,其結(jié)果將以2.1.2節(jié)(第32頁)介紹的方法轉(zhuǎn)換,并帶來該節(jié)描述的所有副作用。
  • 剩下的一種情況是帶符號類型大于無符號類型,此時轉(zhuǎn)換的結(jié)果依賴于機器。如果無符號類型的所有值都能存在該帶符號類型中,則無符號類型的運算對象轉(zhuǎn)換成帶符號類型。如果不能,那么帶符號類型的運算對象轉(zhuǎn)換成無符號類型。例如,如果兩個運算對象的類型分別是long和unsigned int,并且int和long的大小相同,則long類型的運算對象轉(zhuǎn)換成unsignedint類型;如果long類型占用的空間比int更多,則unsigned int類型的運算對象轉(zhuǎn)換成long類型。

理解算術(shù)轉(zhuǎn)換

  • 要想理解算術(shù)轉(zhuǎn)換,辦法之一就是研究大量的例子:

  • 在第一個加法運算中,小寫字母,a,是char型的字符常量,它其實能表示一個數(shù)字值(參見2.1.1節(jié),第30頁)。到底這個數(shù)字值是多少完全依賴于機器上的字符集,在我們的環(huán)境中,a,對應(yīng)的數(shù)字值是97。當(dāng)把,a,和一個longdouble類型的數(shù)相加時,char類型的值首先提升成int類型,然后int類型的值再轉(zhuǎn)換成longdouble類型。最終我們把這個轉(zhuǎn)換后的值與那個字面值相加。最后的兩個含有無符號類型值的表達式也比較有趣,它們的結(jié)果依賴于機器

4.11.2其他隱式類型轉(zhuǎn)換

  • 除了算術(shù)轉(zhuǎn)換之外還有幾種隱式類型轉(zhuǎn)換,包括如下幾種。
  • 數(shù)組轉(zhuǎn)換成指針:在大多數(shù)用到數(shù)組的表達式中,數(shù)組自動轉(zhuǎn)換成指向數(shù)組首元素的指針:

  • 當(dāng)數(shù)組被用作decltype關(guān)鍵字的參數(shù),或者作為取地址符(&)、sizeof及typeid(第19.2.2節(jié),732頁將介紹)等運算符的運算對象時,上述轉(zhuǎn)換不會發(fā)生。同樣的,如果用一個引用來初始化數(shù)組(參見3.5.1節(jié),第102頁),上述轉(zhuǎn)換也不會發(fā)生。我們將在6.7節(jié)(第221頁)看到,當(dāng)在表達式中使用函數(shù)類型時會發(fā)生類似的指針轉(zhuǎn)換。
  • 指針的轉(zhuǎn)換:C++還規(guī)定了幾種其他的指針轉(zhuǎn)換方式,包括常量整數(shù)值0或者字面值nullptr能轉(zhuǎn)換成任意指針類型;指向任意非常量的指針能轉(zhuǎn)換成void*;指向任意對象的指針能轉(zhuǎn)換成const void*.15.2.2節(jié)(第530頁)將要介紹,在有繼承關(guān)系的型間還有另外一種指針轉(zhuǎn)換的方式。

4.11.3顯式轉(zhuǎn)換

  • 有時我們希望顯式地將對象強制轉(zhuǎn)換成另外一種類型。例如,如果想在下面的代碼中執(zhí)行浮點數(shù)除法:
  • int i,j;? ?double? ?slope? = i/j;
  • 就要使用某種方法將i和/或j顯式地轉(zhuǎn)換成double,這種方法稱作強制類型轉(zhuǎn)換(cast)
  • 然有時不得不使用強制類型轉(zhuǎn)換,但這種方法本質(zhì)上是非常危險的

命名的強制類型轉(zhuǎn)換

  • 一個命名的強制類型轉(zhuǎn)換具有如下形式:
  • cast-name<type> (expression); 其中,type是轉(zhuǎn)換的目標類型而expression是要轉(zhuǎn)換的值。如果是引用類型 ,則結(jié)果是左值 。?cast-name是static cast、dynamic cast、const cast和
    reinterpret_cast中的一種。dynamic_cast支持運行時類型識別,我們將在19.2節(jié)(第730頁)其做更詳細的介紹。cast-name指定了執(zhí)行的是哪種轉(zhuǎn)換。

reinterpret__cast

  • reinterpret_cast通常為運算對象的位模式提供較低層次上的重新解釋。舉個例子,假設(shè)有如下的轉(zhuǎn)換

  • reinterpret_cast本質(zhì)上依賴于機器。要想安全地使用reinterpret_cast必須對涉及的類型和編譯器實現(xiàn)轉(zhuǎn)換的過程都非常了解;

?4 . 1 2 運算符優(yōu)先級表

?

總結(jié)

以上是生活随笔為你收集整理的C++primer 第 4 章 表达式 4.7条件运算符 4.8位运算符 4.9 sizeof运算符 4.10逗号运算符 4.11类型转换 4 . 1 2 运算符优先级表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。