《C++Primer》第二章-變量和基本類型-學習筆記(1)

《C++Primer》第二章-變量和基本類型-學習筆記(1)

日誌:
1,2020-02-25 筆者提交文章的初版V1.0

作者按:
最近在學習C++ primer,初步打算把所學的記錄下來。之前學的知識有些淡忘了,看來得經常複習,得三省吾身,傳不習乎才能牢固啊。
Nobody trips over mountains. It is the small pebble that causes you to stumble. Pass all the pebbles in your path and you will find you have crossed the mountain.

傳送門/推廣
《C++Primer》第二章-變量和基本類型-學習筆記(2)

摘要

類型是所有程序的基礎。類型可以告訴我們數據代表什麼樣的意思以及我們可以對數據執行哪些操作。
類型的概念在C ++中非常重要。每個變量,函數參數和函數返回值都必須具有類型才能進行編譯。同樣,編譯器在評估每個表達式(包括字面值)之前會隱式[5]爲其指定類型。
C++ 中對類型的支持是非常廣泛的:語言本身定義了一組基本類型和修改已有類型的方法,還提供了一組特徵用於自定義類型。

  • C++定義的基本類型有:字符型,整型,浮點型等。
  • 同時C++還提供了可用於自定義數據類型的機制,舉個例子,標準庫正是利用這些機制定義了許多更復雜的類型,例如可變長字符串類型string。
  • 此外我們還能夠修改已有的類型形成複合類型(compound type)

主體

一種語言,首先有基本類型,其實就是數據在內存的佈局,方便表示不同種類的數據,例如整型和浮點是一定要有的,因爲 cpu 的規範。再組合得到數組,函數類型等,再發展出代數類型,然後包裝成接口、類、泛型等高級概念。
基本類型在編譯器裏規定。至於標準庫中定義的類型,通常是某種組合的封裝,例如標準庫的容器類等。c_str 實際是字符數組,而 std::string 則是進一步的封裝,來實現更多的接口方便用戶。
有個區別的概念是類型系統。類型系統本身放在編譯器(或解釋器)裏比較好,在編譯的同時做類型檢查,而在庫裏,就是運行期檢查了。類型系統,描述對類型的判斷、推導,例如推導 AST 節點的類型,判斷合法或非法,又如類型之間可以如何上下轉化。
再比如高階的多態類型(泛型)或者依賴類型,一般把類型的定義(名稱 + 表達式)也放在庫裏。但是類型系統,即根據定義(表達式)產生實際類型的推導規則(即算法),是在編譯器(或解釋器)中。
C ++是一種強類型的語言,它也是靜態類型的[6]。每個對象都有一個類型,並且該類型永不更改(不要與靜態數據對象混淆)。在代碼中聲明變量時,必須要麼明確指定其類型,要麼使用auto關鍵字指示編譯器從初始化程序中推斷類型。在代碼中聲明函數時,必須指定每個參數的類型及其返回值;如果函數未返回任何值,則必須指定void。唯一的例外是使用函數模板時,該模板允許使用任意類型的參數。

C++首次聲明變量後,以後將無法更改其類型。但是,可以將變量的值或函數的返回值複製到其他類型的變量中。這種操作稱爲類型轉換,有時是必需的,但它們也是數據丟失或不正確的潛在原因。

基本(內置)類型

C++包括許多基本類型(fundamental type),也稱爲內置類型(built-in type)。這包括數值類型(numeric types),例如int,double,long,bool,以及分別用於ASCII和UNICODE字符的char和wchar_t類型。大多數基本類型(bool,double,wchar_t以及它們的相關類型除外)都具有無符號版本,這些版本會修改變量可以存儲的值的範圍。例如,一個int存儲32位帶符號整數時,其值範圍可以表示-2,147,483,648到2,147,483,647。一個無符號整數(也存儲爲32位)可以存儲從0到4,294,967,295的值。在每種情況下,可能值的總數相同,只有範圍不同。

