日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Unicode简介

發布時間:2023/12/29 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unicode简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Unicode簡介

壹佰軟件開發小組??整理編譯??

在第一章中,我已經預告,C語言中在Microsoft Windows程序設計中扮演著重要角色的任何部分都會講述到,您也許在傳統文字模式程序設計中還尚未遇到過這些問題。寬字符集和Unicode差不多就是這樣的問題。

簡單地說,Unicode擴展自ASCII字符集。在嚴格的ASCII中,每個字符用7位表示,或者計算機上普遍使用的每字符有8位寬;而Unicode使用全16位字符集。這使得Unicode能夠表示世界上所有的書寫語言中可能用于計算機通訊的字符、象形文字和其它符號。Unicode最初打算作為ASCII的補充,可能的話,最終將代替它。考慮到ASCII是計算機中最具支配地位的標準,所以這的確是一個很高的目標。

Unicode影響到了計算機工業的每個部分,但也許會對操作系統和程序設計語言的影響最大。從這方面來看,我們已經上路了。Windows NT從底層支持Unicode(不幸的是,Windows 98只是小部分支持Unicode)。先天即被ANSI束縛的C程序設計語言通過對寬字符集的支持來支持Unicode。下面將詳細討論這些內容。

自然,作為程序寫作者,我們通常會面對許多繁重的工作。我已試圖透過使本書中的所有程序「Unicode化」來減輕負擔。其含義會隨著本章對Unicode的討論而清晰起來。

字符集簡史

雖然不能確定人類開始講話的時間,但書寫已有大約6000年的歷史了。實際上,早期書寫的內容是象形文字。每個字符都對應于發聲的字母表則出現于大約3000年前。雖然人們過去使用的多種書寫語言都用得好好的,但19世紀的幾個發明者還是看到了更多的需求。Samuel F. B. Morse在1838年到1854年間發明了電報,當時他還發明了一種電報上使用的代碼。字母表中的每個字符對應于一系列短的和長的脈沖(點和破折號)。雖然其中大小寫字母之間沒有區別,但數字和標點符號都有了自己的代碼。

Morse代碼并不是以其它圖畫的或印刷的象形文字來代表書寫語言的第一個例子。1821年到1824年之間,年輕的Louis Braille受到在夜間讀寫信息的軍用系統的啟發,發明了一種代碼,它用紙上突起的點作為代碼來幫助盲人閱讀。Braille代碼實際上是一種6位代碼,它把字符、常用字母組合、常用單字和標點進行編碼。一個特殊的escape代碼表示后續的字符代碼應解釋為大寫。一個特殊的shift代碼允許后續代碼被解釋為數字。

Telex代碼,包括Baudot (以一個法國工程師命名,該工程師死于1903年)以及一種被稱為CCITT #2的代碼(1931年被標準化),都是包括字符和數字的5位代碼。

美國標準

早期計算機的字符碼是從Hollerith卡片(號稱不能被折迭、卷曲或毀傷)發展而來的,該卡片由Herman Hollerith發明并首次在1890年的美國人口普查中使用。6位字符碼系統BCDIC(Binary-Coded Decimal Interchange Code:二進制編碼十進制交換編碼)源自Hollerith代碼,在60年代逐步擴展為8位EBCDIC,并一直是IBM大型主機的標準,但沒使用在其它地方。

美國信息交換標準碼(ASCII:American Standard Code for Information Interchange)起始于50年代后期,最后完成于1967年。開發ASCII的過程中,在字符長度是6位、7位還是8位的問題上產生了很大的爭議。從可靠性的觀點來看不應使用替換字符,因此ASCII不能是6位編碼,但由于費用的原因也排除了8位版本的方案(當時每位的儲存空間成本仍很昂貴)。這樣,最終的字符碼就有26個小寫字母、26個大寫字母、10個數字、32個符號、33個句柄和一個空格,總共128個字符碼。ASCII現在記錄在ANSI X3.4-1986字符集-用于信息交換的7位美國國家標準碼(7-Bit ASCII:7-Bit American National Standard Code for Information Interchange),由美國國家標準協會(American National Standards Institute)發布。圖2-1中所示的ASCII字符碼與ANSI文件中的格式相似。

ASCII有許多優點。例如,26個字母代碼是連續的(在EBCDIC代碼中就不是這樣的);大寫字母和小寫字母可通過改變一位數據而相互轉化;10個數字的代碼可從數值本身方便地得到(在BCDIC代碼中,字符「0」的編碼在字符「9」的后面!)

最棒的是,ASCII是一個非常可靠的標準。在鍵盤、視訊顯示卡、系統硬件、打印機、字體文件、操作系統和Internet上,其它標準都不如ASCII碼流行而且根深蒂固。


 

圖2-1 ASCII字符集

國際方面

ASCII的最大問題就是該縮寫的第一個字母。ASCII是一個真正的美國標準,所以它不能良好滿足其它講英語國家的需要。例如英國的英鎊符號(£)在哪里?

英語使用拉丁(或羅馬)字母表。在使用拉丁語字母表的書寫語言中,英語中的單詞通常很少需要重音符號(或讀音符號)。即使那些傳統慣例加上讀音符號也無不當的英語單字,例如c鰋perate或者résumé,拼寫中沒有讀音符號也會被完全接受。

但在美國以南、以北,以及大西洋地區的許多國家,在語言中使用讀音符號很普遍。這些重音符號最初是為使拉丁字母表適合這些語言讀音不同的需要。在遠東或西歐的南部旅游,您會遇到根本不使用拉丁字母的語言,例如希臘語、希伯來語、阿拉伯語和俄語(使用斯拉夫字母表)。如果您向東走得更遠,就會發現中國象形漢字,日本和朝鮮也采用漢字系統。

ASCII的歷史開始于1967年,此后它主要致力于克服其自身限制以更適合于非美國英語的其它語言。例如,1967年,國際標準化組織(ISO:International Standards Organization)推薦一個ASCII的變種,代碼0x40、0x5B、0x5C、0x5D、0x7B、0x7C和0x7D「為國家使用保留」,而代碼0x5E、0x60和0x7E標為「當國內要求的特殊字符需要8、9或10個空間位置時,可用于其它圖形符號」。這顯然不是一個最佳的國際解決方案,因為這并不能保證一致性。但這卻顯示了人們如何想盡辦法為不同的語言來編碼的。

擴展ASCII

在小型計算機開發的初期,就已經嚴格地建立了8位字節。因此,如果使用一個字節來保存字符,則需要128個附加的字符來補充ASCII。1981年,當最初的IBM PC推出時,視訊卡的ROM中燒有一個提供256個字符的字符集,這也成為IBM標準的一個重要組成部分。

最初的IBM擴展字符集包括某些帶重音的字符和一個小寫希臘字母表(在數學符號中非常有用),還包括一些塊型和線狀圖形字符。附加的字符也被添加到ASCII控制字符的編碼位置,這是因為大多數控制字符都不是拿來顯示用的。

該IBM擴展字符集被燒進無數顯示卡和打印機的ROM中,并被許多應用程序用于修飾其文字模式的顯示方式。不過,該字符集并沒有為所有使用拉丁字母表的西歐語言提供足夠多的帶重音字符,而且也不適用于Windows。Windows不需要圖形字符,因為它有一個完全圖形化的系統。

在Windows 1.0(1985年11月發行)中,Microsoft沒有完全放棄IBM擴展字符集,但它已退居第二重要位置。因為遵循了ANSI草案和ISO標準,純Windows字符集被稱作「ANSI字符集」。ANSI草案和ISO標準最終成為ANSI/ISO 8859-1-1987,即「American National Standard for Information Processing-8-Bit Single-Byte Coded Graphic Character Sets-Part 1: Latin Alphabet No 1」,通常也簡寫為「Latin 1」。

在Windows 1.0的《Programmer's Reference》中印出了ANSI字符集的最初版本,如圖2-2所示。


 

圖2-2 Windows ANSI字符集(基于ANSI/ISO 8859-1)

空方框表示該位置未定義字符。這與ANSI/ISO 8859-1的最終定義一致。ANSI/ISO 8859-1僅顯示了圖形字符,而沒有控制字符,因此沒有定義DEL。此外,代碼0xA0定義為一個非斷開的空格(這意味著在編排格式時,該字符不用于斷開一行),代碼0xAD是一個軟連字符(表示除非在行尾斷開單詞時使用,否則不顯示)。此外,ANSI/ISO 8859-1將代碼0xD7定義為乘號(*),0xF7為除號(/)。Windows中的某些字體也定義了從0x80到0x9F的某些字符,但這些不是ANSI/ISO 8859-1標準的一部分。

