原創文章,轉載請註明作者及出處。
首發
http://blog.csdn.net/beyondcode
http://www.cnblogs.com/beyond-code/
http://hi.baidu.com/beyondcode
今天,開始第二篇文章,這章我準備介紹一下Windows平台下編程中Unicode編碼和ASCII編碼的相關問題。
不知道各位新手朋友們遇到這樣的問題沒有呢,建立一個Windows應用程式,調用MessageBox這個函數,準備讓它彈出一段提示文本,可是編譯器在編譯的時候卻報錯說,不能將 const char* 或者 const char[] 轉換為 const wchar_t* 之類的提示呢,很多剛接觸Windows API編程的朋友們在這裡可能就卡住了,不知如何下手解決了,其實,這就是Unicode編碼和ASCII編碼的問題了。我下面就會一一道來
關於Unicode和ASCII具體的編碼是怎麼的,我這裡就不詳細介紹了,也介紹不了,如果需要深入瞭解,網上有很多這方面的專門文章,我這裡就只對Unicode編碼和ASCII編碼在Windows平台下的編程相關的內容進行介紹。
我們都知道Unicode和ASCII最大的區別就是Unicode採用2個位元組來儲存一個字元,不管是英文,漢字,還是其他國家的文字,都有能用2個位元組來進行編碼,而ASCII採用一個位元組儲存一個字元,所以對於英文的編碼,那是足夠的了,可是對於漢字的編碼,則必須採用一些特殊的方法,用2個ASCII字元來表示一個漢字。
我們在寫程式的過程中,勢必要和字元打交道,要輸入,擷取,顯示字元,到底是選用Unicode字元呢還是ASCII字元呢,這都是各位自己的權利。但為了程式的通用性和符合目前作業系統的主流趨勢,Unicode編碼是被推薦的。由於Unicode字元要比ASCII字元佔用的空間大一倍,編譯出來的程式在體積上和佔用的記憶體上必定要大一些,不過這並不是什麼很大的問題。所以微軟目前的SDK中保留了2套API,一套用於採用Unicode編碼處理字元的程式的編寫,一套用於採用ASCII編碼處理字元的程式的編寫。 例如,我們上面提到的MessageBox,它其實不是一個函數名,而是一個宏定義,我們先來看看它是怎麼被定義的,再來討論它。
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif
看到了嗎? 很簡單是不是, 如果定義了UNICODE 這個宏 那麼就定義MessageBox為MessageBoxW,如果沒有定義UNICODE這個宏, 那麼就定義MessageBox 為MessageBoxA,MessageBox後面的W和A 就是代表寬位元組(Unicode)和ASCII,這樣,其實存在於SDK中的函數是MessageBoxW和MessageBoxA這兩個函數.
MessageBox只是一個宏而已。所以在程式中,這3個名字你都可以使用,只不過需要注意的是,使用MessageBoxA的話,那麼你要注意傳給它的參數,字元都必須是單位元組,也就是ASCII, 在程式中就是char,如果使用MessageBoxW的話,那麼,字元都必須使用Unicode,程式中就是 wchar_t。 但是這樣有個非常不方便的地方那就是,如果你使用W尾碼系列的函數的話,那麼你的程式使用的字元就是Unicode字元編碼的,但是如果你需要用這個程式的原始碼編譯出字元採用ASCII編碼的程式,那麼需要改動的地方就太大了。凡是涉及到字元操作的地方都需要改變。那麼 ,有沒有比較好的辦法不做更改就可以用同樣的代碼編譯出ASCII版本的程式呢。
當然有,就是我們在編程的時候盡量使用不帶尾碼的宏定義,如上例,就使用MessageBox,其中的參數也不明確使用char 還是wchar_t 而是使用微軟給我們定義的TCHAR字元資料類型,它的定義和上面MessageBox函數的定義差不多,都是根據是否定義了UNICODE這個宏來判斷是將TCHAR定義為char還是wchar_t,所以這樣一來,這個TCHAR的資料類型就是可變的了,它根據工程的設定而定義為相應的最終字元類型,這樣我們的程式就可以不做任何更改就可以輕鬆的編譯出另外一個版本的了。是不是非常方便。
前面2篇文章純文字的介紹比較多,因為很多是概念性的,需要理解,後面的文章我準備配合一些小樣本程式,使用一些簡單的API函數,遇到的相關的概念在一併介紹的方法進行。所以,前2篇文章如果各位朋友不是很能理解,不用擔心,影響不是很大,經過後面的學習,你就會慢慢的理解前面所說的內容了。
By-deathcode