轉自http://blog.chinaunix.net/uid-7608308-id-2048125.htmlhtml
簡介:這是DWORD及LPCTSTR類型的瞭解的詳細頁面,介紹了和類,有關的知識,加入收藏請按鍵盤ctrl+D,謝謝你們的觀看!要查看更多有關信息,請點擊此處c++
首先聲明,這都是在網上找的資料,我再整理修改的:編程
一:關於DWORDc#
DWORD就是32bit的unsigned long無符號長整型,DWORD是雙字類型 ,4個字節,API函數中有不少參數和返回值是DWORD的。安全
二:如何理解LPCTSTR類型?asp.net
(一)LPCTSTR類型的概念ide
L表示long指針 這是爲了兼容Windows 3.1等16位操做系統遺留下來的,在win32中以及其餘的32爲操做系統中, long指針和near指針及far修飾符都是爲了兼容的做用。沒有實際意義。函數
P表示這是一個指針ui
C表示是一個常量編碼
T表示在Win32環境中, 有一個_T宏
這個宏用來表示你的字符是否使用UNICODE, 若是你的程序定義了UNICODE或者其餘相關的宏,那麼這個字符或者字符串將被做爲UNICODE字符串,不然就是標準的ANSI字符串。
和 "DWORD及LPCTSTR類型的瞭解" 有關的 c#、asp.net、c++ 編程小帖士: strong>Sqrt(number)取得一數值得平方根。 |
因此LPCTSTR就表示一個指向常固定地址的能夠根據一些宏定義改變語義的字符串。
一樣, LPCSTR就只能是一個ANSI字符串,在程序中咱們大部分時間要使用帶T的類型定義。
LPCTSTR == const TCHAR *
UNICODE方式下,CString 和 LPCTSTR 能夠說通用。
常量字符串ansi和unicode的區分是由宏_T來決定的。可是用_T("abcd")時, 字符串"abcd"就會根據編譯時的是否認義_UNICODE來決定是char* 仍是 wchar_t*。
(二)這裏插入一些關於char,wchar_t,WCHAR,TCHAR,ACHAR的區別的說明:
如今C++的字符分紅兩種類型wchar_t和char。
char:
ANSI字符串,可用字符串處理函數strcat( ),strcpy( ), strlen( )等以str打頭的函數。
wchar_t :
wchar_t是Unicode字符的數據類型,它的實際定義爲:
typedef unsigned short wchar_t;
wchar_t 可用字符串處理函數:wcscat(),wcscpy(),wcslen()等以wcs打頭的函數。
WCHAR:
在頭文件中有這樣的定義:typedef wchar_t WCHAR; 因此WCHAR實際就是wchar_t。
在C語言裏面提供了_UNICODE宏(有下劃線),在Windows裏面提供了UNICODE宏(無下劃線),只要定了_UNICODE宏和UNICODE宏,系統就會自動切換到UNICODE版本,不然,系統按照ANSI的方式進行編譯和運行。只定義了宏並不能實現自動的轉換,他還須要一系列的字符定義支持。
TCHAR:
若是定義了UNICODE宏則TCHAR被定義爲wchar_t。typedef wchar_t TCHAR; 不然TCHAR被定義爲char typedef char TCHAR;
ACHAR:
此類型是AUTODESK公司在adachar.h 頭文件中定義的。
當定義了AD_UNICODE(AUTODESK公司使用UNICODE宏)時爲wchar_t。
WCHAR,CHAR,TCHAR的關係其實是這樣的
typedef unsigned short wchar_t;
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef unsigned char TCHAR;
#endif
typedef unsigned char CHAR;
typedef unsigned wchar_t WCHAR;
在VS2005/2008中,c++對字符串的處理已經默認採用了unicode版本了。 Unicode可使你的程序可以更全面的支持多國語言文字,即便在英文,日文等系統下也不會出現亂碼。並且NT內核基於Unicode,能夠減小了系統 的編碼轉換開銷,提升程序運行速度,而且能夠支持更多的微軟新推出的僅支持Unicode的API。可是有可能會形成在95/98下程序運轉不正常。
(三)CString類對象
CString是基於TCHAR數據類型的對象。若是在你的程序中定義了符號_UNICODE,則TCHAR被定義爲類型wchar_t,即16位字符類型;不然,TCHAR被定義爲char,即8位字符類型。
在UNICODE方式下,CString對象由16位字符組成。非UNICODE方式下,CString對象由8位字符組成。
當不使用_UNICODE時,CString是多字節字符集(MBCS,也被認爲是雙字節字符集,DBCS)。注意,對於MBCS字符串,CString仍然基於8位字符來計算,返回,以及處理字符串,而且你的應用程序必須本身解釋MBCS的開始和結束字節。
UNICODE方式下CString與wchar_t是通用的
就是說在vs2005中,
WCHAR str=L"字符串";
CString str1=str;
是能夠經過編譯的,但到vc6中就不能夠了
通用 MFC 數據類型 |
映射到 ASCII |
映射到 UNICODE |
註釋 |
_TCHAR |
char |
wchar_t |
_TCHAR 是一個映射宏,當定義 UNICODE 時,該數據類型映射到 wchar_t,若是沒有定義 UNICODE,那麼它映射到 char。 |
_T 或 _TEXT |
char 常量字符串 |
wchar_t 常量字符串 |
功能與宏相同,在 ASCII 模式下,它們被忽略,也就是說被預處理器刪除掉,可是若是定義了UNICODE, 則它們會將常量字符串轉換成等價的 UNICODE 。 |
LPTSTR |
char*, LPSTR(Win32) |
wchar_t* |
可移植的32位字符串指針。它將字符類型映射到工程設置的類型。 |
LPCTSTR |
const char*, LPCSTR(Win32) |
const wchar_t* |
可移植的32位常量字符串指針。它將字符類型常量映射到工程設置的類型。 |
(五)UNICODE WCHAR*到 char *
CString str(wchar*);
LPCSTR 32-bit 指針,指向一個常量字串
LPSTR 32-bit 指針,指向一個字串
LPCTSTR 32-bit 指針,指向一個常量字串。此字串可移植到Unicode和DBCS
LPTSTR 32-bit 指針,指向一個字串。此字串可移植到Unicode和DBCS
LPWSTR 32-bit 指針,指向一個unicode字符串的指針
LPCWSTR 32-bit 指針, 指向一個unicode字符串常量的指針
前面的L表明LONG,P就是指針的意思,C就是constant的意思, W是wide的意思,STR就是string的意思
(六)ANSI的狀況
ANSI狀況下,LPCTSTR 就是 const char*, 是常量字符串(不能修改的)。
而LPTSTR 就是 char*, 即普通字符串(很是量,可修改的)。
這兩種都是基本類型, 而CString 是 C++類, 兼容這兩種基本類型是最起碼的任務了。
因爲const char* 最簡單(常量,不涉及內存變動,操做迅速), CString 直接定義了一個類型轉換函數
operator LPCTSTR() {......}, 直接返回他所維護的字符串。
當你須要一個const char* 而傳入了CString時, C++編譯器自動調用 CString重載的操做符 LPCTSTR()來進行隱式的類型轉換。
當須要CString , 而傳入了 const char* 時(其實 char* 也能夠),C++編譯器則自動調用CString的構造函數來構造臨時的 CString對象。
所以CString 和 LPCTSTR 基本能夠通用。
可是 LPTSTR又不一樣了,他是 char*, 意味着你隨時可能修改裏面的數據,這就須要內存管理了(如字符串變長,原來的存貯空間就不夠了,則須要從新調整分配內存)。
因此 不能隨便的將 const char* 強制轉換成 char* 使用。
如例子:
LPSTR lpstr = (LPSTR)(LPCTSTR)string;
就是這種不安全的使用方法。
這個地方使用的是強制類型轉換,你都強制轉換了,C++編譯器固然不會拒絕你,但同時他也認爲你確實知道本身要作的是什麼。所以是不會給出警告的。
強制的任意類型轉換是C(++)的一項強大之處,但也是一大弊端。這一問題在 vc6 之後的版本(僅針對vc而言)中獲得逐步的改進(你須要更明確的類型轉換聲明)。
其實在不少地方均可以看到相似
LPSTR lpstr = (LPSTR)(LPCTSTR)string;
地用法,這種狀況通常是函數的約束定義不夠完善的緣由, 好比一個函數接受一個字符串參數的輸入,裏面對該字符串又沒有任何的修改,那麼該參數就應該定義成 const char*, 可是不少初學者弄不清const地用法,或者是懶, 總之就是隨意寫成了 char* 。 這樣子傳入CString時就須要強制的轉換一下。
這種作法是不安全的,也是不被建議的用法,你必須徹底明白、確認該字符串沒有被修改。
CString 轉換到 LPTSTR (char*), 預約的作法是調用CString的GetBuffer函數,使用完畢以後通常都要再調用ReleaseBuffer函數來確認修改 (某些狀況下也有不調用ReleaseBuffer的,一樣你須要很是明確爲何這麼作時才能這樣子處理,通常應用環境能夠不考慮這種狀況)。
同時須要注意的是, 在GetBuffer 和 ReleaseBuffer之間,CString分配了內存交由你來處理,所以不能再調用其餘的CString函數。
CString 轉LPCTSTR:
CString cStr;
const char *lpctStr=(LPCTSTR)cStr;
LPCTSTR轉CString:
LPCTSTR lpctStr;
CString cStr=lpctStr;
|