官术网_书友最值得收藏!

2.1 基本類型

基本類型是最基本的對(duì)象類型,包括整數(shù)、浮點(diǎn)數(shù)、字符、布爾、bytesize_tvoid。有些人把基本類型稱為原始類型或內(nèi)置類型,因?yàn)樗鼈兪呛诵恼Z(yǔ)言的一部分,幾乎總是使用的。這些類型可以在任何平臺(tái)上工作,但它們的特性,如大小和內(nèi)存布局,則取決于具體的實(shí)現(xiàn)。

基本類型取得了一種平衡。一方面,它們?cè)噲D映射從C++結(jié)構(gòu)到計(jì)算機(jī)硬件的直接關(guān)系;另一方面,它們簡(jiǎn)化了跨平臺(tái)代碼的編寫,允許程序員寫一次代碼就可以在許多平臺(tái)上運(yùn)行。下面的幾節(jié)將詳細(xì)介紹這些基本類型。

2.1.1 整數(shù)類型

整數(shù)類型存儲(chǔ)的是整數(shù)。四種大小的整數(shù)類型分別是short intint、long intlong long int。每個(gè)類型都可以是有符號(hào)(signed)或無(wú)符號(hào)(unsigned)的。有符號(hào)變量可以是正數(shù)、負(fù)數(shù)或零,無(wú)符號(hào)變量必須是非負(fù)數(shù)。

整數(shù)類型默認(rèn)是有符號(hào)的int類型,這意味著我們可以在程序中使用簡(jiǎn)寫符號(hào)shortlonglong long,而不是short intlong intlong long int。表2-1列出了所有可用的C++整數(shù)類型,展示了每種類型有無(wú)符號(hào),在不同平臺(tái)上的大小(以字節(jié)為單位),以及每種類型的格式指定符。

表2-1 整數(shù)類型及其大小和格式指定符

注意,不同平臺(tái)下整數(shù)類型的大小不同:64位Windows和Linux/Mac的long大小不同(分別為4字節(jié)和8字節(jié))。

通常情況下,編譯器會(huì)在格式指定符和整數(shù)類型不匹配時(shí)發(fā)出警告。但是,在printf語(yǔ)句中使用格式指定符時(shí),必須確保它們是正確的。這里列出格式指定符是為了讓你可以在后面的例子中向控制臺(tái)打印整數(shù)。

注意 如果想確保整數(shù)的大小,那么可以使用<cstdint>庫(kù)中的整數(shù)類型。例如,如果你需要一個(gè)正好是8、16、32或64位的有符號(hào)整數(shù),則可以使用int8_tint16_tint32_tint64_t。你可以在這個(gè)庫(kù)中找到速度最快、最小、最大、有符號(hào)和無(wú)符號(hào)整數(shù)類型,以滿足各種要求。但由于這個(gè)頭文件并不總是在每個(gè)平臺(tái)上都可用,因此你應(yīng)該只在沒(méi)有其他選擇時(shí)使用cstdint類型。

字面量是程序中的硬編碼值。我們可以使用四種硬編碼的、整數(shù)字面量表示:

? 二進(jìn)制:使用前綴0b

? 八進(jìn)制:使用前綴0

? 十進(jìn)制:這是默認(rèn)的。

? 十六進(jìn)制:使用前綴0x

這是同一組整數(shù)的四種不同寫法。例如,代碼清單2-1顯示了如何使用每一種非十進(jìn)制表示來(lái)賦值整數(shù)變量。

代碼清單2-1 給幾個(gè)整數(shù)變量賦值并以適當(dāng)?shù)母袷街付ǚ蛴∷鼈兊某绦?/b>

這個(gè)程序使用非十進(jìn)制表示整數(shù)(二進(jìn)制?、八進(jìn)制?和十六進(jìn)制?),并使用表2-1中列出的格式指定符將它們用printf打印出來(lái)。每個(gè)printf的輸出都顯示在代碼下方。