來自英文百科的關於內置類型的介紹
built-in type
A data type provided by a programming language as a basic building block, such as integer, character or Boolean, but in some languages
also list, hash table or first class function.[2]

上面的英文意思是說內置類型是編程語言提供的,用來作爲基礎構建模塊的數據類型,比如整型,字符型或布爾型,但是在有的語言中也可以是list類型,哈希表,first class function等。

基本類型由編譯器識別,該編譯器具有內置規則( built-in rules),這些規則控制可以對它們執行的操作以及如何將它們轉換爲其他基本類型。

關於基本內置類型,C++ 定義了一套包括算術類型(arithmetic type)空類型(void)在內的基本數據類型.

算數類型

算術類型分爲兩類:

  • 整型(integral type)
    • 表示整數,字符和布爾值(int,char,bool)的算數類型合稱爲整型。
  • 浮點型(floating-point type )
    • 包括float,double,long double。
    • 浮點型簡單來說表示帶有小數的數據,小數點可以在相應的二進制的不同位置浮動。
    • 注意,浮點型都是有符號的。

算術類型的尺寸(該類型數據所佔的比特數)在不同機器上有所差別,C++ 標準規定了尺寸的最小值,同時允許編譯器賦予這些類型更大的尺寸。某一類型所佔的比特數不同,它所能表示的數據範圍也不同。
除字符和布爾類型之外,其他整型用於表示(可能)不同尺寸的整數。
C++標準指定了一個浮點數有效位數的最小值,然而大多數編譯器都實現了更高的精度。表1列出了內置算術類型及其對應的最小存儲空間。

類型 含義 最小存儲空間
bool 布爾型 -
char 字符型 8位
short 短字符型 16位
wchar_t 寬字符型 16位
int 整型 16位
long 長整型 32位
float 長整型 6位有效數字
double 雙精度浮點型 10位有效數字
long double 擴展精度浮點型 10位有效數字
表1.C++內置算術類型表
整型

C++中表示整數(short,int, ,long),字符(char ,wchar_t)和布爾值(bool)的算數類型合稱爲整型。
字符類型有兩種:char 和 wchar_t。char類型保證了有足夠的空間,能夠存儲機器基本字符集中任何字符相應的數值,因此,char 類型通常是單個機器字節(byte)。char類型用於表示ASCII字符。wchar_t 類型用於擴展字符集,比如漢字和日語,這些字符集中的一些字符不能用單個 char 表示。wchar_t類型用於表示UNICODE字符。
short、int 和 long 類型都表示整型值,存儲空間的大小不同。一般, short類型爲半個機器字長,int 類型爲一個機器字長,而 long 類型爲一個或兩個機器字長(在 32 位機器中 int 類型和 long 類型通常字長是相同的)。

除了 bool 類型外,整型可以是帶符號的(signed)也可以是無符號的(unsigned)
整型 int、short 和 long 都默認爲帶符號型。要獲得無符號型則必須指定該類型爲 unsigned,比如 unsigned long。unsigned int 類型可以簡寫爲unsigned
和其他整型不同,char 有三種不同的類型:plain charunsigned charsigned char。雖然 char 有三種不同的類型,但只有兩種表示方式。可以使用unsigned char 或 signed char 表示 char 類型。使用哪種 char 表示方式由編譯器而定。(plain char就是不加前綴的char ,具體是否有符號,要看編譯器是否有選項–signed_chars)

整型的賦值
對象的類型決定對象的取值。對於整型的賦值而言,當把一個超出其取值範圍的值賦給一個指定類型的對象時,會產生什麼效果呢?答案取決於這種類型是 signed 還是 unsigned 的。

對於 unsigned 類型來說,編譯器必須調整越界值使其滿足要求。編譯器會將該值對 unsigned 類型的可能取值數目求模,然後取所得值。例如,如果試圖將 336 存儲到 8 位的 unsigned char 中,則實際賦值爲 80,因爲 80 是 336 對 256 求模後的值。
對於 unsigned 類型來說,負數總是超出其取值範圍。unsigned 類型的對象可能永遠不會保存負數。有些語言中將負數賦給 unsigned 類型是非法的,但在 C++ 中這是合法的。
當將超過取值範圍的值賦給 signed 類型時,由編譯器決定實際賦的值。

