自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么采用中文編程不行?

開發(fā) 前端
通過上面的分析,我們可以得出一個結(jié)論,那就是采用中文編程,如果沒有統(tǒng)一編碼規(guī)則的情況下,會是個災(zāi)難;其次也會增加程序員們的工作難度,因為從字節(jié)來看,一個漢字至少等于英文的兩個字符,所以使用漢字會更加占內(nèi)存。

一、背景介紹

很多剛接觸計算機的同學(xué),可能會發(fā)出一個疑問,為什么不能直接使用中文編程?

要了解這個問題,還得從計算機的起源說起!

在計算機軟件里面,一切的信息都可以用 1 和 0 來表示(嚴(yán)格說連 0 和 1 都沒有,只有開和關(guān)),也被稱為二進(jìn)制位,英文簡稱:bit,音譯為“比特”,比特是計算機內(nèi)存中的最小單位(也稱原子單位),在計算機系統(tǒng)中,每 bit 可用 0 或 1 表示數(shù)位訊號。

在上篇文章中,我們了解到不管是磁盤還是網(wǎng)絡(luò)傳輸,最小的存儲單元都是字節(jié)。

有的同學(xué)可能又會發(fā)出疑問,為什么不直接使用比特存儲?字節(jié)和比特又有什么關(guān)系呢?

雖然比特是硬件上的最小單元,但是光靠 1 和 0 很難知道是什么意思,比特就好比身體的細(xì)胞,由于顆粒度太細(xì),很難知道這個細(xì)胞屬于那個地方,于是就有了字節(jié)這個概念,字節(jié)就好比身體的某個器官,更便于識別。

簡單的說,從單位換算角度,一個字節(jié) = 8 個比特!

圖片

通過這一串的 8 個 1 和 0 的不同排列方式,可以表達(dá)出 256 個(2的8次方)不同的意思,這樣換算率在當(dāng)時的美國科學(xué)家看來,已經(jīng)足夠表達(dá)英文中全部字母大小寫及符號加控制符了,也就是下文我們要介紹的 ASCII 字母代碼表。

上個世紀(jì) 60 年代,為了更好的便于計算機傳輸字符信息,美國制定了一套字符編碼規(guī)則,對英語字符與二進(jìn)制位之間的關(guān)系做了統(tǒng)一規(guī)定,這編碼規(guī)則被稱為 ASCII 編碼(美國標(biāo)準(zhǔn)信息交換碼),一直沿用至今。

圖片

ASCII 編碼一共規(guī)定了 128 個字符的編碼規(guī)則,這 128 個字符形成的集合就叫做ASCII 字符集。

在早期的 ASCII 編碼中,規(guī)定使用單字節(jié)中低位的 7 個比特去編碼所有的字符,每個字符占用一個字節(jié)的后面7位,最前面的1位統(tǒng)一規(guī)定為 0。

在這個編碼規(guī)則下,當(dāng)你在鍵盤上輸入字母 A,計算機會根據(jù) ASCII 字符代碼表,找到對應(yīng)的十進(jìn)制碼值 65,然后換算成二進(jìn)制碼值 01000001,傳輸?shù)侥康牡?;接受端收到信號之后,會將二進(jìn)制碼值 01000001 再換算成十進(jìn)制碼值 65,然后再根據(jù)字符代碼表,將十進(jìn)制碼值 65 解碼成字母 A,最后輸出到控制臺。

由此,整個計算機之間的信息傳輸交換完成!

在 ASCII 編碼中,編號 0~31 是控制字符如換行回車刪除等,32~126 是可打印字符,可以通過鍵盤輸入并且能夠顯示出來,一個英文字符占用一個字節(jié)。

對于英語來說,用 128 個符號編碼就夠了,但是隨著計算機的快速發(fā)展,用來表示其他語言,128 個符號是遠(yuǎn)遠(yuǎn)不夠的。

所以當(dāng) ASCII 碼到歐洲的時候,一些歐洲國家就決定對 ASCII 編碼進(jìn)行適當(dāng)?shù)?擴展和改造,現(xiàn)有的編碼規(guī)則維持不變,把字節(jié)中閑置的最高位也編入新的符號。比如,法語中的 é 的編碼為 130(二進(jìn)制 10000010 )。這樣一來,這些歐洲國家使用的編碼體系,可以表示最多 256 個符號,這個編碼統(tǒng)稱為 EASCII(Extended ASCII)。

但是歐洲的語言體系有個特點:小國家特別多,每個國家可能都有自己的語言體系,語言環(huán)境十分復(fù)雜。因此即使 EASCII 可以表示 256 個字符,也不能統(tǒng)一歐洲的語言環(huán)境。

