第九章 数据名称
9.4 非正式命名约定
绝大多数项目都采用如下所述的非正式命名约定。
9.4.1 与语言无关的约定准则
以下是一些与语言无关的约定准则:
标识全局变量。常见的编程问题之一是误用全局变量。可以在所有的全局变量前面都加 上 g_作为前缀来解决。比如看到 g_Running Total 时,程序员就会知道这是一个全局变量,从而
把它作为全局变量对待。
标识模块变量。模块变量是在模块内部供几个子程序使用的变量。要能清楚地表明它既不 是全局变量也不是局部变量。这可以用在变量前加 m_作为前缀来解决。在 C 中,你可以通过在 任何子程序外说明 Static 变量来建立模块层次的数据。这样的变量对文件中子程序来说都是可 用的,但文件外的子程序则无法使用。
标识类型定义。类型的命名约定需要有两个功能:它们要明确地指出某一名称是类型名称,
同时要可以避免类型名称与变量名称相冲突。为了达到这两个要求,使用前缀或后缀不失为一 个好办法。在 Pascal 中,可以使用小写的_t 来表示类型名称,例如 Color_t 或 Menu_t。在 C 中用这种办法稍有些困难,常见的办法是用大写字母组合如 COLOR 或 MENU 来表示类型名,但这 可能与命名预处理程序常量相混淆。而“_t”这一约定已经被标准类型 size_t 所采用了,因此可 以用“_T"表示类型名称,如 COLOR_T 和 MENU_T。
标识命名常量。需要对命名常量加以标识,以便可以使你知道是在用一个变量(其值可能 变动)还是在用一个命名常量给某个变量赋值。在 Pascal 或 C 中,你还可能是在用函数给某一 变量赋值。这些语言,并不要求函数使用括号。而在 C 中,即使是不带参数的函数也必须使用 括号。
给命名常量命名的一种办法是“_C”作为其名称的后缀。在 Pascal 中,用这种方法可以产 生出像 MaxRecs_C 或 MaxlinesPerPage_ C 之类的名字。在 C 中,你可以用“_C”作为其后缀。
标识枚举类型。与命名常量同样的原因,枚举类型也需要被标识出来。即将其与变量、命 名常量和函数加以区别。常用的方式是用“_e”或“_E”作为后缀。
标识输入参数。有时输入参数会被错误改动。在像 C 或 Pascal 这样的语言中,当一个被改 变过的值返回调用子程序时,必须予以明确地说明。在 C 中,这是用“*”说明的,在 Pascal 中用的是 VAR,Ada 语言中使用的是 out 限定词。在其它语言如 Fortran 中,如果你改变了一个 输入值,那么不管你是否愿意,它都将被返回,但假如你建立了命名约定,在约定中规定只用 于输入的参数前面要采用 IP 作为前缀,那么当发现在等号左边出现了带有 IP 前缀的变量时,
你就可以知道发生了错误。比如在程序中看到 IPMAX = IPMAX+l 语句,就可以立刻认定它是 错误的,因为前缀 IP 表明 IPMAX 的值是不允许变动的。
对名字作格式化以增强可读性。增强可读性常见的两项技术是用分隔字符或大写字母将单 词分隔开来。例如,GymnasticsPointTotal 或 Gymnastic_Point_Total 的可读性显然是要强于 GYMNASTICSPOINTTOTAL。C、PASCAL、Ada 和其它语言都允许大小写混用的方式。C、
Pascal 和其它语言都允许使用的下划线“_”作为分隔符。
尽量不要混合使用这两项技术,那样会降低可读性。如果坚持采用其中任何一种,那么你的 代码的可读性将大为改观,关于变量名第一个字母是否应该大写的问题,激烈的争论已经持续 了很长时间(是 TotalPoints 好还是 totalPoints 好?)。但是只要保持一致性,我认为二者区 别实际上并不大。
9.4.2 与语言有关的命名约定
应当遵守所使用语言的标准命名约定。
你可以发现许多书中都讲述了语言的形式准则。关于 C、Pascal 和 Fortran 的准则将在下 面予以论述。
C 约定
有些命名的约定是只适用于 C 的,可以在 C 中使用这些约定,也可以改变它以使其适应其 它语言。
・ c 和 ch 是字符变量
・ i 和 j 整型下标
・ n 是数量
・ p 是指针
・ s 是字符串
・ 预处理程序宏指令是以全部大写来表示的,这通常扩展到包含 typedef
・ 变量和子程序名称都是小写的
・ 下划线“_”用做分隔符
这些是在 UNIX 操作系统下用 C 语言编程的一些通用约定。在不同的环境下,这些约定是 有区别的。在 Microsoft Windows 环境下,C 程序员们往往愿意使用匈牙利命名约定,并且对变 量名称是大小写混用的。在 Macintosh 环境下,C 程序员们往往乐于使用类 Pascal 的命名约定 给子程序命名。因为 Macintosh 工具箱和操作系统子程序都是为 Pascal 接口设计的。
Pascal 约定
Pascal 中只有几条特殊的约定,你可以在 Pascal 中使用它们,也可以改进它们以适应其它 语言需要。
・ i、j 和 k 是整型下标
・ 变量和子程序名称是以大小写混用的形式出现的 Fortran 约定
Fortran 有一些语言本身固有的命名约定,在 Fortran 中可以使用它们。但我想如果不把它们 扩展到其它语言的话,全世界都会因此而感激你的。
・ 以字母 I 到 N 开头的变量名是整型的
・ I、J 和 K 只能作为循环控制变量
・ X、Y 和 Z 是浮点数 9.4.3 命名约定举例
当命名约定准则长达几页时,它们看起来是非常复杂的。事实上,命名约定是完全不必要 复杂到可怕程度的,你可以改进它们以适应你的需要。变量名应包括三个方面的信息:
・ 变量内容(它代表的是什么)
・ 变量数据类型(整型、浮点等)
・ 变量在程序结构中的位置——例如,定义变量的模块名称或者一个表示变量是全局的 前缀。
以下是 C 和 Pascal 中采用前面讲过的命名原则进行命名的一些例子。我并不是想把这些约 定推荐给你,而是想给你一些变量名应包括哪些信息的想法。
Pascal 命名约定示例
约定类别 约定内容
LocalVariable 局部变量名是大小写混用的。这个名称应与潜在的数据类型无关,且应 指出这个变量代表的到底是什么
RoutineName() 子程序也是大小混用的(具体讨论见 5.2 节)
m_ModuleVariable 仅供某一模块子程序使用的变量以 m_作为前缀 g_GlobalVariable 全局变是用 g_为前缀 Constant_C 命名常量以_C 作为后缀
Type_t 类型以_t 作为后缀
Base_EnumeratedType 枚 举 类 型 是 以 其 基 本 类 型 的 助 记 符 作 为 前 缀 的 , 如 Color_Red, Color_Blue
C 命名约定示例
约定类别 约定内容
GlobalRoutineName() 公用程序名称是大小写混合使用的
_FileRoutineName() 供某一个模块专用的子程序以下划线作为前缀
LocalVariable 局部变量名是大小写混用的。其名称应与数据类型无关且应指明变 量代表的究竟是什么
_FileStaticVariable 模块(文件)变量以一个下划线作前缀
GLOBAL_GlobalVariable 全局变量是以定义它的模块(文件)名称的全大写形式助记符作为 前缀的,如 SCR_Dimension
LOCAL_CONSTANT 仅供某一子程序或模块 (文件) 专用的命名常量是全大写的
GLOBAL_CONSTATNT 全 局 命 名 常 量 名 字 是 全 大 写 的 , 且 以 它 的 模 块 ( 文 件 ) 名 称 助记符的大写形式来作前缀的,如 SCR_MAXROWS
TYPE 类型定义是全大写的
LOCAL_MACRO() 仅供某一子程序或模块(文件)专用的宏定义是大写的
GLOBAL_MACRO() 全局宏定义是大写的且以它的模块(文件)名称助记符大写形式为 前缀