MS-DOS 3.3(1987年4月發行)向IBM PC用戶引進了代碼頁(code page)的概念,Windows也使用此概念。代碼頁定義了字符的映像代碼。最初的IBM字符集被稱作代碼頁437,或者「MS-DOS Latin US)。代碼頁850就是「MS-DOS Latin 1」,它用附加的帶重音字母(但不是圖2-2所示的Latin 1 ISO/ANSI標準)代替了一些線形字符。其它代碼頁被其它語言定義。最低的128個代碼總是相同的;較高的128個代碼取決于定義代碼頁的語言。

在MS-DOS中,如果用戶為PC的鍵盤、顯示卡和打印機指定了一個代碼頁,然后在PC上創建、編輯和打印文件,一切都很正常,每件事都會保持一致。然而,如果用戶試圖與使用不同代碼頁的用戶交換文件,或者在機器上改變代碼頁,就會產生問題。字符碼與錯誤的字符相關聯。應用程序能夠將代碼頁信息與文件一起保存來試圖減少問題的產生,但該策略包括了某些在代碼頁間轉換的工作。

雖然代碼頁最初僅提供了不包括帶重音符號字母的附加拉丁字符集,但最終代碼頁的較高的128個字符還是包括了完整的非拉丁字母,例如希伯來語、希臘語和斯拉夫語。自然,如此多樣會導致代碼頁變得混亂;如果少數帶重音的字母未正確顯示,那么整個文字便會混亂不堪而不可閱讀。

代碼頁的擴展正是基于所有這些原因,但是還不夠。斯拉夫語的MS-DOS代碼頁855與斯拉夫語的Windows代碼頁1251以及斯拉夫語的Macintosh代碼頁10007不同。每個環境下的代碼頁都是對該環境所作的標準字符集修正。IBM OS/2也支援多種EBCDIC代碼頁。

但等一下,你會發現事情變得更糟糕。

雙字節字符集

迄今為止,我們已經看到了256個字符的字符集。但中國、日本和韓國的象形文字符號有大約21,000個。如何容納這些語言而仍保持和ASCII的某種兼容性呢?

解決方案(如果這個說法正確的話)是雙字節字符集(DBCS:double-byte character set)。DBCS從256代碼開始,就像ASCII一樣。與任何行為良好的代碼頁一樣,最初的128個代碼是ASCII。然而,較高的128個代碼中的某些總是跟隨著第二個字節。這兩個字節一起(稱作首字節和跟隨字節)定義一個字符,通常是一個復雜的象形文字。

雖然中文、日文和韓文共享一些相同的象形文字,但顯然這三種語言是不同的,而且經常是同一個象形文字在三種不同的語言中代表三件不同的事。Windows支持四個不同的雙字節字符集:代碼頁932(日文)、936(簡體中文)、949(韓語)和950(繁體漢字)。只有為這些國家(地區)生產的Windows版本才支持DBCS。

雙字符集問題并不是說字符由兩個字節代表。問題在于一些字符(特別是ASCII字符)由1個字節表示。這會引起附加的程序設計問題。例如,字符串中的字符數不能由字符串的字節數決定。必須剖析字符串來決定其長度,而且必須檢查每個字節以確定它是否為雙字節字符的首字節。如果有一個指向DBCS字符串中間的指針,那么該字符串前一個字符的地址是什么呢?慣用的解決方案是從開始的指針分析該字符串!

Unicode解決方案

我們面臨的基本問題是世界上的書寫語言不能簡單地用256個8位代碼表示。以前的解決方案包括代碼頁和DBCS已被證明是不能滿足需要的,而且也是笨拙的。那什么才是真正的解決方案呢?

身為程序寫作者,我們經歷過這類問題。如果事情太多,用8位數值已經不能表示,那么我們就試更寬的值,例如16位值。而且這很有趣的,正是Unicode被制定的原因。與混亂的256個字符代碼映像,以及含有一些1字節代碼和一些2字節代碼的雙字節字符集不同,Unicode是統一的16位系統,這樣就允許表示65,536個字符。這對表示所有字符及世界上使用象形文字的語言,包括一系列的數學、符號和貨幣單位符號的集合來說是充裕的。

明白Unicode和DBCS之間的區別很重要。Unicode使用(特別在C程序設計語言環境里)「寬字符集」。「Unicode中的每個字符都是16位寬而不是8位寬。」在Unicode中,沒有單單使用8位數值的意義存在。相比之下,在雙字節字符集中我們仍然處理8位數值。有些字節自身定義字符,而某些字節則顯示需要和另一個字節共同定義一個字符。

處理DBCS字符串非常雜亂,但是處理Unicode文字則像處理有秩序的文字。您也許會高興地知道前128個Unicode字符(16位代碼從0x0000到0x007F)就是ASCII字符,而接下來的128個Unicode字符(代碼從0x0080到0x00FF)是ISO 8859-1對ASCII的擴展。Unicode中不同部分的字符都同樣基于現有的標準。這是為了便于轉換。希臘字母表使用從0x0370到0x03FF的代碼,斯拉夫語使用從0x0400到0x04FF的代碼,美國使用從0x0530到0x058F的代碼,希伯來語使用從0x0590到0x05FF的代碼。中國、日本和韓國的象形文字(總稱為CJK)占用了從0x3000到0x9FFF的代碼。

Unicode的最大好處是這里只有一個字符集,沒有一點含糊。Unicode實際上是個人計算機行業中幾乎每個重要公司共同合作的結果,并且它與ISO 10646-1標準中的代碼是一一對應的。Unicode的重要參考文獻是《The Unicode Standard,Version 2.0》(Addison-Wesley出版社,1996年)。這是一本特別的書,它以其它文件少有的方式顯示了世界上書寫語言的豐富性和多樣性。此外,該書還提供了開發Unicode的基本原理和細節。

Unicode有缺點嗎?當然有。Unicode字符串占用的內存是ASCII字符串的兩倍。(然而壓縮文件有助于極大地減少文件所占的磁盤空間。)但也許最糟的缺點是:人們相對來說還不習慣使用Unicode。身為程序寫作者,這就是我們的工作。

寬字符和 C

對C程序寫作者來說,16位字符的想法的確讓人掃興。一個char和一個字節同寬是最不能確定的事情之一。沒幾個程序寫作者清楚ANSI/ISO 9899-1990,這是「美國國家標準程序設計語言-C」(也稱作「ANSI C」)通過一個稱作「寬字符」的概念來支持用多個字節代表一字符的字符集。這些寬字符與常用的字符完美地共存。

ANSI C也支持多字節字符集,例如中文、日文和韓文版本Windows支持的字符集。然而,這些多字節字符集被當成單字節構成的字符串看待,只不過其中一些字符改變了后續字符的含義而已。多字節字符集主要影響C語言程序執行時期鏈接庫函數。相比之下,寬字符比正常字符寬,而且會引起一些編譯問題。

寬字符不需要是Unicode。Unicode是一種可能的寬字符集。然而,因為本書的焦點是Windows而不是C執行的理論,所以我將把寬字符和Unicode作為同義語。

Char數據型態

假定我們都非常熟悉在C程序中使用char數據型態來定義和儲存字符跟字符串。但為了便于理解C如何處理寬字符,讓我們先回顧一下可能在Win32程序中出現的標準字符定義。

下面的語句定義并初始化了一個只包含一個字符的變量:

char c = 'A' ;

變量c需要1個字節來保存,并將用十六進制數0x41初始化,這是字母A的ASCII代碼。

您可以像這樣定義一個指向字符串的指針:

char * p ;

因為Windows是一個32位操作系統,所以指針變量p需要用4個字節保存。您還可初始化一個指向字符串的指針:

char * p = "Hello!" ;

像前面一樣,變量p也需要用4個字節保存。該字符串保存在靜態內存中并占用7個字節-6個字節保存字符串,另1個字節保存終止符號0。

您還可以像這樣定義字符數組:

char a[10] ;

在這種情況下,編譯器為該數組保留了10個字節的儲存空間。表達式sizeof(a)將返回10。如果數組是整體變量(即在所有函數外定義),您可使用像下面的語句來初始化一個字符數組:

char a[] = "Hello!" ;

如果您將該數組定義為一個函數的區域變量,則必須將它定義為一個static變量,如下:

static char a[] = "Hello!" ;

無論哪種情況,字符串都儲存在靜態程序內存中,并在末尾添加0,這樣就需要7個字節的儲存空間。

寬字符

Unicode或者寬字符都沒有改變char數據型態在C中的含義。char繼續表示1個字節的儲存空間,sizeof (char)繼續返回1。理論上,C中1個字節可比8位長,但對我們大多數人來說,1個字節(也就是1個char)是8位寬。

C中的寬字符基于wchar_t數據型態,它在幾個表頭文件包括WCHAR.H中都有定義,像這樣:

typedef unsigned short wchar_t ;

因此,wchar_t數據型態與無符號短整數型態相同,都是16位寬。

要定義包含一個寬字符的變量,可使用下面的語句:

wchar_t c = 'A' ;