注意 整數(shù)字面量可以包含任何數(shù)量的單引號(hào)('),以方便閱讀。編譯器會(huì)完全忽略這些引號(hào)。例如,10000001'000'000都是表示一百萬(wàn)的字面量。

有時(shí),打印無(wú)符號(hào)整數(shù)的十六進(jìn)制表示或八進(jìn)制表示(較少見)是很有用的。我們可以使用printf格式指定符%x%o實(shí)現(xiàn)這個(gè)目的,如代碼清單2-2所示。

代碼清單2-2 一個(gè)使用無(wú)符號(hào)整數(shù)的八進(jìn)制和十六進(jìn)制表示的程序

十進(jìn)制數(shù)3669732608的十六進(jìn)制表示是dabbad00,由于十六進(jìn)制格式指定符%x?,因此它出現(xiàn)在輸出的第一行。十進(jìn)制數(shù)69的八進(jìn)制表示是105。無(wú)符號(hào)整數(shù)的格式指定符%u?和八進(jìn)制整數(shù)的格式指定符%o?分別對(duì)應(yīng)于參數(shù)?和?。printf語(yǔ)句將這些量?替換到格式化字符串中,產(chǎn)生信息There are 69, 105 leaves here.

警告 八進(jìn)制前綴是B語(yǔ)言的遺留問(wèn)題,可追溯到PDP-8計(jì)算機(jī)和八進(jìn)制無(wú)處不在的時(shí)代。C以及C++延續(xù)了這個(gè)可疑的傳統(tǒng)。例如,在對(duì)美國(guó)郵政編碼進(jìn)行硬編碼時(shí)必須小心:

去除十進(jìn)制數(shù)的前面的零;否則,它們將不再是十進(jìn)制數(shù)。這一行無(wú)法編譯,因?yàn)?不是八進(jìn)制數(shù)字。

默認(rèn)情況下,整數(shù)字面量的類型一般是intlonglong long。整數(shù)字面量的類型是這三種類型中最小的那種。這是由語(yǔ)言定義的,并將由編譯器強(qiáng)制執(zhí)行。

如果想更靈活,則可以給整數(shù)字面量提供后綴來(lái)指定它的類型(后綴不區(qū)分大小寫,所以你可以選擇自己最喜歡的風(fēng)格)。

? unsigned對(duì)應(yīng)后綴uU

? long對(duì)應(yīng)后綴lL

? long long對(duì)應(yīng)后綴llLL

unsigned后綴和long后綴或long long后綴結(jié)合起來(lái)可以指定整數(shù)類型的符號(hào)性和大小。表2-2顯示了后綴組合可能對(duì)應(yīng)的類型。允許的類型用復(fù)選標(biāo)記(√)表示。對(duì)于二進(jìn)制、八進(jìn)制和十六進(jìn)制字面量,可以省略后綴uU。這些都用星號(hào)(*)來(lái)描述。

表2-2 整數(shù)后綴

允許的最小類型仍能表示整數(shù)字面量的類型就是最終類型。這意味著,在特定整數(shù)允許的所有類型中,最小的類型將被應(yīng)用。例如,整數(shù)字面量112114可以是intlonglong long類型的。由于int可以存儲(chǔ)112114,因此最終的整數(shù)字面量是int類型的。如果真的想采用long類型,則可以指定為112114L(或112114l)。

2.1.2 浮點(diǎn)類型

浮點(diǎn)類型存儲(chǔ)的是實(shí)數(shù)(在這里可以定義為任何帶有小數(shù)點(diǎn)和小數(shù)部分的數(shù)字,如0.33333或98.6)的近似值。雖然無(wú)法在計(jì)算機(jī)內(nèi)存中準(zhǔn)確地表示某些實(shí)數(shù),但可以存儲(chǔ)一個(gè)近似值。如果這看起來(lái)很難相信,那么可以想一想像π這樣的數(shù)字,它有無(wú)限多的位數(shù)。在有限的計(jì)算機(jī)內(nèi)存中,怎么可能表示無(wú)限多位的數(shù)字?

與所有其他類型一樣,浮點(diǎn)類型占用的內(nèi)存是有限的,這被稱為類型的精度。浮點(diǎn)類型的精度越高,它對(duì)實(shí)數(shù)的近似就越準(zhǔn)確。C++為近似值提供了三個(gè)級(jí)別的精度:

? float:?jiǎn)尉取?/p>

? double:雙精度。

? long double:擴(kuò)展精度。

和整數(shù)類型一樣,每種浮點(diǎn)表示都取決于實(shí)現(xiàn)。本節(jié)不會(huì)詳細(xì)介紹浮點(diǎn)類型,但請(qǐng)注意,這些實(shí)現(xiàn)方式存在大量的細(xì)微差別。在主流桌面操作系統(tǒng)上,float通常有4字節(jié)的精度。doublelong double通常有8字節(jié)的精度(雙精度)。

大多數(shù)不參與科學(xué)計(jì)算的用戶可以安全地忽略浮點(diǎn)表示的細(xì)節(jié)。在這種情況下,可以使用double