浮點型

類型 float、 double 和 long double 分別表示單精度浮點數、雙精度浮點數和擴展精度浮點數。一般 float 類型用一個字(32 位)來表示,double 類型用兩個字(64 位)來表示,long double 類型用三個或四個字(96 或 128 位)來表示。類型的取值範圍決定了浮點數所含的有效數字位數。

空類型

void類型沒有對應的值,僅僅用在有限的一些情況下,通常用作爲無返回值函數的返回類型。
空類型(void)是一種特殊類型; C++中不能聲明類型爲void的變量,但是可以聲明類型爲void *(指向void的指針)的變量,這在分配原始(un-typed/未類型化)內存時有時是必需的。
但是,指向void的指針不是類型安全(type-safe)的,通常在現代C ++中強烈建議不要使用它們。在函數聲明中,返回值無效意味着函數不返回值;這是void的常見且可接受的用法。儘管C語言要求參數爲零的函數在參數列表中聲明void,比如function(void),在現代C ++中不鼓勵這種做法,應該聲明function()。

字符串類型

嚴格來說,C ++語言沒有內置的字符串類型。在C++中字符串類型分爲兩種,分別是C-style stringstring類庫的string
因爲char和wchar_t只能存儲單個字符,所以要存儲字符串的話必須聲明這些類型的數組,並將在添加一個終止的空值(例如ASCII 的’\0’)在數組元素的最後一個有效字符之後(也稱爲C樣式字符串,C-style string) 。C-style string需要編寫更多代碼或使用外部字符串實用程序庫函數。
但是在現代C ++中,我們有標準庫類型std::string(對於8位char型字符串)或std::wstring(對於16位wchar_t型字符串)。這些C ++標準庫容器可被視爲本機字符串類型,因爲它們是任何兼容C ++構建環境中包含的標準庫的一部分。只需使用#include 指令即可在程序中使用這些類型。(如果使用的是MFC或ATL,也可以使用CString類,但它不是C ++標準的一部分。)在現代C ++中,強烈建議不要使用以空字符結尾的字符數組(即前面提到的C樣式字符串)。

參考資料

【1】C++ Primer 中文版(第四版·特別版)
【2】built-in type 英文百科
【3】Microsoft Basic Concepts (C++)
【4】Microsoft C++ type system

註解

【5】隱式:編譯器完成的轉換。顯式:用戶完成的轉換。https://www.cnblogs.com/pityhero233/p/8146585.html
【6】強類型語言:也稱爲強類型定義語言。是一種總是強制類型定義的語言,要求變量的使用要嚴格符合定義,所有變量都必須先定義後使用。C++ 是一門靜態類型語言,在編譯時會作類型檢查。
在大多數語言中,對象的類型限制了對象可以執行的操作。如果某種類型不支持某種操作,那麼這種類型的對象也就不能執行該操作。在 C++ 中,操作是否合法是在編譯時檢查的。當編寫表達式時,編譯器檢查表達式中的對象是否按該對象的類型定義的使用方式使用。如果不是的話,那麼編譯器會提示錯誤,而不產生可執行文件。隨着程序和使用的類型變得越來越複雜,我們將看到靜態類型檢查能幫助我們更早地發現錯誤。靜態類型檢查使得編譯器必須能識別程序中的每個實體的類型。因此,程序中使用變量前必須先定義變量的類型。

本文許可證

本文遵循 CC BY-NC-SA 4.0(署名 - 非商業性使用 - 相同方式共享) 協議,轉載請註明出處,不得用於商業目的。
CC BY-NC-SA 4.0
下一篇
《C++Primer》第二章-變量和基本類型-學習筆記(2)

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