變量c是一個雙字節值0x0041,是Unicode表示的字母A。(然而,因為Intel微處理器從最小的字節開始儲存多字節數值,該字節實際上是以0x41、0x00的順序保存在內存中。如果檢查Unicode文字的計算機儲存應注意這一點。)

您還可定義指向寬字符串的指針:

wchar_t * p = L"Hello!" ;

注意緊接在第一個引號前面的大寫字母L(代表「long」)。這將告訴編譯器該字符串按寬字符保存-即每個字符占用2個字節。通常,指針變量p要占用4個字節,而字符串變量需要14個字節-每個字符需要2個字節,末尾的0還需要2個字節。

同樣,您還可以用下面的語句定義寬字符數組:

static wchar_t a[] = L"Hello!" ;

該字符串也需要14個字節的儲存空間,sizeof (a) 將返回14。索引數組a可得到單獨的字符。a[1] 的值是寬字符「e」,或者0x0065。

雖然看上去更像一個印刷符號,但第一個引號前面的L非常重要,并且在兩個符號之間必須沒有空格。只有帶有L,編譯器才知道您需要將字符串存為每個字符2字節。稍后,當我們看到使用寬字符串而不是變量定義時,您還會遇到第一個引號前面的L。幸運的是,如果忘記了包含L,C編譯器通常會給提出警告或錯誤信息。

您還可在單個字符文字前面使用L前綴,來表示它們應解釋為寬字符。如下所示:

wchar_t c = L'A' ;

但通常這是不必要的,C編譯器會對該字符進行擴充,使它成為寬字符。

寬字符鏈接庫函數

我們都知道如何獲得字符串的長度。例如,如果我們已經像下面這樣定義了一個字符串指針:

char * pc = "Hello!" ;

我們可以呼叫

iLength = strlen (pc) ;

這時變量iLength將等于6,也就是字符串中的字符數。

太好了!現在讓我們試著定義一個指向寬字符的指針:

wchar_t * pw = L"Hello!" ;

再次呼叫strlen :

iLength = strlen (pw) ;

現在麻煩來了。首先,C編譯器會顯示一條警告消息,可能是這樣的內容:

'function' : incompatible types - from 'unsigned short *' to 'const char *'

這條消息的意思是:聲明strlen函數時,該函數應接收char類型的指標,但它現在卻接收了一個unsigned short類型的指標。您仍然可編譯并執行該程序,但您會發現iLength等于1。為什么?

字符串「Hello!」中的6個字符占用16位:

0x0048 0x0065 0x006C 0x006C 0x006F 0x0021

Intel處理器在內存中將其存為:

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

假定strlen函數正試圖得到一個字符串的長度,并把第1個字節作為字符開始計數,但接著假定如果下一個字節是0,則表示字符串結束。

這個小練習清楚地說明了C語言本身和執行時期鏈接庫函數之間的區別。編譯器將字符串L"Hello!" 解釋為一組16位短整數型態數據,并將其保存在wchar_t數組中。編譯器還處理數組索引和sizeof操作符,因此這些都能正常工作,但在連結時才添加執行時期鏈接庫函數,例如strlen。這些函數認為字符串由單字節字符組成。遇到寬字符串時,函數就不像我們所希望那樣執行了。

您可能要說:「噢,太麻煩了!」現在每個C語言鏈接庫函數都必須重寫以接受寬字符。但事實上并不是每個C語言鏈接庫函數都需要重寫,只是那些有字符串參數的函數才需要重寫,而且也不用由您來完成。它們已經重寫完了。

strlen函數的寬字符版是wcslen(wide-character string length:寬字符串長度),并且在STRING.H(其中也說明了strlen)和WCHAR.H中均有說明。strlen函數說明如下:

size_t __cdecl strlen (const char *) ;

而wcslen函數則說明如下:

size_t __cdecl wcslen (const wchar_t *) ;

這時我們知道,要得到寬字符串的長度可以呼叫

iLength = wcslen (pw) ;

函數將返回字符串中的字符數6。請記住,改成寬字節后,字符串的字符長度不改變,只是位組長度改變了。

您熟悉的所有帶有字符串參數的C執行時期鏈接庫函數都有寬字符版。例如,wprintf是printf的寬字符版。這些函數在WCHAR.H和含有標準函數說明的表頭文件中說明。

維護單一原始碼

當然,使用Unicode也有缺點。第一點也是最主要的一點是,程序中的每個字符串都將占用兩倍的儲存空間。此外,您將發現寬字符執行時期鏈接庫中的函數比常規的函數大。出于這個原因,您也許想建立兩個版本的程序-一個處理ASCII字符串,另一個處理Unicode字符串。最好的解決辦法是維護既能按ASCII編譯又能按Unicode編譯的單一原始碼文件。

雖然只是一小段程序,但由于執行時期鏈接庫函數有不同的名稱,您也要定義不同的字符,這將在處理前面有L的字符串文字時遇到麻煩。

一個辦法是使用Microsoft Visual C++包含的TCHAR.H表頭文件。該表頭文件不是ANSI C標準的一部分,因此那里定義的每個函數和宏定義的前面都有一條底線。TCHAR.H為需要字符串參數的標準執行時期鏈接庫函數提供了一系列的替代名稱(例如,_tprintf和_tcslen)。有時這些名稱也稱為「通用」函數名稱,因為它們既可以指向函數的Unicode版也可以指向非Unicode版。

如果定義了名為_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 ;

現在開始討論字符串文字中的L問題。如果定義了_UNICODE標識符,那么一個稱作__T的宏就定義如下:

#define __T(x) L##x

這是相當晦澀的語法,但合乎ANSI C標準的前置處理器規范。那一對井字號稱為「粘貼符號(token paste)」,它將字母L添加到宏參數上。因此,如果宏參數是"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位的字符字符串。

寬字符和 Windows

Windows NT從底層支援Unicode。這意味著Windows NT內部使用由16位字符組成的字符串。因為世界上其它許多地方還不使用16位字符串,所以Windows NT必須經常將字符串在操作系統內轉換。Windows NT可執行為ASCII、Unicode或者ASCII和Unicode混合編寫的程序。即,Windows NT支持不同的API函數呼叫,這些函數接受8位或16位的字符串(我們將馬上看到這是如何動作的。)

相對于Windows NT,Windows 98對Unicode的支持要少得多。只有很少的Windows 98函數呼叫支持寬字符串(這些函數列在《Microsoft Knowledge Base article Q125671》中;它們包括MessageBox)。如果要發行的程序中只有一個.EXE文件要求在Windows NT和Windows 98下都能執行,那么就不應該使用Unicode,否則就不能在Windows 98下執行;尤其程序不能呼叫Unicode版的Windows函數。這樣,將來發行Unicode版的程序時會處于更有利的位置,您應試著編寫既為ASCII又為Unicode編譯的原始碼。這就是本書中所有程序的編寫方式。

Windows表頭文件類型

正如您在第一章所看到的那樣,一個Windows程序包括表頭文件WINDOWS.H。該文件包括許多其它表頭文件,包括WINDEF.H,該文件中有許多在Windows中使用的基本型態定義,而且它本身也包括WINNT.H。WINNT.H處理基本的Unicode支持。

WINNT.H的前面包含C的表頭文件CTYPE.H,這是C的眾多表頭文件之一,包括wchar_t的定義。WINNT.H定義了新的數據型態,稱作CHAR和WCHAR:

typedef char CHAR ; typedef wchar_t WCHAR ; // wc

當您需要定義8位字符或者16位字符時,推薦您在Windows程序中使用的數據型態是CHAR和WCHAR。WCHAR定義后面的注釋是匈牙利標記法的建議:一個基于WCHAR數據型態的變量可在前面附加上字母wc以說明一個寬字符。

WINNT.H表頭文件進而定義了可用做8位字符串指針的六種數據型態和四個可用做const 8位字符串指針的數據型態。這里精選了表頭文件中一些實用的說明數據型態語句:

typedef CHAR * PCHAR, * LPCH, * PCH, * NPSTR, * LPSTR, * PSTR ; typedef CONST CHAR * LPCCH, * PCCH, * LPCSTR, * PCSTR ;

前綴N和L表示「near」和「long」,指的是16位Windows中兩種大小不同的指標。在Win32中near和long指標沒有區別。

類似地,WINNT.H定義了六種可作為16位字符串指針的數據型態和四種可作為const 16位字符串指針的數據型態:

typedef WCHAR * PWCHAR, * LPWCH, * PWCH, * NWPSTR, * LPWSTR, * PWSTR ; typedef CONST WCHAR * LPCWCH, * PCWCH, * LPCWSTR, * PCWSTR ;

至此,我們有了數據型態CHAR(一個8位的char)和WCHAR(一個16位的wchar_t),以及指向CHAR和WCHAR的指標。與TCHAR.H一樣,WINNT.H將TCHAR定義為一般的字符類型。如果定義了標識符UNICODE(沒有底線),則TCHAR和指向TCHAR的指標就分別定義為WCHAR和指向WCHAR的指標;如果沒有定義標識符UNICODE,則TCHAR和指向TCHAR的指標就分別定義為char和指向char的指標:

