[C++, CPP] 基本資料型態(Fundamental Data Type)
算術型態(Arithmetic Type)
- 資料型態可以自行定義,也可以使用C++預設提供的幾種資料型態
- 基本資料型態:C++預設提供的資料型態。
算術型態
(Arithmetic Type)整數 有號整數 signed char short int long 無號整數 bool char wchar_t 浮點數 float double long double - 數值範圍:這裡介紹的數值範圍會符合大部份系統
- 有時因系統或硬體的關係,數值範圍可能會和這裡介紹的有所出入,確切的數值範圍應查看相關的標頭檔。
- 例如PC上int是4byte,嵌入式系統上int可能是2byte
- 整數型態的範圍:可參考climits標頭檔裡的定義
- 浮點數型態的範圍及精確度:可參考float.h、cfloat
或limits標頭檔裡的定義
- #include <limits>
- 最大值:std::numberic_limits<型態>::max( );
- 最小值:std::numberic_limits<型態>::min( );
- 二進位的位數:std::numeric_limits<型態>::digits
- 浮點數取出來為假數的二進位值位數
- 有時因系統或硬體的關係,數值範圍可能會和這裡介紹的有所出入,確切的數值範圍應查看相關的標頭檔。
- int:整數,即沒有小數的數值
- 一般32位元電腦int變數的大小為4bytes(32bits)
- int的長度通常以硬體能最高速運算的長度決定
- float:浮點數,浮點數是有小數的數值
- 電腦中記憶浮點數的方法是基值和倍數分開儲存,倍數值和小數點移動的位數有關,所以稱為浮點數
- 電腦上使用的浮點數精確度有限,所以有些運算常發生錯誤:
- 很多10進位浮點數無法轉換成完全精確的2進位浮點數
cout << 10.0/3.0 << endl; //顯示3.33333
- 用2個接近的值相減,可能會失去精確度
cout << 3.33333 - 1.0/3.0 << endl; //顯示-3.41733e-006
- 處理大範圍的值可能會出現錯誤
cout << 9000000.0f + 0.0000009 << endl; //顯示9e+006
- 很多10進位浮點數無法轉換成完全精確的2進位浮點數
- NaN(Not a Number):表示非數學定義的結果,如除以0
- +infinity(正無窮大):符號為+,假數bit皆為0,指數bit皆為1
- -infinity(負無窮大):符號為-,假數bit皆為0,指數bit皆為1
運算 | 結果 |
---|---|
±n/0 | ±infinity |
±infinity ± n | ±infinity |
±infinity * n | ±infinity |
±infinity / n | ±infinity |
0 / 0 | NaN |
±infinity / ±infinity | NaN |
infinity - infinity | NaN |
infinity * 0 | NaN |
魔術數字(Magic Number)
在程式碼中直接使用數字稱為魔術數字,讓人很難瞭解該數值的意義,時間一久可能連設計者也記不得。這種數字就像魔術一樣,讓人不清楚是怎麼變出來的。
float priceWithTax = 1.03 * price; // Magic Number = 1.03
1.03是什麼東西或由何而來,很不清楚,可以改寫成:
float tax = 1.03; float priceWithTax = tax * price;
- 精確度(Precision):
- 指基值(假數)的有效位數,最後一位數有可能是四捨五入的結果
- char:字元型態
- 主要是用來儲存ASCII(American Standard Code for Information Interchange)字元,也可以儲存1byte的整數
- 儲存ASCII字元時,需使用單引號括住
-
char letter1 = 'A'; char letter2 = 65; char letter3 = 0x41; char letter4 = ++64;
- char可能是有號,也有可能是無號,即儲存的範圍可能是(0~255)也可能是(-128~127)
- char是否有號,由編譯器的開發廠商決定
- 要測試char是否有號,可指派一個負數給char變數,再將char變數轉為整數印出,若可正確印出負數,即為有號
- 測試char是否有正負號?
char c = -125; cout << (int) c << endl; //顯示-125即為有號,顯示131即為無號
- bool:布林型態,記錄真(true)或假(false)
- bool型態的大小為1byte,所以也可以儲存0 ~ 255的整數
- 舊的C++程式會使用0代表假,非0的數值代表真(負數也代表真)
- wchar_t(Wide Character Type):寬字元型態,
- 有些系統支援大於char的1byte的延伸字元集,要開發國際型的程式時就需使用wchar_t型態
- 指派字面字元給wchar_t時,前面需加上L
-
wchar_t wl = L'Z'; wchar_t wl = L'\x0438';
- cout不適合處理wchar_t,新版的iostream提供wcin和wout來處理wchar_t
- 型態的Byte數:不同的作業系統對基本型態可能定義不同的byte數,可以用sizeof運算子來確認,用法如下:
- sizeof(型態)
-
cout << sizeof(int) << endl;
- sizeof 變數名稱
-
int num = 0; cout << sizeof num << endl;
- 變數型態會決定配置多大的記憶體,所以宣告的型態會影響可儲存數值的範圍。
- 若配置不夠大的範圍,多餘的部份將被捨去
-
int intValue = 9999999; short shortValue = 0; shortValue = intValue; cout << shortValue << endl; //顯示 -27009
- C++中各資料型態大小範圍
- 前置詞(Prefix):放在數值前面,改面數值基底
- 16進位:可用0x或0X開頭的數字代表16進位數字
- 指派16進位的A0給num1,16進位的50給num2
int num1 = 0xA0; int num2 = 0x50;
- 指派16進位的A0給num1,16進位的50給num2
- 8進位:可用0開頭的數字代表8進位數字
- 指派8進位的30給num1,8進位的35給num2
int num1 = 030; int num2 = 035;
- 指派8進位的30給num1,8進位的35給num2
- 16進位:可用0x或0X開頭的數字代表16進位數字
- 後置詞(Postfix or Suffix):為了讓編譯器更清楚的知道數值的型態,可以在整數後面加上下列字元,
- 後置詞不分大小寫及順序,若無標明或值沒有超過int範圍,則C++預設使用int儲存整數常數。
- 整數字尾表示法:
- L:long
-
long num1 = 999L;
-
- U:unsigned
-
unsigned long num1 = 999UL;
-
- L:long
- 浮點數字尾表示法:
- F:float
-
float num1 = 999.02F;
-
- L:long double
-
double num1 = 999.02L;
-
- F:float
- 進位運作子:iostream中除endl外,還定義了dec、hex、oct等運作子,可以控制串流中數字的操作進制
- 進位運作子可將整數以指定進制顯示
- 進位運作子是強制式(modal),除非更改設定,否則影響會持續到程式結束
- 進位運作子不會影響浮點數,浮點數仍會以十進位顯示
-
cout << 50; //顯示50 cout << hex << 50; //將10進制的50以16進制顯示 ⇒ 顯示32 cout << dec << 0x50; //將16進制的0x50以10進制顯示 ⇒ 顯示80 cout << hex << 0x50; //將16進制的0x50以16進制顯示 ⇒ 顯示50
- 科學記號表示法:數值後面接E或e再接10的乘方
- E左邊的數字稱為假數(Mantissa),E右邊的數字稱為指數(Exponent)
-
314.159 = 3.14159E2 float floatValue1 = 3.14e2 float floatValue2 = 3.14e+2
- 綜合範例
#include "stdafx.h" #include <iostream> using std::cout; using std::endl; using std::dec; using std::hex; using std::oct; int main(void) { int intNum1 = 50; int intNum2 = 0x50; int intNum3 = 050; cout << "int = " << sizeof(int) << " bytes" << endl; cout << "intNum1 = " << sizeof intNum1 << " bytes" << endl; cout << "int 50 : " << intNum1 << endl; cout << "int 0x50 : " << intNum2 << endl; cout << "int 050 : " << intNum3 << endl << endl; cout << "int 50 : " << dec << intNum1 << endl; cout << "int 0x50 : " << hex << intNum2 << endl; cout << "int 050 : " << oct << intNum3 << endl; cout << dec << endl; char charLetter1 = 'A'; char charLetter2 = 65; cout << "char = " << sizeof(char) << " bytes" << endl; cout << "charLetter1 = " << sizeof charLetter1 << " bytes" << endl; cout << "char \'A\' : " << charLetter1 << endl; cout << "char 65 : " << charLetter2 << endl << endl; bool boolValue1 = true; bool boolValue2 = false; bool boolValue3 = 1; bool boolValue4 = 0; cout << "bool = " << sizeof(bool) << " bytes" << endl; cout << "boolValue1 = " << sizeof boolValue1 << " bytes" << endl; cout << "bool true : " << boolValue1 << endl; cout << "bool false : " << boolValue2 << endl; cout << "bool 1 : " << boolValue3 << endl; cout << "bool 0 : " << boolValue4 << endl << endl; unsigned long ulongNumber1 = 999; unsigned long ulongNumber2 = 999UL; cout << "unsigned long = " << sizeof(unsigned long) << " bytes" << endl; cout << "ulongNumber1 = " << sizeof ulongNumber1 << " bytes" << endl; cout << "unsigned long 999 : " << ulongNumber1 << endl; cout << "unsigned long 999UL : " << ulongNumber2 << endl; system("PAUSE"); }