為了解決上面這個問題,歐洲的工程師們想出了一個折中的方案:在 EASCII 中表示的 256 個字符中,前 128 字符和 ASCII 編碼表示的字符完全一樣,后 128 個字符每個國家或地區(qū)都有自己的編碼標(biāo)準(zhǔn)。

比如,130 在法語編碼中代表了 é,但是在希伯來語編碼中代表字母 Gimel (?),在俄語編碼中又會代表另一個符號。但是不管怎樣,所有這些編碼方式中,0—127 表示的符號是一樣的,不一樣的只是 128—255 的這一段。

根據(jù)這個規(guī)則,就形成了很多子標(biāo)準(zhǔn):ISO-8859-1、ISO-8859-2、ISO-8859-3、……、ISO-8859-16。這些子標(biāo)準(zhǔn)適用于歐洲不同的國家地區(qū)。具體關(guān)于 ISO-8859 的標(biāo)準(zhǔn)請參考這個鏈接地址。

到了亞洲國家,使用的文字符號就更多了,漢字就多達(dá) 10 萬多個。根據(jù)上面的信息,我們知道一個字節(jié)最多只能表示 256 種符號,這對于漢字來說肯定是不夠的,必須使用多個字節(jié)表達(dá)一個符號。因此才出現(xiàn)了后面的 GB2312、Unicode 等字符集,簡體中文常見的編碼方式是 GB2312,使用兩個字節(jié)表示一個漢字,所以理論上最多可以表示 65536 個符號;而 Unicode 字符集是一個很大的字符集合,最多可以使用 4 個字節(jié)來表示一個符號,可以容納 100 多萬個符號。

關(guān)于字符集的故事發(fā)展,我們在此不過深入的講解,有興趣的朋友可以看看這個鏈接地址!

下面我們重點介紹一下 Unicode 字符集!

二、Unicode 字符集

在上文的信息中,我們了解到不同的國家有不同的字符集,如果通過電子郵件把信息傳送到另外一個國家的計算機系統(tǒng)中,看到的可能就不是那個原始發(fā)送的字符了,很有可能而是亂碼!

因為計算機里面并沒有真正的字符,字符都是以數(shù)字的形式存在的,通過郵件傳送一個字符,實際上傳送的是這個字符對應(yīng)的字符編碼,同一個數(shù)字在不同的國家和地區(qū)代表的很可能是不同的符號。

為了解決各個國家和地區(qū)之間各自使用不同的本地化字符編碼帶來的不便,工程師們將全世界所有的符號進(jìn)行了統(tǒng)一編碼,稱之為 Unicode,也被稱為統(tǒng)一碼、萬國碼。

所有字符不再區(qū)分國家和地區(qū),都是人類共有的符號,如""字在 Unicode 中不再是 GBK 中的 D6D0,而是在任何地方都是 4e2d,如果所有的計算機系統(tǒng)都使用這種編碼方式,那么 4e2d 這個字在任何地方都代表漢字中的""。

需要注意的是,Unicode 只是一個字符集,它只規(guī)定了符號的二進(jìn)制代碼,卻沒有規(guī)定這個二進(jìn)制代碼應(yīng)該如何編碼如何存儲。這就造成了兩個問題:

  • 問題1:如何才能區(qū)別 Unicode 和 ASCII ?計算機怎么知道三個字節(jié)表示一個符號,而不是分別表示三個符號呢?
  • 問題2:我們知道,英文字母只用一個字節(jié)表示就夠了,如果 unicode 統(tǒng)一規(guī)定,每個符號用三個或四個字節(jié)表示,那么每個英文字母前都必然有二到三個字節(jié)是 0,這對于存儲來說是極大的浪費,文本文件的大小會因此大出二三倍,這對當(dāng)時存儲器來說,是無法滿足的。

為了解決 Unicode 字符集中的一些問題,就出現(xiàn)了 UTF(Unicode Transformation Formats) 系列的編碼規(guī)則。UTF 編碼規(guī)則具體規(guī)定了 Unicode 字符集中的字符是如何編碼的。

下面我們就來看看 UTF 系列編碼的具體實現(xiàn)。

三、UTF 編碼規(guī)則

3.1、UTF-16

早期,Unicode 轉(zhuǎn)換格式規(guī)定不管什么字符都使用兩個字節(jié)表示,兩個字節(jié)其實就是 16 Bit,所以叫做 UTF-16。

