[轉]寬字符的介紹
2009-04-28 10:51
轉自:http://dev.csdn.net/article/77757.shtm2.2 寬字符和C
寬字符不一定是Unicode。Unicode是寬字符集的一種。然而,因為本書的焦點是Windows而不是C執(zhí)行的理論,所以書中把寬字符和Unicode作為同義語。
2.2.1
char
數(shù)據(jù)類型
(
1)下面的語句定義并初始化了一個只包含一個字符的變量:
char c = 'A' ;
變量c需要1個字節(jié)來保存,并將用十六進位數(shù)0x41初始化,這是字母A的ASCII代碼。
(2)可以這樣定義一個指向字串的指針:
char * p ;
因為Windows是一個32位元作業(yè)系統(tǒng),所以指針變量p需要用4個字節(jié)保存。還可初始化一個指向字串的指針:
char * p = "Hello!" ;
字串”Hello!”保存在靜態(tài)記憶體中并占用7個字節(jié),其中6個字節(jié)保存字串,另1個字節(jié)保存終止符號0。
(3)可以這樣定義字符數(shù)組:
char a[10] ;
在這種情況下,編譯器為該數(shù)組保留了10個字節(jié)的儲存空間。運算式sizeof(a) 將返回10。
(4)如果數(shù)組是全體變量(即在所有函數(shù)外定義),您可使用像下面的語句來初始化一個字符數(shù)組:
char a[] = "Hello!" ;
(5)如果您將該數(shù)組定義為一個函數(shù)的區(qū)域變量,則必須將它定義為一個static變量,如下:
static char a[] = "Hello!" ;
無論哪種情況,字串都儲存在靜態(tài)程序記憶體中,并在末尾添加0,這樣就需要7個字節(jié)的儲存空間。
2.2.2???????
寬字符
(1)Unicode或者寬字符都沒有改變char數(shù)據(jù)類型在C中的定義。
(2)C中的寬字符基於wchar_t數(shù)據(jù)類型,它在幾個頭文件包括WCHAR.H中都有定義,如下:
typedef unsigned short wchar_t ;
因此,wchar_t數(shù)據(jù)類型與無符號短整數(shù)型相同,都是16位寬。
(3)要定義包含一個寬字符的變量,可使用下面的語句:
wchar_t c = 'A' ;
變量c是一個雙字節(jié)值0x0041,是Unicode表示的字母A。(
然而,因為
Intel
微處理器從最小的字節(jié)開始儲存多字節(jié)數(shù)值,該字節(jié)實際上是以
0x41
、
0x00
的順序保存在記憶體中。如果檢查
Unicode
文字的電腦儲存應注意這一點。
)
(4)可定義指向寬字串的指針:
wchar_t * p = L"Hello!" ;
注意緊接在第一個引號前面的大寫字母L(代表「long」)。這將告訴編譯器該字串按寬字符保存——即每個字符占用2個字節(jié)。通常,指針變量p要占用4個字節(jié),而字串變量需要14個字節(jié)-每個字符需要2個字節(jié),末尾的0還需要2個字節(jié)。
(5)可以用下面的語句定義寬字符數(shù)組:
static wchar_t a[] = L"Hello!" ;
該字串也需要14個字節(jié)的儲存空間,sizeof (a) 將返回14。索引數(shù)組a可得到單獨的字符。a[1] 的值是寬字符「e」,或者0x0065。第一個引號和L兩個符號之間必須沒有空格。L使編譯器將字串存為每個字符2字節(jié)。
(6)可在單個字符文字前面使用L字首,來表示它們應解釋為寬字符。如下所示:
wchar_t c = L'A' ;
但通常這是不必要的,C編譯器會對該字符進行擴充,使它成為寬字符。
2.2.3???????
寬字符程序庫函數(shù)
??????? strlen函數(shù)的寬字符版是wcslen(
wide-character string length:寬字串長度
),并且在STRING.H(
其中也說明了strlen
)和WCHAR.H中均有說明。strlen函數(shù)說明如下:
size_t __cdecl strlen (const char *) ;
??????? 而wcslen函數(shù)則說明如下:
size_t __cdecl wcslen (const wchar_t *) ;
??????? 要得到寬字串的長度可以調用
wchar_t * pw = L"Hello!" ;
iLength = wcslen (pw) ;
??????? 函數(shù)將返回字串中的字符數(shù)6。
改成寬字節(jié)後,字串的字符長度不改變,只是字節(jié)長度改變了。
所有帶有字串參數(shù)的C執(zhí)行時期程序庫函數(shù)都有寬字符版。例如,wprintf是printf的寬字符版。這些函數(shù)在WCHAR.H和含有標準函數(shù)說明的頭文件中說明。
2.2.4???????
維護單一原始碼
??????? 使用Unicode最主要缺點是,程序中的每個字串都將占用兩倍的儲存空間。此外,寬字符執(zhí)行時期程序庫中的函數(shù)比常規(guī)的函數(shù)大。
??????? 因此,就有必要建立兩個版本的程序——一個處理ASCII字串,另一個處理Unicode字串。最好的解決辦法是維護既能按ASCII編譯又能按Unicode編譯的單一原始碼檔案。
一個辦法是使用Microsoft Visual C++包含的TCHAR.H頭文件。(
該頭文件不是ANSI C標準的一部分,因此其中定義的每個函數(shù)和巨集定義的前面都有一條下橫線。
)
??????? TCHAR.H為需要字串參數(shù)的標準執(zhí)行時期程序庫函數(shù)提供了一系列的替代名稱(例如,_tprintf和_tcslen)。有時這些名稱也稱為「通用」函數(shù)名稱,因為它們既可以指向函數(shù)的Unicode版也可以指向非Unicode版。
?????? 如果定義了名為_UNICODE的識別字,并且程序中包含了TCHAR.H頭文件,那么_tcslen就定義為wcslen:
#define _tcslen wcslen
????? 如果沒有定義UNICODE,則_tcslen定義為strlen:
#define _tcslen strlen
等等。
?????? TCHAR.H還用一個新的數(shù)據(jù)類型TCHAR來解決兩種字符數(shù)據(jù)類型的問題。如果定義了 _UNICODE識別字,那么TCHAR就是wchar_t:
typedef??? wchar_t??? TCHAR ;
?????? 否則,TCHAR就是char:
typedef char TCHAR ;
?????? 現(xiàn)在開始討論字串文字中的L問題。如果定義了_UNICODE識別字,那么一個稱作__T的巨集就定義如下:
#define __T(x) L##x
?????? 這是相當晦澀的語法,但合乎ANSI C標準的前置處理器規(guī)范。那一對井字號稱為「
粘貼符號(token paste)
」,它將字母L添加到巨集引數(shù)上。因此,如果巨集引數(shù)是"Hello!",則L##x就是L"Hello!"。
?????? 如果沒有定義_UNICODE識別字,則__T巨集只簡單地定義如下:
#define __T(x) x
?????? 此外,還有兩個巨集與__T定義相同:
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
在Win32 console程序中使用哪個巨集,取決於您喜歡簡潔還是詳細。基本地,必須按下述方法在_T或_TEXT巨集內定義字串文字:
_TEXT ("Hello!")
?????? 這樣做的話,如果定義了_UNICODE,那么該串將解釋為寬字符的組合,否則解釋為8位元的字符字串。
|
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
