C语言最佳实践
上QQ阅读APP看书,第一时间看更新

1.6 命名的艺术

在给代码中的变量和函数取名时,要尽量使用正确的英文术语及其简写。

但需要注意的是,不同的领域有不同的术语使用习惯。比如,当我们的代码涉及树形数据结构时,就会经常使用如下英文术语。

node:表示树形数据结构中的一个节点;不要用itemelement表示节点,这两个词的准确含义为条目元素

child:表示子节点。

sibling:表示兄弟节点,不要用brother表示兄弟节点。

parentroot:分别表示父节点和根节点,不要使用father或者mother等表示上一级节点。

firstlast:分别表示头节点和尾节点。

nextprevious(或prev):分别表示下一节点和前一节点。

ascendantdescendants:分别表示祖先节点或子孙节点。

再比如,当我们的代码涉及链表(linked list)这种数据结构时,则会经常使用如下英文术语。

node:表示链表中的一个节点。

headtail:分别表示链表的头节点和尾节点。

nextprevious(或prev):分别表示下一节点和前一节点。

针对相应的领域使用正确的英文术语并基于这些英文术语来命名,可以避免很多误解,这是提升代码可读性的一种重要手段。需要特别提醒的是,在有合适英文术语的情形下,要避免使用一些“万金油”名称,如itemdata等含义广泛的名称。

为变量和函数取名时,还要考虑正确的时态和单复数形式。如前所述,表示链表的变量应该取名为linked_list而不是link_list。又如,双链表可以用dbl_linked_list表示。表示单个元素的变量用单数形式,如node表示一个节点、child表示一个子节点。表示多个元素的变量则用复数形式,如nodes表示节点数组、children表示子节点数组等。

在代码中,缩写是十分常见的。采用约定俗成的缩写不仅可以提高代码的输入效率、节省版面空间,而且完全不会影响代码的可读性。但是,要尽量采用约定俗成的缩写,不要自创,更不要使用汉字拼音首字母缩写的名称。C代码中经常使用的一些缩写如表1.1所示。

表1.1 C代码中经常使用的一些缩写

图片表格

为局部变量命名时,应该尽量采用简洁的名称。例如,ijk一般并不推荐作为变量的名称,但在forwhile循环中,将这3个字母作为变量的名称非常方便,不会有任何歧义;而且循环变量一般仅限于这3个字母,如果一个循环中还需要更多的循环变量,则说明程序的结构存在问题,需要进行重构。

在局部代码块中,还可以用n表示数量,用len表示长度,用sz表示大小或尺寸,用p表示指针,用tmp表示临时变量,用buf表示临时缓冲区。这些都是约定俗成的简洁名称,不会影响代码的可读性。

对于函数或全局变量的命名,应采用下面的约定。

(1)函数库接口:<type> <lib prefix>_<short phrase>(...)。例如:

void mylib_init_linked_list(struct linked_list *p);

(2)文件内:static <type><short phrase>(...)。例如:

static void init_liked_list(struct linked_list *p);

(3)模块间:<type>_<module_prefix>_<short phrase>(...)。例如:

void _mymodule_init_liked_list(struct linked_list *p);

此外,如果使用的是GCC这样的编译器,那么可以在声明模块间接口时添加属性,例如:

void _mymodule_init_liked_list(struct linked_list *p)
    __attribute__((visibility("hidden")));

这里的visibility(可见性)属性取值为hidden,表示这个符号(即函数名)在形成函数库后对外不可见,从而可以有效地防止命名污染。