UTF-16 編碼非常方便,每兩個字節(jié)表示一個字符,這個在字符串操作時大大簡化了操作,編碼效率也比較高,尤其適合在本地磁盤和內(nèi)存之間操作,可以進(jìn)行字符和字節(jié)之間的快速切換。

但是缺陷也很明顯,首先就是一個字符占用兩個字節(jié),因為很大一部分字符用一個字節(jié)表示就夠了,現(xiàn)在需要用兩個字節(jié),存儲空間放大了一倍;其次在網(wǎng)絡(luò)之間傳輸數(shù)據(jù),容易因為大小端問題,傳輸后讀取的數(shù)據(jù)會出現(xiàn)亂碼。

3.2、UTF-8

隨著互聯(lián)網(wǎng)的普及,強烈要求出現(xiàn)一種統(tǒng)一的編碼方式,為了解決 UTF-16  中的缺陷,基于此又誕生了一種可變長度技術(shù),每個編碼區(qū)域有不同的字節(jié)長度,不同類型的字符可以是由 1~4 個字節(jié)組成,這種編碼規(guī)則我們成它為 UTF-8,由 Ken Thompson 于1992年創(chuàng)建,用在網(wǎng)頁上可以統(tǒng)一展示頁面上的中文英文繁體及其它語言正常顯示。

UTF-8 最大的一個特點,就是它是一種變長的編碼方式。它使用 1~4 個字節(jié)表示一個符號,根據(jù)不同的符號而變化字節(jié)長度,UTF-8 編碼可以容納 2^21 個字符,總共 200 多萬個字符。

UTF-8的編碼規(guī)則很簡單,只有二條:

  • 1.對于單字節(jié)的符號,字節(jié)的第一位設(shè)為0,后面7位為這個符號的 unicode碼。因此對于英語字母,UTF-8 編碼和 ASCII 碼是相同的,可以完全兼容過去的編碼規(guī)則
  • 2.對于 n 字節(jié)的符號(n>1),第一個字節(jié)的前 n 位都設(shè)為1,第 n+1 位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為 10。剩下的沒有提及的二進(jìn)制位,全部為這個符號的 unicode 碼

對不同范圍的字符使用不同長度的編碼方式,詳細(xì)的規(guī)則如下,其中字母 x 表示可用編碼的二進(jìn)制位。

圖片

比如『漢』這個字的 Unicode 編碼是 0x6C49。0x6C49 在 0x0800 ~ 0xFFFF 之間,使用 3 字節(jié)模板:1110xxxx 10xxxxxx 10xxxxxx。將 0x6C49 寫成二進(jìn)制是:0110 1100 0100 1001, 用這個比特流依次代替模板中的x,得到:11100110 10110001 10001001。

關(guān)于 UTF-8 編碼技術(shù)更加詳細(xì)的解說,可以參考這個鏈接!

四、Java 與字符編碼

Java 語言內(nèi)部使用的是 Unicode 字符集,采用 UTF-16 方式編碼字符。

但其實,Java 內(nèi)部還實現(xiàn)了ASCII、LATIN1、ISO8859-1、UTF-8、GBK 等字符集的編碼規(guī)則,可以很容易實現(xiàn)這些編碼之間的相互轉(zhuǎn)換。

在保證跨平臺特性的前提下,也支持了全擴展的本地平臺字符集,默認(rèn)顯示輸出和鍵盤輸入都是采用的本地編碼規(guī)則,因此,免不了二者的轉(zhuǎn)化問題。

以 windows 操作系統(tǒng)為例,我們看一個簡單的例子!

public static void main(String[] args) throws Exception {
    // 我們采用 GBK 進(jìn)行編碼
    byte b[] = "我們一起來學(xué)習(xí) Java 語言".getBytes("GBK");
    File file = new File("encoding.txt");
    OutputStream out = new FileOutputStream(file);
    out.write(b);
    out.close();
}

打開輸出的文件,內(nèi)容如下:

我們一起來學(xué)習(xí) Java 語言

正常情況下輸出,無編碼問題,但是如果改成這樣呢

public static void main(String[] args) throws Exception {
    // 我們采用 ISO8859-1 進(jìn)行編碼
    byte b[] = "我們一起來學(xué)習(xí) Java 語言".getBytes("ISO8859-1");
    File file = new File("encoding.txt");
    OutputStream out = new FileOutputStream(file);
    out.write(b);
    out.close();
}

輸出的文件,內(nèi)容如下:

?????Java??

亂碼問題就出現(xiàn)了!

原因相信大家都知道了,就是字符編碼和解碼的規(guī)則不一樣導(dǎo)致的。

