第87章:代码风格——命名规范、缩进、注释
说实话,做了十几年嵌入式开发,我见过最让人头疼的代码,往往不是逻辑多复杂,而是——根本看不懂。
你想想看,一段代码交到你手上,变量名叫 a、b、tmp,函数名清一色 func1、func2,缩进乱七八糟,注释要么没有,要么全是废话。这种代码,别说维护了,读一遍都想摔键盘。
代码风格这件事,说白了就是「写给人看的」。机器只关心你编译后对不对,但人——包括你自己——要能读得懂、改得动。今天我就把这块掰开揉碎讲清楚。
命名规范:名字就是最好的注释
我个人的习惯是:变量名、函数名,一定要让人看一眼就知道它是什么、干什么用。别偷懒,别用拼音,更别用单字母。
核心原则:
- 变量名:小写 + 下划线,如
motor_speed、adc_value - 函数名:动词 + 名词,如
set_pwm_duty()、read_temperature() - 宏定义:全大写 + 下划线,如
#define BUFFER_SIZE 256 - 类型定义:加
_t后缀,如typedef uint32_t motor_state_t;
我在项目中遇到过一件事:有个同事写了个函数叫 deal(),我看了半天不知道它在处理什么。后来打开函数体才发现是处理串口数据包的。你说,改成 process_uart_packet() 不好吗?
小技巧:命名时问自己一句——「如果别人不看函数体,能猜出这个函数在做什么吗?」如果答案是否定的,那就改。
缩进:对齐是代码的呼吸
缩进这件事,我建议团队统一用 4个空格。别用 Tab,因为不同编辑器对 Tab 的解析不一样,换台机器就乱套了。
来看个对比:
// 糟糕的缩进
if(flag){
x=1;
y=2;
if(sub_flag){
z=3;
}
}
// 良好的缩进
if (flag) {
x = 1;
y = 2;
if (sub_flag) {
z = 3;
}
}
你看,第二种一眼就能看出代码的层级关系。第一种?嗯,得数花括号。
注意:花括号的位置也要统一。我个人推荐 K&R风格——左花括号不换行,右花括号单独一行。这样节省行数,结构也清晰。
注释:写给人看的说明书
注释不是越多越好。我曾经见过有人给 i++ 写注释:「i 自增 1」——这不是废话吗?
好的注释应该回答「为什么」,而不是「是什么」。
注释的黄金法则:
- 文件头注释:作者、日期、功能描述
- 函数注释:功能、参数、返回值、注意事项
- 关键逻辑注释:解释为什么这么写,而不是写了什么
- TODO/FIXME:标记待办事项或已知问题
举个例子:
/**
* @brief 读取温度传感器值
* @param channel 传感器通道号,范围 0-3
* @return 温度值,单位摄氏度,返回 -1 表示读取失败
* @note 该函数会阻塞 10ms 等待传感器稳定
*/
int read_temperature(uint8_t channel) {
// 等待传感器稳定,否则读到的值可能跳变
delay_ms(10);
return sensor_read(channel);
}
嗯,这里要注意:注释要和代码同步更新。我踩过这个坑——注释写的是旧逻辑,代码已经改了,结果后来的人按注释理解,出了 bug 查了半天。
知识体系总览
下面这张图,是我自己总结的代码风格核心框架。你可以把它当作写代码时的检查清单:
避坑指南
我曾经在一个项目里接手过一段代码,全局变量叫 g1、g2、g3……一共十几个。我花了整整两天才理清楚每个变量是干什么的。后来我重构时,把 g1 改成了 system_tick_count,g2 改成了 uart_rx_buffer_index——改完以后,整个团队都说好。
还有一次,我看到一段代码的注释写着「这里不要动,动了会出问题」。我心想这是什么鬼?后来发现是前人留下的坑,他自己也说不清为什么。这种注释,说白了就是「不负责任」。正确的做法是:写清楚为什么不能动,或者干脆把代码修好。
我的建议:每次提交代码前,花5分钟做一次「代码风格自检」——命名是否清晰?缩进是否对齐?注释是否准确?这5分钟,能省下后面5小时的排查时间。
总结
代码风格不是花架子,它是工程质量的基石。好的风格,能让代码自己说话;差的风格,再好的逻辑也会被埋没。
记住三句话:
- 命名:让名字替你说话
- 缩进:让结构替你说话
- 注释:让思路替你说话
做到这三点,你的代码就是别人眼中的「好代码」。
公众号:蓝海资料掘金营,微信 deep3321