C++ 快速導覽 - 型態轉換

基本內建資料型態 (primitive built-in data type) 分為兩大類,整數類及浮點數類都屬於算術型態 (arithmetic type) ,若是在運算式 (expression) 中出現兩個分屬於不同基本資料型態的變數,編譯器會依隱性型態轉換規則 (implicit type conversion) 進行型態的轉換 (conversion) ,如下程式

#include <iostream>
 
int main()
{
    char a = 'a';
    short b = 5;
    int c = 156;
    long d = 5;
    float e = 9.8;
    double f = 12.5;
    
    std::cout << "被轉換成整數 " << (b / z) << std::endl;
    if (b) {
        std::cout << "整數被轉換成布林型態" << std::endl;
    }
    std::cout << "字元被轉換成整數 " << (a / b) << std::endl; 
    std::cout << sizeof(a / b) << std::endl;
    std::cout << "整數被轉換成整數" << (b * d) << std::endl;
    std::cout << sizeof(b * d) << std::endl;
    std::cout << "整數被轉換成浮點數 " << (c / e) << std::endl;
    std::cout << sizeof(c / e) << std::endl;
    std::cout << "浮點數被轉換成整數 " << (c = f) << std::endl;
    std::cout << sizeof(c) << std::endl;

    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:ptconversion.cpp
    功能:示範基本資料型態的轉換
    作者:張凱慶
    時間:西元 2010 年 10 月 */


編譯後執行,結果如下



第 12 行
if (b) {


原本變數 b 的型態為 short 整數,直接放在 if 陳述後的條件 (condition) ,也就是小括弧之中,由於條件為運算式的結果必須是布林值,因此這裡 short 整數會被轉換成布林值。 C++ 中,所有非 0 的值都會被轉換成 true ,包括浮點數 0.0 以外的值,而只有 0 為 false ,包括浮點數的 0.0 。


第 15 行
std::cout << "字元被轉換成整數 " << (a / b) << std::endl;


這裡,字元型態的變數與整數相除,前者會被先轉換成後者的資料型態,然後才會進行計算。由於字元型態對應到 ASCII 編碼的順序,因此 'a' 的值會是 97 ,除以 5 會得到整數 19 的結果,注意這裡是整數除法 (integer division) 。


第 17 行
std::cout << "整數被轉換成整數" << (b * d) << std::endl;


雖然是兩個數相乘,但是變數 b 為 short 型態,而變數 d 為 long 型態,由於兩種型態所佔用的記憶體空間不同,也就是說可儲存的整數範圍不同,因此這裡的計算也會做型態轉換,內定規則為範圍小的轉換成成範圍大的,也就是short 型態會先被轉換成 long 型態,然後才進行計算。


第 19 行
std::cout << "整數被轉換成浮點數 " << (c / e) << std::endl;


同樣的,由於浮點數可儲存的範圍遠較整數型態大,所以浮點數與整數進行算術計算時,整數會先被轉換成浮點數的型態。


第 21 行
std::cout << "浮點數被轉換成整數 " << (c = f) << std::endl;


指派運算會依所要存入的變數型態為主,這裡變數 c 會是最後的結果,因此變數 f 會先轉換成整數,也就是將小數點後的部份截調,轉換成 int 型態後存入變數 c 之中。


像這樣的自動的隱性轉換也被稱為提昇規則 (promotion) ,因為是由資料型態依容量大小進行的轉換方向,如下
boolshortintlongfloatdouble
char


另有顯性型態轉換規則 (explicit conversion) ,包括具名強制轉型 (named cast) 及舊式轉型 (old-style cast) ,可以任意強制將某個型態轉換成另一個型態,前者具名強制轉型的形式如下
cast-name<type>(expression)


cast-name 有以下種類
  • dynamic_cast
  • const_cast
  • static_cast
  • reinterpret_cast


如下例
#include <iostream>
 
int main()
{
    char a = 'a';
    int b = 97;
    
    std::cout << a << std::endl;
    std::cout << b << std::endl; 
    std::cout << static_cast<char>(b) << std::endl;
    std::cout << static_cast<int>(a) << std::endl;

    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:nctest.cpp
    功能:示範基本資料型態的轉換
    作者:張凱慶
    時間:西元 2010 年 10 月 */


編譯後執行,結果如下



第 10 行強制將整數 97 改以字元型態印出,而第 11 行強制將字元 'a' 改以整數型態印出。


有關具名強制轉型往後才會詳細討論,至於舊式轉型則是利用小括弧圍住型態型稱,然後放置在某一變數或運算式之前,便可將該變數強制轉換成小括弧的資料型態。形式如下
(type) (expression)


但顯性型態轉換須注意,通常從可儲存範圍大的資料型態轉換成儲存範圍小的資料型態,例如從 long 轉換成 short ,常常會造成資料的流失,因此須小心使用。


中英文術語對照
基本內建資料型態primitive built-in data type
算術型態arithmetic type
運算式expression
隱性型態轉換規則implicit type conversion
轉換conversion
條件condition
整數除法integer division
提昇規則promotion
顯性型態轉換規則explicit conversion
具名強制轉型named cast
舊式轉型old-style cast


您可以繼續參考
運算式
型態轉換


相關目錄
回 C++ 快速導覽
回 C++ 教材
回首頁


參考資料
C++ reference
cplusplus.com
Cprogramming.com C++ Tutorial

C++ Primer, Fourth Edition, Stanley B. Lippman...


本文於 2013 年 1 月更新

沒有留言: