“filesystem.h”,则定义如下:“#ifndef _FILE_SYSTEM_H_”。 原则2.2.2 用 #include
原则2.2.3 用 #include “filename.h” 格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。
原则2.2.4 头文件中只存放“声明”而不存放“定义”。
原则2.2.5 头文件中应包含所有定义文件所定义的函数声明,如果一个头文件对应多个定义文件,则不同定义文件内实现的函数要分开声明,并作注释以解释所声明的函数从属于那一个定义文件。
原则2.2.6 .c/.h文件禁止包含用不到的头文件。很多系统中头文件包含关系复杂,开发人员为了省事起见,可能不会去一一钻研,直接包含一切想到的头文件,甚至有些产品干脆发布了一个god.h,其中包含了所有头文件,然后发布给各个项目组使用,这种只图一时省事的做法,导致整个系统的编译时间进一步恶化,并对后来人的维护造成了巨大的麻烦。
2.3 函数编写规则
函数设计的精髓:编写整洁函数,同时把代码有效组织起来。
整洁函数要求:代码简单直接、不隐藏设计者的意图、用干净利落的抽象和直截了当的控制语句将函数有机组织起来。 原则2.3.1 一个函数仅完成一件功能。
说明:一个函数实现多个功能给开发、使用、维护都带来很大的困难。将没有关联或者关联很弱的语句放到同一函数中,会导致函数职责不明确,代码混乱,难以理解,难以测试和改动。 延伸阅读材料:《敏捷软件开发:原则、模式与实践》 第八章,单一职责原则(SRP)。
原则2.3.2 重复代码应该尽可能提炼成函数。
6 / 19
说明:重复代码提炼成函数可以带来维护成本的降低。
项目组应当使用代码重复度检查工具,在持续集成环境中持续检查代码重复度指标变化趋势,并对新增重复代码及时重构。当一段代码重复两次时,即应考虑消除重复,当代码重复超过三次时,应当立刻着手消除重复。 原则2.3.3 避免函数过长,新增函数不超过50行(非空非注释行)。 说明:本规则仅对新增函数做要求,对已有函数修改时,建议不增加代码行。 过长的函数往往意味着函数功能不单一,过于复杂 函数的有效代码行数,即非空非注释行应当在[1,50]区间。 原则2.3.4 避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层。
说明:本规则仅对新增函数做要求,对已有的代码建议不增加嵌套层次。函数的代码块嵌套深度指的是函数中的代码控制块(例如:if、for、while、switch等)之间互相包含的深度。每级嵌套都会增加阅读代码时的脑力消耗,因为需要在脑子里维护一个“栈”(比如,进入条件语句、进入循环??)。应该做进一步的功能分解,从而避免使代码的阅读者一次记住太多的上下文。
原则2.3.5 废弃代码(没有被调用的函数和变量)要及时清除。 说明:程序中的废弃代码不仅占用额外的空间,而且还常常影响程序的功能与性能,很可能给程序的测试、维护等造成不必要的麻烦。
原则2.3.6 函数不变参数使用const。
说明:不变的值更易于理解/跟踪和分析,把const作为默认选项,在编译时会对其进行检查,使代码更牢固/更安全。 原则2.3.7 函数的参数个数不超过5个。
说明:函数的参数过多,会使得该函数易于受外部(其他部分的代码)变化的影响,从而影响维护工作。函数的参数过多同时也会增大测试的工作量。 函数的参数个数不要超过5个,如果超过了建议拆分为不同函数。
原则2.3.8 在源文件范围内声明和定义的所有函数,除非外部可见,否则应该增加static关键字。
说明:如果一个函数只是在同一文件中的其他地方调用,那么就用static声明。使用static确保只是在声明它的文件中是可见的,并且避免了和其他文件或库中的相同标识符发生混淆的可能性。
7 / 19
3 标示符的命名规则
目前比较使用的如下几种命名风格: unix like风格:单词用小写字母,每个单词直接用下划线?_?分割,例如text_mutex,kernel_text_address。
Windows风格:大小写字母混用,单词连在一起,每个单词首字母大写。不过Windows风格如果遇到大写专有用语时会有些别扭,例如命名一个读取RFC文本的函数,命令为ReadRFCText,看起来就没有unix like的read_rfc_text清晰了。
匈牙利命名法:是计算机程序设计中的一种命名规则,用这种方法命名的变量显示了其数据类型。匈牙利命名主要包括三个部分:基本类型、一个或更多的前缀、一个限定词。实际上,各种风格都有其优势也有其劣势,而且往往和个人的审美观有关。我们对标识符定义主要是为了让团队的代码看起来尽可能统一,有利于代码的后续阅读和修改。
原则3.1 标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。
说明:尽可能给出描述性名称,不要节约空间,让别人很快理解你的代码更重要。
示例:好的命名:即使不注释也能理解。
不好的命名:使用模糊的缩写或随意的字符。
原则3.2 除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音。
说明:较短的单词可通过去掉“元音”形成缩写,较长的单词可取单词的头几个字母形成缩写,一些单词有大家公认的缩写,常用单词的缩写必须统一。协议中的单词的缩写与协议保持一致。对于某个系统使用的专用缩写应该在注视或者某处做统一说明。 示例:一些常见可以缩写的例子: argument 可缩写为 arg buffer 可缩写为 buff clock 可缩写为 clk
command 可缩写为 cmd
8 / 19
compare 可缩写为 cmp configuration 可缩写为 cfg device 可缩写为 dev error 可缩写为 err
hexadecimal 可缩写为 hex increment 可缩写为 inc、 initialize 可缩写为 init maximum 可缩写为 max message 可缩写为 msg minimum 可缩写为 min parameter 可缩写为 para previous 可缩写为 prev register 可缩写为 reg semaphore 可缩写为 sem statistic 可缩写为 stat
synchronize 可缩写为 sync temp 可缩写为 tmp
原则3.3 产品/项目组内部应保持统一的命名风格。
说明:Unix like和windows like风格均有其拥趸,产品应根据自己的部署平台,选择其中一种,并在产品内部保持一致。 原则3.4 尽量避免名字中出现数字编号,除非逻辑上的确需要编号。 示例:如下命名,使人产生疑惑。
应改为有意义的单词命名
原则3.5 重构/修改部分代码时,应保持和原有代码的命名风格一致。 说明:根据源代码现有的风格继续编写代码,有利于保持总体一致。
4 文件命名规则
建议3.6 文件命名统一采用小写字符。
说明:因为不同系统对文件名大小写处理会不同(如MS的DOS、Windows系统不区分大小写,但是Linux系统则区分),所以代码文件命名建议统一采用全小写字母命名。
9 / 19
5 变量命名规则
规则5.1 全局变量应增加“g_”前缀。 规则5.2 静态变量应增加“s_”前缀。
说明:增加g_前缀或者s_前缀,原因如下:
首先,全局变量十分危险,通过前缀使得全局变量更加醒目,促使开发人员对这些变量的使用更加小心。
其次,从根本上说,应当尽量不使用全局变量,增加g_和s_前缀,会使得全局变量的名字显得很丑陋,从而促使开发人员尽量少使用全局变量。
规则5.3 禁止使用单字节命名变量,但允许定义i、j、k作为局部循环变量。
6 函数命名规则
规则6.1 函数命名应以函数要执行的动作命名,一般采用动词或者动词+名词的结构。
示例:找到当前进程的当前目录
7 宏命名规则
规则7.1 对于数值或者字符串等等常量的定义,建议采用全大写字母,单词之间加下划线?_?的方式命名(枚举同样建议使用此方式定义)。 示例:
规则7.2 除了头文件或编译开关等特殊标识定义,宏定义不能使用下划线?_?开头和结尾。 说明:一般来说,“_”开头、结尾的宏都是一些内部的定义,
8 变量
原则8.1 一个变量只有一个功能,不能把一个变量用作多种用途。 说明:一个变量只用来表示一个特定功能,不能把一个变量作多种用途,即同一变量取值不同时,其代表的意义也不同。
10 / 19