Windows编码约定

​翻译自MSDN上的英语原文​

如果你是编写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上的代码示例是使用匈牙利表示法。但你不需要记住前缀理解代码。