• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            colorful

            zc qq:1337220912

             

            每個軟件開發者必須絕對至少需要了解的Unicode和Character Sets的知識(沒有借口!)

            http://blog.csdn.net/natsu1211/article/details/8518398

            每個軟件開發者必須絕對至少需要了解的Unicode和Character Sets的知識(沒有借口!)

             

            原文:http://www.joelonsoftware.com/articles/Unicode.html

             

            by Joel Spolsky

            windam

             

            2003.10.8 星期三

            你是否曾經對那個神秘的Content-Type標記感到不解?

            譯注:每個HTML頁面的head塊中都可能包含一個Content-Type標記,例如:

            <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />

            你知道這東西應該被放到HTML里,但是你從來都沒有確切得弄清楚它到底應該是什么?

             

            你是否曾經收到過你朋友從Bulgaria發來的Email,它的主題行是“???? ?????? ??? ????”?

             

            當我發現還有那么多的軟件開發者并沒有真正領會關于字符集(Character sets),編碼(encoding),Unicode以及相關知識的時候,我非常失望。幾年前,FogBUGZ的一個beta測試者對于它是否能處理收到的日語郵件感到疑惑。日語?他們有日文的Email?我不知道。但當我仔細研究我們用來解析MIME email的商業ActiveX控件時,我們發現它恰恰正好對字符集做了完全錯誤的處理,于 是,為了撤銷控件中所做的錯誤轉換,并正確的重新處理,我們不得不編寫修正它的補救代碼。而當我研究另一個商業庫的時候,發現它有一樣的完全錯誤的字符代 碼實現。我和那個代碼庫的開發者通信,發現他的想法是,他們“不能(對字符集)做任何事(正確的處理)”。就像很多程序員一樣,他只是祈禱著,這一切麻煩 事都可以被吹走。

             

            但事實上不會!當我發現流行的web開發語言PHP幾乎完全的忽略了字符編碼的問題,沒心沒肺的用了8bit字符,這種傻逼的行為讓開發好的國際化web應用變得幾乎不可能的時候,我想,我受夠了。

             

            我在此聲明:如果你是一個工作在2003年或之后的程序員(此文寫于2003年10月),并且你還沒有對字符,字符集,編碼和Unicode有所了解,而且你被我我抓住了,我會罰你在潛艇里剝6個月的洋蔥皮!我發誓我會這樣做的!

             

            此外還有一事:

             

            這真的沒那么難

             

            在本文中,我將會告訴你每個在工作中的程序員所應知道的。所有關于“plain text = ascii = character就是8bit”的知識不僅僅是錯誤的,而且是錯得令人絕望。如果你依然像這樣編程,那么你真不比一個不信基因的醫生好到哪里去。在讀完本文之前,請不要再編寫任何一行代碼!

             

            在我開始之前,我應該提醒你,如果你是那些少數懂得國 際化的知識的程序員,那么你會發現我討論的整個話題有那么一點過于簡化。我僅僅只是希望在此設立一個門檻,使得每個人都理解關于字符編碼究竟都發生了些什 么事情,并有希望使寫出的代碼可以在任意語言下正常工作,而非僅僅只能工作在在不帶方言詞匯的英語環境中。我還要再提醒你,想創建可以在國際化語言環境下 工作的軟件,字符處理僅僅只是很小的一部分工作,但是我一次只能寫一個主題,所以本文就是關于字符集的。

             

            從歷史的角度

             

            理解一件事情的最簡單的方法,就是回到它發生的時候去。

             

            你可能以為我要在此談論那些非常老舊的字符集如EBCDIC。嘛,我們不討論那些。EBCDIC和你的生活沒有關聯。我們不需要走到那么遠古的時期。

             

            clip_image002[13]回到再近一點的時間,當Unix被發明,K&R正在寫那本著名的The C Programming Language的時候,一切都還很簡單。EBCDIC正逐漸消亡。那時唯一有意義的就是那些美好的,不包含方言字符的英文字母。于是我們將這套將每一個字符通過32到127之間的數進行表示的編碼,記做ASCII。例如,空格是32, 字母“A”是65。這些字符用7個bit就可以存儲。那個年代的電腦多數采用8bit為一字節,因此你不光可以用7個bit保存每個可能的ASCII字 符,你還有一個bit的空余,如果你夠邪惡,你也可以將之用于自己的狡猾目的:WordStar用了一個很2B的做法——用最高位來標識一個單詞的最后一 個字母,這宣告了WordStar僅能用于英文文本。比32小的編碼被稱為不可打印字符,并且被用來釋放詛咒——只是開個玩笑,實際上它們是控制字符,比 如7可以讓你的電腦發出蜂鳴聲,12可以讓當前頁紙被送出打印機并傳入新紙。

             

            如果你只是一個英語使用者的話,這一切都很美好。

             

            因為一個字節有8個比特,于是很多人就想,“哎,我們可以使用128-255作為自己的用途”。不過麻煩在于,很多人同時有了這個想法,并且他們關于如何使用128~255的想法又各不相同。IBM-PC弄出來一個被稱為OEM字符集的玩意,為歐洲的語言提供了一些方言字母,以及一串用來繪制線條的字符如水平條,豎直條,右側帶有小的拐角的水平條等。這樣,你就可以使用這些畫線字符,在屏幕上繪制整潔漂亮的方框與線條了。你至今依然可以在那些那些運行于8088計算機的干洗機上看到這些字符。事實上,當除美國之外的人們開始購買PC時,人們憑空捏造出各種各樣的OEM字符集,都將高128位用于自己的用途。舉例來說,在一些PC上,字符碼130被顯示為é,而在以色列銷售的計算機,這個字符碼則顯示為希伯來字母(clip_image004[32]) ,于是,如果美國人將他們的résumés(簡歷)發送到以色列,這簡歷在到達后就變成了rclip_image004[33]sumclip_image004[34]s。在很多場合,比如俄語中,關于如何使用高128位字符有各種各樣的辦法,因此你甚至無法可靠的交換俄語文檔。

             

            最終,這種混亂無序的OEM編碼被ANSI標準統一了。在ANSI標準中,所有人都同意對低128的定義,與ASCII碼保持一致,高128位編碼的處理方式,則取決于你生活在什么地方。這些對高128位編碼做不同處理的體系被稱為code pages(代碼頁)。所以,例如以色列的DOS使用 的代碼頁被稱為862,而希臘的用戶使用的代碼頁是737。這些不同代碼頁在128以下的部分都是相同的,而對于128以上的編碼則有不同的處理方案(那 些搞笑的字母皆被含在其中)。MS-DOS的國家版本中包含了很多上述這種代碼頁,可以處理從英語到冰島語的一切,他們甚至還包括了少數“多語言”代碼 頁,可以在一臺電腦上同時支持世界語和加利西亞語!WOW!但是話說回來,由于希伯來語和希臘語分屬不同的代碼頁,對大于128的字符有完全不同的解釋,因此除非使用位圖,否則想在一臺電腦上同時支持這兩種語言則是一件完全不可能的任務。

             

            另一方面,在亞洲,事情則更加令人抓狂了,因為亞洲的許多語言擁有數以千記的字符,這是無論如何不可能用8 個bit進行編碼的。這種情況通常是用“DBCS”的方式進行解決,也即雙字節字符集,在雙字節字符集中,有的字符使用一個字節進行表示,而有的則需要存 儲在2個字節中。這種字符集的問題在于,通常想要在字符串中順序遍歷比較容易,但是要想反向遍歷,則幾乎不可能。對于這類字符串,程序員們最好不要使用 s++或者s–對其進行遍歷,而是最好使用預定義的函數,例如Windows平臺上的AnsiNext和AnsiPrev函數,它們知道如何處理這一切亂 七八糟的麻煩事。

             

            但是,絕大多數人依然以為一個字節就恰好對應著一個字 母,或是一個字母就是一個字節。只要你永遠不把一個字符串從一臺電腦上拷貝到另一臺電腦上,或者從來不使用超過一種語言,這種做法就可以在某種意義上正常 的工作。但是,理所當然的,由于因特網的普及,現在將字符串從一臺電腦拷貝到另一臺電腦變得越來越常見,那么這一切做法的基礎就垮臺了。幸運的是,Unicode被發明了。

             

            Unicode

             

            針對人們想要創建一個可以囊括這顆星球上一切可能的書寫系統的字符集的目標,Unicode 是一次勇敢的嘗試。一些人以為Unicode只是一個簡單的16bit編碼,其中的每個字符都可以擁有16個bit,因而可以支持最多65536種可能的字符,這種對Unicode的認識,事實上,是錯誤的。這是針對Unicode流傳得最廣的一種誤解,所以,如果你也是這樣認為的,不用覺得過于沮喪。

             

            事實上,Unicode針對字符有一套完全不同的思路,因此你必須遵循Unicode看待事物的思維模式,否則你什么都理解不了。

             

            直到現在,我們都認為一個字母可以被映射為若干比特,你可以將之存儲于內存中或者磁盤上。

             

            例如 A -> 0100 0001

             

            Unicode中,一個字母被映射到一個稱為code point的東西,這只是一個理論上的抽象概念。至于這個code point如何在內存中表示,或是在磁盤中存儲,則又是另一回事了。

             

            Unicode中,字母A是抽象的形象。它在天堂中漂浮著:

             

            A

            這個抽象的Unicode中的A不同于B,且不同于a。但是與A或者A以 及A都是等同的。關鍵的地方在于,Times New Roman字體中的A與Helvetica字體中的A是相同的字符,而與小寫的“a”是不同的字符。這看起來并沒有什么有所疑議的,但是在某些語言中,僅 僅指出一個字母是什么就可能引發疑議。德文字母ß究竟是一個真實的字母,還是僅僅只是s的另一種花式寫法?如果一個單詞末尾的字母的形狀改變了,那么這個 字母是否意味著一個不同的字母——請作答?在希伯來文中,上面這個問題的回答為真,而在阿拉伯語中,則為假。無論如何,Unicode協會的那些聰明人們 已經在上一個十年間把這些東西都搞定了,盡管那其中依然包含了一大堆政治上的討價還價,但是最終的結果是,你不用再為這些麻煩事而煩神了——他們把這些玩 意都搞定了。

             

            Unicode協會為每一個字母表中的每一個抽象字母都賦予了一個Magic number,寫起來就像是這樣:U+0639。這個Magic number(魔數)就被稱為code point。其中的U+意味著“Unicode”,而數字的部分則是16進制的(譯注:4位16進制數也就意味著需要16個bit的存儲空間)。那么U+0639實際上就是阿拉伯字母Ain。英文字母A則是U+0041。你可以在Windows 2000/XP(譯注:在Vista or Win7上也可)使用charmap實用工具來查詢這些code point(譯注:點擊開始菜單,運行,輸入charmap回車啟動該工具),也可以通過訪問Unicode的網站查詢。

             

            clip_image006[13]

            (譯補圖:這是charmap實用工具的運行界面,其中英文字母A如圖所示恰為U+0041)

             

            并沒有人真正對Unicode所能表示字母數目上限進行限制,事實上,Unicode所能表示的字母數目可以超過65536,所以并不是每一個Unicode字母都可以被塞進2字節的空間中,不過這只是個傳聞。

             

            OK,假設我們有這樣一個字符串

             

            Hello

            Unicode中,這被表示為以下五個code point:

             

            U+0047  U+0065  U+006C  U+006C  U+006F.

             

            只是一組code point。事實上,也就是數字。到目前為止,我們還沒有提到過如何在內存中存儲它們,或是在email中如何表示它們。

             

            Encodings

             

            這就是encodings (編碼)發揮作用的地方了。

             

            關于Unicode編碼的最早的主意是這樣的,嘿伙計,咱們把這些數字每個存成2字節吧。(這個主意也正是2字節神話的淵源)于是,我們的Helllo就變成了下面這樣:

             

            00 48 00 65 00 6C 00 6C 00 6F

             

            對嗎?別著急!為什么不能是下面這樣呢:

             

            48 00 65 00 6C 00 6C 00 6F 00

             

            好吧,從技術上說,這樣也可以,我確實這么認為,而事實上,由于早期的實現者們在他們要存儲Unicode code point的時候,希望依據特定的CPU架構選擇是使用大端(high-endian)還是小端(low-endian)模式,這樣使得CPU處理速度得 以最佳化。于是,看哪,很快的,就出現了兩種不同的存儲Unicode的方式。于是人們不得不創造一個離奇的約定,在Unicode的字符串的最前面加上 一個FE FF標識符。這個標識符被稱為Unicode Byte Order Mark(Unicode字節序標識符),并且,如果你反轉了你的高低字節,那么這個標識符就會變成FF FE,于是讀取你的字符串的人就可以知道他們必須要翻轉你的每一對高低字節。但是,喔,并不是每一個Unicode字符串都在開頭有這個字節序標識符。

             

            一開始,這一切看起來似乎還是挺好的,但是逐漸的,程序員們開始抱怨,“看那一堆沒用的0!” ——由于這些美國程序員多數情況下只使用英文文本,也就意味著他們幾乎不會用到那些高于U+00FF的code point。尤其是他們多數還是加州的新自由主義嬉皮士,假若他們是德州人,那么他們多半不會在意這些多出來的字節。但是最終,這幫加州的苦孩子們終于無 法容忍字符串存儲空間被無端的增長一倍,并且,由于有那么多的文檔已經用各種ANSI和DBCS字符集存在了,誰會把這些文檔都轉換到Unicode下來 呢?難道是我(法語)來?僅僅因為這樣的想法,于是在好幾年的時間里,大多數人都決定無視Unicode,這使得事情變得更糟。

             

            終于,一個天才的概念被發明出來了——UTF-8UTF-8在內存中通過8bit的字節來保存U + magic number,定義了保存Unicode字符串的一整套系統。在UTF-8中,0-127之間的code point被保存在一個單字節中。只有那些大于等于128的code point,需要用到2,3以及多至6個字節來保存。

             

            clip_image008[14]

             

            這種做法獲得了一個非常不錯的副作用——那就是UTF-8中的英文文本與ASCII中的英文文本可以完全的保持一致,于是美國人們都不會發現有什么事情變得不一樣了。只有這世界上其他地方的人們不得不跳過這個坑。舉例來說,Hello, 這個字符串由code point:U+0048 U+0065 U+006C U+006C U+006F組成,在存儲的時候,被保存為48 65 6C 6C 6F,這,恰恰正好與ASCII,ANSI,以及這顆星球上所有的OEM字符集中的表示都完全一樣。現在,如果你需要去使用方言字母,或者是希臘字母,或 者是克林貢語字母的話,那么你就不得不為每個code point使用多個字節去存儲了,不過美國人永遠都不用在意這些了。(UTF-8還有一個非常漂亮的特性,以往的Unicode字符串想使用老式的以單個 byte的0作為字符串的結尾并不至于切斷字符串的話需要一些處理代碼,而UTF-8則可以忽略之。)

             

            到目前為止,我已經告訴了你Unicode 編碼的三種方法。最傳統的兩字節存儲方式被稱為UCS-2(因為有2個字節)或者UTF-16(因為有16個Bit),并且你還得自己弄清楚究竟這是一個 大端(High-endian)UCS-2還是一個小端(low-endian)UCS-2。你還可以采用全新的UTF-8標準,如果你只使用英文文本, 它會讓你在碰到一個無腦程序時,即便它完全無視了除ACSII之外的一切,你依然會過得很幸福!

             

            事實上還有其他一系列方法來編碼Unicode。 有一種編碼叫做UTF-7,它與UTF-8有很多相似之處,但是它假定所有字節的最高比特都是0。因為這個原因,如果你要把Unicode字符串傳遞給一 個嚴格認為7bit就足夠用的警方郵件系統,那么感謝UTF-7吧,它能使你免于痛苦。還有種UCS-4編碼,它使用4個字節存儲一個code point,它有個不錯的特性,每個code point都是等長的,但是麻煩在于,它是在浪費了太多的內存,以至于即便是得克薩斯人也不敢使用它。

             

            事實上你正在使用Unicode code point所表示的柏拉圖式的理想的字母來考慮這些問題,這些Unicode code point同樣也可以使用任何一種舊的學院派的編碼方案來表示。舉例而言,你同樣可以用ASCII或古希臘OEM編碼或希伯來ANSI編碼,乃至迄今為止 已被發明的數百種編碼,來表示一個Unicode編碼的字符串Hello(U+0048 U+0065 U+006C U+006C U+006F)。但是這些做法有一個陷阱,那就是某些字母可能不能正常顯示!如果你想要將某個Unicode code point在某種編碼中表示,而該編碼中又沒有能對應上該code point的,你常常會得到一些小的問號:?或者,如果你的人品不錯,你會得到一個?

             

            存在數以百計的傳統編碼,它們都只能正確表示Unicode code point的某些子集,而對那些處理不了的code point,則用問號來處理。有一些流行的英文編碼,諸如Windows-1252(這是Windows 9x中的西歐語言標準),以及ISO-8859-1aka Latin-1(同樣在任何一個西歐語言中都會有用的),如果你想要用上面這些編碼來處理俄文或者是希伯來字母,那么你會得到大量的問號。與之對應的,UTF7,8,16以及32等編碼則有非常棒的特性,它們可以正確表示任何Unicode code point

             

            關于編碼的最重要的事實

             

            如果你把我之前所解釋的所有一切都忘光了,請你至少記住一個最最最重要的事實。如果你有一個字符串,而不知道它的編碼,那么這個字符串是毫無意義的。你再也不能把腦袋埋到沙子里,然后假裝“普通”文本就是ASCII。

             

            這世界上就沒有普通文本這回事。

             

            如果你有一個字符串,不管是在內存里,還是在文件里,還是在一封email中,你必須知道它的確切的編碼,否則你不可能做到正確的解釋它,或是向用戶顯示。

             

            幾乎所有的像是“我的網站看起來像是在胡言亂語”,或者是“如果我在郵件里用了方言字母,那么她就無法閱讀”的傻逼問題,幾乎都是由于某些天真犯二的程序員沒能理解下面這個事實:如果你不告訴我一個特定的字符串用的是哪一種編碼,UTF-8或是ASCII或是ISO 8859-1(Latin 1)或是Windows 1252(西歐),那么我就不可能正確的顯示這個字符串,甚至不可能知道哪里是它的結尾。有上百種編碼格式的存在,并且一旦出現大于127的code point,那么一切就全完了。

             

            一個字符串是如何編碼的,我們要如何維護這樣一個信息呢?好吧,關于這件事情,有一些標準做法。對于email消息,你最好在正文的頭部,加入這樣一行字符串:

             

            Content-Type: text/plain; charset=”UTF-8″

             

            對于網頁頁面,最早的想法是由web服務器返回一個類似的Content-Type,把這個信息放在與網頁內容一同傳輸的HTTP報頭中,不是放在HTML頁面里,而是放在響應報頭里,在HTML內容之前被發送。

             

            但這種做法會導致問題。想象一下你有一個巨大的web 服務器,上面跑著很多網站,并且有著由不同的人貢獻的數以百計的網頁。這些人創建網頁的時候,他們所使用的Microsoft FrontPage可能以任何它覺得合適的方式來選擇編碼進行存儲。web服務器本身對此一無所知,它不可能知道每一個文件是以什么編碼格式寫的,所以它 也就無法為之發送Content-Type頭。

             

            如果你使用某種特殊的tag,把 HTML文件所使用的Content-Type直接寫到HTML文件里,就會讓后續的事情變得更加方便。當然這種做法會讓某些純化論者感到抓狂…如果你不 知道這個HTML文件的編碼,你要如何去讀取它?!幸運的是,幾乎所有的編碼對32到127之間的字符都是同樣對待的,于是,在需要使用任何詭異的字母之 前,你總是可以在HTML頁面中讀取到至少像下面這樣多的內容:

             

            <html>

            <head>

            <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>

             

            但是需要注意的是,這個meta tag必須是<head>節中最先出現的東西。因為只要網頁瀏覽器見到這個tag,它就會停止解析這個頁面,并且使用你所指定的編碼開始重新解釋整個頁面。

             

            如果網頁瀏覽器即無法從http報頭也 無法從HTML的meta標記中找到任何Content-Type信息,那么它們會如何對待這個網頁呢?事實上,Internet Explorer做了一些有趣的事情,它基于一種啟發式的方法去猜(依照典型編碼的典型文本中,各種不同的語言使其字節呈現不同的分布頻率的規律)。因為 各種舊的8bit代碼頁會嘗試把他們國家的字母放在128~255中不同的區間段里,同時又由于每一種人類語言對字母的使用都呈現不同的統計特征,所以上 述方案,有一定的概率是可以工作的。這做法是很怪異的,這使得那些天真無邪的網頁作者,在從來不知道每個HTML頁面都需要一個Content-Type 頭的情況下繼續寫網頁,并且當他們在瀏覽器中查看時,發現一切都是正常的。直到有一天,他們寫了點東西,與他們母語中的字母頻率分布不相符合,于是 Internet Explorer便認為這是一段韓語,然后,就這么繼續顯示出來……我相信,這證明了Postel法則中所說的,“寬容的對待輸入,而保守的輸出”,坦白說并不是一個好的工程原則。無論如何,當這個網站的可憐的讀者,在面對這個被顯示成韓語(并且事實上是根本無法理解的韓語)而事實上是保加利亞語的網頁時,要怎么做呢?他使用View|Encoding菜單,并且依次嘗試每一個編碼的選項(至少有十數個東歐語言選項),直到一切變得正常。但是,事實上,多數人都不知道要這么做。

             

            clip_image009[13]

             

            我公司所發布的網站管理軟件CityDesk的最新版本中,我們決定內部的一切都用UCS-2(2字節)Unicode表示,這也是Visual Basic,COM以及Windows NT/2000/XP所使用的原生的字符串類型。

             

            C++代碼中,這意味著當定義字符串時,我們使用wchar_t(寬字符)來替代char,并且使用wcs系函數來替代str系函數(例如,使用wcscatwcslen而不是strcatstrlen)。要在C代碼中創建一個UCS-2的字符串,你只需要在字符串定義前增加一個L,如:L”Hello”

             

            CityDesk發布網頁時,它將之轉換為已經為網頁瀏覽器所支持多年的UTF-8編碼格式。這也是Joel on Software全部29種語言版本所使用的編碼,并且我從來沒有聽到過任何一個人抱怨說在閱讀它的時候遇到麻煩。

             

            本文的篇幅有點長,并且我也不可能覆蓋關于Unicode和字符編碼的所有話題,我希望的是,如果你已經閱讀到這里,你已經知道了足夠多的知識,我留給你的任務,就是回去編寫程序,并且記得在對付疾病的時候使用抗生素,而不是水蛭和魔咒。

             

            還想知道更多?你現在閱讀的是Joel on Software,這里填滿了各種經年累月積累下來的關于軟件開發,管理軟件團隊,設計用戶界面,成功運營一家軟件公司,以及橡皮鴨的各種胡言亂語的文章。

             

            關于作者:我 是Joel Spolsky,Fog Creek Software的共同創始人,Fog Creek Software是一家紐約的公司,它證明了你可以在對待程序員們很好的同時創造出很高的利潤。這里的程序員擁有私人的辦公室,免費的午餐,以及每周40 個小時的工作時間。公司的客戶只為他們滿意的軟件付費。我們創造了一個更先進的bug跟蹤軟件FogBugz,以及軟件開發工具。Kiln,一個分布式的源代碼管理系統,如果你迷戀svn,它會讓你非常驚喜,以及Fog Creek Copilot,可以讓訪問遠程桌面變得更加容易。我同時也是Stack Overflow的共同創始人。

             

             

            譯注:本文對Unicode和編碼的解釋非常棒,將編碼和字符集的來龍去脈解釋得深入淺出,是每個合格的程序員所必知必會的基礎知識,本人在閱讀《Game Engine Architecture》一書時,了解到此文,遂生出翻譯的興趣,翻譯的過程中確又發現再次理清了若干此前未曾真正理解的概念,只因英文水平和精力有限,難免有所錯漏,如有指正,不吝感激。

            posted on 2013-06-22 15:47 多彩人生 閱讀(2975) 評論(2)  編輯 收藏 引用

            評論

            # re: 每個軟件開發者必須絕對至少需要了解的Unicode和Character Sets的知識(沒有借口!) [未登錄] 2013-06-23 04:12 simon

            非常好的文章,使我受益匪淺!

            翻譯方面只有一點小地方值得商榷 - 關于大端和小端編碼,比較普通的英文應為big endian 和little endian,可以參考Wiki的網站:http://en.wikipedia.org/wiki/Endianness

              回復  更多評論   

            # re: 每個軟件開發者必須絕對至少需要了解的Unicode和Character Sets的知識(沒有借口!) 2014-12-16 17:25 SH

            同樣是閱讀《游戲引擎架構》一書被作者要求讀的  回復  更多評論   

            導航

            統計

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            亚洲一本综合久久| 一本久久知道综合久久| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 国产精品久久久久影视不卡| 99久久精品免费看国产一区二区三区| 亚洲国产成人精品女人久久久| 亚洲国产日韩综合久久精品| 久久99九九国产免费看小说| 四虎亚洲国产成人久久精品| 久久久无码一区二区三区| 免费观看成人久久网免费观看| 欧美精品乱码99久久蜜桃| 久久亚洲精品成人AV| 欧美午夜精品久久久久久浪潮| 久久久久人妻一区精品果冻| 99久久免费国产精品热| 久久人人爽人人爽人人片AV东京热| 伊色综合久久之综合久久| 久久精品国产69国产精品亚洲| 久久婷婷色香五月综合激情| 国内精品久久久久| 日韩欧美亚洲综合久久影院d3| 久久久久青草线蕉综合超碰| 亚洲日本va午夜中文字幕久久| 品成人欧美大片久久国产欧美...| 久久99免费视频| 91精品国产高清久久久久久国产嫩草 | 日韩AV无码久久一区二区| 中文字幕亚洲综合久久菠萝蜜| 99久久久久| 亚洲欧美日韩中文久久| 97久久精品午夜一区二区| 成人久久久观看免费毛片| 精品国产婷婷久久久| 伊人 久久 精品| 久久精品国产免费| 久久亚洲国产成人影院网站| 久久成人国产精品免费软件| 无码人妻久久一区二区三区免费 | 久久综合亚洲色HEZYO国产| 日韩十八禁一区二区久久|