#ifdef UNICODE typedef WCHAR TCHAR, * PTCHAR ; typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ; typedef LPCWSTR LPCTSTR ; #else typedef char TCHAR, * PTCHAR ; typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ; typedef LPCSTR LPCTSTR ; #endif

如果已經在某個表頭文件或者其它表頭文件中定義了TCHAR數據型態,那么WINNT.H和WCHAR.H表頭文件都能防止其重復定義。不過,無論何時在程序中使用其它表頭文件時,都應在所有其它表頭文件之前包含WINDOWS.H。

WINNT.H表頭文件還定義了一個宏,該宏將L添加到字符串的第一個引號前。如果定義了UNICODE標識符,則一個稱作 __TEXT的宏定義如下:

#define __TEXT(quote) L##quote

如果沒有定義標識符UNICODE,則像這樣定義__TEXT宏:

#define __TEXT(quote) quote

此外, TEXT宏可這樣定義:

#define TEXT(quote) __TEXT(quote)

這與TCHAR.H中定義_TEXT宏的方法一樣,只是不必操心底線。我將在本書中使用這個宏的TEXT版本。

這些定義可使您在同一程序中混合使用ASCII和Unicode字符串,或者編寫一個可被ASCII或Unicode編譯的程序。如果您希望明確定義8位字符變量和字符串,請使用CHAR、PCHAR(或者其它),以及帶引號的字符串。為明確地使用16位字符變量和字符串,請使用WCHAR、PWCHAR,并將L添加到引號前面。對于是8位還是16位取決于UNICODE標識符的定義的變量或字符串,要使用TCHAR、PTCHAR和TEXT宏。

Windows函數呼叫

從Windows 1.0到Windows 3.1的16位Windows中,MessageBox函數位于動態鏈接庫USER.EXE。在Windows 3.1軟件開發套件的WINDOWS.H中,MessageBox函數定義如下:

int WINAPI MessageBox (HWND, LPCSTR, LPCSTR, UINT) ;

注意,函數的第二個、第三個參數是指向常數字符串的指針。當編譯連結一個Win16程序時,Windows并不處理MessageBox呼叫。程序.EXE文件中的表格,允許Windows將該程序的呼叫與USER中的MessageBox函數動態鏈接起來。

32位的Windows(即所有版本的Windows NT,以及Windows 95和Windows 98)除了含有與16位兼容的USER.EXE以外,還含有一個稱為USER32.DLL的動態鏈接庫,該動態鏈接庫含有32位使用者接口函數的進入點,包括32位的MessageBox。

這就是Windows支持Unicode的關鍵:在USER32.DLL中,沒有32位MessageBox函數的進入點。實際上,有兩個進入點,一個名為MessageBoxA(ASCII版),另一個名為MessageBoxW(寬字符版)。用字符串作參數的每個Win32函數都在操作系統中有兩個進入點!幸運的是,您通常不必關心這個問題,程序中只需使用MessageBox。與TCHAR表頭文件一樣,每個Windows表頭文件都有我們需要的技巧。

下面是MessageBoxA在WINUSER.H中定義的方法。這與MessageBox早期的定義很相似:

WINUSERAPI int WINAPI MessageBoxA (HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) ;

下面是MessageBoxW:

WINUSERAPI int WINAPI MessageBoxW (HWND hWnd, LPCWSTR lpText,LPCWSTR lpCaption, UINT uType) ;

注意,MessageBoxW函數的第二個和第三個參數是指向寬字符的指針。

如果需要同時使用并分別匹配ASCII和寬字符函數呼叫,那么您可在Windows程序中明確地使用MessageBoxA和MessageBoxW函數。但大多數程序寫作者將繼續使用MessageBox。根據是否定義了UNICODE,MessageBox將與MessageBoxA或MessageBoxW一樣。在WINUSER.H中完成這一技巧時,程序相當瑣碎:

#ifdef UNICODE#define MessageBox MessageBoxW#else#define MessageBox MessageBoxA#endif

這樣,如果定義了UNICODE標識符,那么程序中所有的MessageBox函數呼叫實際上就是MessageBoxW函數;否則,就是MessageBoxA函數。

執行該程序時,Windows將程序中不同的函數呼叫與不同的Windows動態鏈接庫的進入點連結。雖然只有少數例外,但是,在Windows 98中不能執行Unicode版的Windows函數。雖然這些函數有進入點,但通常返回錯誤代碼。應用程序注意這些返回的錯誤并采取一些合理的動作。

Windows的字符串函數

正如前面談到的,Microsoft C包括寬字符和需要字符串參數的C語言執行時期鏈接庫函數的所有普通版本。不過,Windows復制了其中一部分。例如,下面是Windows定義的一組字符串函數,這些函數用來計算字符串長度、復制字符串、連接字符串和比較字符串:

ILength = lstrlen (pString) ;pString = lstrcpy (pString1, pString2) ;pString = lstrcpyn (pString1, pString2, iCount) ;pString = lstrcat (pString1, pString2) ;iComp = lstrcmp (pString1, pString2) ;iComp = lstrcmpi (pString1, pString2) ;

這些函數與C鏈接庫中對應的函數功能相同。如果定義了UNICODE標識符,那么這些函數將接受寬字符串,否則只接受常規字符串。寬字符串版的lstrlenW函數可在Windows 98中執行。

在Windows中使用printf

有文字模式、命令列C語言程序寫作歷史的程序寫作者往往特別喜歡printf函數。即使可以使用更簡單的命令(例如puts),但printf出現在Kernighan和Ritchie的「hello, world」程序中一點也不會令人驚奇。我們知道,增強后的「hello, world」最終還是需要printf的格式化輸出,因此我們最好從頭開始就使用它。

但有個壞消息:在Windows程序中不能使用printf。雖然Windows程序中可以使用大多數C的執行時期鏈接庫-實際上,許多程序寫作者更愿意使用C內存管理和文件I/O函數而不是Windows中等效的函數-Windows對標準輸入和標準輸出沒有概念。在Windows程序中可使用fprintf,而不是printf。

還有一個好消息,那就是仍然可以使用sprintf及sprintf系列中的其它函數來顯示文字。這些函數除了將內容格式化輸出到函數第一個參數所提供的字符串緩沖區以外,其功能與printfI相同。然后便可對該字符串進行操作(例如將其傳給MessageBox)。

如果您從未使用過sprintf (我第一次開始寫Windows程序時也沒用過此函數),這里有一個簡短的執行實體,printf函數說明如下:

int printf (const char * szFormat, ...) ;

第一個參數是一個格式字符串,后面是與格式字符串中的代碼相對應的不同類型多個參數。

sprintf函數定義如下:

int sprintf (char * szBuffer, const char * szFormat, ...) ;

第一個參數是字符緩沖區;后面是一個格式字符串。Sprintf不是將格式化結果標準輸出,而是將其存入szBuffer。該函數返回該字符串的長度。在文字模式程序設計中,

printf ("The sum of %i and %i is %i", 5, 3, 5+3) ;

的功能相同于

char szBuffer [100] ;sprintf (szBuffer, "The sum of %i and %i is %i", 5, 3, 5+3) ;puts (szBuffer) ;

在Windows中,使用MessageBox顯示結果優于puts。

幾乎每個人都經歷過,當格式字符串與被格式化的變量不合時,可能使printf執行錯誤并可能造成程序當掉。使用sprintf時,您不但要擔心這些,而且還有一個新的負擔:您定義的字符串緩沖區必須足夠大以存放結果。Microsoft專用函數_snprintf解決了這一問題,此函數引進了另一個參數,表示以字符計算的緩沖區大小。

vsprintf是sprintf的一個變形,它只有三個參數。vsprintf用于執行有多個參數的自訂函數,類似printf格式。vsprintf的前兩個參數與sprintf相同:一個用于保存結果的字符緩沖區和一個格式字符串。第三個參數是指向格式化參數數組的指針。實際上,該指針指向在堆棧中供函數呼叫的變量。va_list、va_start和va_end宏(在STDARG.H中定義)幫助我們處理堆棧指針。本章最后的SCRNSIZE程序展示了使用這些宏的方法。使用vsprintf函數,sprintf函數可以這樣編寫:

int sprintf (char * szBuffer, const char * szFormat, ...){int iReturn ;va_list pArgs ;va_start (pArgs, szFormat) ;iReturn = vsprintf (szBuffer, szFormat, pArgs) ;va_end (pArgs) ;return iReturn ;}

va_start宏將pArg設置為指向一個堆棧變量,該變量地址在堆棧參數szFormat的上面。