注意 對(duì)于那些不能安全地忽略浮點(diǎn)表示細(xì)節(jié)的人來(lái)說(shuō),可以看看與自己硬件平臺(tái)相關(guān)的浮點(diǎn)規(guī)范。浮點(diǎn)存儲(chǔ)和算術(shù)的主要實(shí)現(xiàn)方式在《IEEE浮點(diǎn)算術(shù)標(biāo)準(zhǔn)》(IEEE 754)中有所概述。

1.浮點(diǎn)字面量

浮點(diǎn)字面量默認(rèn)為雙精度。如果需要單精度字面量,則使用fF后綴;如果需要擴(kuò)展精度字面量,則使用lL,如下所示:

字面量也可以使用科學(xué)計(jì)數(shù)法:

基數(shù)?和指數(shù)?之間不允許有空格。

2.浮點(diǎn)格式指定符

格式指定符%f顯示帶有小數(shù)位的浮點(diǎn)數(shù),而%e則以科學(xué)計(jì)數(shù)法顯示相同的數(shù)字。我們也可以讓printf使用%g格式指定符,選擇%e%f中更緊湊的一個(gè)。

對(duì)于double,只需在說(shuō)明符前面加上小寫字母l,而對(duì)于long double,在前面加上大寫字母L。例如,如果想要一個(gè)帶小數(shù)位的double,則可以指定%lf%le%lg;對(duì)于long double,則可以指定%Lf%Le%Lg

考慮代碼清單2-3,它探討了打印浮點(diǎn)數(shù)的不同選項(xiàng)。

代碼清單2-3 一個(gè)打印浮點(diǎn)數(shù)的程序

這個(gè)程序聲明了一個(gè)名為andouble?。格式指定符%le?輸出科學(xué)計(jì)數(shù)法結(jié)果6.022141e+23,而%lf?輸出小數(shù)點(diǎn)表示602214090000000006225920.000000%lg?指定符選擇了科學(xué)計(jì)數(shù)法結(jié)果6.02214e+23。名為hp?的浮點(diǎn)數(shù)(float)使用%e%f指定符產(chǎn)生類似的printf輸出。但是格式指定符%g決定輸出十進(jìn)制表示9.75而不是科學(xué)計(jì)數(shù)法結(jié)果。

一般來(lái)說(shuō),使用%g來(lái)打印浮點(diǎn)類型。

注意 在實(shí)踐中,可以省略double格式指定符中的l前綴,因?yàn)?b>printf會(huì)將浮點(diǎn)數(shù)參數(shù)提升為雙精度類型。

2.1.3 字符類型

字符類型存儲(chǔ)人類語(yǔ)言信息。這六種字符類型是:

? char:默認(rèn)類型,總是1個(gè)字節(jié)。可能是也可能不是有符號(hào)的(例如:ASCII)。

? char16_t:用于2字節(jié)的字符集(例如:UTF-16)。

? char32_t:用于4字節(jié)的字符集(例如:UTF-32)。

? signed char:與char相同,但保證是有符號(hào)的。

? unsigned char:與char相同,但保證是無(wú)符號(hào)的。

? wchar_t:足夠大以包含實(shí)現(xiàn)平臺(tái)地區(qū)環(huán)境語(yǔ)言設(shè)置中的最大字符(例如:Unicode)。

字符類型charsigned charunsigned char被稱為窄字符,而char16_tchar32_twchar_t由于其相對(duì)的存儲(chǔ)要求,被稱為寬字符。

1.字符字面量

字符字面量是一個(gè)單一的、恒定的字符。所有字符都用單引號(hào)('')括起來(lái)。如果字符是char以外的其他類型,還必須提供一個(gè)前綴:L代表wchar_tu代表char16_t,而U代表char32_t。例如,'J'聲明一個(gè)char字面量,L'J'聲明一個(gè)wchar_t字面量。

2.轉(zhuǎn)義序列

有些字符不能在屏幕上顯示。相反,它們會(huì)迫使顯示器做一些事情,比如將光標(biāo)移到屏幕的左邊(回車)或?qū)⒐鈽?biāo)向下移動(dòng)一行(換行)。其他字符可以在屏幕上顯示,但它們是C++語(yǔ)法的一部分,如單引號(hào)或雙引號(hào),所以必須非常小心地使用它們。為了將這些字符轉(zhuǎn)換為char,可以使用轉(zhuǎn)義序列,如表2-3中所示。

表2-3 保留字符和它們的轉(zhuǎn)義序列

3.Unicode轉(zhuǎn)義字符

我們可以使用通用字符名(universal character name)來(lái)指定Unicode字符字面量,使用通用字符名的方式有兩種:前綴\u加后面4位的Unicode碼位,或前綴\U加后面8位的Unicode碼位。例如,可以將A字符表示為'\u0041',將啤酒杯字符㊣表示為U'\U0001F37A'

