• 编程(代码、软件)规范(适用嵌入式、单片机、上位机等)


    目录

    前言

    第1章 文件

    1.1 头文件

    1.2 定义文件

    第2章 注释规范

    2.1 共性注释规范

    2.2 文档注释规范

    2.3 C语言风格注释规范

    第3章 排版规范

    3.1 缩进与对齐 风格

    3.2 空行

    3.3 代码行

    3.4 代码行内的空格

    3.5 长行拆分

    第4章 标识符命名规范

    4.1 共性命名规则

    4.2 文件命名规则

    4.3 变量命名规则

    4.4 函数命名规则

    4.5 宏的命名规则

    第5章 变量

    第6章 常量、宏

    第7章 数据类型

    附件1 常用单词缩写(英文)(元音:aeiou)

    附件2 常用反义词组(英文)

    附件3 Doxygen格式常用关键字表

    附件4 标识符命名个人风格

    附件5 常见标识符命名风格种类


    前言

            本编程规范是个人工作十几年来,近些年形成较为稳定的版本,已被工作的公司采纳为公司编程规范!本规范主要借鉴了一些大公司(华为,百度,腾讯,阿里巴巴,谷歌,苹果,微软,ARM,ST.....)的编程规范和风格,吸收它们的共性和个别优秀的地方。在一些细节方面请教了一些几十年的老工程师和一些华为等大公司软件工程师!

           本人曾创造过自己的编程风格,也曾想创造出世界上最完美的编程规范和风格,在当时的技术水平和行业局限下,自我感觉还是挺好的!随着经验的丰富,接触的技术越来越多,发现当初的一些规则和适用的环境已不再适用,甚至有些鸡肋,还增加了负担!在这方面也耗费很多没有价值的时间!后来痛定思痛改变编程规范和风格。不再原创,要与世界接轨,用符合当下所处大行业较为流行的,大公司通用的、大公司个别优秀的风格规范作为自己的编程规范和风格,简单说就是吸收大家之长处和共性,这样换了工作也能适用,新人进入也能快速适应,因为这些大多数人的规范和风格,少数服从多数。

            不要试图去创造最完美的编程规范和风格,每种风格都有长处和短处,这些不是我们的工作重心!编程规范和风格是为了给人看的,方便人们交流和阅读,每个人的喜欢都不同,很难满足和统一,如同世界很难统一一样。做到求同存异,兼容并包就可以了!编程规范和风格好与坏对芯片来说都一样,最终都要被翻译成机器码的!

    第1章 文件

            每个 C++/C 程序通常分为两个文件。一个文件用于保存程序的声明(declaration),称为头文件。另一个文件用于保存程序的实现(implementation),称为定义(definition)文件。

            C++/C 程序的头文件以“.h”为后缀,C 程序的定义文件以“.c”为后缀,C++程序的定义文件通常以“.cpp”为后缀(也有一些系统以“.cc”或“.cxx”为后缀)。

    1.1 头文件

            对于C语言来说,头文件的设计体现了大部分的系统设计。不合理的头文件布局是编译时间过长的根因。头文件主要由三部分内容组成:头文件注释;预处理块;函数声明等。

            通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。

            某产品曾经做过一个实验,把所有函数的实现通过工具注释掉,其编译时间只减少了不到10%,究其原因,在于A包含B,B包含C,C包含D,最终几乎每一个源文件都包含了项目组所有的头文件,从而导致绝大部分编译时间都花在解析头文件上。

            某产品更有一个“优秀实践”,用于将.c文件通过工具合并成一个比较大的.c文件,从而大幅度提高编译效率。其根本原因还是在于通过合并.c文件减少了头文件解析次数。但是,这样的“优秀实践”是对合理划分.c文件的一种破坏。

            大部分产品修改一处代码,都得需要编译整个工程,对于TDD之类的实践,要求对于模块级别的编译时间控制在秒级,即使使用分布式编译也难以实现,最终仍然需要合理的划分头文件、以及头文件之间的包含关系,从根本上降低编译时间。

        《google C++ Style Guide》1.2 头文件依赖 章节也给出了类似的阐述:若包含了头文件aa.h,则就引入了新的依赖:一旦aa.h被修改,任何直接和间接包含aa.h代码都会被重新编译。如果aa.h又包含了其他头文件如bb.h,那么bb.h的任何改变都将导致所有包含了aa.h的代码被重新编译,在敏捷开发方式下,代码会被频繁构建,漫长的编译时间将极大的阻碍频繁构建。因此,我们倾向于减少包含头文件,尤其是在头文件中包含头文件,以控制改动代码后的编译时间。

    合理的头文件划分体现了系统设计的思想,但是从编程规范的角度看,仍然有一些通用的方法,用来合理规划头文件。本章节介绍的一些方法,对于合理规划头文件会有一定的帮助。

    原则1.1.1  头文件适合放置对外接口的声明,不适合放置实现,实现应放在定义文件中。

    说明:头文件是模块(Module)或单元(Unit)的对外接口。变量定义应在.c中定义,在.h中仅声明,尽量不要使用全局变量作为接口,变量是程序内部实现细节,应通过函数接口的方式对外暴露。

    个人理解如下:

    h文件:包含需用头文件、对外类型和枚举、对外宏(常量)定义、对外变量声明(尽量不用)、对外函数声明。

    c文件:包含同名头文件、内部类型和枚举、内部宏(常量)定义、内部变量定义、内部函数定义与实现。
    延伸阅读材料:《C语言接口与实现》(David R. Hanson 著 傅蓉 周鹏 张昆琪 权威 译 机械工业出版社 2004年1月)(英文版: "C Interfaces and Implementations")

    原则1.1.2  头文件应当职责单一

    说明:头文件过于复杂,依赖过于复杂是导致编译时间过长的主要原因。很多现有代码中头文件过大,职责过多,再加上循环依赖的问题,可能导致为了在.c中使用一个宏,而包含十几个头文件。

    例如: 如下是某平台定义WORD类型的头文件:

    1. #include <VXWORKS.H>
    2. #include <STDIO.H>
    3. #include <STDLIB.H>
    4. #include <SYSLIB.H>
    5. typedef unsigned short WORD;

            这个头文件不但定义了基本数据类型WORD,还包含了stdio.h syslib.h等等不常用的头文件。如果工程中有10000个源文件,而其中100个源文件使用了stdio.h的printf,由于上述头文件的职责过于庞大,而WORD又是每一个文件必须包含的,从而导致stdio.h/syslib.h等可能被不必要的展开了9900次,大大增加了工程的编译时间。

    规则1.1.1  每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口。

    规则1.1.2  禁止头文件循环依赖。

    说明:头文件循环依赖,是指a.h包含b.hb.h包含c.hc.h包含a.h之类。

    规则1.1.3  头文件应当自包含。

    说明:自包含是指任意一个头文件均可独立编译。如果a文件用到b文件内容,本应该a文件包含b.h头文件即可但要包含b.h头文件前还要先包含c.h头文件才能工作的话,增添不必要的负担。

    例如: a文件用到b文件内容

    1. #include "c.h" //要想用b文件,a文件必须先包含c.h文件,这种情况就不是自包含。
    2. #include "b.h" //a文件本应该包含b.h就可以。

    规则1.1.4  .c/.h文件禁止包含用不到的头文件。

    规则1.1.5  用#include <filename.h> 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。

    规则1.2.6  用#include“filename.h”格式来引用非标准库的头文件(编译器将从用户工作目录开始搜索)。

    规则1.1.7  为防止头文件被重复引用,应用ifndef/define/endif 结构产生预处理。命名格式:FILENAME_H_。

    说明:没有在宏最前面加上“_",是因为一般以"_"和”__"开头的标识符为系统保留或者标准库使用,在有些静态检查工具中,若全局可见的标识符以"_"开头会给出告警。后面加"_"是为了与程序用的宏定义区别。

    例如:

    1. #idndef LED_H_ //很明显这一部分也是为了防止重复引用
    2. #define LED_H_
    3. ……
    4. #endif /* LED_H_ */

    规则1.1.8  禁止在头文件中定义变量。

    说明:在头文件中定义变量,将会由于头文件被其他.c文件包含而导致变量重复定义。

    规则1.1.9   禁止在extern "C"中包含头文件。(来自华为编程规范)

    说明:在extern "C"中包含头文件,会导致extern "C"嵌套,Visual Studio对extern "C"嵌套层次有限制,嵌套层次太多会编译错误。在extern "C"中包含头文件,可能会导致被包含头文件的原有意图遭到破坏。

    错误示例:

    1. extern “C”
    2. {
    3. #include “xxx.h”
    4. ...
    5. }

    正确示例:

    1. #include “xxx.h”
    2. extern “C”
    3. {
    4. ...
    5. }

    建议1.1.1  C程序头文件中加extern "C"。

    说明:extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言(而不是C++)的方式进行编译。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。

    示例:  led头文件

    1. #ifndef LED_H_ //很明显这一部分也是为了防止重复引用
    2. #define LED_H_
    3. #include"xxxx.h"
    4. #ifdef __cplusplus //C++编译环境中(cpp文件定义了)定义了宏__cplusplus (plus plus就是"+ +"的意思)
    5. extern "C"{ // 声明括号内是C语言代码,告诉C++编译器用C语言进行编译,这样C++就可以调用C头文件了
    6. #endif
    7. … //其他代码
    8. #ifdef __cplusplus
    9. }
    10. #endif
    11. #endif  /* LED_H_ */

    建议1.2.2  头文件中只存放“声明”而不存放“定义”。

    建议1.2.3  不提倡使用全局变量,尽量不要在头文件中出现象 extern int value 这类声明。

    建议1.2.4  一个模块通常包含多个.c文件,建议放在同一个目录下,目录名即为模块名。为方便外部使用者,建议每一个模块提供一个.h,文件名为目录名。

    说明:需要注意的是,这个.h并不是简单的包含所有内部的.h,它是为了模块使用者的方便,对外整体提供的模块接口。

    建议1.2.5  如果一个模块包含多个子模块,则建议每一个子模块提供一个对外的.h,文件名为子模块名。

    说明:降低接口使用者的编写难度。

    建议1.2.6  同一产品统一包含头文件排列方式。

    说明:常见的包含头文件排列方式:功能块排序、文件名升序、稳定度排序。建议以稳定度排序。

    1. #include <C标准库头文件>
    2. #include <C++标准库头文件>
    3. #include "平台头文件" //MCU厂家、系统等头文件
    4. #include "第三方头文件" //公司或第三方提供的成熟头文件
    5. #include "自己写的基础全局头文件"
    6.           //base.h基础头文件,提供常用的数据类型、修饰符以及基础操作宏
    7.           //global.h包含了其他基础的应用的头文件,第一个文件包含在应用相关c文件中。
    8. #include "自己写的工具头文件"
    9. #include "本项目头文件"
    10. #include "本文头文件"

      

    1.2 定义文件

            定义文件主要由三部分内容:定义文件注释;头文件的引用;程序的实现体(包括数据和代码)。

            函数设计的精髓:编写整洁函数,同时把代码有效组织起来。代码要求简单直接、不隐藏设计者的意图、用干净利落的抽象和直截了当的控制语句将函数有机组织起来。

            代码的有效组织包括:逻辑层和物理层两个方面。逻辑层,主要是把不同功能的函数通过某种联系组织起来,主要关注模块间的接口,也就是模块的架构。物理层,无论使用什么样的目录或者名字空间等,需要把函数用一种标准的方法组织起来。例如:设计良好的目录结构、函数名字、文件组织等,这样可以方便查找。

    原则1.2.1  一个函数仅完成一件功能。

    说明:一个函数实现多个功能给开发、使用、维护都带来很大的困难。

    原则1.2.2  重复代码应该尽可能提炼成函数。

    说明:重复代码提炼成函数可以带来维护成本的降低。

    规则1.2.1  避免函数过长,新增函数不超过50行(非空非注释行)。

    说明:本规则仅对新增函数做要求,对已有函数修改时,建议不增加代码行。

    规则1.2.2  避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层。

    说明:本规则仅对新增函数做要求,对已有的代码建议不增加嵌套层次。

    规则1.2.3  设计高扇入,合理扇出(小于7)的函数。

    说明:扇出是指一个函数直接调用(控制)其它函数的数目,而扇入是指有多少上级函数调用它。扇出过大,表明函数过分复杂,需要控制和协调过多的下级函数;而扇出过小,例如:总是1,表明函数的调用层次可能过多,这样不利于程序阅读和函数结构的分析,并且程序运行时会对系统资源如堆栈空间等造成压力。通常函数比较合理的扇出(调度函数除外)通常是3~5。

    规则1.2.4  可重入函数应避免使用共享变量;若使用则应通过互斥手段(关中断、信号量)对其加以保护。

    说明:可重入函数是指可能被多个任务并发调用的函数。在多任务操作系统中,函数具有可重入性是多个任务可以共用此函数的必要条件。共享变量指的全局变量和static变量。

    规则1.2.5  废弃代码(没有被调用的函数和变量)要及时清除。

    建议1.2.1  函数不变参数使用const。

    说明:不变的值更易于理解/跟踪和分析,把const作为默认选项,在编译时会对其进行检查,使代码更牢固/更安全。

    建议1.2.2  函数应避免使用全局变量、静态局部变量和I/O操作,不可避免的地方应集中使用。

    建议1.2.3  检查函数所有非参数输入的有效性,如数据文件、公共变量等。

    说明:函数的输入主要有两种:一种是参数输入;另一种是全局变量、数据文件的输入,即非参数输入。函数在使用输入参数之前,应进行有效性检查。

    建议1.2.4  函数的参数个数不超过5个。

    说明:函数的参数过多,会使得该函数易于受外部(其他部分的代码)变化的影响,从而影响维护工作。函数的参数过多同时也会增大测试的工作量。如果超过了5个建议拆分为不同函数。

    建议1.2.5  除打印类函数外,不要使用可变长参函数。

    说明:可变长参函数的处理过程比较复杂容易引入错误,而且性能也比较低,使用过多的可变长参函数将导致函数的维护难度大大增加。

    建议1.2.6  在源文件范围内声明和定义的所有函数,除非外部可见,否则应该增加static关键字。

    说明:如果一个函数只是在同一文件中的其他地方调用,那么就用static声明。使用static确保只是在声明它的文件中是可见的,并且避免了和其他文件或库中的相同标识符发生混淆的可能性。

    第2章 注释规范

            良好的注释可以提高程序的可读性、易防错性、易维护性等。

    2.1 共性注释规范

    原则2.1.1  优秀的代码可以自我解释,不通过注释即可轻易读懂。

    说明:优秀的代码不写注释也可轻易读懂,注释无法把糟糕的代码变好,需要很多注释来解释的代码往往存在坏味道,需要重构。

    原则2.1.2  注释的内容要清楚、明了,含义准确,防止注释二义性。 

    说明:错误的注释不但无益反而有害。

    原则2.1.3  在代码的功能、意图层次上进行注释,提供有用、额外的信息。 

    说明:注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,防止没必要的重复注释信息。 

    示例:如下注释意义不大。 

    1. /* if receive_flag is TRUE */
    2. if (receive_flag)

    而如下的注释则给出了额外有用的信息。 

    1. /* if mtp receive a message from links */
    2. if (receive_flag)

    规则2.1.1  边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。

    规则2.1.2  避免在注释中使用缩写,除非是通用或标准的缩写。 

    说明:在使用缩写时或之前,应对缩写进行必要的说明。

    规则2.1.3  标识符命名中若使用特殊约定或缩写,则要有注释说明。

    规则2.1.4  同一产品或项目组 注释格式统一。

    规则2.1.5  注释应与其描述的代码相靠近。

    规则2.1.6  注释应放在其代码上方相邻位置或右方,不可放在下面。如放于上方则需与其上面的代码用空行隔开,且与下方代码缩进相同。如放于代码后面则与代码空一格。

    说明:可使程序排版整齐,并方便注释的阅读与理解。

    建议2.1.1  避免在一行代码或表达式的中间插入注释。 

    说明:除非必要,不应在代码或表达中间插入注释,否则容易使代码可理解性变差。

    建议2.1.2  注释应考虑程序易读及外观排版的因素,使用的语言若是中、英兼有的,建议多使用中文,除非能用非常流利准确的英文表达。 

    说明:注释语言不统一,影响程序易读性和外观排版,出于对维护人员的考虑,建议使用中文。

    2.2 文档注释规范

    规则2.2.1  对于要生成帮助文档的注释,采用工具可识别的注释格式。风格要统一。注释字符长度≤80。

    说明:采用工具可识别的注释格式,例如Doxygen格式,方便工具导出注释形成帮助文档。(常见工具:Doxygen,JavaDoc,……)

    示例:单行注释格式 1 采用风格:/** …… */  ///……  放在代码上行,表示注释下行代码

    单行注释格式 2 采用风格:/**< …… */ 或 ///<…… 放在代码后面表示注释前面代码

    多行块注释格式 采用风格:/**

    ……

    */

    规则2.2.2  项目、文件、函数、全局变量、全局常量、全局类型定义的注释格式采用工具可识别格式

    规则2.2.3  文件注释必须列出:版权说明、首页标签、工程名称、作者、工号、源码文档路径、项目详细描述、功能描述、用法描述、固件更新记录等。

    示例:以doxygen格式为例(Doxygen格式常用关键字表,见附件1),注释风格如下:

    1. /** @copyright Copyright(c)2014-2011 XXXX Co.,Ltd. All rights reserved.
    2.   ******************************************************************************
    3.   * @mainpage   无人机固件程序
    4.   * <table>
    5.   * <tr><th>Project  <td>A600
    6.   * <tr><th>Author   <td>缪某某(ID:123456)
    7.   * <tr><th>Source   <td>D:\workspace\demo_project\examples\A600\A600-doxygen
    8.   * </table>
    9.   * @section    项目描述
    10.   * 该无人机是主要应用于......
    11.   *
    12.   * @section    功能描述
    13.   * -# 定高悬停
    14.   * -# 路径规划飞行
    15.   *
    16.   * @section    用法描述
    17.   * -# 用遥控器
    18.   *
    19.   * @section    固件更新记录
    20.   * <table>
    21.   * <tr><th>Date        <th>H_Version   <th>S_Version       <th>Author  <th>Description  </tr>
    22.   * <tr><td>2018/08/17  <td>1.0         <td>S02010041808171 <td>lebo    <td>创建初始版本 </tr>
    23.   * <tr><td>2019/06/24  <td>1.1         <td>S02010041906241 <td>lebo    <td>
    24.   * -# 无
    25.   * </tr>
    26.   * </table>
    27.   ******************************************************************************
    28.   */

    规则2.2.4  文件注释必须列出:版权说明、作者、工号、版本号、生成日期、概要内容、注解说明功能、注意事项、修改日志等。

    示例:以doxygen格式为例,注释格式 风格如下:

    1. /** @copyright Copyright(c)2014-2011 XXXX Co.,Ltd. All rights reserved.
    2. ******************************************************************************
    3. * @mainpage FreeRTOS实验
    4. * <table>
    5. * <tr><th>Project <td>FreeRTOSDemo
    6. * <tr><th>Author <td>匠在江湖(ID:1234)
    7. * <tr><th>Source <td>F:\BaiduNetdiskWorkspace\Work\FreeRTOSDemo
    8. * </table>
    9. * @section 项目描述
    10.   * - 类别1
    11.   *     -# 情况1......
    12.   *     -# 情况2......
    13.   * - 类别2
    14.   *     -# 情况1......
    15.   *     -# 情况2......
    16. * @section 用法描述
    17. *
    18. * @section 固件更新记录
    19. * <table>
    20. * <tr><th>Date <th>H_Version <th>S_Version <th>Author(ID:xxxxxx) <th>Description </tr>
    21. * <tr><td>2018/08/17 <td>1.0 <td>S02010041808171 <td>匠在江湖(ID:1234) <td>创建初始版本 </tr>
    22. * </table>
    23. ******************************************************************************
    24. */

    规则2.2.5  函数注释必须列出:概要、参数、返回值等。根据实际情况增加相关项。

    示例1:以doxygen格式为例,注释格式 风格如下:

    1. /**
    2. ******************************************************************************
    3. * @brief 发送接收 模拟函数
    4. * @param None
    5. * @retval None
    6. * @note
    7. ******************************************************************************
    8. */

    示例2:

    1. /**
    2.   ******************************************************************************
    3.   * @brief  xxx 函数
    4.   * @param  None
    5.   * @return 函数执行结果
    6.   * - E_SUCCESS 成功
    7.   * - E_FAIL 失败
    8.   * @par 示例:
    9.   * @code
    10.   *    int ret = register_all(&data, len, RT_TYPE_T1)
    11.   * @endcode
    12.   * @see :: xx表  
    13.   ******************************************************************************
    14.   */

    示例3:

    1. /**
    2.   ******************************************************************************
    3.   * @brief  Register a User ADC Callback
    4.   *         To be used instead of the weak predefined callback
    5.   * @param  hadc Pointer to a ADC_HandleTypeDef structure that contains
    6.   *         the configuration information for the specified ADC.
    7.   * @param  CallbackID ID of the callback to be registered
    8.   *         This parameter can be one of the following values:
    9.   *          @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID      ADC conversion complete callback ID
    10.   *          @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID          ADC conversion complete callback ID
    11.   *          @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID    ADC analog watchdog 1 callback ID
    12.   *          @arg @ref HAL_ADC_ERROR_CB_ID                    ADC error callback ID
    13.   *          @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID  ADC group injected conversion complete callback ID
    14.   *          @arg @ref HAL_ADC_MSPINIT_CB_ID                  ADC Msp Init callback ID
    15.   *          @arg @ref HAL_ADC_MSPDEINIT_CB_ID                ADC Msp DeInit callback ID
    16.   *          @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID
    17.   *          @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit callback ID
    18.   * @param  pCallback pointer to the Callback function
    19.   * @retval HAL status
    20.   ******************************************************************************
    21.   */

    示例4:

    1. /**
    2.   ******************************************************************************
    3.   * @brief  Enables ADC, starts conversion of regular group and transfers result
    4.   *         through DMA.
    5.   *         Interruptions enabled in this function:
    6.   *          - DMA transfer complete
    7.   *          - DMA half transfer
    8.   *          - overrun (if available)
    9.   *         Each of these interruptions has its dedicated callback function.
    10.   * @note   Case of multimode enabled (for devices with several ADCs): This
    11.   *         function is for single-ADC mode only. For multimode, use the
    12.   *         dedicated MultimodeStart function.
    13.   * @param  hadc ADC handle
    14.   * @param  pData The destination Buffer address.
    15.   * @param  Length The length of data to be transferred from ADC peripheral to memory.
    16.   * @retval None
    17.   ******************************************************************************
    18.   */

    建议2.2.6  类型定义列出:类型名称、概要等。根据实际情况增加相关项。

    示例1:以doxygen格式为例,注释格式 风格如下:

    1. /** @enum BoolTypeE
    2.   * @brief 布尔类型(逻辑型变量的定义符)
    3.   */
    4. typedef enum
    5. {
    6.     E_FALSE = 0, //假(错误)
    7.     E_TRUE = !E_FALSE //真(正确)
    8. }BoolTypeE;

    示例2以doxygen格式为例,注释格式 风格如下:

    1. /** @struct info
    2.   * @brief 信息结构体 \n
    3.   * 定义存储的信息
    4.   */
    5. typedef struct 结构体名字
    6. {
    7.    成员1, ///< 简要说明文字, 如果不加< 则会认为是成员2的注释
    8.    成员2, ///< 简要说明文字
    9.    成员3, ///< 简要说明文字
    10. }结构体别名;

    建议2.2.7  模块定义:模块组号 + 模块组名等。根据实际情况增加相关项。

    示例1纯定义。模块组号 MCU_Driver, 模块名 MCU Driver

    1. /**
    2.   * @defgroup MCU_Driver MCU Driver
    3.   */
    4. /**  @defgroup MCU_Driver MCU Driver */

    示例2定义 + 概要描述

    1. /** @defgroup MCU_Driver MCU Driver
    2.   * @brief
    3.   */

    示例3定义 + 组范围

    1. /** @defgroup MCU_Driver MCU Driver
    2.   * @{
    3.   */
    4. ......
    5. /** @} end of MCU_Driver */

    示例3定义 + 组范围,加入到 MCU_Driver 模块组中,成为其子组

    1. /** @defgroup ADC_C_Includes ADC.C Includes
    2.   * @ingroup  MCU_Driver
    3.   * @{
    4.   */
    5. #include "base.h"
    6. #include "adc.h"
    7. /** @} end of ADC_C_Includes */

    2.3 C语言风格注释规范

    规则2.3.1  不用生成注释文档 的注释, 采用编程语言标准注释格式。风格要统一。注释字符长度≤80。

    示例:多行或单行注释格式 采用风格:/* …… */

    只可单行注释格式 采用风格://…… 

    建议2.3.1  包含头文件,类型定义,常量定义,宏定义,变量定义,函数定义与声明 要用注释划分模块,以便程序清晰易读

    建议2.3.2  定义文件中 包含头文件,类型定义,宏定义,变量定义,函数定义 注释风格。

    1. /** @copyright Copyright(c)2014-2011 XXXX Co.,Ltd. All rights reserved.
    2. ******************************************************************************
    3. * @file mcu.c
    4. * @brief
    5. * @details
    6. * @author 匠在江湖(ID:1234)
    7. * @version V1.0
    8. * @date 2014/05/08
    9. ******************************************************************************
    10. * @attention
    11. *
    12. * @par 修改日志:
    13. * <table>
    14. * <tr><th>Date <th>Version <th>Author(ID:xxxxxx) <th>Description</tr>
    15. * <tr><td>2014/05/08 <td>V1.0 <td>匠在江湖(ID:1234) <td>创建初始版本</tr>
    16. * </table>
    17. ******************************************************************************
    18. */
    19. /* Includes *******************************************************************/
    20. ……用户定义内容
    21. /* Private typedef ************************************************************/
    22. ……用户定义内容
    23. /* Private constants **********************************************************/
    24. ……用户定义内容
    25. /* Private macro **************************************************************/
    26. ……用户定义内容
    27. /* Private variables **********************************************************/
    28. ……用户定义内容
    29. /* Private function prototypes ************************************************/
    30. ……用户定义内容
    31. /**
    32. ******************************************************************************
    33. * @brief MCU 初始化 函数
    34. * @param None
    35. * @return None
    36. * @note
    37. ******************************************************************************
    38. */
    39. void MCU_Init(void)
    40. {
    41. }
    42. /********************************* END OF FILE ********************************/

    建议2.3.3  头文件中 包含头文件,类型定义,常量定义,宏定义,函数声明 注释风格。

    1. /** @copyright Copyright(c)2014-2011 XXXX Co.,Ltd. All rights reserved.
    2. ******************************************************************************
    3. * @file mcu.h
    4. * @brief 与硬件相关的寄存器定义,包含头文件等。为了适用平台的转换
    5. * @details
    6. * @author 匠在江湖(ID:1234)
    7. * @version V1.0
    8. * @date 2014/05/08
    9. ******************************************************************************
    10. * @attention
    11. *
    12. * @par 修改日志:
    13. * <table>
    14. * <tr><th>Date <th>Version <th>Author(ID:xxxxxx) <th>Description</tr>
    15. * <tr><td>2014/05/08 <td>V1.0 <td>匠在江湖(ID:1234) <td>创建初始版本</tr>
    16. * </table>
    17. ******************************************************************************
    18. */
    19. #ifndef MCU_H_
    20. #define MCU_H_
    21. /* Includes *******************************************************************/
    22. #include "stm32f1xx.h"
    23. #include "stm32f1xx_hal.h"
    24. #include "main.h"
    25. #include "usart.h"
    26. #include "base.h"
    27. #include "iwdg.h"
    28. #ifdef __cplusplus
    29. extern "C"{
    30. #endif
    31. /* Exported types *************************************************************/
    32. /* Exported constants *********************************************************/
    33. /* Exported macro *************************************************************/
    34. ///NOP()
    35. #define NOP() __NOP
    36. ///清看门狗
    37. #define CLR_WDG() HAL_IWDG_Refresh(&hiwdg) //清看门狗
    38. /* Exported functions *********************************************************/
    39. void MCU_Init(void);
    40. #ifdef __cplusplus
    41. }
    42. #endif
    43. #endif /* MCU_H_ */
    44. /********************************* END OF FILE ********************************/

    建议2.3.4  在程序块的结束行右方加注释标记,以表明某程序块的结束。 

    说明:当代码段较长,特别是多重嵌套时,这样做可以使代码更清晰,更便于阅读。 

    示例:参见如下例子。 

    1. if (...)
    2. {
    3. // program code
    4. while (index < MAX_INDEX)
    5. {
    6. // program code
    7. } /* end of while (index < MAX_INDEX) */ // 指明该条while语句结束
    8. // program code
    9. } /* end of if (...)*/ // 指明是哪条if语句结束 

    第3章 排版规范

            良好的排版可以提高程序的可读性、易防错性、易维护性等。

    3.1 缩进与对齐 风格

    规则3.1.1  程序块要采用缩进风格编写,缩进的空格数为4个。 不轻易使用TAB键。

    说明:编辑器可用TAB键代替空格时方可使用,否则程序会因缩进不同而变乱。

    规则3.1.2  程序块的分界符(如C/C++语言的大括号{})应各独占一行并且位于同一列,同时与引用它们的语句左对齐。{ }之内的代码块在‘{’右边数格处左对齐。

    说明:在函数体的开始、类的定义、结构的定义、枚举的定义以及iffordowhileswitchcase语句中的程序都要采用如上的缩进方式。 

    示例:

    1. ​​​​​​​如下例子不符合规范。 
    2. for (...) {
    3. ... // program code
    4. }
    5. 应如下书写。 
    6. for (...)
    7. {
    8. ... // program code
    9. }

    3.2 空行

    规则3.2.1  在每个类声明之后、每个函数定义结束之后都要加空行。

    规则3.2.2  在一个函数体内,逻揖上密切相关的语句之间不加空行,其它地方应

    加空行分隔。

    3.3 代码行

    规则3.3.1  不允许把多个短语句写在一行中,即一行只写一条语句。 

    示例:

    1. ​​​​​​​如下例子不符合规范。 
    2. rect.length = 0; rect.width = 0;
    3. 应如下书写 
    4. rect.length = 0;
    5. rect.width = 0;

    规则3.3.2  iffordowhilecaseswitchdefault等语句自占一行,且iffordowhile等语句的执行语句部分无论多少都要加括号{} 

    示例:

    1. ​​​​​​​如下例子不符合规范。 
    2. if (pUserCR == NULL) return;
    3. 应如下书写: 
    4. if (pUserCR == NULL)
    5. {
    6. return;
    7. }

    3.4 代码行内的空格

    规则3.4.1  关键字之后要留空格。象const、virtual、inline、case 等关键字之后至少要留一个空格,否则无法辨析关键字。象if、for、while 等关键字之后应留一个空格再跟左括号‘(’,以突出关键字。

    规则3.4.2  函数名之后不要留空格,紧跟左括号‘(’,以与关键字区别。

    规则3.4.3  ‘(’向后紧跟,‘)’、‘,’、‘;’向前紧跟,紧跟处不留空格。

    规则3.4.4  ‘,’之后要留空格,如Function(x, y, z)。如果‘;’不是一行的结束符号,其后要留空格,如for (initialization; condition; update)。

    规则3.4.5  赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后应当加空格。

    规则3.4.6  一元操作符如“!”、“~”、“++”、“--”、“&”(地址运算符)等前后不加空格。

    规则3.4.7  像“[]”、“.”、“->”这类操作符前后不加空格。

    建议3.4.1  对于表达式比较长的for 语句和if 语句,为了紧凑起见可以适当地去掉一些空格,如for (i=0; i<10; i++)和if ((a<=b) && (c<=d))

    建议3.4.2  代码或注释结束后不要有多余的空格,防止空格后面有未知东西。

    如下会存在未知隐患

    应该如下

    3.5 长行拆分

    规则3.5.1  代码行不要过长,最长不超过80 个字符。否则眼睛看不过来,也不便于打印。

    规则3.5.2  长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。

    示例: 

    1. if( (very_longer_variable1 >= very_longer_variable12)
    2. && (very_longer_variable3 <= very_longer_variable14)
    3. && (very_longer_variable5 <= very_longer_variable16))
    4. {
    5. dosomething();
    6. }

    第4章 标识符命名规范

            规范的标识符命名可以提高程序的可读性、易防错性、易维护性等。标识符命名的种类繁多,各有优缺点。没有一种命名规则可以让所有的程序员赞同,程序设计教科书一般都不指定命名规则。命名规则对软件产品而言并不是“成败悠关”的事,我们不要化太多精力试图发明世界上最好的命名规则,而应当制定一种令大多数项目成员满意的命名规则,并在项目中贯彻实施。本章仅提出了大多都认可的规范,对于命名风格可依下面规范作为指导思想参考附件常见的风格。

    4.1 共性命名规则

    共性规则是被大多数程序员采纳的,我们应当在遵循这些共性规则的前提下,再扩充特定的规则。

    原则4.1.1  标识符的命名要清晰、明了,有明确含义,使用完整的英文单词或大家基本可以理解的缩写,避免使人产生误解,让人快速理解你的代码很重要。

    说明:较短的单词可通过去掉元音形成缩写;较长的单词可取单词的头几个字母形成缩写;一些单词有大家公认的缩写。

    示例: temp缩写为tmp;flag缩写为flg;message缩写为msg。

    规则4.1.1  产品/项目组内部应保持统一的命名风格。

    说明:Unix like(小写下划线)和windows like(大小写混排)风格均有其支持者,产品应根据自己的部署平台,选择其中一种,并在产品内部保持一致。 不要使用大小写与下划线混排的方式,用作特殊标识如标识成员变量、全局变量或静态变量的m_g_s_,其后加上大小写混排的方式是允许的。

    示例:Add_User不允许;add_userAddUserm_AddUser允许。

    规则4.1.2  程序中不要出现仅靠大小写区分的相似的标识符。

    示例:x 与 X 容易混淆。

    建议4.1.1  用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。

    示例: min/max ……

    建议4.1.2  尽量避免名字中出现数字编号,除非逻辑上的确需要编号。

    示例:

    1. ​​​​​​​如下命名,使人产生疑惑。
    2. #define _EXAMPLE_0_TEST_
    3. 应改为有意义的单词命名 
    4. #define _EXAMPLE_UNIT_TEST_

    建议4.1.3  标识符前不应添加模块、项目、产品、部门的名称作为前缀。

    说明:很多已有代码中已经习惯在文件名中增加模块名,这种写法类似匈牙利命名法,导致文件名不可读,并且带来如下问题:第一眼看到的是模块名,而不是真正的文件功能,阻碍阅读;文件名太长;文件名和模块绑定,不利于维护和移植。若foo.c进行重构后,从a模块挪到b模块,若foo.c中有模块名,则需要将文件名从a_module_foo.c改为b_module_foo.c 。

    建议4.1.4  平台/驱动等适配代码的标识符命名风格保持和平台/驱动一致。

    说明:涉及到外购芯片以及配套的驱动,这部分的代码变动(包括为产品做适配的新增代码),应该保持原有的风格。

    建议4.1.5  重构/修改部分代码时,应保持和原有代码的命名风格一致。

    说明:根据源代码现有的风格继续编写代码,有利于保持总体一致。

    4.2 文件命名规则

    建议4.2.1  文件命名统一采用小写字符。

    说明:因为不同系统对文件名大小写处理会不同(如MS的DOS、Windows系统不区分大小写,但是Linux系统则区分),所以代码文件命名建议统一采用全小写字母命名。

    4.3 变量命名规则

    规则4.3.1  全局变量应增加“g_”前缀。

    规则4.3.2  静态变量应增加“s_”前缀。

    说明:全局变量十分危险,增加前缀更加醒目,名字丑陋,促使开发人员小心和少使用。从根本上来说,尽量不使用全局变量。

    规则4.3.3  禁止使用单个字符命名变量,但ijk作局部循环变量是允许的。

    建议4.3.1  变量的名字应当使用“名词”或者“形容词+名词”。

    建议4.3.2  全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)。类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身。

    4.4 函数命名规则

    建议4.4.1  函数命名应以函数要执行的动作命名,一般采用动词或者动词+名词的结构。

    建议4.4.2  函数指针除了前缀,其他按照函数的命名规则命名。

    4.5 宏的命名规则

    规则4.4.1  对于数值或者字符串等常量的定义,建议采用全大写字母,单词之间加下划线的方式命名(枚举同样建议使用此方式定义)

    规则4.4.2 除了编译开关/头文件等特殊应用,应避免使用_EXAMPLE_TEST_之类以下划线开始和结尾的定义。

    说明:一般来说,“_”开头、结尾的宏都是一些内部的定义,ISO/IEC 9899(俗称C99)中有描述。

    第5章 变量

    原则5.1.1 一个变量只有一个功能,不能把一个变量作多种用途。

    原则5.1.2 结构单一,不要设计面面俱到的结构。

    原则5.1.3 不用或者少用全局变量。

    规则5.1.1 防止局部变量与全局变量重名。

    规则5.1.2 通讯过程中使用的结构,必须注意字节序。

    规则5.1.3 严禁使用未经初始化的变量作为右值

    说明:在首次使用前初始化变量,初始化的地方离使用的地方越近越好,可以有效避免未初始化错误。

    建议5.1.1 构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问全局变量,防止多个模块或函数都可以修改、创建同一全局变量的现象。

    说明:降低全局变量耦合度。

    建议5.1.2 使用面向接口编程思想,通过API访问数据:如果本模块的数据需要对外部模块开放,应提供接口函数来设置、获取,同时注意注意全局数据的访问互斥。

    建议5.1.3 明确全局变量初始化的顺序,避免跨模块初始化的依赖。

    建议5.1.4 尽量减少没有必要的数据类型默认转换或强制转换。

    第6章 常量、宏

    规则6.1.1 用宏定义表达式时,要使用完备的括号。

    说明:因为宏只是简单的代码替换,不会计算,存在一定的风险。

    规则6.1.2 将宏定义的多条表达式放在大括号中。

    说明:更好的方法是多条语句写成do while(0)的方式。

    示例:

    1. 看下面的语句,只有宏的第一条表达式被执行。
    2. #define FOO(x) \
    3. printf("arg is %d\n", x); \
    4. do_something_useful(x);
    5. 为了说明问题,下面for语句的书写稍不符规范
    6. for (blah = 1; blah < 10; blah++)
    7. FOO(blah)
    8. 用大括号定义的方式可以解决上面的问题:
    9. #define FOO(x) { \
    10. printf("arg is %s\n", x); \
    11. do_something_useful(x); \
    12. }
    13. 但是如果有人这样调用:
    14. if (condition == 1)
    15. FOO(10);
    16. else
    17. FOO(20);
    18. 那么这个宏还是不能正常使用,所以必须这样定义才能避免各种问题:
    19. #define FOO(x) do{ \
    20. printf("arg is %s\n", x); \
    21. do_something_useful(x); \
    22. }while(0)
    23. do-while(0)方式定义宏,完全不用担心使用者如何使用宏,也不用给使用者加什么约束。

    规则6.1.3 使用宏时,不允许参数发生变化。

    示例:

    1. ​​​​​​​如下用法可能导致错误。
    2. #define  SQUARE(a) ((a)*(a))
    3. int a=5;
    4. int b;
    5. b= SQUARE(a++);//结果:a=7,即执行了两次增。
    6. 正确用法:
    7. b= SQUARE(a++);
    8. a++;//结果:a=6,即执行了一次增。
    9. 同时也建议即使函数调用,也不要在参数中做变量变化操作,因为可能引用的接口函数,在某个版本升级后,变成了一个兼容老版本所做的一个宏,结果可能不可预知。

    规则6.1.4 不允许直接使用魔鬼数字(没有具体含义的数字,字符串)。

    说明:魔鬼数字含义不明确,维护难。使用常量定义魔鬼数字。0为特殊字符,没有歧义时,不用特别定义。

    建议6.1.1 除非必要,应尽可能使用函数代替宏。

    建议6.1.2 常量建议使用const定义代替宏。

    建议6.1.3 宏定义中尽量不使用return、goto、continue、break等改变程序流程的语句。

    建议6.1.4 常量后加后缀。32位常量要加ul。

    U 或 u 无符号数

    L 或 l 长整型

    F 或 f 浮点数

    第7章 数据类型

    规则7.1.1 signed char和unsigned char用于数字型数据;char用于字符型数据。

    说明:单纯的char所能接收的操作只有“ =、==、!= ”。

    规则7.1.2 位域只能被定义为signed int和unsigned int。

    说明:由于行为未被定义,所以不允许位域使用enum、short、char类型。

    建议7.1.1 应使用指示了 大小 和 符号 的typedef以替代基本数据类型。

    说明:不使用基本类型 char、int、short、long、float、double,而使用typedef创建别名体现大小和符号。

    1. 例如:32位计算机
    2. typedef char               char_t;
    3. typedef signed char         int8_t;
    4. typedef unsigned char       uint8_t;
    5. typedef signed short        int16_t;
    6. typedef unsigned short      uint16_t;
    7. typedef signed int     int32_t;
    8. typedef unsigned int   uint32_t;
    9. typedef signed long long    int64_t;
    10. typedef unsigned long long  uint64_t;
    11. typedef float               float32_t;
    12. typedef double              float64_t;

    附件1 常用单词缩写(英文)(元音:aeiou

    全词

    缩词/简写

    中译

    全词

    缩词/简写

    中译

    指令内核相关类

    source

    src

    源头

    default

    def

    默认

    destination

    dst或des

    目的地,目标

    define

    def

    定义

    operator

    optr

    操作符

    macro

    mcr

    operand

    opnd

    操作数

    return

    ret

    返回

    offset

    ofs

    偏移

    assemble

    asm

    汇编

    clear

    clr

    清除

    interrupt

    intr

    中断

    move

    mov

    移动

    priority

    prio

    优先级

    instruction

    instr

    指令

    vector

    vect

    向量

    变量内存相关类

    temperature

    temper

    温度

    address

    addr

    地址

    temporary

    tmp

    临时

    pointer

    ptr

    指针

    counter

    ctr

    计数器

    buffer

    buf

    缓冲区

    count

    cnt

    计数

    stack

    stk

    flag

    flg

    旗帜、标识

    memory

    mem

    内存

    parameter

    par

    参数

    storage

    stg

    存储器

    argument

    arg

    参数

    block

    blk

    variable

    var

    变量

    allocate

    alloc

    分配

    array

    arr

    数组

    object

    obj

    对象

    string

    str

    字符串

    character

    char

    字符

    数学计算相关类

    increment

    inc

    增加

    average

    avg

    平均数

    decrease

    dec

    减少

    summation

    sum

    求和;总和

    addition

    add

    增加;加法

    calculate

    calc

    计算

    subtraction

    sub

    减少,减法

    total

    tot

    总计

    multiplication

    mul

    乘法

    magnitude

    mag

    巨大

    division

    div

    除法;除以

    maximum

    max

    最大

    proportion

    kp

    比例

    minimum

    min

    最小

    integral

    ki

    积分

    middle

    mid

    中间

    differential

    kd

    微分

    equivalent

    equiv

    相等的

    absolute

    abs

    绝对值

    greater equal

    ge

    大于等于

    algorithm

    algo

    算法

    greater than

    gt

    大于

    exponent

    expo

    指数

    less equal

    le

    小于等于

    recur

    recu

    递归

    less than

    lt

    小于

    limit

    lim

    限制

    quarter

    quar

    四分之一

    mantissa

    mant

    尾数

    scale

    scal

    比例

    fraction

    fract

    小数

    double

    dbl

    两倍

    digit

    dig

    数字

    number

    num

    数字;数量

    value

    val

    其他计算相关类

    reference

    ref

    引用,参考

    between

    btw

    之间

    compare

    cmp

    比较

    interval

    intvl

    间隔

    different

    diff

    对比

    different

    diff

    区别

    optimization

    opt

    最优化

    error

    err

    错误

    degree

    deg

    度数,程度

    exception

    exc

    异常

    full

    ful

    全量

    multiplex

    mux

    多路复用

    result

    rslt

    结果

    overflow

    ovf

    溢出

    complete

    comp

    完成

    check

    chk

    检查,核对

    success

    succ

    成功

    test

    tst

    测试

    error

    err

    错误

    detect

    检测,识别

    measure

    meas

    测量

    sample

    smp

    样本

    make

    mk

    制造

    时间顺序相关类

    timer

    tmr或tim

    定时器

    new

    新的

    time

    tm

    时间

    old

    老的;旧的

    second

    sec

    秒、第二

    now

    现在;目前

    minute

    min

    分钟

    current

    cur

    当前

    hour

    hr

    小时

    previous

    prev

    先前的

    day

    delay

    dly

    延迟

    month

    mth

    expiration

    expi

    过期

    year

    next

    nex

    下一个

    period

    perd

    时期

    timestamp

    ts

    时间戳

    timeout

    to

    超时

    age

    年龄

    结构方向相关类

    positon

    pos

    位置

    origin

    org

    起源,原点

    coordinates

    coord

    坐标系

    point

    pt

    row

    rect

    rc

    矩形

    column

    col

    rectangle

    rect

    长方形

    vertical

    vert/v

    垂直

    cylinder

    cyl

    圆柱体

    horizontal

    hori/h

    水平的

    length

    len

    长度

    dimension

    dim

    维度

    high

    hi

    高度;高的

    permutation

    perm

    排列

    invert

    invt

    颠倒

    信息相关类

    information

    info

    信息

    command

    cmd

    命令

    communication

    comu

    通信

    config

    conf

    配置

    message

    msg

    消息;信息

    request

    req

    请求

    packet

    pkt

    信息包

    acknowledge

    ack

    承认;应答

    package

    pkg

    answer

    ans

    回答

    protocol

    proto

    协议

    response

    rsp

    响应

    stream

    stm

    header

    hdr

    index

    idx

    索引

    decode

    deco

    解码

    frame

    frm

    帧率;框架

    encode

    enc

    编码

    clock

    clok

    时钟

    coding

    译码;编码

    receive

    recv

    接收

    authentication

    auth

    校验

    send

    send

    发送

    authentication code

    authcode

    校验码

    context

    ctx

    上下文

    unknown

    unk

    未知

    connect

    con

    连接

    extension

    ext

    扩展

    ethernet

    eth

    以太网

    expand

    expa

    扩展

    mailbox

    mbox

    邮箱

    field

    fld

    字段

    mask

    msk

    掩码

    identifier

    id

    标识符

    decode

    deco

    解码

    encode

    enc

    编码

    计算机动作操作类

    construct

    cons

    构建

    select

    sel

    选择

    control

    ctl

    控制

    delete

    del

    删除

    execute

    exec

    执行

    insert

    ins

    插入

    register

    reg

    注册

    copy

    cpy

    复制

    click

    clk

    点击

    paste

    粘贴

    back

    bk

    后退

    cut

    剪切

    disable

    dis

    使失效

    print

    Prn/prt

    打印

    enable

    en

    使能

    input

    in

    输入

    effective

    eff

    有效的

    output

    out

    输出

    invalid

    inv

    无效的

    lock

    lck

    上锁

    logic

    lgc

    逻辑的

    unlock

    unlk

    解锁

    read

    r

    scan

    sca

    扫描

    write

    w

    search

    srch

    搜索

    计算机专业名称类

    iteration

    itr

    迭代;反复;重复

    initialization

    init

    初始化

    version

    ver

    版本

    program

    prg

    程序

    password

    psw

    密码

    system

    sys

    系统

    permission

    perms

    许可

    android

    adr

    安卓操作系统

    device

    dev

    设备

    application

    app

    应用程序

    administrator

    adm

    管理员

    driver

    drv

    驱动

    manager

    mgr

    管理者,管理器

    update

    upd

    更新

    standard

    std

    标准

    upgrade

    upg

    升级

    library

    lib

    静态库

    environment

    env

    运行环境

    database

    db

    数据库

    process

    proc

    进程

    dynamic

    dyna

    动态

    ready

    rdy

    就绪

    synchronization

    sync

    同步

    suspend

    susp

    挂起

    asynchronization

    asyn

    异步

    status

    sts

    状态

    link

    lnk

    链接

    signal

    sig

    信号

    server

    svr

    服务

    semaphore

    sem

    信号量

    executable file

    exe

    可执行文件

    scheduler

    scher

    调度器

    sequence

    seq

    序列

    task

    tsk

    任务

    serialize

    seri

    序列化

    statistic

    stat

    统计

    virus

    vir

    病毒

    process

    proc

    进程

    ready

    rdy

    就绪

    文档图片类

    directory

    dir

    目录

    bitmap

    bmp

    位图纹理

    list

    lst

    列表

    image

    img

    图像

    log

    log

    日志

    picture

    pic

    图片

    document

    doc

    文档

    color

    clr

    颜色

    text

    txt

    文本

    record

    rcd

    记录

    table

    tab或tbl

    表格

    dictionary

    dict

    词典、字典

    manual

    man

    手册

    specification

    spec

    说明

    软件界面名称类

    screen

    scr

    屏幕

    button

    btn

    按钮

    display

    disp

    显示

    component

    com

    组件(多用于ui组件目录命名)

    util

    工具

    window

    wnd

    窗口

    attribute

    attr

    属性

    dialog

    dlg

    对话框

    feature

    fea

    特征

    cursor

    csr

    光标

    bottom

    btm

    底部

    markdown

    md

    文本标记语言

    descriptor

    desc

    描述符

    visible

    vis

    可见的

    电气相关类

    frequency

    freq

    频率

    poweron

    pwron

    上电

    voltage

    vol

    电压

    back electromotive force

    BEF

    反电动势

    current

    cur

    电流

    speed

    spd

    速度

    power

    pwr

    功率/电源

    electric

    elec

    电子的

    trigger

    trig

    触发器

    threshold

    thold

    阈值

    switch

    sw

    开关

    toggle

    tgl

    切换

    其他类

    resource

    res

    资源

    prefix

    pre

    前缀

    region

    rgn

    区域、领域

    reactive

    react

    有反应的

    group

    grp

    recall

    rcl

    召回

    assemble

    asm

    集合

    release

    rel

    发布

    repeat

    rpt

    重复

    action

    act

    动作

    duplicate

    dup

    重复

    common

    comm

    通用

    repository

    repo

    仓库

    dependency

    dep

    依赖

    reserve

    resv

    保留

    debug

    dbg

    调试

    reset

    rst

    重置

    direct

    dirt

    直接的

    resume

    resu

    重新开始

    engine

    eng

    引擎

    reverse

    revs

    反转

    experiment

    exp

    实验

    schedule

    sch

    计划

    exposure

    expo

    曝光

    section

    sect

    generate

    gen

    产生

    segment

    seg

    handler

    处理者

    strategy

    stra

    策略

    marshal

    mar

    序列化

    change

    chg

    改变

    unmarshal

    unmar

    反序列化

    convert

    conv

    转换

    deserialize

    dese

    反序列化

    translate

    tran

    翻译,转换

    manufacturer

    mft

    制造商

    positive

    posi

    积极的

    negative

    neg

    消极的

    neutral

    neut

    中立

    quality

    qlty

    质量

    properties

    prop

    性能

    performance

    perf

    性能

    product

    prod

    产品

    profile

    pf

    用户画像

    project

    proj

    项目

    protect

    prot

    保护

    proxy

    prx

    代理

    public

    pub

    公共的

    附件2 常用反义词组(英文)

    反义词

    中译

    反义词

    中译

    add

    remove

    添加/移除

    min

    max

    最小/最大

    add

    delete

    添加/删除

    old

    new

    旧/新

    begin

    end

    开始/最后

    start

    stop

    开始/停止

    create

    destroy

    创建/破坏

    next

    previous

    下个/以前的

    insert

    delete

    插入/删除

    source

    target

    源头/目标

    first

    last

    第一/最后

    show

    hide

    显示/隐藏

    get

    release

    获得/释放

    send

    receive

    发送/接收

    put

    get

    放下/获得

    source

    destination

    源头/目的

    increment

    decrement

    增加/减少

    cut

    paste

    剪切/粘贴

    lock

    unlock

    上锁/解锁

    up

    down

    上/下

    open

    close

    打开/关闭

    top

    btm

    顶部/底部

    附件3 Doxygen格式常用关键字表

    Doxygen注释关键字更多内容详见Doxygen手册

    注释命令

    标签名

    功能描述

    特殊功能

    \li

    生成一个黑心圆.

    -

                  

    生成一个黑心圆.                                                                                                            

    -#

                  

    指定按顺序标记。                                                                                                           

    ::

                  

    指定连接函数功能。(注:空格和“:”有连接功能,但建议还是使用”::”。只对函数有用。)                                       

    文件信息

    @mainpage   

    首页          

    描述内容,并将注释提到首页标签中去                                                                                         

    @copyright  

    版权所有      

                                                                                                                               

    @file       

                  

    文件名,可以默认为空,DoxyGen会自己加                                                                                      

    @details

    详细描述

    @author     

    作者          

                                                                                                                               

    @version    

    版本          

                                                                                                                               

    @date       

    日期          

                                                                                                                               

    @remarks    

    备注          

                                                                                                                               

    @par        

    自定义名      

    开始一个段落,段落名称描述由你自己指定                                                                                     

    @section    

    自定义名

    开始一个段落,段落名称描述由你自己指定                                                                                     

    @name       

    自定义名      

    分组名强制给注释段给定自定义名称,自动列在注释前,比@brief还前。                                                           

    @since {text}    

    自从          

    通常用来说明从什么版本、时间写此部分代码。                                                  

    @todo { things to be done }     

    待办事项:    

    对将要做的事情进行注释,链接到所有TODO 汇总的TODO 列表                                                                                

    模块信息

    @include

    包含文件

    @var        

    变量          

    对模块 变量 进行标注,Doxygen会在该变量处产生一个链接,归纳到变量列表中去。                                                      

    @typedef

    对模块 变量类型 进行标注

    @enum       

    枚举          

    对模块 枚举 进行标注,Doxygen会在该枚举处产生一个链接,归纳到枚举列表中去。                                                      

    @struct     

    结构体        

    对模块 结构体 进行标注,Doxygen会在该枚举处产生一个链接,归纳到结构体列表中去。                                                  

    @class      

    类            

    引用某个类 进行标注,格式:@class <name> [<header-file>] [<header-name>] eg:@class CTest "inc/class.h"                              

    @defgroup [gTag] [gName]

    [gName]

    定义模块组                                                                                                                  

    @addtogroup [gTag]

      

    添加到一个模块组                                                                                                      

    @ingroup [gTag]  

      

    加入到一个模块组                                                                                                         

    @{          

                  

    模块开始                                                                                                                  

    @}          

                  

    模块结束                                                                                                                  

    @code       

                  

    在注释中开始说明一段代码,直到@endcode命令。                                                                              

    @endcode    

                  

    在注释中代码段的结束。                                                                                                    

    @pre { description of the precondition }

    置条件  

    用来说明代码项的前提条件。

    @post { description of the postcondition }     

    后置条件      

    用来说明代码项之后的使用条件。                                                                                             

    @relates <name>

    通常用来把非成员函数的注释文档包含在类的说明文档中。

    函数信息

    @fn

    函数说明

    @param      

    参数          

    主要用于函数说明中,后面接参数的名字,然后再接关于该参数的说明。标记一个参数的意义                                                           

    @prg

    列表说明参数信息

    @return     

    返回          

    描述返回值情况eg: @return 本函数返回执行结果,若成功则返回TRUE,否则返回FLASE                                      

    @retval     

    返回值        

    描述返回值类型 eg: @retval NULL 空字符串。@retval !NULL 非空字符串                                                         

    @note       

    注解          

    开始一个段落,用来描述一些注意事项                                                                                                                          

    提醒信息

    @brief      

                  

    概要信息,简短描述,自动列在注释前。                                                                                        

    @see {comment with reference to other items }         

    参见          

    一段包含其他部分引用的注释,中间包含对其他代码项的标识符,自动产生对其标识符的引用链接。                                       

    @attention  

    注意          

                                                                                                                               

    @bug        

    Bug:         

    缺陷,链接到所有缺陷汇总的缺陷列表                                                                           

    @warning {warning message }

    警告          

    一些需要注意的事情     

    @sa

    参考资料

    @exception <exception-object> {exception description}

    异常          

    可能产生的异常描述 eg: @exception 本函数执行可能会产生超出范围的异常                                                       

    @deprecated

    弃用:        

    已废弃函数,链接到 待办事项列表                                             

    附件4 标识符命名个人风格

    标识符命名个人风格

    标识符

    其他环境

    FreeRTOS环境

    uCos-II环境

    文件夹名

    帕斯卡(大驼峰)

    帕斯卡(大驼峰)

    帕斯卡(大驼峰)

    文件名

    下划线

    下划线

    下划线

    变量名

    骆驼(小驼峰)

    静态变量加前缀s_
    全局变量加前缀g_
    类的数据成员加前缀m_

    结构体变量加前缀st_

    联合体变量加前缀ut_

    枚举变量加前缀et_

    匈牙利 (有修改)
    标识符名:类型+对象描述
    类型:
    uint32_t对应前缀ul
    uint16_t对应前缀us
    uint8_t对应前缀uc
    char(仅用于字符)对应前缀c
    枚举类型对应e
    指针类型对应p
    其他类型对应x
    char *对应前缀pc

    下划线

    常量/宏名

    全大写

    小写(文件名部分)+大写
    例:configUSE_PRE

    全大写

    函数名

    帕斯卡(大驼峰)
    谓-宾(动-名)结构

    匈牙利 (有修改)
    static限定函数对应前缀prv(私有)
    API函数返回值类型为函数名前缀
    API函数名使用所在的文件名,例如在tasks.c文件中函数 vTaskDelete();

    帕斯卡(大驼峰)
    程序类别作为前缀
    OS_TaskIdle( )

    方法名

    帕斯卡(大驼峰)

    接口名

    帕斯卡(大驼峰)

    类名

    帕斯卡(大驼峰)
    以C开头

    结构体类型名

    帕斯卡(大驼峰)
    以S开头

    联合体类型名

    帕斯卡(大驼峰)
    以U开头

    枚举类型名

    帕斯卡(大驼峰)
    以E开头
    枚举值同 常量/宏名

    附件5 常见标识符命名风格种类

    常见 编程标识符命名风格 种类

    类别

    别称

    命名法逻辑 特点

    举例

    优缺点

    常见应用场合

    帕斯卡

    大驼峰

    大小写混排,每个单词的首字母大写。

    void GetKey(void);
    int TimeCount;

    函数库和Jave平台下居多。

    骆驼

    小驼峰

    大小写混排,每个单词的首字母大写,第一个单词的首字母小写。

    void getKey(void);
    int timeCount;

    面向对象语言(Java、C#)变量、方法常用。
    事实上,很多程序员在实际命名时将骆驼命名法和帕斯卡命名结合使用。例如:变量用骆驼命名法;函数用帕斯卡命名法。

    匈牙利

    类同
    小驼峰

    大小写混排,每个单词的首字母大写,第一个单词的首字母小写,小写字母用来表明标识符的属性、类型等。

    标识符名:属性+类型+对象描述。
    属性:g_ 全局变量;c_ 常量;m_ c++类成员变量;s_ 静态变量
    类型:a数组;p指针;v无返回值;fn函数;h句柄;u无符号;
          b布尔;c字符;i整型;l长整型;f浮点型;n短整型;
          d双精度浮点;r实型;w字;dw双字;by字节;sz字符串;
    描述:Max最大;Min最小;Init初始化;Temp临时变量;
          Src源对象;Dest目的对象。 

    void vGetKey(void);
    int g_iTimeCount;

    优点:可读性很强,清晰。
    缺点:变更变量类型和属性麻烦;C++是强类型,体现不出优点。随着编译器的优化,优点也在被弱化。此法争议多。

    非Windows系统开发,笔者不建议使用匈牙利法,可扬长去短,保留:g_全局变量,m_成员变量,s_静态变量。

    常见于Windows。

    下划线

    全小写,以 下划线 分割逻辑断点。上面是以大写字母为逻辑断点。

    void get_key(void);
    int time_count;

    常见于Linux内核,C++标准库,Boost以及Ruby,Rust等语言。C、Python变量常用。

  • 相关阅读:
    花了 3000 美元,我在 SaaStr 大会学到了什么?——码农驱动的 SaaS 增长之路
    【C++】lambda函数
    JAVA关于Spring 面试题汇总
    NVIDIA 7th SkyHackathon(七)Tao 目标检测模型可视化推理与导出
    iOS 新建本地数据库FMDB
    什么是微服务?
    如果在学习spring的时候没看过这份学习笔记+源码剖析,真的亏大了!
    【檀越剑指大厂--泛型】泛型总结
    java学习第二天笔记-java基础概念11-键盘输入-33
    多线程和并发编程(6)—并发编程的设计模式
  • 原文地址:https://blog.csdn.net/weixin_46672094/article/details/124852340