Java 中的各個類,對于英文字符的支持都非常好,可以正常地寫入文件中,但對于中文字符就未必了!

從 Java 源代碼到寫入文件正確的內(nèi)容,要經(jīng)過 Java 源代碼 -> Java 字節(jié)碼 -> 虛擬機 -> 文件幾個步驟,在上述過程中的每一步都必須正確地處理漢字的編碼,才能夠使最終有我們期望的結(jié)果。

其中 Java 源代碼 -> Java 字節(jié)碼這一步驟,Java 編譯器 Javac 使用的字符集是系統(tǒng)默認(rèn)的字符集,比如在中文 Windows 操作系統(tǒng)上就是 GBK,而在 Linux 操作系統(tǒng)上是 ISO8859-1。所以經(jīng)常有同學(xué)發(fā)出疑問,自己在本地的 windows 系統(tǒng)上運行的很正常,但是把代碼部署到了 Linux 操作系統(tǒng)上編譯的類中源文件中的中文字符就出現(xiàn)亂碼了。

解決辦法就是在編譯的時候添加 encoding 參數(shù),并指定對應(yīng)的編碼規(guī)則,比如 GBK 或者 UTF-8,這樣才能夠與平臺無關(guān)。

如果想要查詢 jdk 使用的是哪種編碼規(guī)則,可以通過如下方式查詢:

public static void main(String[] args) {
    System.getProperties().list(System.out);
}

輸出的內(nèi)容比較多,重點看下file.encoding變量值就可以,比如小編當(dāng)前的電腦顯示結(jié)果如下:

file.encoding=GBK

表明了 JDK 使用的是 GBK 字符集,當(dāng)對字符串進(jìn)行操作時,都做了 Unicode 到 GBK 的轉(zhuǎn)換,既然 JDK 用的 GBK 編碼,那么用 ISO8859-1 字符集顯示 GBK 編碼出來的中文當(dāng)然是有問題的。

因此在實際使用過程中,推薦大家統(tǒng)一編碼規(guī)則,比如采用比較通用的 UTF-8 編碼規(guī)則,可以避免無端的文字亂碼問題。

五、小結(jié)

最近網(wǎng)上有傳聞?wù)f,采用中文來編程,大家可以試想一下,采用中文來編程會是個什么樣的結(jié)果?

通過上面的分析,我們可以得出一個結(jié)論,那就是采用中文編程,如果沒有統(tǒng)一編碼規(guī)則的情況下,會是個災(zāi)難;其次也會增加程序員們的工作難度,因為從字節(jié)來看,一個漢字至少等于英文的兩個字符,所以使用漢字會更加占內(nèi)存。

還有一點就是,英文最多也就 26 個字符,比較簡單,在所有的計算機上都非常通用,如果換成中文的話,截止目前,中文的符號已經(jīng)超過 10 萬個了,還沒有完全收集全,如果換成中文來編程,需要窮舉所有的中文字符,以防干擾程序的正常執(zhí)行,這在目前看來基本弊大于利!

六、參考

1、知乎 - 爐石不傳說 - 字符、字符集、字符編碼的基礎(chǔ)知識科普

2、博客園 - 五月的倉頡 - 字符編碼

3、知乎 - 韓蘭若 - UTF-8 到底是什么意思?unicode編碼簡介

責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2015-08-06 10:19:19

編程腦子

2021-01-20 12:44:22

JAVA編程語言軟件

2021-01-20 12:43:07

編程語言Java

2021-04-05 14:47:05

裝飾器Python代碼

2013-01-22 09:35:27

Hadoop存儲

2018-06-04 15:17:10

編程語言中文編程

2023-09-27 08:22:28

Windows系統(tǒng)管理器

2019-08-13 21:49:54

編程中文API中文編程

2021-05-08 08:55:54

CPUIBMIntel

2021-07-21 09:35:36

switchbreakJava

2015-08-27 16:48:11

FirefoxChrome

2019-12-30 08:34:40

ZabbixPrometheus監(jiān)控

2011-07-21 11:11:10

Scrum

2022-04-02 09:32:06

大數(shù)據(jù)數(shù)據(jù)智能企業(yè)

2020-04-14 10:09:22

混合云公共云云計算

2022-10-28 10:01:43

云應(yīng)用云計算

2021-07-15 10:17:24

混合云云計算云遷移

2019-08-15 16:48:30

2023-10-09 08:24:54

IPC機制Binder

2012-12-16 15:26:49

超級計算機LinuxHPC
點贊
收藏

51CTO技術(shù)棧公眾號