4.格式指定符

charprintf格式指定符為%cwchar_t的格式指定符是%lc。代碼清單2-4初始化了兩個(gè)字符字面量xy,用來(lái)構(gòu)建printf調(diào)用。

代碼清單2-4 一個(gè)為幾個(gè)字符型變量賦值并打印它們的程序

這個(gè)程序輸出Windows binaries start with MZ.。盡管M是窄字符,而Z是寬字符,但printf仍能工作,因?yàn)樵摮绦蚴褂昧苏_的格式指定符。

注意 所有Windows二進(jìn)制文件的前兩個(gè)字節(jié)是字符M和Z,這是對(duì)MS-DOS可執(zhí)行二進(jìn)制文件格式的設(shè)計(jì)者M(jìn)ark Zbikowski的致敬。

2.1.4 布爾類型

布爾類型有兩種狀態(tài):真和假。布爾類型只有一個(gè),即bool。整數(shù)類型和布爾類型可以互相轉(zhuǎn)換:true狀態(tài)轉(zhuǎn)換為1,false狀態(tài)轉(zhuǎn)換為0,任何非零的整數(shù)都轉(zhuǎn)換為true,而0則轉(zhuǎn)換為false

1.布爾字面量

要初始化布爾類型,需要使用兩個(gè)布爾字面量,即truefalse

2.格式指定符

bool沒(méi)有格式指定符,但我們可以在printf中使用int格式指定符%d來(lái)產(chǎn)生1(代表true)或0(代表false)。原因是printf將任何小于int的整數(shù)值提升為int。代碼清單2-5說(shuō)明了如何聲明布爾變量并檢查其值。

代碼清單2-5 用printf語(yǔ)句打印布爾變量

該程序把b1初始化為true?,b2初始化為false?。然后,把b1b2打印成整數(shù)(使用%d格式指定符),得到對(duì)應(yīng)b1的1和對(duì)應(yīng)b2的0?。

3.比較運(yùn)算符

運(yùn)算符是對(duì)操作數(shù)進(jìn)行計(jì)算的函數(shù)(詳見7.1節(jié))。操作數(shù)是一種簡(jiǎn)單對(duì)象。關(guān)于使用bool類型的有意義的例子,詳見本節(jié)“比較運(yùn)算符”和“邏輯運(yùn)算符”。

我們可以使用幾個(gè)運(yùn)算符來(lái)構(gòu)建布爾表達(dá)式。回憶一下,比較運(yùn)算符接受兩個(gè)參數(shù)并返回一個(gè)布爾值。可用的運(yùn)算符有相等(==)、不等(!=)、大于(>)、小于(<)、大于或等于(>=)、小于或等于(<=)。

代碼清單2-6顯示了如何使用這些運(yùn)算符來(lái)產(chǎn)生布爾運(yùn)算。

代碼清單2-6 使用比較運(yùn)算符

每次比較都會(huì)產(chǎn)生一個(gè)布爾值結(jié)果?,printf語(yǔ)句將布爾值打印成一個(gè)int結(jié)果?。

4.邏輯運(yùn)算符

邏輯運(yùn)算符在bool類型上處理布爾邏輯。我們可以通過(guò)操作數(shù)的數(shù)量來(lái)對(duì)運(yùn)算符分類。一元運(yùn)算符需要一個(gè)操作數(shù),二元運(yùn)算符需要兩個(gè),三元運(yùn)算符需要三個(gè),以此類推。我們還可以通過(guò)操作數(shù)的類型進(jìn)一步對(duì)運(yùn)算符分類。

取否運(yùn)算符(!)接受一個(gè)操作數(shù),并返回與操作數(shù)相反的結(jié)果。換句話說(shuō),!true產(chǎn)生false,而!false則產(chǎn)生true

邏輯運(yùn)算符“與”(&&)和“或”(||)是二元的。邏輯“與”(AND)只在兩個(gè)操作數(shù)都為true時(shí)返回true。邏輯“或”(OR)只要有操作數(shù)為true就返回true

注意 閱讀布爾表達(dá)式時(shí),!的發(fā)音是“not”,如表達(dá)式a&&!b表示“a AND not b”。

邏輯運(yùn)算符一開始可能令人困惑,但它們很快就會(huì)變得直觀。代碼清單2-7展示了邏輯運(yùn)算符。

代碼清單2-7 一個(gè)展示邏輯運(yùn)算符用法的程序

在這里,我們可以看到取否運(yùn)算符?,邏輯“與”運(yùn)算符??,以及邏輯“或”運(yùn)算符??。

2.1.5 std::byte類型

