第一章:引言与原则总览
为什么需要函数编写规范?
说实话,我刚开始做嵌入式开发那会儿,也觉得函数规范是件挺烦人的事。
代码能跑就行,管它怎么写呢?
直到有一次,我接手了一个同事离职留下的项目。那个项目里有个函数,足足写了800行。没有注释,变量名全是a、b、c、tmp。我花了整整三天才搞明白它到底在干什么。嗯,从那以后,我再也不敢轻视函数规范了。
你想想看,嵌入式开发跟普通软件开发不太一样。我们面对的是资源受限的MCU,是实时性要求极高的中断响应,是动不动就跑上几年的无人值守系统。一个写得乱七八糟的函数,可能带来的后果是什么?
- 内存泄漏——跑着跑着系统就挂了
- 栈溢出——函数嵌套太深,直接崩了
- 可读性差——三个月后你自己都看不懂
- 难以调试——出问题了根本找不到根因
我在项目中遇到过最惨的一次,就是因为一个函数没有做参数合法性检查,传进来一个空指针,结果整个产线停了两小时。老板的脸都绿了。
⚠️ 我曾经犯过的错: 以为"反正就我一个人维护,怎么写都行"。结果半年后项目交接,新同事看着我的代码直摇头。从那以后,我写每个函数都当它是给陌生人看的。
嵌入式C函数的黄金法则概述
经过这么多年的摸爬滚打,我总结出几条铁律。说白了,就是写嵌入式C函数时必须遵守的底线。
| 法则编号 | 法则名称 | 核心要点 |
|---|---|---|
| 法则一 | 单一职责 | 一个函数只做一件事 |
| 法则二 | 短小精悍 | 函数体不超过50行 |
| 法则三 | 参数可控 | 参数不超过4个,必须做合法性检查 |
| 法则四 | 命名自文档 | 看函数名就知道它干什么 |
| 法则五 | 避免全局变量 | 能用参数传递就别用全局变量 |
| 法则六 | 错误处理 | 每个函数都要有明确的错误返回 |
我个人习惯把这六条法则贴在工位上。每次写完一个函数,就对照着检查一遍。你可能会觉得,这也太严格了吧?
但我想说的是,嵌入式系统不像手机App,崩溃了重启就行。我们的代码跑在医疗设备上、跑在汽车ECU里、跑在工业控制器中。出一次问题,可能就是人命关天的事。
💡 我的经验之谈: 写函数规范不是为了装样子,而是为了降低出错的概率。每一条法则背后,都有无数个血淋淋的教训。
为什么是这六条?
你可能会问,市面上规范那么多,为什么偏偏选这六条?
原因很简单——这六条覆盖了嵌入式C函数最核心的痛点。
- 单一职责解决的是函数"太胖"的问题。我见过一个函数既做初始化又做数据处理还做错误恢复,这种函数神仙都难维护。
- 短小精悍解决的是可读性问题。人的大脑一次能处理的信息有限,超过50行的函数,理解成本直线上升。
- 参数可控解决的是接口稳定性问题。参数越多,调用方越容易出错。我建议最多4个,超过就考虑用结构体。
- 命名自文档解决的是注释依赖问题。好的函数名本身就是最好的注释。
- 避免全局变量解决的是耦合问题。全局变量是万恶之源,这话一点不夸张。
- 错误处理解决的是健壮性问题。嵌入式系统不能假设外部输入都是合法的。
📌 一个小技巧: 写函数前,先写它的调用示例。如果调用示例看起来别扭,那这个函数的设计大概率有问题。
好了,这一章我们先把总体的原则过一遍。后面的章节,我会逐一展开讲每一条法则的具体实践。包括怎么写、怎么检查、怎么重构。
记住一句话:函数是代码的最小单元,单元稳了,系统才能稳。
下一章,我们来聊聊"单一职责"——这个听起来简单,做起来最难的原则。