資料型別和字符集

Linus脫襪子發表於2019-01-19

什麼是資料型別
簡單理解就是資料的型別。
what?資料怎麼會有型別?資料難道不就是0或者1組成的位元組碼嗎?
沒錯,在計算機中,只能儲存0或者1,也就是說從儲存的角度來看,根本沒有型別這種東西,它們確實不過就是0或者1組成的位元組碼。
那為什麼還會有資料型別?
因為,型別是相當於程式設計者(人)來說的,人把資料分成不同的型別,方便理解,方便計算。
比如:

 int a = 0x61;
 char b = 0x61;
 float c = 0x61;
 double d = 0x61;
 System.out.println(a+" "+b+" "+c+" "+d);

輸出結果是:97 a 97.0 97.0。
四個不同型別的變數,給與相同的位元組碼0x61,但是輸出竟然不同!why?
因為程式設計者(人)給0x61這個16進位制數賦予了型別,或者說給它賦予了含義。
為什麼要賦予型別(含義)?是為了讓0或1的位元組碼能夠表示更具體的東西,或是說把它對映為人能理解的東西。
不設定型別,也可以對0x61這個數進行各種運算,但是。。。what is the meaning?
沒有意義,對於一個整數進行加減乘除具有現實意義,對於一個字元小寫變大寫具有現實意義,可是對於一個二進位制數的操作卻是沒有意義的。人不能理解的事情是沒有意義的。

那麼什麼是資料型別?
就是人看待資料的方式,人理解資料的方式,人規定資料的方式,這就是資料型別。
資料之所以有型別,那取決於人的看法,而不卻決於資料本身,資料本身是沒有型別的。

為什麼上面程式的輸出不同?
因為輸出就是把資料變成人想要的格式顯示給人看。
計算機怎麼知道人想要什麼格式?通過資料型別!
當0x61被規定為int型時計算機就知道應該顯示十進位制數6*16+1 = 97。
當0x61被規定為char型時計算機就知道應該顯示十進位制數6*16+1 = 97代表的ascii碼所對應的字元`a`。
雖然它們在計算機中都是同一個位元組碼0x61,但是因為人規定了型別,所以計算機才返回不同的結果。

從編解碼的角度來看
編碼是資訊從一種形式或格式轉換為另一種形式的過程,解碼,是編碼的逆過程。
具體來講編碼就是,把人理解的東西轉換為計算機理解的東西,而解碼則是把計算機理解的東西轉換為人理解的東西。
計算機理解什麼?只理解0和1,人呢?almost everything。
它們之間轉換的橋樑是什麼?就是資料型別!人只有規定了資料的型別,規定人所理解的事情如何轉換為計算機理解的位元組碼,才能完成這種轉換!
舉例:
對於97這個數字,人可以理解它為一個十進位制數,但是計算機只能理解0或者1,那麼如何讓計算機理解?
給97編碼。how?如果用二進位制編碼,則把97變成了1100001這個數。這樣計算機就理解(能儲存和計算)了,那麼人怎麼理解1100001這個二進位制碼呢?計算機在顯示的時候把1100001這個數進行二進位制解碼,解碼成97,人就理解了,而之所以能轉換,是因為規定了二進位制編碼解碼的規則,並且規定了它是個整數。而對於`a`這個字元,人理解為它是一個小寫字母a,如何讓計算機理解?還是編碼?編什麼碼?編ASCII碼,`a`的ASCII碼是1100001,這樣計算機又理解(能儲存和計算)了,計算機如何讓人理解1100001,解碼!ASCII解碼,就變成了`a`,這樣人就又理解了!。

不同的事物,使用不同的編碼方式可能得到相同的二進位制碼,而相同的二進位制碼,使用不同的解碼方式會被理解為不同的事物!

從本質上來講什麼是資料型別?
其實就是資料的編解碼的方式!!!

最後,什麼是字符集?
就是對字元的編碼解碼的方式!
不同字符集,規定了字元的編碼(字元轉換為二進位制數)和解碼(二進位制數轉換為字元)方式。

System.out.println("你好".getBytes("utf-8") );
System.out.println("你好".getBytes("gbk") );

輸出:
[B@677327b6
[B@14ae5a5
可以看到不同的字符集(utf-8和gbk)把相同的中文”你好”,編碼成了不同的二進位制碼。
當然,上面輸出並不是0和1,顯然不是二進位制碼。。。那是因為計算機顯示的時候把二進位制碼使用ASCII碼幫你解了碼。。。都變成了ASCII字元。why?我並不想讓它解碼,但是顯示就是解碼!!!
當然通過一些技巧可以輸出二進位制的字串,但是這個不是重點,這裡就不給出了。

最後的最後
計算機最早在什麼領域應用了編解碼?
組合語言!
計算機命令也是二進位制碼,把組合語言的英語單詞變成二進位制碼就是編碼,而把二進位制碼變成組合語言的單詞就是解碼!

相關文章