轉載自: http://www.ituring.com.cn/article/111027算法
問題的原由是和一個朋友討論不一樣編碼的轉換問題,說到了wchar_t的類型,朋友的見解是,wchar_t的編碼方式是utf-16,長度必定是16位的。個人見解不一樣,我認爲wchar_t的長度和編碼方式都是編譯器和平臺決定的,和語言沒任何關係。ide
後來這個朋友爲了說服我,回家把C++ Primer給我搬出來了,還給我截了個圖(由於我沒這本書),在這本書第30頁有個表格,清楚地寫着wchar_t是unicode字符,而最小尺寸是16。既然「最小尺寸是16」了,那麼其餘尺寸的可能性就有了,可是編碼方式是怎麼回事?由於憑我印象,貌似沒有任何文檔規定過寬字符的編碼方式,我想說服我朋友,但腦子裏有沒有證據,不知道從何提及,所以回家仔細查了查資料,算是有了個瞭解。ui
1. 寬字符的編碼方式究竟是誰定的?編碼
這裏有兩個選擇,要麼是C++語言標準,要麼是編譯器做者設計的;如果前者,則編碼方式就沒有異議了,任何平臺、任何編譯器,都應該同樣;但如果後者,這就徹底取決於編譯器製做者的想法了。那麼,C++中,究竟是什麼狀況?設計
咱們能夠翻閱下C++ ISO 2003的文檔,在3.91章第五條,清楚地寫着wchar_t的定義以下:code
Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales (22.1.1). Type wchar_t shall have the same size, signedness, and alignment requirements (3.9) as one of the other integral types, called its underlying type.ci
從這段描述中能夠得出幾個結論:1. wchar_t是用來存儲全部支持區域的字符的;2. wchar_t的底層存儲方式是整形,本質上也就是個整形。unicode
其實不管是char仍是wchar_t,底層的存儲都是整形,所以即便你存了個字符進去,仍然會以整形的形式存儲,因此這裏面涉及到了一個轉化問題,也就是咱們所談的字符編碼。開發
而編碼方式在以上的C++ ISO文檔裏並找不到文字說明,所以,能夠肯定,編碼方式是編譯器實現的,而且是沒有標準的。rem
那麼,就引出了第二個問題。
2. 編碼方式有幾種?寬字符存儲的長度同樣嗎?
先從char提及,char型的常見編碼方式是ASCII,ASCII編碼是一種基於8位二進制數的字符編碼算法,是美國ANSI制定的一種單字符編碼方案,能表示256種可能的字符,常見的字母、符號、鍵盤指令等,全能用ASCII碼錶示,而因爲ASCII碼是基於8位的編碼,所以用這種算法的編譯器,char類型都佔8位。請注意因果關係,是由於用了ASCII,因此char纔是8位,而不是char是8位,因此採用ASCII。
同理可適用於wchar_t類型。
wchar_t的出現,是出於程序兼容多語言的需求,由於在不少語言中,字符的數量遠遠大於256,所以須要把原字符進行擴容,必須能表示更多的字符類型。所以wchar_t出現了,wchar_t全稱是wide character type,也就是寬字符。最多見的寬字符編碼方式就是unicode了,utf-16和utf-32都是unicode編碼。wchar_t也主要以這兩種方式實現。
utf-16是徹底基於ucs-2的,但存儲的方式分爲Big Endian和Little Endian,區別在於存儲的順序,好比字符A用utf-16BE的方式表示是0x0041,用utf-16LE的方式表示則是0x4100,我在個人機器上試了下,用VC10編譯器,wchar_t的編碼方式是utf-16BE。而在gcc下是utf-32BE。
關於各類的編碼算法,資料繁多,我就很少說了。
但這個問題是解決了,那就是,wchar_t的目的是編碼並存儲全部字符集,編碼方式和存儲空間大小和語言無關,只和編譯器有關,所以說wchar_t的編碼方式是unicode是錯的。C++ Primer上的描述也是不許確的。
哦,對,最後補充一下,unicode是兼容ASCII的,ASCII所能表示的字符,用unicode編碼能夠得出同樣的值。但不兼容GBK(也就是中文編碼),若是混用兩種方式編碼的字符串,須要開發者手動去轉換。