(博文參考書籍《C++ Primer 中文版》,摘錄易忘知識點和容易混淆的內容)
C++定義了一套包括算術類型(arithmetic type)和空類型(void)在內的基本數據類型。
其中算術類型包含:字符、整數型、布爾值、浮點數。
空類型不對應具體的值,僅用於一些特定場合,常見的如:函數不返回任何值是,使用空類型作為函數的返回類型。
一、算術類型
算術類型分為兩類:整形(intergral type,包括字符和布爾類型在內)、浮點型。
算術類型的尺寸(也就是該類型數據所占的比特數)在不同機器上有所差別。下方列出了C++標准規定的尺寸的最小值,同時允許編譯器賦予這些類型更大的尺寸。某一類型所占的比特數不同,他所能表示的數據范圍也不一樣。
類型 |
含義 | 最小尺寸 | 數據范圍 |
bool | 布爾類型 | 未定義 | |
char | 字符 | 8位 | 帶符號:signed char -128 ~127 無符號:unsiged char 0~255 |
wchar_t | 寬字符 | 16位 | |
char16_t | Unicode字符 | 16位 | |
char32_t | Unicode字符 | 32位 | |
short | 短整型 | 16位 | -2的8次方 ~ 2的8次方-1 |
int | 整型 | 16位 | -2的8次方 ~ 2的8次方-1 |
long | 長整型 | 32位 | -2的16次方 ~ 2的16次方-1 |
long long | 長整型 | 64位 | -2的32次方 ~ 2的32次方-1 |
float | 單精度浮點型 | 6位有效數字 | |
double | 雙精度浮點型 | 10位有效數字 | |
long double | 擴展精度浮點型 | 10位有效數字 |
布爾類型的取值是真(true)或假(false)。
基本的字符類型是char,一個char的空間應確保可以存放機器基本字符集中任意字符對應的數字值。也就是說,一個char的大小和一個機器字節一樣。
內置類型的機器實現
計算機以比特序列存儲數據,每個比特非0即1。
大多數的計算機以2的整數次冪個比特作為塊來處理內存,可尋址的最小內存塊成為“字節(byte)”,存儲的基本單元稱為“字(word)”,它通常由幾個字節組成。C++語言中,一個字節要至少能容納機器基本字符集中的字符。大多數機器的字節由8比特構成,字則由32或64比特構成,也就是4或8字節。
大多數計算機將內存中的每個字節與一個數字(被稱為“地址(address)”)關聯起來,在一個字節位8比特、字為32比特的機器上,我們可能看到一個字的內存區域如下所示
地址 | 內容 |
736424 | 1 0 0 1 0 1 1 0 |
736425 | 0 0 1 1 0 1 0 1 |
736426 | 0 1 0 1 0 0 1 1 |
736427 | 0 1 1 0 0 1 0 0 |
我們能夠使用地址來表述這個地址開始的大小不同的比特串,為了賦予內存中某個地址明確的含義,必須首先知道存儲在該地址的數據的類型。類型決定了數據所占的比特數以及該如何解釋這些比特的內容。
帶符號類型和無符號類型
除去布爾型和擴展的字符型之外,其他整型可以划分為帶符號的(signed)和無符號的(unsigned)兩種。類型int、short、long 和long long都是帶符號的,通過在這些類型名前添加unsigned即可得到無符號類型。類型 unsigned int 可以縮寫為 unsigned.
與其他整型不同,字符型被分為了三種:char、 singed char 和unsigned char。特別需要注意的是:類型char 和類型 signed char並不一樣。盡管字符型有三種,但是字符的表現形式卻只有兩種,帶符號的和無符號的。類型char 實際上會表現為上述兩種形式中的一種,具體是哪種由編譯器決定。
二、自動類型轉換
1、非布爾型 --> 布爾型:初始值為0則為false,否則為true
2、布爾型 --> 非布爾型:true --> 1; false --> 0
3、整數值 --> 浮點型:小數部分記為0
4、負值 --> 無符號型:結果為初始值對無符號類型表示數值總數取模后的余數。列如:unsigned char 可以表示0~255,我們給個-1,就是對256取模,得到余數255.
這里我們來看一個代碼示例:通過控制變量遞減的方式把10到0的數字降序輸出
#include <iostream> using namespace std; //倒序輸出10-0 void DescPrintTenToOne() { cout << "帶符號的" << endl; for (int i = 10;i >= 0; i--)//正確,如我們預取的效果一樣 { cout << i << endl; } cout << "無符號的" << endl; for (unsigned j = 10; j >= 0; j--) //由於負值向無符號轉換,進入了死循環 { cout << j << endl; } } int main() { DescPrintTenToOne(); return 0; }
下面我們看一下控制台的打印效果
5、當我們給帶符號類型一個超出它表示范圍的值時,結果是未定義的(undefined)。此時,程序可能繼續工作、可能崩潰、也可能生成垃圾數據