Win32學習筆記 第二章 Unicode (轉)
學習筆記
作者: 姜學哲(tosail0@163.net">netsail0@163.net)
教材: 設計(第五版)北京大學出版社
[美]Charles Petzold 著
北京博彥科技發展有限公司 譯 ¥:160
參考資料:
Windows 應用程式設計原理_方法_技術(因為是PDF格式的EBOOK,作者等不詳)
新編Windows 參考大全 電子工業出版社 ¥:98
C++ Primer(第三版)中國電力出版社 Stanley B.Lippman & Josee Lajo著 潘愛民 張麗 譯 ¥:128
TURBO C實用大全 徐金梧 楊德斌 徐科 編 ¥:42
環境: server + Internet Explorer 6.0 + 7.0 + Visual C++ 6.0
圖們江程式編制小組(chulsoft.xiloo.com)版權所有,轉載請說明出處
--------------------------------------------------------------------
【第二章 Unicode】
佛曰:眾生皆平等。但是人卻可以利用較高等的智慧站在了眾多生物的至高點。吃早飯的時候我看著被做成菜的那條魚,想到它也是生命。所以說到底,還是有些等級之分。學習WIN32過程中讓我知道了Unicode的存在。Unicode最終會取代ASCII碼成為標準。但是之前還有很長一段路要走。雖然Unicode的優勢很明顯,但是因為歷史遺留問題,ASCII會存在很長一段時間。
學習C語言的時候您應該接觸過ASCII碼。學習本章的內容需要ASCII知識。
學習Unicode有必要了解字符集的歷史。從最早的象形字開始,我們使用字元文字已經有近6000年了。19世紀的幾個發明家發明了電報,當時在電報中使用的程式碼是Morse程式碼。字母表中的每個字元對應於一系列短和長的脈衝。
計算機是處理的資料其實是一系列1和0。每一段數字都代表一種字元。這就是ASCII碼。7位數的ASCII碼對於美國的字符集支援得很好。不幸的是地球上有一百多個國家和地區,2000多個民族。對於美國以外的來講在計算機中顯示自己國家的文字困難重重。
尤其是中國,日本,朝鮮更是如此。以中國為例,有數也數不清的漢字。辦法總是有的。人們引入了"內碼表"和"雙位元組字符集"的概念。這種編碼方式非常龐大和複雜,不利於維護。這個時候Unicode應運而生了。
Unicode的解決方案非常簡單。既然不能用7位或者8位數值表示,那麼我們應該試一下更寬的值。例如16位,這樣就允許表示65536個字元。Unicode和ASCII是相容的。也就是說,前128個字元的數值是相同的。
Unicode的最大好處是隻有一個字符集。當然Unicode也有缺點,Unicode佔用的是ASCII碼的兩倍。而且人們還不太習慣Unicode。
對於程式設計師來講,8位的ASCII碼和16位的Unicode是我們必須面對的問題。為了解決寬字元(16位)問題,Windows在頭中定義了"新"資料型別。
typedef unsigned short wchar_t;
可以看出wchar_t其實是16位的無符號短整型數。Windows用這種方法存貯16位字元。
wchar_t *p = L"Hello!";
在"Hello!"前有一個大寫字母L(代表long)。這將告訴該字串按寬字元儲存。即每個字元佔用2個字元。存貯該字串需要14個位元組。字串末尾還有一個/0也需要2個位元組。
我們都知道如何獲得字串的長度。
int iLength;
char *pc = "Hello!";
iLength = strlen(pc);
strlen()返回字串的長度,長度將不包括末尾的/0。變數iLength將等於6,也就是字串中的字元數。
接下來我們試著用strlen()檢查寬字元的字串。
wchar_t *pw = L"Hello!";
iLength = strlen(pw);
strlen()的引數應該是char型別的指標,但是現在卻接受了一個unsigned short型別的指標。編譯後您會發現iLength等於1。
why?字串"Hello!"中的6個字元寬字元程式碼如下:
0x0048 0x0065 0x006c 0x006c 0x006f 0x0021
在記憶體中將其存為:
48 00 65 00 6c 00 6c 00 6f 00 21 00
strlen()的工作過程是遇到0就結束。因為0表示一個字串的結束。當讀完"48"後strlen()遇到的是0,所以strlen()返回1。
由上例可以看出C語言的函式無法正確處理寬字元。在引數中有字串的函式全部需要重寫。strlen()的寬字元版本是wcslen(),並且在STRING.H中和WCHAR.H中均有宣告.
現在我們知道,要得到寬字串的長度,可以
iLength = wcslen(pw);
該函式返回將返回字串中的字元數6。請記住,改成寬位元組後字串的字元長度不變,只是位元組長度改變了。千萬不要混淆。
因為Unicode佔用兩倍的空間,所以寬位元組執行庫中的函式比常規的函式大。所以最好是建立兩個版本的程式,一個處理ASCII字串,另一個處理Unicode字串。但是這樣以來又引來了另一個小問題。因為每一個實現特定功能的函式都有兩個版本,所以名字不好記。不管是ASCII版本還是Unicode版本,都用相同的名字該多好啊?幸好這個問題已經得到了解決。
解決辦法是使用Visual C++包含的TCHAR.H標頭檔案。該標頭檔案不是標準C的一部分。為了與標準C的標頭檔案分別開來,該標頭檔案內定義的每個函式和宏定義的前面都有一條下劃線。
TCHAR.H為需要字串的標準執行庫函式提供了一系列的替代名稱。有時這些名稱被稱為"通用"函式名,因為它們既可以指向函式的Unicode版本,也可以指向ASCII版本。
以_tcslen()為例如果定義了_UNICODE的識別符號,並且程式中包含了TCHAR.H,那麼_tcslen()就定義為wcslen():
#define _tcslen wcslen
如果沒有定義_UNICODE,則_tcslen()被定義為strlen()。
#define _tcslen strlen
TCHAR.H還用一個新的資料型別TCHAR來解決兩種字元資料型別的問題。如果定義了_UNICODE識別符號,那麼TCHAR就是wchar_t:
typedef wchar_t TCHAR;
否則TCHAR就是char:
typedef char TCHAR;
還記得第一章裡出現過的TEXT()嗎?那是為了相容UNICODE字符集所做的改動。下面就來看看TEXT()在標頭檔案中是怎麼定義的。
#define __T(x) L##x
後面的L##x您可能看不懂。很少有書提到它。但那確實是標準C預處理的一部分。這一對"##"稱為貼上號(token paste)。看來我們對標準C的瞭解還不夠。是時候買本"The C Programming Language"了。它將字母L新增到宏引數上。
__T("Hello!") 等於 L##"Hello!" 等於 L"Hello!"。
此外還有兩個宏與__T定義相同:
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
WINNT.H標頭檔案中還定義了一個宏,該宏也跟__T一樣,將L新增到字串前。
#ifdef UNICODE
#define __TEXT(quote) L##quote
#else
#define __TEXT(quote) quote
#endif
#define TEXT(quote) __TEXT(quote)
在本書中使用的就是TEXT(quote)。現在您知道了為什麼會把字串用TEXT()括起來了吧。what?還不明白?您可以先惡補標準C,然後再多讀幾遍。再不會那就是天份問題了。不過,連像我這樣的村民都能看懂,您沒理由不會啊!
◎第三十四頁
scrnsize是可以檢測出您當前顯示器解析度的東東,比如我的是1024*768
有關這個程式,執行一次就可以了,不要想看懂它,讓他見鬼去吧。我們要看懂的是第三章的HelloWin。可能看完幾遍後您對第二章還是不太懂,沒關係,一回生,兩回熟。再多看幾遍就可以了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993188/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Win32學習筆記 第二章 (轉)Win32筆記
- Win32學習筆記 序 (轉)Win32筆記
- Unicode學習筆記Unicode筆記
- Java中文處理學習筆記——Hello Unicode (轉)Java筆記Unicode
- Win32學習筆記 第一章 (轉)Win32筆記
- Win32學習筆記 第三章 HelloWin (轉)Win32筆記
- Win32學習筆記 第一章 開始 (轉)Win32筆記
- Java_EE企業級開發學習筆記——spring學習筆記第二章Java筆記Spring
- sed學習筆記(轉)筆記
- gurb學習筆記(轉)筆記
- ANT學習筆記 (轉)筆記
- GRUB學習筆記(轉)筆記
- TreeView學習筆記 (轉)View筆記
- 計算機網路學習筆記:第二章計算機網路筆記
- C++ primer Plus學習筆記(第二章)C++筆記
- 資料結構 第二章(學習筆記一)資料結構筆記
- Unicode 筆記Unicode筆記
- C++ Primer 第二章 學習筆記及習題答案C++筆記
- Win32學習筆記 第六章 程式6-3 Typer 說明 (轉)Win32筆記
- ctf學習筆記[轉載]筆記
- SAP BASIS學習筆記(轉)筆記
- PE學習筆記(一) (轉)筆記
- JSP標記學習筆記 (轉)JS筆記
- repuest轉發學習筆記一筆記
- C#學習筆記(一) (轉)C#筆記
- 我的Hook學習筆記 (轉)Hook筆記
- Microsoft Agent 學習筆記 (一) (轉)ROS筆記
- 我的COM學習筆記 (轉)筆記
- APT HOWTO 學習筆記(轉)APT筆記
- 學習筆記:debfoster & deborphan(轉)筆記
- linux安全學習筆記(轉)Linux筆記
- 【知識圖譜 趙軍 學習筆記】第二章 知識表示筆記
- SA299學習筆記 第二章描述CS模式(1)筆記模式
- SA299學習筆記 第二章 描述CS模式(2)筆記模式
- numpy的學習筆記\pandas學習筆記筆記
- Delphi Unicode學習Unicode
- nndl-復旦-神經網路與深度學習筆記第二章習題神經網路深度學習筆記
- Win32除錯API學習心得(一) (轉)Win32除錯API