修复规范矛盾并定案5项规则,保护宏统一XXX_H
规则定案:常量在右(a>5)、保护宏XXX_H(禁双下划线)、 头文件常量用#define、存储类前缀(g_/s_)优先、允许void返回值 全库32个.h头文件保护宏 __XXX_H → XXX_H 改名(字节级替换) S1检查规则同步更新(拒绝双下划线),Inc/gpio.h 反向验证被正确拦截 规范示例矛盾修复:K&R括号、标准类型、变量初始化、命名常量、注释字段补全
This commit is contained in:
@@ -126,7 +126,7 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法
|
||||
|
||||
| 编号 | 规范条款 | 规则 |
|
||||
|---|---|---|
|
||||
| S1 | 2.3.1 | .h 文件必须有 `__XXX_H` 格式头文件保护宏 |
|
||||
| S1 | 2.3.1 | .h 文件必须有 `XXX_H` 格式头文件保护宏(禁止 `__` 前缀) |
|
||||
| S2 | 5.2 | 文件开头必须有文件头注释(含 模块名称/作者) |
|
||||
| S3 | 3.4.1 | `#define` 宏名必须全大写+下划线+数字 |
|
||||
| S4 | 3.5.1 | typedef 类型名必须以 `_t` 结尾 |
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
| 版本号 | 修订日期 | 修订内容 | 修订人 |
|
||||
| ---- | ---------- | ------ | --- |
|
||||
| V1.0 | 2026-05-11 | 创建初始版本 | 王建锋 |
|
||||
| V1.0.1 | 2026-09-01 | 修复示例与规则矛盾(括号风格、示例类型、变量初始化、硬编码、注释补全);规则定案:保护宏改`XXX_H`、常量在右、头文件常量用`#define`、存储类前缀优先、允许`void`返回值 | 王建锋 |
|
||||
## 2. 文件结构规范
|
||||
|
||||
### 2.1 头文件(.h)结构
|
||||
```c
|
||||
#ifndef __MODULE_NAME_H
|
||||
#define __MODULE_NAME_H
|
||||
#ifndef MODULE_NAME_H
|
||||
#define MODULE_NAME_H
|
||||
|
||||
/*
|
||||
* 模块名称:模块英文名称
|
||||
@@ -30,7 +31,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* 头文件包含区 - 仅包含本模块必需的头文件 */
|
||||
#include "stdint.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* 宏定义区 */
|
||||
#define MODULE_NAME_CONSTANT 100
|
||||
@@ -48,7 +49,7 @@ void module_name_init(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MODULE_NAME_H */
|
||||
#endif /* MODULE_NAME_H */
|
||||
```
|
||||
### 2.2 源文件(.c)结构
|
||||
```c
|
||||
@@ -74,10 +75,10 @@ typedef struct {
|
||||
} module_name_private_t;
|
||||
|
||||
/* 全局变量定义区 - 尽量避免使用全局变量 */
|
||||
uint8_t g_module_name_global_var = 0;
|
||||
uint8_t g_module_name_global_var = 0; /* 全局状态变量(示例) */
|
||||
|
||||
/* 静态变量定义区 */
|
||||
static module_name_private_t s_module_name_private_var;
|
||||
static module_name_private_t s_module_name_private_var; /* 私有状态变量(示例) */
|
||||
|
||||
/* 私有函数声明区 */
|
||||
static void module_name_private_function(void);
|
||||
@@ -92,7 +93,7 @@ static void module_name_private_function(void) {
|
||||
}
|
||||
```
|
||||
### 2.3 头文件包含规则
|
||||
1. 头文件必须包含头文件保护宏,格式为`__MODULE_NAME_H`
|
||||
1. 头文件必须包含头文件保护宏,格式为`MODULE_NAME_H`(不得使用`__`双下划线前缀,其为C标准保留标识符)
|
||||
2. 头文件中只包含本模块接口必需的其他头文件
|
||||
3. 源文件中先包含系统头文件,再包含自定义头文件
|
||||
4. 禁止在头文件中定义变量和函数体
|
||||
@@ -111,13 +112,14 @@ static void module_name_private_function(void) {
|
||||
4. 指针变量以`p_`前缀开头
|
||||
5. 数组变量以`a_`前缀开头
|
||||
6. 布尔变量以`is_`、`has_`、`can_`等前缀开头
|
||||
7. 前缀冲突时,存储类前缀(`g_`/`s_`)优先于类型前缀(`p_`/`a_`),如静态数组`s_uart_rx_buffer`
|
||||
**示例:**
|
||||
```c
|
||||
uint8_t g_system_status; /* 全局系统状态变量 */
|
||||
static uint16_t s_timer_count; /* 静态定时器计数变量 */
|
||||
uint8_t *p_data_buffer; /* 数据缓冲区指针 */
|
||||
uint16_t a_adc_value[10]; /* ADC采样值数组 */
|
||||
bool is_button_pressed; /* 按钮是否按下标志 */
|
||||
uint8_t g_system_status = 0; /* 全局系统状态变量 */
|
||||
static uint16_t s_timer_count = 0; /* 静态定时器计数变量 */
|
||||
uint8_t *p_data_buffer = NULL; /* 数据缓冲区指针 */
|
||||
uint16_t a_adc_value[10] = { 0 }; /* ADC采样值数组 */
|
||||
bool is_button_pressed = false; /* 按钮是否按下标志 */
|
||||
```
|
||||
### 3.3 函数命名
|
||||
1. 采用**小写字母+下划线**命名法
|
||||
@@ -136,13 +138,15 @@ static void uart_private_handle_interrupt(void);
|
||||
### 3.4 宏和常量命名
|
||||
1. 采用**大写字母+下划线**命名法
|
||||
2. 以**模块名**作为前缀
|
||||
3. 常量优先使用`const`定义,而非`#define`
|
||||
3. 头文件对外常量使用`#define`(见2.3.4);源文件内私有常量可用`const`,命名遵循3.2(小写+下划线)
|
||||
**示例:**
|
||||
```c
|
||||
/* 头文件对外常量:使用 #define */
|
||||
#define UART_BAUD_RATE_9600 9600
|
||||
#define UART_BUFFER_SIZE 128
|
||||
|
||||
const uint8_t UART_DEFAULT_DATA_BITS = 8;
|
||||
/* 源文件内私有常量:可用 const,命名遵循 3.2(小写) */
|
||||
const uint8_t uart_default_data_bits = 8;
|
||||
```
|
||||
### 3.5 类型定义命名
|
||||
1. 采用**小写字母+下划线**命名法
|
||||
@@ -176,7 +180,11 @@ typedef struct {
|
||||
5. 一元运算符前后不加空格
|
||||
**正确示例:**
|
||||
```c
|
||||
int a = 10;
|
||||
int32_t a = 10;
|
||||
int32_t b = 0;
|
||||
int32_t i = 0;
|
||||
uint8_t c[10] = { 0 };
|
||||
|
||||
if (a > 5) {
|
||||
b = a + 3;
|
||||
}
|
||||
@@ -186,7 +194,10 @@ for (i = 0; i < 10; i++) {
|
||||
```
|
||||
**错误示例:**
|
||||
```c
|
||||
int a=10;
|
||||
int32_t a=10;
|
||||
int32_t b=0;
|
||||
int32_t i=0;
|
||||
uint8_t c[10]={0};
|
||||
if(a>5){
|
||||
b=a+3;
|
||||
}
|
||||
@@ -202,8 +213,8 @@ for(i=0;i<10;i++){
|
||||
5. 长表达式应在运算符处换行,新行与运算符对齐
|
||||
**示例:**
|
||||
```c
|
||||
int calculate_sum(int a, int b, int c, int d) {
|
||||
int sum;
|
||||
int32_t calculate_sum(int32_t a, int32_t b, int32_t c, int32_t d) {
|
||||
int32_t sum = 0;
|
||||
|
||||
sum = a + b
|
||||
+ c
|
||||
@@ -260,21 +271,25 @@ while (1) ;
|
||||
```
|
||||
**示例:**
|
||||
```c
|
||||
#define DELAY_INNER_LOOP 123 /* 延时内层循环次数,按12MHz时钟整定 */
|
||||
|
||||
/*
|
||||
* 函数功能:毫秒级软件延时函数
|
||||
* 入口参数:ms - 需要延时的毫秒数 unsigned int 0 - 65535
|
||||
* 入口参数:ms - 需要延时的毫秒数 uint32_t 0 - 65535
|
||||
* 出口参数:无
|
||||
* 返回值:无(void)
|
||||
* 限定条件:0 <= ms <= 65535
|
||||
* 函数说明:1. 采用空指令循环方式实现延时,会阻塞CPU运行
|
||||
* 2. 延时精度依赖系统时钟,默认适配12MHz时钟(12T模式)
|
||||
* 3. 系统时钟改变时,需重新调整内层循环次数
|
||||
* 2. 延时精度依赖系统时钟,默认适配12MHz时钟
|
||||
* 3. 系统时钟改变时,需重新调整内层循环次数(DELAY_INNER_LOOP)
|
||||
* 4. 当ms为0时,函数立即返回
|
||||
*/
|
||||
void delay_ms(unsigned int ms) {
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
void delay_ms(uint32_t ms) {
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
|
||||
for (i = 0; i < ms; i++) {
|
||||
for (j = 0; j < 123; j++) {
|
||||
for (j = 0; j < DELAY_INNER_LOOP; j++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,13 +308,16 @@ static uint8_t s_uart_rx_buffer[UART_BUFFER_SIZE]; /* UART接收缓冲区 */
|
||||
### 5.5 代码行注释
|
||||
1. **关键逻辑代码每一行都要添加注释**
|
||||
2. 复杂的算法和逻辑必须添加详细注释
|
||||
3. 注释应单独占一行,与被注释代码缩进级别相同
|
||||
3. 注释应单独占一行(变量定义的行内注释除外,见5.4.3),与被注释代码缩进级别相同
|
||||
**示例:**
|
||||
```c
|
||||
#define CRC16_INITIAL 0xFFFF /* CRC-16初值 */
|
||||
#define CRC16_POLY_REFLECTED 0xA001 /* CRC-16/MCC反射多项式 */
|
||||
#define BITS_PER_BYTE 8 /* 每字节的位数 */
|
||||
|
||||
/* 计算CRC校验值 */
|
||||
uint16_t crc_calculate(uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint16_t crc = 0xFFFF;
|
||||
uint16_t crc_calculate(uint8_t *data, uint16_t length) {
|
||||
uint16_t crc = CRC16_INITIAL;
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
|
||||
@@ -309,11 +327,11 @@ uint16_t crc_calculate(uint8_t *data, uint16_t length)
|
||||
crc ^= data[i];
|
||||
|
||||
/* 对每个位进行处理 */
|
||||
for (j = 0; j < 8; j++) {
|
||||
for (j = 0; j < BITS_PER_BYTE; j++) {
|
||||
/* 检查最低位是否为1 */
|
||||
if (crc & 0x0001) {
|
||||
/* 最低位为1,右移并与多项式异或 */
|
||||
crc = (crc >> 1) ^ 0xA001;
|
||||
crc = (crc >> 1) ^ CRC16_POLY_REFLECTED;
|
||||
} else {
|
||||
/* 最低位为0,直接右移 */
|
||||
crc = crc >> 1;
|
||||
@@ -334,12 +352,14 @@ uint16_t crc_calculate(uint8_t *data, uint16_t length)
|
||||
5. 使用标准数据类型(`uint8_t`、`int32_t`等),避免使用`char`、`int`等不确定长度的类型
|
||||
**示例:**
|
||||
```c
|
||||
#define DATA_BUF_SIZE 100 /* 数据缓冲区大小(字节) */
|
||||
|
||||
void function(void) {
|
||||
uint8_t status = 0;
|
||||
uint16_t count = 0;
|
||||
uint8_t *p_data = NULL;
|
||||
|
||||
p_data = (uint8_t *)malloc(100);
|
||||
p_data = (uint8_t *)malloc(DATA_BUF_SIZE);
|
||||
if (p_data == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -354,17 +374,17 @@ void function(void) {
|
||||
1. 函数应遵循"单一职责原则",一个函数只做一件事
|
||||
2. 函数长度不宜过长,一般不超过50行
|
||||
3. 函数参数不宜过多,一般不超过5个
|
||||
4. 函数必须有明确的返回值,用于表示执行状态
|
||||
4. 有失败路径的函数必须有明确的返回值,用于表示执行状态;无失败路径的纯输出函数可返回`void`
|
||||
5. 避免使用函数参数作为返回值
|
||||
6. 私有函数必须声明为`static`
|
||||
### 6.3 控制结构
|
||||
1. `if`语句中,常量应写在比较运算符的左边
|
||||
1. `if`语句中,常量应写在比较运算符的右边
|
||||
2. `switch`语句必须包含`default`分支
|
||||
3. 避免使用`goto`语句,除非用于错误处理
|
||||
4. 循环嵌套不宜超过3层
|
||||
**示例:**
|
||||
```c
|
||||
if (0 == status) {
|
||||
if (status == 0) {
|
||||
do_something();
|
||||
}
|
||||
|
||||
@@ -423,8 +443,8 @@ uint8_t uart_send_data(uint8_t *data, uint16_t length) {
|
||||
## 9. 附录
|
||||
### 9.1 完整示例代码
|
||||
```c
|
||||
#ifndef __LED_H
|
||||
#define __LED_H
|
||||
#ifndef LED_H
|
||||
#define LED_H
|
||||
|
||||
/*
|
||||
* 模块名称:LED控制模块
|
||||
@@ -440,7 +460,7 @@ uint8_t uart_send_data(uint8_t *data, uint16_t length) {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* LED编号定义 */
|
||||
#define LED_NUM_1 0
|
||||
@@ -491,5 +511,5 @@ uint8_t led_toggle(uint8_t led_num);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LED_H */
|
||||
#endif /* LED_H */
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user