Windows編碼約定
如果你是編寫windows程序的新手,當你第一次看到windows程序源碼時,它會令人感到不安。這些代碼充滿了奇怪的定義,如 DWORD,LPRECT等等;以及變量的名稱,如 “hWnd”,“pwsz”(匈牙利表示法)。值得花點時間來了解一些windows編程的編碼約定。
絕大多數的Windows API 是由 函數或者組件對象模型(COM)接口組成。很少的Windows API 是提供C++ 類的(有一個顯著的例外是GDI+中,一個2D圖形API)。
類型定義
Windows頭文件包含大量的類型定義,大多是在WinDef.h中定義的。這裏是經常會遇到的一些類型定義。
Integer(整數)類型
數據類型 |
數據大小 |
有無正負符號 |
BYTE |
8位二進制 |
Unsigned無符號 |
DWORD |
32位二進制 |
Unsigned無符號 |
INT32 |
32位二進制 |
Signed有符號 |
INT64 |
64位二進制 |
Signed有符號 |
LONG |
32位二進制 |
Signed有符號 |
LONGLONG |
64位二進制 |
Signed有符號 |
UINT32 |
32位二進制 |
Unsigned無符號 |
UINT64 |
64位二進制 |
Unsigned無符號 |
ULONG |
32位二進制 |
Unsigned無符號 |
ULONGLONG |
64位二進制 |
Unsigned無符號 |
WORD |
16位二進制 |
Unsigned無符號 |
正如你所看到的,這些數據類型定義有一定的冗餘,這些重疊的部分是因爲兼顧舊版Windows API 。這裏列出的類型都有固定的大小,並且在這些類型的大小在32位和64位應用程序中都是相同的。例如:DWORD類型,在32位或64位應用程序中始終是32位寬。
Boolean 類型(布爾)
BOOL 是一個整數值,用於在布爾上下文的類型定義,頭文件WinDef.h還定義了兩個值與BOOL一起使用:
#define FALSE 0
#define TRUE 1
儘管這一定義爲 TRUE,然而,大多數返回BOOL值的函數是可以返回任何非零值來表示布爾真值。因此,布爾類型的應用應該這樣寫:
//正確的寫法
BOOL result=SomeFunctionThatReturnsBoolean();
If (result)
{
...
}
並且不應該這樣:
//錯誤的寫法
If (result == TRUE)
{
...
}
請注意 BOOL 是一個整數類型,與C++的bool類型是不可互換的。
Pointer類型(指針)
Windows定義了許多形式如 Pointer-to-X的數據類型,這些數據類型通常以P或LP作爲名稱的前綴,例如:LPRECT是一個指向RECT的指針,RECT是一個描述矩形的結構。以下的變量聲明是等效的:
RECT* rect; //指向RECT結構的指針
LPRECT rect; //同上
PRECT rect; //一樣同上
從歷史來講,P代表指針,LP代表長指針;長指針(也稱爲遠指針)是16位Windows的延續,當需要當前段的內存地址範圍之外。這個LP前綴被保留了下來,以使其更易於16位代碼連接在32位Windows。如今已沒有區別,一個指針就是一個指針而已。
Pointer Precision類型(指針精度)
下面的數據類型都是指針的大小——確切的說,在32位應用程序是32位寬,64位應用程序是64位寬。大小是在編譯是確定的。當一個32位程序運行在64位Windows上,這些數據類型仍然是4個字節寬(一個64位程序無法在32位Windows上運行,所以不會發生相反的情況)。
l DWORD_PTR
l INT_PTR
l LONG_PTR
l ULONG_PTR
l UINT_PTR
在使用這些類型情況下,一個整數可能會轉換爲指針。它們還用來定義指針算法的變量,和定義循環計數器全方位的遍歷這內存緩衝區中的字節。更普遍的,它們出現的地方,在64位Windows上,現有的32位值擴展到64位。
匈牙利表示法
匈牙利表示法的做法是將前綴添加到變量名,給變量附加信息(這個表示法的發明者查爾斯-西蒙是匈牙利人,故以此命名)。
在它最初的形式,匈牙利表示法賦予一個變量語義信息,告訴你預期的用途。例如,i的語義是索引,cb的語義是以字節爲單位的大小(字節的計數),以及rw和col語義是行和列的數。這些前綴的目的在於避免意外使用在錯誤上下文的一個變量。例如,你看到一個表達式rwPointer + cbTable 你就會知道一個行號加到一個大小,幾乎可以肯定這是代碼中的bug。
更常見的匈牙利表示法形式是使用前綴來給類型信息。例如,dw表示DWORD,w表示WORD。
如果你在網絡上搜索匈牙利表示法,你將會發現很多有關匈牙利表示法是好還是壞的意見,一些程序員強烈的反感匈牙利表示法,其他人發現很好用。不論如何,許多人在MSDN上的代碼示例是使用匈牙利表示法。但你不需要記住前綴理解代碼。