計算機程式的思維邏輯 (8) - char的真正含義

swiftma發表於2016-08-02

本系列文章經補充和完善,已修訂整理成書《Java程式設計的邏輯》(馬俊昌著),由機械工業出版社華章分社出版,於2018年1月上市熱銷,讀者好評如潮!各大網店和書店有售,歡迎購買:京東自營連結

計算機程式的思維邏輯 (8) - char的真正含義

看似簡單的char

通過前兩節,我們應該對字元和文字的編碼和亂碼有了一個清晰的認識,但前兩節都是與程式語言無關的,我們還是不知道怎麼在程式中處理字元和文字。

本節討論在Java中進行字元處理的基礎 - char,Java中還有Character, String, StringBuffer, StringBuilder等類進行文字處理,他們的基礎都是char,我們在後續文章中介紹這些類。

char看上去是很簡單的,正如我們在第2節所說,char用於表示一個字元,這個字元可以是中文字元,也可以是英文字元。賦值時把常量字元用單引號括起來,例如:

char c = 'A';
char z = '中';
複製程式碼

但我們在第3節丟擲了一個問題,為什麼字元型別也可以進行算術運算和比較?char的本質到底是什麼呢?

char的本質

在Java內部進行字元處理時,採用的都是Unicode,具體編碼格式是UTF-16BE。簡單回顧一下,UTF-16使用兩個或四個位元組表示一個字 符,Unicode編號範圍在65536以內的佔兩個位元組,超出範圍的佔四個位元組,BE (Big Endian)就是先輸出高位位元組,再輸出低位位元組,這與整數的記憶體表示是一致的。

char本質上是一個固定佔用兩個位元組的無符號正整數,這個正整數對應於Unicode編號,用於表示那個Unicode編號對應的字元。

由於固定佔用兩個位元組,char只能表示Unicode編號在65536以內的字元,而不能表示超出範圍的字元。

那超出範圍的字元怎麼表示呢?使用兩個char。類Character/String有一些相關的方法,後續文章介紹。

在這個認識的基礎上,我們再來看下char的一些行為,就比較容易理解了。

char的賦值

char有多種賦值方式:

  1. char c = 'A'
  2. char c = '馬'
  3. char c = 39532
  4. char c = 0x9a6c
  5. char c = '\u9a6c'

第1種賦值方式是最常見的,將一個能用Ascii碼錶示的字元賦給一個字元變數。

第 2種也很常見,但這裡是箇中文字元,需要注意的是,直接寫字元常量的時候應該注意檔案的編碼,比如說,GBK編碼的程式碼檔案按UTF-8開啟,字元會變成亂碼,賦值的時候是按當前的編碼解讀方式,將這個字元形式對應的Unicode編號值賦給變數,'馬'對應的Unicode編號是39532,所以第2種賦值和第3種是一樣的。

第3種是直接將十進位制的常量賦給字元,第4種是將16進位制常量賦給字元,第5種是按Unicode字元形式。

以上,2,3,4,5都是一樣的,本質都是將Unicode編號39532賦給了字元。

char的運算

由於char本質上是一個整數,所以可以進行整數可以進行的一些運算,在進行運算時會被看做int,但由於char佔兩個位元組,運算結果不能直接賦值給char型別,需要進行強制型別轉換,這和byte, short參與整數運算是類似的。

char型別的比較就是其Unicode編號的比較。

char的加減運算就是按其Unicode編號進行運算,一般對字元做加減運算沒什麼意義,但Ascii碼字元是有意義的。比如大小寫轉換,大寫A-Z的編號是 65-90,小寫a-z的編號是97-122,正好相差32,所以大寫轉小寫只需加32,而小寫轉大寫只需減32。加減運算的另一個應用是加密和解密,將 字元進行某種可逆的數學運算可以做加解密。

char的位運算可以看做就是對應整數的位運算,只是它是無符號數,也就是說,有符號右移>>和無符號右移>>>的結果是一樣的。

char的二進位制

既然char本質上是整數,檢視char的二進位制表示,同樣可以用Integer的方法,如下所示:

char c = '馬';
System.out.println(Integer.toBinaryString(c));
複製程式碼

輸出為 1001101001101100

小結

本節介紹了char的本質,它固定佔用兩個位元組,實際上是一個整數,表示字元的Unicode編號,不在65536編號內的字元一個char表示不了,需要用兩個char。

我們回顧一下以前所有的章節,整理一下思路。

我們說,所謂程式,主要就是告訴計算機要對什麼資料做什麼操作。第1節我們介紹瞭如何通過變數定義資料,第2節介紹了資料的第一個操作 - 賦值,第3節介紹了資料的基本運算,第4節到本節介紹了資料的二進位制表示及位運算。

至此,我們可以定義基本資料型別,以及對基本資料進行基本運算了,但實際操作中不是隻有運算本身的,我們需要有表達類似"如果"/"那麼"邏輯的機制,即根據具體情況選擇執行的機制,也就是流程控制。


未完待續,檢視最新文章,敬請關注微信公眾號“老馬說程式設計”(掃描下方二維碼),深入淺出,老馬和你一起探索Java程式設計及計算機技術的本質。原創文章,保留所有版權。

計算機程式的思維邏輯 (8) - char的真正含義

相關文章