資料型態 (data type) 用來界定電腦程式可處理的資料的形式。C++ 除了承襲 C 的資料型態外,還可以用類別 (class) 定義新的資料型態。
基礎型態無法再化約成更小的資料型態。以下是 C++ 的基礎型態:
std::byte
(C++17)void
複合型態由其他資料型態來定義。以下是 C++ 的複合型態:
由於篇幅限制,本文不說明複合型態。留在後文再說明。
bool
型態用來表達數學上的布林數,有 true
和 false
兩個值。
以下值視為偽 (falsy):
false
本身0
0.0
NULL
或 nullptr
但以下值視為真 (truly):
'0'
和空白字元 ' '
""
為了避免在語意上模糊,建議明確地寫出條件句。
字元形態用來表達單一字元,像是 'c'
就是一個字元。以下是 C++ 支援的字元型態:
char
signed char
unsigned char
char16_t
char32_t
wchar_t
寬字元牽涉到非英語文字,剛學程式設計時不會馬上用到。
整數型態用來表達數學上的整數。但電腦的整數型態會受到硬體的限制,其範圍是有限的。以下是 C++ 的整數型態:
short
int
long
long long
unsigned short
unsigned int
unsigned long
unsigned long long
C++ 的整數型態的範圍不是定值,會因系統架構、實作品 (編譯器) 等因素而異。以下小程式可展示系統上的整數型態的寬度:
#include <iostream>
using std::cout;
using std::endl;
/* Common word size. */
#define WORD_SIZE 8
int main(void)
{
cout << "short: " << WORD_SIZE * sizeof(short) << endl;
cout << "int: " << WORD_SIZE * sizeof(int) << endl;
cout << "long: " << WORD_SIZE * sizeof(long) << endl;
cout << "long long: " << WORD_SIZE * sizeof(long long) << endl;
cout << endl; /* Separator. */
cout << "unsigned short: " << WORD_SIZE * sizeof(unsigned short) << endl;
cout << "unsigned int: " << WORD_SIZE * sizeof(unsigned int) << endl;
cout << "unsigned long: " << WORD_SIZE * sizeof(unsigned long) << endl;
cout << "unsigned long long: " << WORD_SIZE * sizeof(unsigned long long) << endl;
return 0;
}
並非所有的架構的 word 寬度皆為 8,只是在常見的系統架構上 word 寬度剛好是 8,所以這個程式在家用電腦上可用。
除了整數寬度外,C++ 提供整數上下限的函式。以下程式利用該函式來取得系統上的整數上下限:
#include <iostream>
#include <limits>
/* std::iostream */
using std::cout;
using std::endl;
/* std::limits */
using std::numeric_limits;
int main(void)
{
cout << "short: " << numeric_limits<short>::min()
<< " to " << numeric_limits<short>::max() << endl;
cout << "int: " << numeric_limits<int>::min()
<< " to " << numeric_limits<int>::max() << endl;
cout << "long: " << numeric_limits<long>::min()
<< " to " << numeric_limits<long>::max() << endl;
cout << "long long: " << numeric_limits<long long>::min()
<< " to " << numeric_limits<long long>::max() << endl;
cout << endl; /* Separator. */
cout << "unsigned short: " << numeric_limits<unsigned short>::min()
<< " to " << numeric_limits<unsigned short>::max() << endl;
cout << "unsigned int: " << numeric_limits<unsigned int>::min()
<< " to " << numeric_limits<unsigned int>::max() << endl;
cout << "unsigned long: " << numeric_limits<unsigned long>::min()
<< " to " << numeric_limits<unsigned long>::max() << endl;
cout << "unsigned long long: " << numeric_limits<unsigned long long>::min()
<< " to " << numeric_limits<unsigned long long>::max() << endl;
return 0;
}
這裡用到了一點點泛型函式。目前先知道泛型程式把資料型態當成參數來用即可。
C++ 的整數實字 (integer literal) 支援以下進位:
12345
0xff
077
0b1010
十進位是最常見的。有時候用其他的進位系統會比較方便,可以自行選擇。
std::byte
(C++17)std::byte
是 C++17 新增的資料型態,用於二進位數運算。
浮點數型態用來表示數學上的小數。電腦的浮點數有寬度的限制,以下是 C++ 支援的浮點數型態:
float
double
long double
以下 C++ 程式用來取得系統上的浮點數型態的寬度:
#include <iostream>
using std::cout;
using std::endl;
/* Common word size. */
#define WORD_SIZE 8
int main(void)
{
cout << "float: " << WORD_SIZE * sizeof(float) << endl;
cout << "double: " << WORD_SIZE * sizeof(double) << endl;
cout << "long double: " << WORD_SIZE * sizeof(long double) << endl;
return 0;
}
以下 C++ 程式用來取得浮點數型態的極值:
#include <iostream>
#include <limits>
/* std::iostream */
using std::cout;
using std::endl;
/* std::limits */
using std::numeric_limits;
int main(void)
{
cout << "float: " << numeric_limits<float>::min()
<< " to " << numeric_limits<float>::max() << endl;
cout << "double: " << numeric_limits<double>::min()
<< " to " << numeric_limits<double>::max() << endl;
cout << "long double: " << numeric_limits<long double>::min()
<< " to " << numeric_limits<long double>::max() << endl;
return 0;
}
這裡的極小值是指各種浮點數型態可表示的最小正數。
浮點數實子有兩種表示法:
12.345
5E3
科學記號是為了避色寫太多零時難以閱讀的浮點數實字,可視需求使用。
string
型態是 C++ 類別,在 C++ 標準函式庫中提供多個 string
的方法 (method),用來操作 string
物件。
雖然在 C++ 中仍可使用 C 字串,由於 C++ 已有更加方便的 string
型態,除非要和 C 程式交互操作,不應使用 C 字串來操作字串資料。
void
型態void
不是真正的資料型態,而是用來表示函式沒有參數或沒有回傳值的資料型態註記。
由於 C 沒有泛型,會用指向 void
的指標來模擬泛型程式。C++ 有真正的泛型可用,就不需要用這種次佳的方式來寫程式。
不同的型態間可藉由轉型轉換至相容的型態。以本文來說,就是在數字型態間轉換。
現代 C++ 中,使用 static_cast
來轉換數字型態,這項特性在 C++11 後皆可使用。以下例子從浮點數轉至整數:
#include <cassert>
int main(void)
{
auto a = 10.1;
auto b = 15.9;
auto c = static_cast<int>(a) + static_cast<int>(b);
assert(25 == c);
return 0;
}
轉換數字型態時,由小寬度整數轉大寬度整數不會損失資料,其餘情境可能會損失資料。在轉型時要先自行確認是否會導致資料損失。
必要時,仍可回頭用 C 風格的轉型:
#include <cassert>
int main(void)
{
auto a = 10.1;
auto b = 15.9;
auto c = (int)a + (int)b;
assert(25 == c);
return 0;
}