文字處理軟件應該是軟件開發中的一大支柱,而任何軟件中字符串的處理更不可或缺。這裡主要借鑑windows核心編程談談使用UNICODE的好處。
既 然是基於windows編程,就得看看windows平台本身對字符的處理方式。由於ANSI字符採用8位進行編碼,對於西歐ABC之類足夠,然而對於中 東的字符不實用(考慮下我們中國的漢字),所以就出現了UNICODE。window98是基於ANSI的平台,windows2000是基於 UNICODE開發的平台,因此可以知道在調用Windows API的時候,假如我們在98系統上傳遞UNICODE字符,那麼系統在背後會先把字符轉化為ANSI字符然後調用API;相反,我們在2000系統上傳 遞ANSI字符,那麼會先轉化為UNICODE字符。
去年看過(準確說是翻了一下,沒時間看)一本書《C/C++-編程高手箴言》(梁肇 新 超級解霸作者),他裡面有一部分是談到使CPU降溫,很好奇翻了一下,主要講如何使CPU少轉幾圈。我的感想是,要想成為一名優秀的軟件開發人員,必須 make good use of (有時漢語無法表達這麼好) CPU和RAM,儘量少浪費時鐘和內存塊,當然也需要充分利用否則也是浪費,其中把握的是一個度,扯遠了,回來繼續談UNICODE。
先看看使用UNICODE的好處(書上的):
1、可以很容易地在不同語言之間進行數據交換。
2、使你能夠分配支持所有語言的單個二進制。exe文件或DLL文件。
3、提高應用程序的運行效率。
如何基於UNICODE編譯:
只需定義宏_UNICODE或者UNICODE (VC 2005默認採用Unicode編譯)
Windows宏定義處理支持ANSI和UNICODE編譯
大學C、C++語言中我們學習字符表示是char,由於書中講解全部一個模式,而開發類書籍很少講解ANSI、UNICODE字符串區別,使得很少有人關注。在進行函數調用的時候,很少去關注接口處字符串處理,可能無意中你就使CPU多轉幾圈。
ANSI字符表示是char,佔8位;UNICODE字符表示是wchar_t,佔16位。Windows編程用宏對這兩種類型進行了封裝:
typedef char CHAR;
typedef wchar_t WCHAR; 表示這兩種字符串數據:
CHAR chANSI[] = "hello";
WCHAR chUnicode[] = L"hello"; 同樣表示字符串卻要使用兩種表示方法,Windows為我們定義了一套宏用來處理這些問題,例如用TCHAR宏表示字符,用_T()宏來表示字符常量類型,它根據編譯字符集選項來確定具體類型。同樣定義了字符處理函數宏,具體參看msdn。
下面基於提高應用程序的運行效率來探討,純理論分析:
CHAR chANSI[100];
WCHAR chUnicode[100];
// Normal sprintf: all string are ANSI
sprintf(chANSI, "%s", "ANSI Str");
// Converts Unicode string to ANSI (Be careful %s and %S)
sprintf(chANSI, "%S", L"Unicode Str");
// Normal swprintf: all string are Unicode
swprintf(chUnicode, L"%s", L"Unicode Str");
// Converts ANSI string to Unicode (Be careful %s and %S)
swprintf(chUnicode, L"%S", "ANSI Str"); 從 上面可以看出,簡單的一個打印函數都可能導致CPU多花時鐘來進行函數調用前處理,所以編程時一定要養成好習慣,隨手做到可能使你的代碼與眾不同。由於我 們目前的系統大多是Windows 2000以上版本,採用Uincode字符集,在API調用的時候接口字符都是Unicode的,所以最好採用Unicode字符風格進行編碼,這樣可以 減少調用時轉換開銷。
應該注意的問題:
假設定義一個字符數組TCHAR szName[100],當基於Unicode編譯的時候,它實際佔用200字節,假設有一個給字符賦值函數:
void SetName(TCHAR* pName, int iSize) 調用該函數:
SetName(szName, sizeof(szName)) 這樣就可能產生錯誤,sizeof求出的是數組所佔字節數目,而不是字符個數,字符個數應該是sizeof(szName)/sizeof(TCHAR)。所以編程的時候腦袋一定要繃緊一根弦,提防類似錯誤。