基本內建資料型態都屬於算術型態,若是程式中出現不相符的基本資料型態變數,編譯器會依隱性型態轉換規則 進行型態的轉換。
舉例如下
001 | #include <iostream> |
002 | |
003 | int main() { |
004 | char a = 'a'; |
005 | short b = 5; |
006 | int c = 156; |
007 | long d = 5; |
008 | float e = 9.8; |
009 | double f = 12.5; |
010 | |
011 | if (b) { |
012 | std::cout << "short => bool, " |
013 | << typeid(b).name() |
014 | << std::endl; |
015 | } |
016 | std::cout << "char => int, " |
017 | << (a / b) |
018 | << ", " |
019 | << typeid(a / b).name() |
020 | << std::endl; |
021 | std::cout << "short => long, " |
022 | << (b * d) |
023 | << ", " |
024 | << typeid(b * d).name() |
025 | << std::endl; |
026 | std::cout << "int => float, " |
027 | << (c / e) |
028 | << ", " |
029 | << typeid(c / e).name() |
030 | << std::endl; |
031 | std::cout << "double => int, " |
032 | << (c = f) |
033 | << ", " |
034 | << typeid(c).name() |
035 | << std::endl; |
036 | |
037 | return 0; |
038 | } |
039 | |
040 | /* Kaiching Chang |
041 | u1201.cpp |
042 | 2014-02 */ |
編譯後執行,結果如下
$ g++ u1201.cpp |
$ ./a.out |
short => bool, s |
char => int, 19, i |
short => long, 25, l |
int => float, 15.9184, f |
double => int, 12, i |
$ |
第 11 行
011 | if (b) { |
原本變數 b 的型態為 short 整數,直接放在 if 陳述後的條件 (condition) ,也就是小括弧之中,由於條件為運算式 (expression) 的結果必須是布林值,因此這裡 short 整數會被轉換成布林值。 C++ 中,所有非 0 的值都會被轉換成 true ,而只有 0 為 false 。
下面輸出利用關鍵字 typeid 取得標準程式庫中的 std::type_info 物件,然後印出 name() 回傳的字串
013 | << typeid(b).name() |
可是印出結果為 s ,也就是 short ,這是因為型態轉換只發生在 if 後面小括弧,至於 b 的型態並沒有改變。
第 16 到 20 行
016 | std::cout << "char => int, " |
017 | << (a / b) |
018 | << ", " |
019 | << typeid(a / b).name() |
020 | << std::endl; |
這裡,字元型態的變數與整數相除,前者會被先轉換成後者的資料型態,然後才會進行計算。由於字元型態對應到 ASCII 編碼的順序,因此 'a' 的值會是 97 ,除以 5 會得到整數 19 的結果,注意這裡是整數除法 (integer division) 。
第 21 到 25 行
021 | std::cout << "short => long, " |
022 | << (b * d) |
023 | << ", " |
024 | << typeid(b * d).name() |
025 | << std::endl; |
兩個整數相乘,但是變數 b 為 short 型態,而變數 d 為 long 型態,由於兩種型態所佔用的記憶體空間不同,也就是說可儲存的整數範圍不同,因此這裡的計算也會做型態轉換,內定規則為範圍小的轉換成成範圍大的,也就是short 型態會先被轉換成 long 型態,然後才進行計算。
第 26 到 30 行
026 | std::cout << "int => float, " |
027 | << (c / e) |
028 | << ", " |
029 | << typeid(c / e).name() |
030 | << std::endl; |
同樣的,由於浮點數可儲存的範圍遠較整數型態大,所以浮點數與整數進行計算時,整數會先被轉換成浮點數的型態。
第 31 到 35 行
031 | std::cout << "double => int, " |
032 | << (c = f) |
033 | << ", " |
034 | << typeid(c).name() |
035 | << std::endl; |
指派運算會依所要存入的變數型態為主,這裡變數 c 會是最後的結果,因此變數 f 會先轉換成整數,也就是將小數點後的部份截調,轉換成 int 型態後存入變數 c 之中。
像這樣的自動的隱性轉換也被稱為提昇規則 (promotion) ,因為是由資料型態依容量大小進行的轉換方向,如下
continue ...
沒有留言:
張貼留言