前言
資料型態 (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 <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 新增的資料型態,用於二進位數運算。
浮點數 (Floating-Point Numbers)
浮點數的寬度和範圍
浮點數型態用來表示數學上的小數。電腦的浮點數有寬度的限制,以下是 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)
string
型態是 C++ 類別,在 C++ 標準函式庫中提供多個 string
的方法 (method),用來操作 string
物件。
雖然在 C++ 中仍可使用 C 字串,由於 C++ 已有更加方便的 string
型態,除非要和 C 程式交互操作,不應使用 C 字串來操作字串資料。
void
型態
void
不是真正的資料型態,而是用來表示函式沒有參數或沒有回傳值的資料型態註記。
由於 C 沒有泛型,會用指向 void
的指標來模擬泛型程式。C++ 有真正的泛型可用,就不需要用這種次佳的方式來寫程式。
轉型 (Casting)
不同的型態間可藉由轉型轉換至相容的型態。以本文來說,就是在數字型態間轉換。
現代 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;
}