前言
資料型態 (data type) 用來界定電腦程式可處理的資料的形式。C++ 除了承襲 C 的資料型態外,還可以用類別 (class) 定義新的資料型態。
C++ 的資料型態
基礎型態 (Fundamental Type)
基礎型態無法再化約成更小的資料型態。以下是 C++ 的基礎型態:
布林 (Boolean)
字元 (character) 相關型態
整數 (integer) 相關型態
浮點數 (floating-point numbers) 相關型態
std::byte (C++17)
void
複合型態 (Compound Type)
複合型態由其他資料型態來定義。以下是 C++ 的複合型態:
指標 (pointer)
參考 (reference)
陣列 (array)
函式 (function)
列舉 (enumeration)
結構體 (structure)
聯合體 (union)
類別 (class)
由於篇幅限制,本文不說明複合型態。留在後文再說明。
布林數 (Boolean)
bool 型態用來表達數學上的布林數,有 true 和 false 兩個值。
以下值視為偽 (falsy):
false 本身
整數 0
浮點數 0.0
空指標 NULL 或 nullptr
但以下值視為真 (truly):
零字元 '0' 和空白字元 ' '
空字串 ""
空陣列
為了避免在語意上模糊,建議明確地寫出條件句。
字元 (Character)
字元形態用來表達單一字元,像是 'c' 就是一個字元。以下是 C++ 支援的字元型態:
窄字元型態
char
signed char
unsigned char
寬字元型態
char16_t
char32_t
wchar_t
寬字元牽涉到非英語文字,剛學程式設計時不會馬上用到。
整數 (Integer)
整數的寬度和範圍
整數型態用來表達數學上的整數。但電腦的整數型態會受到硬體的限制,其範圍是有限的。以下是 C++ 的整數型態:
帶號整數型態 (signed integer types)
short
int
long
long long
無號整數型態 (unsigned integer types)
unsigned short
unsigned int
unsigned long
unsigned long long
C++ 的整數型態的範圍不是定值,會因系統架構、實作品 (編譯器) 等因素而異。以下小程式可展示系統上的整數型態的寬度:
#include
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
#include
/* std::iostream */
using std::cout;
using std::endl;
/* std::limits */
using std::numeric_limits;
int main(void)
{
cout << "short: " << numeric_limits
<< " to " << numeric_limits
cout << "int: " << numeric_limits
<< " to " << numeric_limits
cout << "long: " << numeric_limits
<< " to " << numeric_limits
cout << "long long: " << numeric_limits
<< " to " << numeric_limits
cout << endl; /* Separator. */
cout << "unsigned short: " << numeric_limits
<< " to " << numeric_limits
cout << "unsigned int: " << numeric_limits
<< " to " << numeric_limits
cout << "unsigned long: " << numeric_limits
<< " to " << numeric_limits
cout << "unsigned long long: " << numeric_limits
<< " to " << numeric_limits
return 0;
}
這裡用到了一點點泛型函式。目前先知道泛型程式把資料型態當成參數來用即可。
整數表示法
C++ 的整數實字 (integer literal) 支援以下進位:
十進位:12345
十六進位:0xff
八進位:077
二進位:0b1010
十進位是最常見的。有時候用其他的進位系統會比較方便,可以自行選擇。
std::byte (C++17)
std::byte 是 C++17 新增的資料型態,用於二進位數運算。
浮點數 (Floating-Point Numbers)
浮點數的寬度和範圍
浮點數型態用來表示數學上的小數。電腦的浮點數有寬度的限制,以下是 C++ 支援的浮點數型態:
float
double
long double
以下 C++ 程式用來取得系統上的浮點數型態的寬度:
#include
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
#include
/* std::iostream */
using std::cout;
using std::endl;
/* std::limits */
using std::numeric_limits;
int main(void)
{
cout << "float: " << numeric_limits
<< " to " << numeric_limits
cout << "double: " << numeric_limits
<< " to " << numeric_limits
cout << "long double: " << numeric_limits
<< " to " << numeric_limits
return 0;
}
這裡的極小值是指各種浮點數型態可表示的最小正數。
浮點數表示法
浮點數實子有兩種表示法:
一般表示法:12.345
科學記號:5E3
科學記號是為了避色寫太多零時難以閱讀的浮點數實字,可視需求使用。
字串 (String)
string 型態是 C++ 類別,在 C++ 標準函式庫中提供多個 string 的方法 (method),用來操作 string 物件。
雖然在 C++ 中仍可使用 C 字串,由於 C++ 已有更加方便的 string 型態,除非要和 C 程式交互操作,不應使用 C 字串來操作字串資料。
void 型態
void 不是真正的資料型態,而是用來表示函式沒有參數或沒有回傳值的資料型態註記。
由於 C 沒有泛型,會用指向 void 的指標來模擬泛型程式。C++ 有真正的泛型可用,就不需要用這種次佳的方式來寫程式。
轉型 (Casting)
不同的型態間可藉由轉型轉換至相容的型態。以本文來說,就是在數字型態間轉換。
現代 C++ 中,使用 static_cast 來轉換數字型態,這項特性在 C++11 後皆可使用。以下例子從浮點數轉至整數:
#include
int main(void)
{
auto a = 10.1;
auto b = 15.9;
auto c = static_cast
assert(25 == c);
return 0;
}
轉換數字型態時,由小寬度整數轉大寬度整數不會損失資料,其餘情境可能會損失資料。在轉型時要先自行確認是否會導致資料損失。
必要時,仍可回頭用 C 風格的轉型:
#include
int main(void)
{
auto a = 10.1;
auto b = 15.9;
auto c = (int)a + (int)b;
assert(25 == c);
return 0;
}
關於作者
位元詩人 (ByteBard) 是資訊領域碩士,喜歡用開源技術來解決各式各樣的問題。這類技術跨平台、重用性高、技術生命長。
除了開源技術以外,位元詩人喜歡日本料理和黑咖啡,會一些日文,有時會自助旅行。
