编程规范

规范

1. 原则

  1. 简洁明了,提高代码可读性,读的是代码而不是注释,注释永远都是辅助的。
  2. 零告警,严谨的语法才能保障代码表达和编译器理解的是一至的。

2. 排版

  1. 程序块之间、变量声明之间,用空行分隔
  2. 突出语法关键字
  3. 一行不要太长,换行增加可读性
  4. Tab键排版

3. 注释

  1. 注释的目的是阐明意图目的,而不是翻译某行代码的动作

  2. 注释的原则是尽量代码自注释,代码越清晰,可读性越高

  3. 统一格式 **/* 注释内容 */**, *号与注释内容之间有一个空格

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /*************************************************
    Copyright //版权
    File name: // 文件名
    Author: //作者
    Version: //版本号
    Description: // 用于详细说明此程序文件完成的主要功能,与其他模块
    // 或函数的接口,输出值、取值范围、含义及参数间的控
    // 制、顺序、独立或依赖等关系
    Others: // 其它内容的说明
    Log: // 修改日志,包括修改内容,日期,修改人等
    *************************************************/
    1
    2
    3
    4
    5
    6
    /*
    *@ Description: 函数描述,描述本函数的基本功能
    * @param 1 – 参数 1.
    * @param 2 – 参数 2
    * @return – 返回值
    */

4. 定义

  1. 命名风格

    1. 模块名+文件名+功能描述,之间采用短下划线分隔
    2. 功能描述部分,采用驼峰风格

    例如,

    1
    void SAFE_LASER_setLaserShield(uint8_t _EN);
  2. 宏定义

    1. define 必须大写
    2. typedef 可以小写

    例如,

    1
    2
    #define OS_TASK_R200RXID1 		0x198 	/* HEX格式 */
    typedef uint32_t StackSize_t; /* 仅用于堆栈 */
  3. 类型定义

    使用linux自带类型定义规则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #define uint8_t  	unsigned char
    #define int8_t char
    #define uint16_t unsigned short
    #define int16_t short
    #define uint32_t unsigned int
    #define int32_t int
    #define uint64_t unsigned long long
    #define int64_t long long

    #define TRUE 1
    #define FALSE 0
    #define NULL 0

5. 变量

  1. 变量通用规则
    1. 采用驼峰风格,首字母大写
    2. 在函数开始是全部定义,不允许在函数中间定义
    3. 变量命名必须可以表示其含义
    4. 必须初始化
  2. 局部变量
    1. 本地局部变量必须用static关键字修饰
  3. 全局变量
    1. 全局变量必须以g开头
  4. 函数变量
    1. 变量必须以_开头
1
2
3
static uint8_t SafeLaserSet = 0;
uint8_t gSafeLaserSet = 0;
static uint8_t _SafeLaserSet = 0;

6. 函数

  1. 函数名必须能够自注释,必要是需要增加注释写明意图
  2. 内部函数必须使用static定义,命名可以不加模块名
  3. 外部函数
    1. 必须在头文件中声明,
    2. 命名时必须带模块名,
    3. 必须给出带注释,并写明函数意图,参数说明,返回值
1
2
static uint_t SAFE_LASER_setLaseShield(uint8_t _EN);
void SAFE_LASER_setLaseShield(uint8_t _EN);

7. 文件

  1. 头文件

    1. 命名规则模块名+功能,小写,例如os_task.h

    2. 格式如下

      1
      2
      3
      4
      5
      6
      7
      8
      #ifndef __OS_TASK_H__
      #define __OS_TASK_H__

      ..../* 开放的宏定义 */
      ..../* 开放的全局变量声明 */
      ..../* 开放的函数声明 */

      #endif
  2. 源文件

    1. 命名规则模块名+功能,小写,例如os_task.c

    2. 格式如下,举例只为说明源文件中,各元素的顺序

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      <- 1 - 引用头文件 ->
      #include "os_task.h"

      <- 2 - 定义本文件用到的宏 ->
      #define OS_TASK_SWITCH_INTERVAL 10 /* 单位ms */
      typedef uint32_t StackSize_t ; /* 仅用于堆栈 */
      typedef enum{};
      typedef union{};
      typedef struct{};

      <- 3 - 本地变量 ->
      static StackSize_t *TopStack = NULL

      <- 4 - 开放的全局变量 ->
      uint32_t gOsTaskEventBitMap = 0;

      <- 5 - 本地函数,仅在本文件使用 ->
      static void TASK_TaskSwitch(void)
      {
      return
      }

      <- 6 - 开放的函数 ->
      void OS_TASK_TaskDelay(uint16_t _ms)
      {
      return
      }

8.约定俗成简写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
addition           	add           		加
subtraction sub 减
multiplication mul 乘法
division div 除法
answer ans 响应、回答
array arr 数组、集合
average avg 平均
buffer buf或buff 缓冲区
capture cap或capt 捕获
check chk 检查
count cnt 计数器
column col 列
control ctrl 控制
decode dec 解码、译码
define def 定义
delete del 删除
destination dst或dest 目的
display disp 显示
encode enc 编码
environment env 环境
error err 错误
float flt 浮动、浮点
frequency freq 频率
header hdr 开始、开头
index idx 索引、指示、
image img 影像、镜像
increment inc 增加、增量
initalize init 初始化
iteration itr 循环、迭代
length len 长度
memory mem 内存
middle mid 中值
make mk 制造、形成
message msg 消息
number num 数量、编号
operand opnd 操作数
optimization opt 最优
operator optr 操作
packet pkt 消息包
positon pos 位置
previous pre或prev 以前的
pointer ptr 指针
record rcd 记录
receive recv 收到、接收
result res 结果
return ret 返回
source src 源头
stack stk 栈
string str 字符串
table tab 表
temporary tmp或temp 临时
total tot 全部的
time stamp ts 时间戳
value val 值

有互斥意义的变量或者动作相反的函数应该是用互斥词组命名

1
2
3
4
5
add/remove  	begin/end 		create/destroy 		insert/delete 
first/last get/release increment/decrement put/get add/delete
lock/unlock open/close min/max old/new
start/stop next/previous source/target show/hide
send/receive source/destination copy/paste up/down

9. 模块

  1. 模块必须具有封装性,且对外提供尽量少的必要接口,接口必须提供详细的注释描述

  2. 模块的组织形式可以是文件夹形式,也可以是文件形式

  3. 文件都以小写命名

    例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .
    ├── src /* 应用层代码 */
    │   ├── main.c /* 应用入口 */
    │   ├── test.c
    │   ├── test1.c
    ├── include /* 设备驱动代码 */
    │   ├── test.h
    │   ├── test1.h
    ├── debug /* 芯片厂家提供的库代码 */
    │   ├── MakeFile
    │   ├── CMake
    │   └── main