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

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