位元詩人 [C++] 程式設計教學:資料型態 (Data Type)

C++資料型態
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

資料型態 (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 型態用來表達數學上的布林數,有 truefalse 兩個值。

以下值視為偽 (falsy):

  • false 本身
  • 整數 0
  • 浮點數 0.0
  • 空指標 NULLnullptr

但以下值視為真 (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::byteC++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;
}
關於作者

身為資訊領域碩士,位元詩人 (ByteBard) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。