第九章 数据名称
9.5 匈牙利命名约定
匈牙利命名约定是一整套对子程序和变量进行命名的详细约定。这一约定广泛应用在 C 语 言中,特别是在 Microsoft Windows 环境下用 C 编程时,之所以称其为“匈牙利”是因为遵循这 一约定的命名看起来像是外文。而且其发明者 Charles Simonyi 原来是匈牙利人。
匈牙利命名主要包括三个部分:基本类型、一个或更多的前缀、一个限定词。在下面的例 子是在 C 中采用匈牙利命名约定写成的,你很容易就可以对其加以改进以扩展到其它语言中。
9.5.1 基本类型
基本类型是指待命名变量的数据类型。基本类型名称通常不指向程序语言中任何一种已定 义的标准数据类型。基本类型是一种更抽象的数据类型,基本类型名称指向的可能是窗口、屏 幕区和字体等实体。在匈牙利名称中只能使用一种基本类型。
基本类型是用你为某一特定程序建立的简写代码来表示的,然后对其作标准化以便在这一 程序中继续使用。以下是在一个文字处理程序中你可能用到的基本类型:
基本类型 含义
wn 窗口
scr 屏幕区
fon 字体
ch 字符(不是 C 意义上的字符,而是这个文字处理程序 将用来在文件中代表字符数据结构意义上的)
pa 段落
使用匈牙利基本类型时,同时也定义了与基本类型使用同样缩写的数据类型。因此,如果 使用了如上表列出的基本类型,就会看到像这样的数据说明:
WN wnMain;
SCR scrUserWorkspace;
CH chCursorPosition;
9.5.2 前缀
前缀放在基本类型前面并描述了变量的使用。与基本类型不同的是前缀在某种程度上是标 准化的。表 9-1 中示出了一级标准匈牙利前缀:
表 9-1 匈牙利变量名称前缀
前缀 含义
a 数组
c 数目(如记录、字符等等的个数等)
e 数组的元素
g 全局变量
h 处理
i 数组下标
m 模块层次上的变量
p(lp,np) 指针(长指针、近指针——对于 Intel 机器)
前缀是小写的,并且放在变量名中基本类型的前面。如果需要的话,可以把它与基本类型 或与其自身组合使用。例如,一个表示窗口的数组,可以用“a”来表示它是个数组,用“wn”
表示窗口,因此可以用“awn”来作这个数组的名称;而对窗口的操作可称为 hwn;cwn 是窗口 的数目;cfon 是字体的种类等等。
9.5.3 限定记号
匈牙利名称的最后一个要素是限定词。限定词是名称的描述部分。没有使用匈牙利约定
时 也 可 利 用 这 部 分 来 补 偿 。 在 上 前 面 给 出 的 例 子 — — wnMain 、 scrUserWorkspace 和 chCursorPosition 中,Main、UserWorkspace 和 CursorPosition 都是限定词。在本章前面给出的关 于变量命名的准则也适用于限定词。
除了自己生成的限定词以外,匈牙利约定中还对容易在处理时产生混淆的概念给出了标准 化限定词。在表 9-2 中,表示了些标准限定词。
表 9-2 匈牙利约定中的标准限定词
限定词 含义
Min 数组或其它表中绝对的第一个元素
First 数组中需要进行处理的第一个元素。First 含义与 Min 相近,但 First 是相 对操作的第一个,而 Min 则是指数组本身的第一个元素
Last 在一个数组中需要最后进行处理的元素。Last 是 First 的反义词
Lim 在一个数组中需要处理的元素上界。与 Last 一样,Lim 也是 First 的反义 词,但与 Last 不同的是,Lim 代表的是数组的不完全上界;而 Last 代表
的则是最后一个元素。通常,Lim 等于 Last 加 1 Max Max 指的是数组或表列中的绝对最后一个元素而不是相对操作的最后一
个元素
限定词能够而且应该与基本类型和前缀联合使用。例如,paReformat 指的是要重新格式化 的段落;apaReformat 指的是要重新格式化的段落数组。而 ipaReformat 则指的是需要重新格式 化的段落的数量。一个 for 循环来重新格式化段落的 C 程序如下:
for (
ipaReformat = ipaFirstReformat;
ipaReformat <= ipaLastReformat;
ipaReformat++;
)…
可以用 PaLimReformat 来代替上例中的变量名 IpaLastReformat 重写相同的循环,这时,由 于 Lim 和 Last 的区别,在确定循环是否结束的检查中,将用“<”来代替“<=”。即用:
ipaReformat < ipaLastReformat 来代替
ipaReformat <= ipaLastReformat
9.5.4 匈牙利名称举例
以下是利用匈牙利约定产生的变量名。其中变量名的基本类型部分采用的是前面文字处理 程序示例中的基本类型。
变量名 意义
ch 字符变量(并不是 C 语言意义上字符,而是指文字处理程序中用来 在文件中代替字符的数据结构)
achDelete 要删去的一个字符数组 ich 字符数组的下标
ichMin 字符数组中绝对第一个元素的下标
ichFirst 字符数组中第一个需要进行某种操作的元素的下标 echDelete 字符数组中产生的某一元素,如 ecbDelete = acbDelete
[icbFirst]的结果
pachInsert 要插入字符数组中的指针 ppach 指向某一字符数组指针的指针 cchInser 要插入字符的数量
cscrMenu 用作菜单屏幕区的数量 hscrMenu 对用作菜单屏幕区的操作
mhserUserInput 用户输入屏幕区的模块层次上的操作(所有在这一模块中的子程序 都可对这一变量进行存取操作)
ghscrMessages 为获得信息而对屏幕区进行的全局操作
注:上表中某些变量名不含限定词。虽然省略限定词是很常见的,但我们并不提倡这样做,
应尽可能使用限定同。
9.5.5 匈牙利约定优点
匈牙利约定与其它命名约定一样,拥有由命名约定所带来的一切共同优点。由于有这样多 的标准名称,因此在任何一个单个子程序或程序中要特殊记忆的名字是非常少的。匈牙利约定 完全可以在不同项目中采用。
匈牙利约定可以使得在命名中容易产生定义的区域变得准确清楚。特别是约定中对 First,
Min,Last,Max 和 Lim 的准确区分在实际中是尤其有帮助的。匈牙利约定可以使人对编译程序 无法检查的抽象数据类型进行检查:cpaReformat[i]很可能是错误的,因为 cpaReformat 不是数 组,而 apaReformat[i]则可能是正确的,因为 apaReformat[i]是数组。
匈牙利约定可以在类型不严格的语言或环境中对类型进行说明。例如,在 Windows 环境下 编程时,需要你放弃许多类型,这极大地限制了编译程序进行严格类型检查的能力。而建立约 定则可以对环境的这一弱点作出补偿,匈牙利约定还可以使名称更简洁,可以用 CMedals 而不 用 TotalMedals 来代表奖牌的数量,使用 pNewScore,而不是用 NewScorePtr 命名一个新分数指 针。
9.5.6 匈牙利约定缺点
一些版本的匈牙利约定事实上忽视了用抽象数据类型作为基本类型。它们以程序语言中整 型、长整型、浮点数和字符串为基础来建立基本类型。匈牙利约定基本类型事实上是没有什么 价值的,因为它使得程序员陷入对类型进行人工检查的困扰之中,而不是让编译程序对类型进 行更加快速而又准确的检查。
这种形式匈牙利约定的另一个问题是它把数据的意义与其表现联系在一起。比如,说明某 一变量是整型的,把它改为长整型的时,不得不改动这一变量的名称。
匈牙利约定的最后一个问题是它鼓励了懒惰、不含什么信息的变量名的出现。当程序员用 hwnd 来命名对窗口的操作时,往往忽视了他所指的到底是哪种窗口、对话框、菜单还是帮助区 的屏幕?显然用 hwndmenu 要比 hwnd 清楚得多。以变量的意义为代价来获得对其类型的精确 描述显然是愚蠢的。不过好在可以用加限定词的办法来同时获得完整的意义和精确的类型。