由于許多Windows早期程序使用了sprintf和vsprintf,最終導致Microsoft向Windows API中增添了兩個相似的函數。Windows的wsprintf和wvsprintf函數在功能上與sprintf和vsprintf相同,但它們不能處理浮點格式。

當然,隨著寬字符的發表,sprintf類型的函數增加許多,使得函數名稱變得極為混亂。表2-1列出了Microsoft的C執行時期鏈接庫和Windows支持的所有sprintf函數。

表2-1

?

?

ASCII

寬字符

常規

參數的變數個數

???

標準版

sprintf

swprintf

_stprintf

最大長度版

_snprintf

_snwprintf

_sntprintf

Windows版

wsprintfA

wsprintfW

wsprintf

參數數組的指針

???

標準版

vsprintf

vswprintf

_vstprintf

最大長度版

_vsnprintf

_vsnwprintf

_vsntprintf

Windows版

wvsprintfA

wvsprintfW

wvsprintf

在寬字符版的sprintf函數中,將字符串緩沖區定義為寬字符串。在寬字符版的所有這些函數中,格式字符串必須是寬字符串。不過,您必須確保傳遞給這些函數的其它字符串也必須由寬字符組成。

格式化消息框

程序2-1所示的SCRNSIZE程序展示了如何實作MessageBoxPrintf函數,該函數有許多參數并能像printf那樣編排它們的格式。

程序2-1 SCRNSIZESCRNSIZE.C/*---------------------------------------------------------------------------SCRNSIZE.C -- Displays screen size in a message box(c) Charles Petzold, 1998----------------------------------------------------------------------------*/#include <windows.h>#include <tchar.h> #include <stdio.h> int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, ...){TCHAR szBuffer [1024] ;va_list pArgList ;// The va_start macro (defined in STDARG.H) is usually equivalent to:// pArgList = (char *) &szFormat + sizeof (szFormat) ;va_start (pArgList, szFormat) ;// The last argument to wvsprintf points to the arguments_vsntprintf ( szBuffer, sizeof (szBuffer) / sizeof (TCHAR),szFormat, pArgList) ;// The va_end macro just zeroes out pArgList for no good reasonva_end (pArgList) ;return MessageBox (NULL, szBuffer, szCaption, 0) ;}int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow){int cxScreen, cyScreen ;cxScreen = GetSystemMetrics (SM_CXSCREEN) ;cyScreen = GetSystemMetrics (SM_CYSCREEN) ;MessageBoxPrintf ( TEXT ("ScrnSize"),TEXT ("The screen is %i pixels wide by %i pixels high."),cxScreen, cyScreen) ;return 0 ;}

經由從GetSystemMetrics函數得到的信息,該程序以圖素為單位顯示了視訊顯示的寬度和高度。GetSystemMetrics是一個能用來獲得Windows中不同對象的尺寸信息的函數。事實上,我將在第四章用GetSystemMetrics函數向您展示如何在一個Windows窗口中顯示和滾動多行文字。

本書與國際化

為國際市場準備的Windows程序不光要使用Unicode。國際化超出了本書的范圍,但在Nadine Kano所寫的《Developing International Software for Windows 95 and Windows NT》(Microsoft Press,1995年)一書中涉獵了許多。

本書中的程序寫作時被限制成既可使用也可不使用定義的UNICODE標識符來編譯。這包括對所有字符和字符串定義使用TCHAR,對字符串文字使用TEXT宏,以及注意不要混淆字節和字符。例如,注意SCRNSIZE中的 _vsntprintf呼叫。第二個參數是緩沖區的字符大小。通常,您使用sizeof (szBuffer)。但如果緩沖區中有寬字符,則返回的不是緩沖區的字符長度,而是緩沖區的字節大小。您必須用sizeof(TCHAR)將其分開。

通常,在Visual C++ Developer Studio中,可使用兩種不同的設定來編譯程序:Debug和Release。為簡便起見,對本書的范例程序,我已修改了Debug設定,以便于定義UNICODE標識符。如果程序使用了需要字符串作參數的C鏈接庫函數,那么_UNICODE標識符也在Debug設定中定義(要了解這是在哪里完成的,請從「Project」菜單中選擇「Settings」,然后單擊「C/C++」標簽)。使用這種方式,這些程序就可以方便地被重新編譯和連結以供測試。

本書中所有程序-無論是否為Unicode編譯-都可以在Windows NT下執行。只有極少數情況例外。本書中按Unicode編譯的程序不能在Windows 98中執行,而非Unicode版則可以。本章和第一章的程序就是兩個特例。MessageBoxW是Windows 98支持的少數寬字符Windows函數之一。在SCRNSIZE.C中,如果用Windows函數wprintf代替了_vsntprintf(您還必須刪除該函數的第二個參數),那么SCRNSIZE.C的Unicode版將不能在Windows 98下執行,這是因為Windows 98不支持wprintfW。

在本書的后面(特別在第六章,介紹鍵盤的使用時),我們將看到,編寫能處理遠東版Windows雙字符集的Windows程序不是一件容易的事情。本書沒有說明如何去做,并且基于這個原因,本書中的某些非Unicode版本的程序在遠東版的Windows下不能正常執行。這也是Unicode對將來的程序設計如此重要的一條理由。Unicode允許程序更容易地跨越國界。

轉載于:https://www.cnblogs.com/caiyonghai/p/cailu.html

總結

以上是生活随笔為你收集整理的Unicode简介的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

