程式在執行的過程中,需要在記憶體空間中運算、儲存資訊,由於資料型態各不相同,儲存時需要的容量不一,不同的資料要配給不同空間大小,因而有了「資料型態」(Data type)的規範。
C++ 中基本資料型態主要區分為整數(Integer)、浮點數(Float)、字元(Character),而這幾種還可以細分,如下所示:
整數
用來表示整數值,可以區分為
short、int、long與long long(C++ 11),可容納的大小各不相同,int至少會跟short一樣大,long至少會跟int一樣大,long long至少 64 個位元。浮點數
用來表示小數值,可以區分為
float、double與long double,越後面的型態使用的記憶體空間越大,精度也就越高。字元
char的sizeof(char)結果要是 1,基本上用來儲存字元資料,但沒有規定什麼是字元資料,也可用來儲存較小範圍的整數。與字元相關的型態,其實還有
wchar_t,C++ 11 的char16_t、char32_t(以及 C++ 20 的char8_t),這之後有機會再來談。
在 C 語言文件的〈資料型態〉中談到,在 C11 標準中,建議包括 stdint.h 程式庫,使用 int8_t、int16_t、int32_t、int64_t uint8_t、uint16_t、uint32_t、uint64_t 等作為整數型態的宣告,以避免平台相依性的問題,在 C++ 中可以包含 cstdint 來使用這些型態。
以上的資料型態在記憶體中佔有的大小,依平台系統而有所差異,字組的大小取決於機器,在 32 位元機器上通常一個字組是 4 個位元組,如果想知道這些資料型態在平台上,佔有的記憶體空間有多少,可以使用 sizeof 運算子,下面這個程式是個簡單示範:
#include <iostream>
using namespace std;
int main() {
cout << "\n型態\t大小(bytes)";
cout << "\nint\t" << sizeof(int);
cout << "\nlong\t" << sizeof(long);
cout << "\nfloat\t" << sizeof(float);
cout << "\ndouble\t" << sizeof(double);
cout << "\nchar\t" << sizeof(char);
cout << "\n";
return 0;
}
其中 '\t' 是跳格字元,相當於在主控台中按下 Tab 鍵的效果,可以用來對齊下一個顯示位置;以下是執行結果:
型態 大小(bytes)
int 4
long 4
float 4
double 8
char 1
由於平台不同,你的執行結果不一定會與這邊相同;因為每種資料型態佔有的記憶體大小不同,因而可以儲存的數值範圍也就不同。
例如在上例中,整數 int 的記憶體空間是 4 個位元組,可以儲存的整數範圍為 -2147483648 至 2147483647,如果儲存值超出這個範圍的話稱之為「溢值」 (Overflow),會造成程式不可預期的結果。
整數計算範圍的方式很簡單,例如 int 整數佔 4 位元組的話,可儲存範圍為 2^32 / 2,除以 2 是因為要分另一半儲存負整數的關係,整數的最左邊位元被用來表示正負號,如果最左邊位元為 0 表示正號,若為 1 表示負號。
在 C++ 中可以使用 signed、unsigned 宣告有號、無號整數,無號整數最左邊位元不用來表示正負號,例如一個 8 位元字元被用來表示整數時,可以表示數值 -128 到 127,而一個無號字元可以表示 0 到 255 的正整數。
size_t 是個機器特定的無號型態,定義於 cstddef 標頭檔,為 C 語言 stddef.h 的 C++ 版本,保證夠大可以容納任何物件,若資料結構具有長度或索引概念,而且需要很大的容量,例如陣列,可以使用 size_t 型態變數來實作長度或索引。
用於儲存整數時,char 有號或無號取決於編譯器,可以明確使用 signed char 表示有號,這時正值與負值平均分配,unsigned char 是無號的。
浮點數的儲存方式則是分為兩個部份,例如 float 佔四個位元組的話,前三個位元組用來儲存假數,後一個位元組儲存指數,例如 3.14 * 10^8, 3.14 儲存在前三位元組,而 8 儲存於後一位元組,所以 float 大致上可以儲存的範圍為 10^38 到 10^-38(就指數來算出的),而 double 可以大致儲存 10^308 至 10^-308 之間的數值。
C++ 有 bool 型別,用來表示布林數,在程式中佔一個位元組,可以使用 true 或 false 字面常量(Literal constant)來表示,實際數值由語言實作決定,不一定對應於 1 與 0,可以使用下面這個程式來檢驗:
#include <iostream>
using namespace std;
int main() {
cout << "sizeof(bool)\t" << sizeof(bool) << "\n";
cout << "sizeof(true)\t" << sizeof(true) << "\n";
cout << "sizeof(false)\t" << sizeof(false) << "\n";
cout << "true\t" << true << "\n";
cout << "false\t" << false << "\n";
return 0;
}
執行結果:
sizeof(bool) 1
sizeof(true) 1
sizeof(false) 1
true 1
false 0

