基本資料型別

何謂基本資料型別?

基本資料型別可以說是程式裡構成資料的基本單位,任何複雜的結構 (struct) 和類別 (class) 便是由許多基本型別組合而成的

有哪些基本資料型別?

以 C 語言來說,基本資料型別有下列幾種:

類型 意義 大小
char ASCII 文字,在其他高階程式語言中儲存的是 Unicode 文字 1 bytes ~ 2bytes
unsigned char 位元組,在大部分的程式語言叫做 byte 1 bytes
short int 短整數,通常會忽略 int 不寫 2 bytes
unsigned short int 無號短整數,通常會忽略 int 不寫 2 bytes
int 整數 2 bytes ~ 4 bytes
unsigned int 無號整數,可以忽略 int 不寫 2 bytes ~ 4 bytes
long int 長整數,通常會忽略 int 不寫 4 bytes ~ 8 bytes
unsigned long int 無號長整數,通常會忽略 int 不寫 4 bytes ~ 8 bytes
long long int 超長整數,通常會忽略 int 不寫
在其他高階語言中沒有這個類型,只有 long int
8 bytes
unsigned long long int 無號超長整數,通常會忽略 int 不寫
在其他高階語言中沒有這個類型,只有 unsigned long int
8 bytes
float 單精確浮點數,某些程式稱為 single 4 bytes
double 雙精確浮點數 8 bytes
* 指標 (pointer),C / C++ 才有的類型,指向一個記憶體位址 4 bytes ~ 8 bytes

各類型的大小關係為

char <= short <= int <= long <= long long

為什麼整數的大小會浮動?

這個數據模型有關,如果你是使用某些編譯器 (例如:Trobo C) ,他們的整數為 2bytes,不過現今已經幾乎沒有程式語言將 int 定為 2bytes了,目前主要都是 4bytes

long 的部份一開始是 4bytes,由於 64 位元的 linux 使用的是 LP64,即 long 和 pointer 為 64 位元,因此對於 64位元的 linux 來說,long 是 bytes

pointer 的部份,在 32位元的電腦上為 4bytes,而在 64位元的電腦上為 8bytes

char 在 C/C++ 是 ascii 字元,然而在其他高階語言中,則是 Unicode 字元,因此長度就從 1bytes 變為 2bytes

string 不是基本型別嗎?

string 我們稱為字串,意思是字元串列,或者在C我們又稱字元陣列,也就是說他是由一連串的字元所組成的,因此我不把它當作基本型別來看

在大部分的高階語言中,string 被視為基本資料型別,string 中有關字元的細節會被隱藏起來,並且統一使用Unicode,如果要將 string 轉成位元組,就要進行編碼 (Encoding)

文字編碼

上面有提到 ASCII 跟 Unicode,這些其實就是文字編碼

我們現在電腦上所看到的文字實際上都是數字,只是電腦透過判斷這些數字,將它們渲染成我們熟悉的文字

那電腦是怎麼將這些數據對應到文字的呢?就是靠文字編碼。每個國家常用的編碼都不同,以繁體中文來說,我們所使用的編碼就是 Big5(950),簡體中文則是 GBK,韓文是 windows-949(949),而一般的英文字、數字等則是 ASCII。

ASCII 是美國資訊交換標準代碼,裡面包含了基本的符號、英文字、數字與控制符號,從 0 到 127,共128個字

Unicode 則是為了能夠方便在各個不同語系國家中互相使用而產生的編碼,俗稱萬國碼

將基本資料型別轉換成一連串位元組

了解各種基本資料型別與其大小後,現在要將他們轉換成一連串位元組,實際上資料都會以位元組的型態被儲存到電腦上,或是被傳送到網路上

一般分成2種方式轉換,一種叫小端序 (little endian),另一種叫大端序 (big endian)

除了 float 跟 double 之外,其他型別通常都是採用小端序進行儲存

小端序

小的先存

舉例來說:

假設一個16進制整數 0x12345678 ,越左邊數字越大

使用小端序的方式就會變成 78 56 34 12,越左邊的資料越早存

大端序

大的先存

舉例來說:

假設一個16進制整數 0x12345678 ,越左邊數字越大

使用大端序的方式就會變成 12 34 56 78,越左邊的資料越早存

float 和 double 如何轉換成位元組

浮點數的儲存方式比較特別,細節可以參考 IEEE 754

浮點數通常會分成 3個區塊:正負號 (signed)、指數 (expon)、分數值 (fraction)

float
S E F
bits 1 8 23
double
S E F
bits 1 11 52

將這些欄位組合起來變成 32bits/64bits 整數後,以整數小端序的方式轉換為位元組,就是 float 跟 double 轉換以位元組表示的模樣了

基本型別的大小是固定的

上面有介紹過每個基本型別的大小,這些型別就算轉成字元組,大小依舊不會改變

假設有一個短整數 (short) 數值為 0x12

以小端序儲存時,會變成 12 00

以大端序儲存時,會變成 00 12

雖然看起來只有 1bytes,但是由於 short的大小為 2bytes,因此轉換成 bytes 時長度要一樣,所以變成2個單獨的 byte

結語

這邊只是粗淺的講了一下基本資料型別,希望能夠讓大家更了解這些基本資料的大小、意義與其如何以位元組的方式處存在電腦上,如果對基本資料型別有了一定的概念,將會更了解 struct、class、union 等複雜結構的原理,也會對儲存的資料大小有所概念,之後如果接觸到檔案存取與網路資料收送的部份,也能夠比較直覺的去進行思考,而不會卡在位元組轉成基本資料的問題上。

如果有寫錯的部份或是有其他建議,可以在下面的 gitalk 上留言告訴我