1. 注释#
所有的注释统一使用 /**/,除了一些特殊的注释以外。
单行注释:
多行注释:
1
2
3
4
| /**
* 多行注释 1
* 多行注释2
*/
|
特殊的注释:用于表面一些待办事项,比如:TODO、FIXME、BUG、HACK。
1
2
| // TODO 实现 xxx 功能
// FIXME 需修复 xxx 功能
|
特殊的注释:在第三方 SDK 中加入修改,并方便后续升级 SDK 时方便区分。
1
2
3
4
5
6
7
8
| // [公司名] [人名] [时间] S : 实现 xxx 功能
...
// [公司名] [人名] [时间] E : 实现 xxx 功能
// Github Zeepunt 2025.10.01 S: 添加调试打印信息
...
// Github Zeepunt 2025.10.01 E: 添加调试打印信息
|
2.大括号#
对于所有非函数的语句块,把起始大括号放在行尾,而把结束大括号放在行首。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| if (var == 0) {
var = 1;
var++;
}
switch (num) {
case NUM_ONE:
return 1;
case NUM_TWO:
return 2;
default:
return 0;
}
do {
printf("1\r\n");
} while(1);
|
对于函数来说,函数的起始大括号放置于下一行的开头。
例如:
1
2
3
4
| int function(void)
{
return 0;
}
|
当只有一个单独的语句的时候,也需要加大括号。
例如:
1
2
3
4
5
6
7
| if (var == 0) {
return false;
}
for (uint i = 0; i < 32; i++) {
printf("i: %d.\n", i);
}
|
3. 空格#
大多数关键字之后放一个空格。
例如:
1
| if, switch, case, for, do, while
|
当声明指针类型或者返回指针类型的函数时, * 的首选使用方式是使之靠近变量名或者函数名,而不是靠近类型名。
例如:
1
2
3
| char *var = NULL;
void sum(int *a, int *b);
char *get_char(char *str);
|
4. 变量命名#
对于仅用于当前文件的内部变量,可以使用以下两种方式的命名:
1
2
3
4
5
6
7
8
| /* 以 s_ 开头, 表示全局内部变量 */
static int s_var = 0;
/* 以 _ 开头, 表示函数内部变量 */
void func(void)
{
static char _module_name = "xxx";
}
|
对于全局变量来说,命名方式为:
1
2
3
4
| /* 以 g_ 开头, 表示全局变量 */
int g_version = 0x0200;
extern int g_version;
|
5. 类型声明#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| /**
* 结构体以 _s 结尾, 表示 struct
* 枚举以 _e 结尾, 表示 enum
* 联合体以 _u 结尾, 表示 union
* 如果使用 typedef 类型声明, 则以 _t 结尾, 表示 typedef
*/
typedef struct dev_info_s {
int dev_num;
} dev_info_t;
typedef enum dev_type_e {
DEV_TYPE_CHAR,
} dev_type_t;
typedef union dev_board_u {
uint16_t data;
struct {
uint8_t var1;
uint8_t var2;
} d;
} dev_board_t;
typedef void (*dev_notify_t)(void *arg);
|
6. 函数命名#
可以对外声明的函数命名格式为:层级 + 模块名 + 名词 + 动词。
仅对内声明的函数命名格式为:priv + 模块名 + 名称 + 动词。
1
2
3
4
5
6
| /* Driver 的 uart 模块 */
int drv_uart_buf_send(uint8_t *buf, uint32_t buf_len);
int drv_uart_buf_recv(uint8_t *buf, uint32_t buf_len);
static void priv_uart_buf_hander(uint8_t *buf, uint32_t buf_len)
static void priv_uart_buf_init(void);
|
7. 函数调用#
如果调用的函数有返回值,那么有两种调用方式:
1
2
3
4
5
6
7
| int ret = 0;
/* 方式一: 获取 test_func 函数的返回值 */
ret = test_func();
/* 方式二: 明确告知编译器"忽略返回值", 避免相关警告, 比如 -Wunused-result */
(void)test_func();
|
这两种调用方式所实现的功能是一样的。
8. 字符串和缓冲区#
字符串使用的 char * 来声明。
用于存放数据的缓冲区使用 uint8_t * 来声明。
1
2
3
| char *str = "AABBCCDDEEFF";
uint8_t *buf[3] = {0x11, 0x22, 0x33};
|