系統(tǒng)程序員有時(shí)會(huì)直接使用原始內(nèi)存,原始內(nèi)存是一個(gè)沒(méi)有類型的位(bit)集合。這種情況下可以使用std::byte類型,它定義在<cstddef>頭文件中。std::byte類型允許按位進(jìn)行邏輯運(yùn)算(見第7章)。使用這種類型而不是整數(shù)類型來(lái)處理原始數(shù)據(jù),常常可以避免難以調(diào)試的編程錯(cuò)誤。

注意,與<cstddef>中的大多數(shù)其他基本類型不同,std::byte在C語(yǔ)言中沒(méi)有確切的對(duì)應(yīng)類型(“C類型”)。像C++一樣,C語(yǔ)言也有charunsigned char。這些類型使用起來(lái)不太安全,因?yàn)樗鼈冎С衷S多std::byte不支持的運(yùn)算。例如,可以對(duì)char進(jìn)行算術(shù)運(yùn)算,比如加法(+),但不能對(duì)std::byte進(jìn)行該運(yùn)算。這個(gè)看起來(lái)很奇怪的std::前綴被稱為命名空間,詳見8.3.2節(jié)(現(xiàn)在,暫且把命名空間std::當(dāng)作類型名稱的一部分)。

注意 關(guān)于std的發(fā)音,有兩種觀點(diǎn)。一種是把它當(dāng)作“ess-tee-dee”的首字母縮寫,另一種是把它當(dāng)作“stood”的縮寫。當(dāng)提到std命名空間中的類時(shí),說(shuō)話者通常會(huì)暗示命名空間操作符::。因此,可以把std::byte讀作“stood byte”或者“ess-tee-dee colon colon byte”。

2.1.6 size_t類型

size_t類型(也在<cstddef>頭文件中)用來(lái)表示對(duì)象的大小。size_t對(duì)象保證其最大值足以代表所有對(duì)象的最大字節(jié)數(shù)。從技術(shù)上講,這意味著size_t可以占用2個(gè)字節(jié),也可以占用200個(gè)字節(jié),具體取決于實(shí)現(xiàn)方式。在實(shí)踐中,它通常與64位架構(gòu)系統(tǒng)的unsigned long long相同。

注意 size_t<stddef>頭文件中的一個(gè)C類型,但它與C++的size_t相同,后者位于std命名空間中。偶爾,我們可以看到用(技術(shù)上正確的)std::size_t來(lái)代替。

1.sizeof

一元運(yùn)算符sizeof接受一個(gè)類型并返回該類型的大小(以字節(jié)為單位)。sizeof運(yùn)算符總是返回一個(gè)size_t對(duì)象。例如,sizeof(float)返回存儲(chǔ)float所需的字節(jié)數(shù)。

2.格式指定符

size_t的格式指定符通常是%zd(十進(jìn)制表示)或%zx(十六進(jìn)制表示)。代碼清單2-8顯示了如何檢查某個(gè)系統(tǒng)的幾種整數(shù)類型的大小。

代碼清單2-8 打印幾種整數(shù)類型的字節(jié)數(shù)的程序(輸出來(lái)自Windows 10 x64)

代碼清單2-8分別計(jì)算char?、short?、int?、long?和long long?的大小,并使用%zd格式指定符打印它們的大小。結(jié)果會(huì)因操作系統(tǒng)的不同而不同。從表2-1可以看出,每個(gè)環(huán)境都為整數(shù)類型定義了自己的大小。請(qǐng)?zhí)貏e注意代碼清單2-8中long的返回值;Linux和macOS都定義了8字節(jié)的long類型。

2.1.7 void

void類型表示一個(gè)空的值集合。因?yàn)?b>void對(duì)象不能擁有值,所以C++不允許使用void對(duì)象。我們只在特殊情況下使用void,比如用作不返回任何值的函數(shù)的返回類型。例如,函數(shù)taunt不返回值,因此我們聲明它的返回類型為void

其他特殊的void用法見第3章。

主站蜘蛛池模板: 普陀区| 通城县| 鞍山市| 宽城| 五大连池市| 台北市| 十堰市| 潢川县| 收藏| 长治市| 泸水县| 克拉玛依市| 高邮市| 通化市| 邢台市| 咸阳市| 汉寿县| 商丘市| 营口市| 康马县| 沅陵县| 三门县| 乐亭县| 榕江县| 闵行区| 齐河县| 铁岭市| 珲春市| 平谷区| 辰溪县| 石阡县| 长海县| 沁阳市| 嘉黎县| 浪卡子县| 长治市| 烟台市| 哈巴河县| 六安市| 林州市| 许昌市|