0 头文件注释
原则
用于说明本文件的用途,作者,协议等信息
示例
1 | //****************************************************************************************** |
1 头文件防冲突宏
原则
用于防止头文件被多次包含,从而导致编译,链接错误
示例
1 | #ifndef __XXX_H__ // XXX是模块名字 |
2 C++保护宏
原则
每个头文件中,必须包含该保护宏,从而避免C++的重命名机制导致C链接失败
示例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef __XXX_H__ // XXX是模块名字
#ifdef __XXX_H__
#ifdef __cpluscplus
extern "C"
{
#endif
// 头文件实现代码
#ifdef __cpluscplus
{
#endif
#endif //__XXX_H__
3 宏函数
原则
一般情况下,建议用内联函数代替宏函数,如果必须使用,则
- 代码中使用到的任何入口参数,都必须包含
()
- 如果代码行数大于一行,则必须用
do{ }while(0)
包裹
示例11
2
#define MAX(a, b) (a)>(b)?(a):(b)
示例21
2
3
4
5
6
7
#define RESET_CPU() \
do \
{ \
__disable_fault_irq(); \
NVIC_SystemReset(); \
}while(0)
4 函数命名规范
原则
- 包含模块名
- 包含功能类型
模块名全部大写,功能类型采用驼峰式命名法
示例1
2void LED_SetState(eState state);
eState LED_GetState(void);
这里LED
表示模块的名称,SetState
和GetState
分别表示对应的操作
5 函数注释模板
原则
采用标准Doxygen注释风格,必须包含
- 函数名字
- 函数功能
- 函数入口参数
- 函数返回值
可适当包含下面信息
- 函数使用条件
- 函数注意事项
注: 如果没有入口参数或者出口参数,则写无
示例
1 | //****************************************************************************************** |
6 代码注释
原则
- 函数注释,使用标准Markdown注释风格
- 宏变量后,使用
//
注释 - 头文件中,同类符号的注释起始位置,需保持一致,从而保证代码整洁
示例1
1 | //! FIFO Memory Model |
7 switch
原则
在switch中,一般情况下,
- 条件分支中必须包含
break
- 条件分支中,无论语句块,都必须包含完整的
{}
- 最后一个必须包含default
从而避免因为忘记break造成的bug,减轻调试负担
如下所示
示例11
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
switch(Status)
{
case POWER_ON:
{
// 上电自检
}
break;
case POWER_OFF:
{
// 掉电处理代码
}
break;
case EVENT_TIMER:
{
// 定时器事件处理代码
}
break;
default:
{
// 默认处理规则
}
}
在某些情况下,需要将多个分支合并,这时要求:
- 在原分支包含break处,编写特殊注释,说明这里是特意省去break
如下所示
上电自检后,进入系统初始化,初始化各种外设,所以这里不需要break
直接从POWER_ON
进入SYS_INIT
示例21
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
switch(Status)
{
case POWER_ON:
{
// 上电自检
}
//break; NOTE:上电自检后,进入系统初始化,初始化各种外设,所以这里不需要break
case SYS_INIT:
{
// 初始化代码
}
break;
case POWER_OFF:
{
// 掉电处理代码
}
break;
case EVENT_TIMER:
{
// 定时器事件处理代码
}
break;
default:
{
// 默认处理规则
}
}
8 if
原则
在任何情况下,如果出现if
或else
或else if
,其后面无论语句块的长短,都必须包含完整的{}
从而有效避免一些潜在bug
示例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 例子1
if(LED_OFF == LedStatus)
{
LedStatus = LED_ON;
}
// 例子2
if(LED_OFF == LedStatus)
{
LedStatus = LED_ON;
}
else
{
LedStatus = LED_OFF;
}
9 goto
原则
一般情况下,不允许使用goto语句,因为复杂的跳转会导致:
- 可读性变差
- 后期维护困难
但在错误处理时,goto可以极大的简化编程逻辑,所以我们规定
只能在错误处理中使用goto
同时要求:
- 标号必须大写
- 标号第一个字母为L
示例
1 |
|