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

1.4.6 正确书写注释

虽然在编译时注释会被编译器忽略,但注释对代码的可读性具有极其重要的作用。代码如果没有注释或者注释很少,那么不仅其他人不容易看懂,即使是代码的作者,一段时间之后再次接触也会一头雾水。但代码中的注释要恰到好处,不宜过多或者画蛇添足。毕竟,如果一段代码的功能是清晰的,变量的命名符合习惯,则代码本身就可以说明其运行逻辑,而不必进行过多的注释。因此,我们更多看到的注释,通常存在于针对接口的说明中,比如函数的功能描述、各个参数的含义、有关返回值的说明、结构体中每个成员的含义等。

关于C代码中注释的书写,建议如下。

(1)为对外的接口提供详细的注释,并采用Doxygen(或其他文档生成工具,如GtkDoc)允许的格式来撰写注释。对于函数,应就其功能、参数以及返回值做详细说明;对于结构体,应就其公开的成员做详细说明。现在,越来越多的开源项目采用Doxygen允许的格式,以随同代码共存的注释形式来编写和维护接口的说明文档。这既方便开发者阅读,又便于维护,尤其在接口发生变化时,开发者可以在修改代码的同时完成对文档的修改。在本章的后面,读者可以看到采用Doxygen允许的格式撰写的接口注释。

(2)在不对外的内部模块中,应就文件的功能、内部函数的用途等做简要的注释。除非代码涉及复杂或重要的算法,否则不必过多地撰写注释。这是因为,当我们使用了合乎习惯的命名方法,并掌握了常见的接口设计模式之后,看接口及其实现就能知悉代码逻辑;此种情况下,额外地撰写注释就是画蛇添足。

(3)避免使用C++的注释形式。C++的注释形式(即“//”形式)输入方便,具有一些优点。但是如前所述,代码最重要的特质就是风格统一,因此在C代码中还是应该统一采用传统的注释风格。在Linux内核以及大多数重要的C语言程序中,我们很少看到C++风格的注释。一个好的习惯是仅在行尾的简短注释中使用C++风格的注释。

(4)巧用XXX、FIXME、TODO等短语。XXX具有告诫意味,表示这段代码非常重要,必须认真阅读。FIXME一般表示这段代码不够完善,存在提高空间。TODO一般表示这段代码的功能还不完整,有待未来完成。有些智能的代码编辑器会将注释中的这些特殊短语用特殊的颜色加以显示,以提醒代码的阅读者。

(5)学习Linux内核编码风格提倡的注释编写风格(见本章前面的内容),而不要添加额外的装饰用字符。

下面的代码片段定义的枚举类型用于区别不同的变体类型,其中两次使用了XXX标记,用于特别提醒开发者。在现代编辑器中查看这段代码,XXX会显示为醒目的红色。

typedef enum purc_variant_type {
    PURC_VARIANT_TYPE_FIRST = 0,
 
    /* XXX: keep consistency with type names */
#define PURC_VARIANT_TYPE_NAME_UNDEFINED    "undefined"
    PURC_VARIANT_TYPE_UNDEFINED = PURC_VARIANT_TYPE_FIRST,
#define PURC_VARIANT_TYPE_NAME_NULL         "null"
    PURC_VARIANT_TYPE_NULL,
#define PURC_VARIANT_TYPE_NAME_BOOLEAN      "boolean"
    PURC_VARIANT_TYPE_BOOLEAN,
#define PURC_VARIANT_TYPE_NAME_NUMBER       "number"
    PURC_VARIANT_TYPE_NUMBER,
#define PURC_VARIANT_TYPE_NAME_STRING       "string"
    PURC_VARIANT_TYPE_STRING,
#define PURC_VARIANT_TYPE_NAME_OBJECT       "object"
    PURC_VARIANT_TYPE_OBJECT,
#define PURC_VARIANT_TYPE_NAME_ARRAY        "array"
    PURC_VARIANT_TYPE_ARRAY,
#define PURC_VARIANT_TYPE_NAME_SET          "set"
    PURC_VARIANT_TYPE_SET,
 
    /* XXX: change this if you append a new type. */
    PURC_VARIANT_TYPE_LAST = PURC_VARIANT_TYPE_SET,
} purc_variant_type;
 
#define PURC_VARIANT_TYPE_NR \
    (PURC_VARIANT_TYPE_LAST - PURC_VARIANT_TYPE_FIRST + 1)

注意,在上述枚举量的定义中,还使用了将字符串常量和枚举量置于上下两行进行定义的技巧。这一技巧既方便了代码的维护,也能帮助我们在改变一个类型或新增一个类型时,确保对枚举量和对应的字符串常量做同步处理。