亚洲欧美视频在线 | 欧美极品xxxxx | 国产女人40精品一区毛片视频 | 国产精品一区二区三区在线看 | 欧美在线视频a | 国产亚洲精品日韩在线tv黄 | 99精品免费久久久久久久久日本 | 亚州五月| 欧美精品视| 干干干操操操 | 91成人看片| 国产小视频福利在线 | 九九热免费精品视频 | 99这里精品 | 国产精品九九视频 | 玖玖玖精品 | 亚洲精品小视频 | 在线精品观看国产 | 视频一区二区免费 | 国产99爱 | 日韩天天综合 | 亚洲艳情 | 在线免费观看成人 | 免费精品在线视频 | 国产精品欧美日韩 | 福利视频第一页 | 国产成人一区二 | 91麻豆精品国产91久久久久久 | 国产精品一区二区三区99 | 五月婷丁香网 | 国产精品乱码久久久久久1区2区 | 久久久久成人精品亚洲国产 | 黄色小说视频在线 | 99 视频 高清| 日韩成人在线一区二区 | 麻豆精品传媒视频 | 午夜狠狠干| 日日爽夜夜操 | 国产三级久久久 | 中文在线中文资源 | 中文字幕精品视频 | 国产 字幕 制服 中文 在线 | 色www免费视频 | www.久久免费 | 国产欧美最新羞羞视频在线观看 | 丁香综合 | 亚洲综合小说 | 999久久久久久久久6666 | 天天射天天干 | 一区二区激情视频 | 国产精品久久久久久久久免费 | 狠狠地操 | 国产精品男女视频 | 亚洲成人xxx | 黄色一级大片免费看 | 成 人 免费 黄 色 视频 | 91麻豆视频| 人人舔人人插 | 午夜精品福利一区二区三区蜜桃 | 中文字幕九九 | wwwwwww黄| 日日噜噜噜噜夜夜爽亚洲精品 | 成年人app网址 | 国产又粗又长又硬免费视频 | 狠狠的干狠狠的操 | 久久久综合香蕉尹人综合网 | 国产91免费在线 | 在线成人中文字幕 | 久久综合狠狠综合 | 欧美最猛性xxxxx亚洲精品 | 九九日九九操 | 久久国产精品一区二区三区四区 | 射射射av| 精品国产视频一区 | 国产毛片aaa | 天堂在线一区 | 国产精品12 | 久久精选 | 国产高清视频免费在线观看 | 中文字幕丰满人伦在线 | 人人射人人插 | 激情婷婷在线 | 日韩在线电影 | 欧美在线观看小视频 | 免费视频成人 | 亚洲综合小说电影qvod | 亚洲视频一 | 91av视屏| 国产一级电影免费观看 | www.色在线| 九九在线视频 | 国产精品一区二区av麻豆 | 国精产品999国精产 久久久久 | 91最新在线观看 | 亚洲精品午夜国产va久久成人 | 黄色国产高清 | 久久免费av电影 | 国产精品久久久亚洲 | 丁香五婷 | 美女视频一区 | 国产男女无遮挡猛进猛出在线观看 | 国产精品视频永久免费播放 | av高清免费在线 | 久草在线观看视频免费 | 在线观看免费中文字幕 | 成人免费一级片 | 欧美日本不卡视频 | 免费久久久久久久 | 免费三级骚 | 精品一区二区综合 | 色噜噜狠狠狠狠色综合 | 九色91在线视频 | 国产精品视频区 | 国产一级淫片在线观看 | 亚洲丝袜一区二区 | 国产视频久久久久 | 亚洲免费观看在线视频 | 蜜臀久久99精品久久久无需会员 | 中文字幕在线播放第一页 | 日本在线中文在线 | 亚洲性xxxx| 精品久久久久久久久中文字幕 | 午夜少妇av| 在线观看电影av | 午夜av电影院 | 正在播放国产一区 | 欧美精品久久久久久久亚洲调教 | 在线视频麻豆 | 国产五月色婷婷六月丁香视频 | av 一区 二区 久久 | 精品久久久久一区二区国产 | 最近中文字幕第一页 | 黄色www在线观看 | 蜜臀av性久久久久av蜜臀妖精 | 国产男女无遮挡猛进猛出在线观看 | 91九色性视频 | 国产美女精品人人做人人爽 | 久久草网站 | 免费观看黄色12片一级视频 | www.97色.com| 日韩久久精品一区二区三区下载 | 欧美午夜精品久久久久久浪潮 | 久久色中文字幕 | 夜夜狠狠| 久久艹国产视频 | 我要看黄色一级片 | 色婷婷电影 | 粉嫩av一区二区三区免费 | 一区二区三区在线影院 | 国产中文字幕在线播放 | 久久久99国产精品免费 | 缴情综合网五月天 | 日本天天色 | 综合久色| 欧美国产日韩激情 | 五月天堂网| 91麻豆看国产在线紧急地址 | 亚洲欧洲精品一区二区精品久久久 | 成人免费共享视频 | 天天操夜夜逼 | 69精品在线 | 婷婷六月在线 | 国产精品18久久久久久久久久久久 | 久久精品中文 | 国内精品久久久久久久久久久 | 久久久福利影院 | 少妇高潮冒白浆 | jizz欧美性9| 亚洲精品美女久久17c | 成年人天堂com | 日本三级香港三级人妇99 | 亚洲精品免费在线视频 | 久久免费精品国产 | av在线直接看 | 你操综合 | 国产a国产| 国产成人性色生活片 | 麻豆久久 | 国产麻豆精品免费视频 | 久草.com| 亚洲一区二区三区miaa149 | 欧美精品二区 | 亚洲一区欧美精品 | 亚洲黄色影院 | 国产午夜精品av一区二区 | 亚洲区精品视频 | 91久久精品一区 | 极品嫩模被强到高潮呻吟91 | 中文字幕有码在线播放 | 高清色免费| 亚洲a成人v | 99久久久国产精品美女 | 日韩三级成人 | 亚洲精品在线播放视频 | 伊人亚洲综合网 | 国产精品免费视频久久久 | 中文字幕区 | 国产四虎在线 | 女人18精品一区二区三区 | 亚洲在线精品 | 99热这里精品 | 国产在线一线 | wwxxxx日本| 欧美va日韩va | 国产日韩欧美在线一区 | 久久久精品二区 | 色五婷婷 | 少妇bbbb搡bbbb搡bbbb | 国产精品视频免费观看 | 激情大尺度视频 | 97在线免费观看 | 夜色资源站wwwcom | 国产精品国产精品 | 天天透天天插 | 97色在线观看 | 91豆花在线观看 | 久久夜色精品国产欧美一区麻豆 | 国产精品18久久久久久久久久久久 | 黄色片亚洲 | 国产一级在线播放 | 国产永久免费高清在线观看视频 | 国产午夜不卡 | 人人草人人草 | 国产亚洲精品成人av久久ww | 亚洲理论影院 | 最近中文字幕在线 | 超碰人人在线 | 欧美精品在线免费 | 天天草天天操 | 色窝资源| 日韩一区二区三区免费视频 | 久久丁香网 | 韩国av免费观看 | 国产精品精品视频 | 欧美精品一二 | 亚洲精品视频大全 | 免费情趣视频 | 久久五月婷婷综合 | 激情五月网站 | 亚洲国产精品99久久久久久久久 | 99视频免费播放 | 欧美另类巨大 | 黄色特级毛片 | 亚洲欧美日韩国产一区二区三区 | 久久精品a | 色在线网| 成人a视频| 日韩久久精品一区二区三区下载 | 亚洲播放一区 | 免费观看的黄色片 | 久久国产精品二国产精品中国洋人 | www亚洲一区| 国产精品一区二区久久久 | 国语精品视频 | 国产不卡免费视频 | 在线观看av国产 | 欧洲av在线| 91九色免费视频 | 亚洲久在线 | 欧美日韩视频在线一区 | 欧美日韩不卡在线 | av久久在线 | 激情图片qvod | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 色姑娘综合 | 国产精品黄色 | 欧美成人黄 | 欧美在线视频精品 | 最新国产精品拍自在线播放 | 香蕉久久国产 | 国产韩国精品一区二区三区 | 在线91播放 | 欧美国产亚洲精品久久久8v | 91看片在线播放 | 久久久久久久网 | 精品欧美小视频在线观看 | 久久午夜色播影院免费高清 | 黄色免费网战 | 久久综合一本 | 色九九在线 | 欧美一级裸体视频 | 超碰97免费在线 | 91久久精品一区二区二区 | 视频一区二区在线 | 99在线观看视频网站 | 久色婷婷 | 亚洲最大av网站 | 91成人精品一区在线播放69 | 一区二区久久久久 | 99热官网 | 亚洲va欧美va人人爽春色影视 | 免费久久久久久久 | 在线观看久 | 97精品一区 | av中文在线| 麻豆国产电影 | 欧美人体xx | 色婷婷国产 | 91精品国产电影 | 91超碰在线播放 | 色综合久久中文字幕综合网 | 天天色天天 | 久久综合婷婷综合 | 国产一级二级三级在线观看 | 一区二区三区在线免费观看视频 | 一级欧美一级日韩 | 天天操天天拍 | 伊人资源站 | 99久久精品网 | 日韩二区三区在线 | 成人污视频在线观看 | 日韩在线中文字幕 | 亚洲 欧美变态 另类 综合 | 97av在线| 一区二区三区 中文字幕 | 激情动态 | 成人久久久精品国产乱码一区二区 | 在线观看www视频 | 黄免费在线观看 | 一区二区中文字幕在线播放 | 久久精品视频网站 | 在线免费观看视频你懂的 | 久久久久久久久久久久久9999 | 国产黑丝袜在线 | 99热最新地址 | 成人av免费在线播放 | av黄色av| 91在线精品视频 | 97人人模人人爽人人喊网 | 久久精品99久久 | 中文字幕亚洲欧美日韩2019 | 四虎成人精品永久免费av九九 | 免费大片av | 日韩精品一区二区三区免费观看视频 | 久久国内视频 | 久久久久女人精品毛片九一 | 午夜久久| 久久国产精品久久w女人spa | 正在播放 国产精品 | 精品久久久999 | 国产视频在线免费观看 | 国产精品久久久久久一二三四五 | 国产91aaa | 欧美日韩国产一区 | 国产精品aⅴ | 国内外成人在线视频 | 国产中文视频 | 国产青草视频在线观看 | 成人小视频在线播放 | 天天草天天摸 | 久久国产精品一区二区三区四区 | 亚洲国产午夜 | 插婷婷| 日韩高清在线一区二区 | 在线播放日韩av | 国产无限资源在线观看 | 激情久久小说 | 亚洲一级在线观看 | 久久精品精品电影网 | 欧美精品久 | 精品国产aⅴ麻豆 | 久久精品久久精品久久39 | 久久精品久久久久电影 | 激情综合六月 | 久久久91精品国产一区二区精品 | 五月花婷婷 | 91福利视频网站 | 国产精品亚洲片在线播放 | 日韩爱爱片 | 久久激情综合网 | 国产免费人成xvideos视频 | 亚洲精品av中文字幕在线在线 | 99久高清在线观看视频99精品热在线观看视频 | 国产精品99久久久久久有的能看 | 四虎国产精品永久在线国在线 | 国产黄色精品在线观看 | 最新国产精品亚洲 | 国产亚洲欧美精品久久久久久 | 亚州精品在线视频 | 亚洲综合精品视频 | 婷婷视频在线观看 | 久久久久综合 | 尤物九九久久国产精品的分类 | 91视频a| 99色精品视频 | 在线 成人 | 久草在线最新免费 | 一区三区视频在线观看 | 国产一区精品在线观看 | 国产第一页精品 | 亚洲欧美精品一区二区 | 亚洲国产成人精品电影在线观看 | 亚洲干视频在线观看 | av色影院 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 国产无套一区二区三区久久 | 国产在线精品一区二区三区 | 亚州欧美视频 | 久99久视频 | 香蕉91视频 | 天天操天天射天天操 | 天天干天天草 | 国产999精品久久久久久绿帽 | 久久精品牌麻豆国产大山 | 国产精品久久久久婷婷 | 激情偷乱人伦小说视频在线观看 | 成人在线免费av | 91麻豆传媒 | 日韩av电影网站在线观看 | 精品久久久99 | 久久久久国产成人精品亚洲午夜 | 亚洲视频在线观看免费 | av电影免费看 | 亚洲人成人在线 | 午夜婷婷综合 | 日韩av在线看 | 97视频精品 | 国产丝袜制服在线 | 黄色免费av | 天天综合人人 | 国内成人综合 | 国产香蕉视频在线观看 | 国产高清视频在线播放 | 免费在线观看a v | 99久久日韩精品视频免费在线观看 | 国产一区二区视频在线播放 | 99国产在线视频 | 天天操夜 | 亚洲女同videos | 国产69精品久久久久9999apgf | 另类五月激情 | 国产在线不卡精品 | 四虎在线观看视频 | 国产精品自在线 | 免费一级片视频 | 福利一区二区 | 亚洲成人精品在线观看 | 国产视频色 | 欧美一二三在线 | 看毛片网站 | 日本特黄特色aaa大片免费 | 欧美成人在线网站 | 97成人精品 | 日本中文字幕视频 | 国产传媒中文字幕 | 久久99精品波多结衣一区 | av中文字幕在线看 | 国产视频精品免费播放 | 丁香激情网 | 久久久久电影网站 | 久草久热 | 激情小说久久 | 91麻豆视频 | 99国产视频在线 | 91女神的呻吟细腰翘臀美女 | 日韩中文字幕视频在线观看 | 久久免费美女视频 | 天天激情天天干 | 久久精品国产免费看久久精品 | 高清不卡一区二区在线 | 在线观看一级片 | 最近免费中文字幕mv在线视频3 | 欧洲精品视频一区二区 | 特级西西444www大胆高清无视频 | 中文字幕在线观看完整版 | 日韩精品一区二区在线观看 | 国产精品1000 | 国产精品一区二区久久久 | 99热最新精品 | 99国产精品免费网站 | 成人在线免费av | 亚洲粉嫩av| 婷婷色网址 | 成人av在线影视 | 国产精品igao视频网入口 | 在线 欧美 日韩 | 久久精品国亚洲 | 在线观看免费黄视频 | 日日草夜夜操 | 俺要去色综合狠狠 | 丁香六月婷婷激情 | 91精品人成在线观看 | 国产一区二区在线观看视频 | 久久毛片高清国产 | 激情婷婷久久 | 久久99中文字幕 | 亚洲一区二区天堂 | 中文字幕中文字幕 | 免费成人黄色av | 亚洲专区视频在线观看 | 日韩免费高清 | 欧美大片在线观看一区 | 国产在线观看午夜 | 激情欧美一区二区三区免费看 | 成人在线视频在线观看 | 日韩网站在线播放 | 亚洲免费观看在线视频 | 91精品国产成人观看 | 久久国产美女视频 | 中文字幕在线播放日韩 | 日本黄色免费在线 | 精品国产美女在线 | 欧美网站黄色 | 国产亚洲精品久久19p | 天天爱天天操天天干 | 天天躁日日躁狠狠躁av中文 | 亚洲精品婷婷 | 性色av一区二区三区在线观看 | 亚洲午夜精品久久久久久久久 | 日韩精品久久久免费观看夜色 | 99精品在这里 | 日本激情视频中文字幕 | 五月婷香蕉久色在线看 | 最近更新好看的中文字幕 | 日韩乱码中文字幕 | 亚洲欧洲精品视频 | 美女黄频视频大全 | 97视频免费在线观看 | 欧洲在线免费视频 | 手机色站| 国产视频色 | 亚洲国产午夜视频 | 免费在线观看视频一区 | 在线观看视频福利 | 国产小视频免费在线观看 | 免费看污在线观看 | 国产视频精品免费播放 | 激情电影在线观看 | 亚洲高清在线视频 | 精品国模一区二区 | 开心激情五月婷婷 | 免费情缘| 日韩免费一区二区三区 | 婷婷综合五月天 | 狠狠操天天操 | 亚洲精品视频免费在线 | 久久久穴 | 久久精品免费播放 | 国产精品久久久久av福利动漫 | 色av男人的天堂免费在线 | 97香蕉超级碰碰久久免费软件 | 久久九九影视网 | 九九色视频 | 天天色天天操天天爽 | 久久综合成人网 | 在线日本v二区不卡 | 国产又粗又猛又黄又爽的视频 | 91视频在线播放视频 | 欧美一级性视频 | 国产精品毛片一区二区在线看 | 人人添人人澡人人澡人人人爽 | 日本午夜免费福利视频 | 久草在线免费看视频 | 91麻豆精品国产自产 | 国产美女精品视频免费观看 | 91精品国产电影 | 亚洲视屏一区 | 不卡av在线免费观看 | 国产黄色在线网站 | 人人藻人人澡人人爽 | 国产精品视频内 | 国产精品久久久久9999吃药 | 欧美在线视频一区二区三区 | 天天草夜夜 | 亚洲丝袜一区二区 | 日本精品视频免费观看 | 日韩性久久 | 欧美一区二区免费在线观看 | 麻豆成人小视频 | 亚洲在线不卡 | 久色婷婷 | 亚洲欧美成人在线 | 偷拍精品一区二区三区 | 成人影片在线播放 | 成人a视频片观看免费 | 亚洲资源在线网 | 精品免费视频123区 午夜久久成人 | 日韩av一区二区三区四区 | 99精品久久久 | 久久a免费视频 | 欧美在线free | 国产成人在线观看免费 | 深爱开心激情 | 午夜视频播放 | 国产免费久久av | 国产黄色播放 | 久久福利在线 | 人人爽影院| 精品av在线播放 | 一 级 黄 色 片免费看的 | 91在线91 | 曰本免费av | 国产视频999 | 国产精品九九九 | 亚洲欧美在线综合 | 亚洲成a人片77777潘金莲 | 公开超碰在线 | 午夜精品区| 一级a毛片高清视频 | 青春草免费在线视频 | 亚洲免费在线观看视频 | 91精彩在线视频 | 亚洲精品久久在线 | 成年人在线观看免费视频 | 亚洲视屏一区 | 激情喷水 | 精品一区二区精品 | 久免费视频 | 国产艹b视频 | 91精品在线免费观看视频 | 国产在线超碰 | 九九热久久久 | 日韩激情av在线 | 在线观看爱爱视频 | 国产精品理论在线观看 | 国产精品国产精品 | 欧美日一级片 | 久久久久久久99精品免费观看 | 黄色av电影网 | 西西4444www大胆艺术 | 欧美一区二区三区特黄 | 午夜影视av| 成人午夜网 | 欧美精品一级视频 | 日韩欧美v| 中文字幕在线视频第一页 | 在线91网| 99亚洲国产精品 | 久久久久国产成人免费精品免费 | 日韩成人av在线 | 尤物九九久久国产精品的分类 | 色婷婷天天干 | 成人av中文字幕 | 久精品在线 | 免费三级黄色片 | 99视频+国产日韩欧美 | 日日天天av | av在线不卡观看 | 五月婷婷播播 | 中文字幕有码在线播放 | 日韩精品免费一区 | 国产精品美女999 | 天天操天天摸天天射 | 欧美日韩综合在线观看 | 成人a在线观看 | 亚洲精品免费看 | 国产精品理论视频 | 91在线porny国产在线看 | 三级性生活视频 | 国产字幕在线看 | 亚洲国内在线 | 日韩精品一区二区三区视频播放 | 丁香婷婷综合激情 | 在线国产日本 | 久人人| 狠狠干夜夜操天天爽 | 三级av在线播放 | 日日干天天爽 | 亚洲丝袜中文 | 亚洲欧美日韩一二三区 | 国产精品美女久久久久久久久久久 | 久久香蕉电影网 | 九九爱免费视频在线观看 | 免费h在线观看 | 色婷婷精品 | 亚洲精品99久久久久久 | 五月天综合婷婷 | 97人人澡人人爽人人模亚洲 | 久久久综合香蕉尹人综合网 | 国产精品久久久久久久久久久免费看 | 天天综合网 天天 | 色网站免费在线观看 | 亚洲女人天堂成人av在线 | 在线欧美日韩 | 精品国产一区二区三区久久久 | 久久综合久色欧美综合狠狠 | 久久字幕精品一区 | 草久在线观看视频 | 在线免费av网 | 超碰97免费在线 | 亚洲精品在线电影 | 中文字幕在线日亚洲9 | 日韩高清在线看 | 日韩免费观看高清 | 激情综合网五月婷婷 | 黄色一级大片在线免费看产 | 久久久黄色免费网站 | 99久久久国产精品免费99 | 成人小视频在线观看免费 | 国产精品久久久久久久免费大片 | 国产一区二区在线播放视频 | 色综合天天综合网国产成人网 | 在线观看黄色小视频 | 国产黄色在线看 | 美女福利视频一区二区 | 国产精品美女视频网站 | 麻豆高清免费国产一区 | 激情在线网站 | 一区二区三区www | 亚洲精品456在线播放乱码 | 久久久久在线观看 | 激情自拍av | 99色视频 | 91av电影在线 | 久久久人人人 | 国产精品久久久久久久久久免费看 | 久久精品国产免费观看 | 天天操天天是 | av免费在线播放 | 日韩精品视频在线观看网址 | 日本黄色免费在线观看 | 99久久久久国产精品免费 | 久久免费成人 | 黄色电影在线免费观看 | 999热视频 | 日女人免费视频 | www.色爱 | 在线视频欧美精品 | 91麻豆精品国产 | 国产又粗又猛又色又黄网站 | 开心激情网五月天 | www.国产视频| 亚洲码国产日韩欧美高潮在线播放 | 国产 视频 久久 | 国产精品一区二区三区四区在线观看 | 中文av影院| 黄色一集片 | 国产精品一区二区免费视频 | 成人黄色片免费看 | 人人干人人做 | 91自拍成人| 日韩二区在线 | 一区二区三区韩国免费中文网站 | av一级片在线观看 | 精品在线一区二区三区 | 免费在线观看毛片网站 | 欧美日韩国产欧美 | 国产精品免费在线观看视频 | 狠狠干狠狠久久 | 国产欧美高清 | 808电影免费观看三年 | 成人羞羞免费 | 友田真希av| 日韩精品免费在线视频 | 成人在线网站观看 | av电影免费在线 | 天天躁日日躁狠狠躁av中文 | 国产无套精品久久久久久 | 九九热有精品 | 久久国产精品精品国产色婷婷 | 日韩一级成人av | 亚洲 欧美日韩 国产 中文 | www.夜色.com | 欧美一级片在线观看视频 | 国产一区二区在线播放 | av成人在线看 | 国产日韩精品一区二区三区在线 | 亚洲va欧美va人人爽春色影视 | 国产系列精品av | 国产美女免费观看 | 日日碰狠狠添天天爽超碰97久久 | 国产精品乱码久久久久久1区2区 | 国产露脸91国语对白 | 99精品视频网站 | 999男人的天堂 | 久久国产精品色婷婷 | 中文字幕区 | 九九日九九操 | 中文字幕在线看视频国产 | 久久69精品 | 亚洲乱码在线 | 精品国产aⅴ一区二区三区 在线直播av | 天天天干天天射天天天操 | 黄色小说在线观看视频 | 欧美大片第1页 | 国产一区二区在线免费 | 精品一区91 | 中文字幕亚洲字幕 | 九九久久成人 | 91在线免费公开视频 | 日日日日干 | 国产精品久久久久久久免费 | 日日操日日| 91高清在线 | 一区二区 精品 | 久久久免费观看视频 | 久久高清国产 | 99精品福利视频 | 欧美日韩中 | 成人影视免费 | 99 久久久久 | 五月婷婷一区 | 激情综合六月 | av免费在线观 | av中文在线播放 | 久久国产精品久久w女人spa | 四虎影视av | 成年人在线免费看片 | 国产又粗又猛又黄视频 | 免费看片成年人 | 久久只精品99品免费久23小说 | 婷婷综合五月天 | www视频免费在线观看 | 欧美一级在线观看视频 | 国产精品乱码久久久久 | 久久综合国产伦精品免费 | 久久情网 | 免费a级大片 | 日本99干网 | 操天天操 | 亚洲国产精品视频在线观看 | 久久www免费人成看片高清 | 久久成人欧美 | 美女在线观看网站 | 国产亚洲精品久久久久久电影 | 丁香六月av| 久久综合狠狠综合久久狠狠色综合 | 亚洲蜜桃av| 免费看黄在线 | 亚洲黄色在线观看 | 97精品视频在线播放 | 免费黄色在线网站 | 一级黄色在线视频 | 成人av在线播放网站 | 天天操天天玩 | 一本色道久久综合亚洲二区三区 | 国产精品一区在线 | 91免费高清观看 | 三级av中文字幕 | 最新av网址大全 | 国产精品夜夜夜一区二区三区尤 | 亚洲精品理论 | 日韩欧美网站 | 不卡的av中文字幕 | 99视频久 | 亚洲国产中文字幕 | 自拍超碰在线 | 91在线免费观看国产 | 又黄又刺激 | 亚洲一区二区91 | 丁香色综合 | 在线精品播放 | 色婷婷色 | 天天干天天弄 | 狠色狠色综合久久 | 久久国产精品一区二区 | 99视频在线免费 | 日日爱夜夜爱 | 亚洲一区在线看 | 婷婷去俺也去六月色 | 国产婷婷一区二区 | 日韩av一区二区在线影视 | 午夜精品一区二区三区免费视频 | 91看片一区二区三区 | 国产成人一区二区在线观看 | 久久99久久99精品免视看婷婷 | 97免费 | 久久尤物电影视频在线观看 | 日日干天天操 | 国产精品大片在线观看 | 中文字幕最新精品 | 国产精品中文在线 | 久久免费视频一区 | 91夜夜夜| 2021国产视频 | 免费看十八岁美女 | 免费能看的黄色片 | 久久久久久视频 | 成人看片 | 在线电影日韩 | 麻豆视频在线播放 | 最近2019年日本中文免费字幕 | 五月婷婷在线观看视频 | 亚洲九九九 | 色综合久久网 | 69av网| 精品av网站| 国产成人精品综合 | 免费在线观看一区 | 亚洲一区视频免费观看 | 成人h视频 | 人交video另类hd | 18做爰免费视频网站 | 在线观看精品一区 | www.av在线.com| 中文区中文字幕免费看 | 亚洲视频电影在线 | 国产原创在线视频 | 久久a久久 | 亚洲综合在线观看视频 | www.97视频| 久久久福利 | 国产一级视频 | 美女网站视频一区 | 麻豆影视在线播放 | 国产精品欧美一区二区三区不卡 | 中文字幕 第二区 | 伊人在线视频 | 久草视频播放 | 久久观看免费视频 | 日日夜夜噜噜噜 | 亚洲精品午夜aaa久久久 | 国产精品igao视频网入口 | 亚洲色图27p | 日韩精品免费专区 | 日韩免费观看av | 欧美日韩69 | 99精品久久久| 亚洲在线视频播放 | 亚洲综合精品视频 | 国产亚洲一级高清 | 久久伊人精品一区二区三区 | 毛片精品免费在线观看 | 久久色中文字幕 | 男女视频久久久 | 国产手机视频在线播放 | 天天干com | 国产+日韩欧美 | 精品国产精品国产偷麻豆 | 2018好看的中文在线观看 | 久久dvd| 精品久久久久久亚洲综合网站 | 国产午夜精品免费一区二区三区视频 | 国产丝袜美腿在线 | 久久99久久99久久 | 久久精品三级 | 亚洲乱码国产乱码精品天美传媒 | 91女神的呻吟细腰翘臀美女 | 久久伊人色综合 | 97在线视频网站 | 黄色小说18 | 久久99在线 | 美女啪啪图片 | 二区中文字幕 | 中文免费在线观看 | 国产精品久久久免费看 | 天堂在线视频中文网 | 亚州性色 | 久久久久久久久久久久99 | 天天综合网~永久入口 | 99视频黄 | 成片免费观看视频大全 | 三级视频片 | 黄污网站在线观看 | 久久人人精| 亚洲日日射 | 久久免费视频在线观看 | 97在线免费观看视频 | 五月天婷亚洲天综合网精品偷 | 国产精品久久久久永久免费 | 不卡av免费在线观看 | 久草在线资源观看 | 超级碰视频| 免费a网站 | 亚洲综合色视频在线观看 | www.亚洲激情.com | 九色琪琪久久综合网天天 | 在线看黄色的网站 | 亚洲成人av一区二区 | 国产成人91 | 99视频久久 | 中文日韩在线视频 | www.av免费观看 | 在线黄色免费 | 美女免费av| 日本中文字幕在线观看 | 欧美激情另类文学 | 91天堂素人约啪 | 亚洲欧美日韩精品久久奇米一区 | 欧美日比视频 | 91精品视频播放 | 国产精品一区二区久久 | 免费视频久久久久久久 | 美女免费视频网站 | 能在线看的av | 日韩剧情| 一级全黄毛片 | 国产三级精品在线 | 国产日韩视频在线 | 狠狠干夜夜操 | 99精品国产视频 | 亚洲天堂网在线视频观看 | 天天摸天天操天天舔 | 一区二区欧美日韩 | 免费成人av| 国产丝袜美腿在线 | 中文字幕精品一区 | 九九久| 国产99自拍 | 日本久久99 | 99国内精品 | 特级毛片在线观看 | 婷婷视频在线播放 | 天天爱天天操天天干 | 色姑娘综合网 | 国内精品久久久久影院一蜜桃 | 四虎视频| 国产午夜精品一区二区三区 |