1. 注释的本质:为什么说注释是写给人的,不是写给机器的?代码即文档的误区。
我刚入行那会儿,有个老前辈跟我说过一句话,到现在我都记得特别清楚——「编译器根本不在乎你写了什么注释,它只在乎你的代码能不能跑。」
这话糙,理不糙。你想想看,我们写注释是为了什么?是为了让机器看懂吗?显然不是。机器只认0和1,只认语法树,只认指令集。你写再多注释,编译器编译的时候一个字节都不会带进去。注释,从头到尾,都是写给人看的。
1.1 注释的「人本」属性
说白了,注释就是代码里的「人话」。代码是写给机器执行的,注释是写给人类理解的。这两者的目标完全不同。
- 代码:告诉机器「做什么」以及「怎么做」
- 注释:告诉下一个开发者「为什么这么做」以及「这里有什么坑」
我见过太多人把注释写成「代码的翻译机」——变量a加1,他就写个「将a加1」。这种注释,说实话,不如不写。因为看代码的人自己就能看懂a++是什么意思,你写个注释反而浪费了别人的时间。
核心观点:好的注释回答的是「为什么」,而不是「是什么」。
1.2 「代码即文档」的陷阱
「代码即文档」这个口号,在嵌入式圈子里特别流行。我承认,这个理念有它的道理——代码本身应该足够清晰,让人读起来就能理解逻辑。但问题是,很多人把这个理念理解偏了。
他们觉得:「既然代码就是文档,那我就不用写注释了。」
嗯,这里要注意。代码能表达「做了什么」,但它很难表达「为什么这么做」。举个例子:
// 错误示范:注释只是翻译代码
// 将定时器计数值加1
timer_count++;
这种注释,就是典型的「代码即文档」的受害者。他以为写了注释,其实什么都没说。
那好的注释应该是什么样的?
// 正确示范:注释解释「为什么」
// 这里用软件计数而不是硬件定时器,是因为硬件定时器资源不够了
// 而且这个计数的精度要求不高,允许±10ms的误差
timer_count++;
你看,这才是注释该有的样子。它告诉后来者:为什么不用硬件方案?因为资源不够。为什么软件方案可行?因为精度要求不高。
我曾经踩过的坑:有一次接手一个项目,前任工程师信奉「代码即文档」,整个工程几乎没有注释。我花了整整三天才理清楚一个中断服务程序的逻辑。后来发现,里面有一个延时操作是为了等待外部芯片的电源稳定——这个信息,代码本身根本表达不出来。
1.3 注释的「保质期」问题
还有一个常见的误区,就是觉得注释写一次就完事了。我告诉你,注释是有「保质期」的。
代码在迭代,逻辑在变化,但注释不会自动更新。你改了一段逻辑,忘了改注释,那注释就成了「误导信息」。比没有注释更可怕的是错误的注释——它会让你在调试的时候走弯路,而且走得特别自信。
| 注释状态 | 对开发者的影响 | 我的建议 |
|---|---|---|
| 没有注释 | 需要花时间读代码理解逻辑 | 至少写关键逻辑的注释 |
| 有正确的注释 | 快速理解设计意图 | 保持更新,与代码同步 |
| 有错误的注释 | 被误导,浪费大量时间 | 立即修正或删除 |
我个人习惯是:每次修改代码的时候,顺手看一眼相关的注释。如果注释和代码对不上,要么改注释,要么删注释。千万别留着,留着就是埋雷。
1.4 注释的「读者」是谁?
写注释之前,先想清楚一个问题:这段注释是写给谁看的?
- 写给未来的自己:三个月后你回来看这段代码,还能不能想起来当时的思路?
- 写给接手你代码的同事:他能不能通过注释快速上手?
- 写给代码审查的人:他能不能通过注释理解你的设计决策?
我自己的经验是:写注释的时候,假设读者是一个水平和你差不多、但对这个模块完全不了解的人。你不需要解释基础语法,但需要解释那些「不显而易见的」东西。
一个小技巧:写完一段注释之后,问自己一个问题——「如果删掉这段注释,只看代码,我还能不能理解同样的信息?」如果答案是「能」,那这段注释就是多余的。
1.5 总结一下
注释的本质,说白了就是「用人类语言记录设计意图」。它不是写给编译器的,是写给人的。代码即文档这个理念,出发点是好的,但千万别走极端——代码能表达逻辑,但表达不了上下文、约束条件和历史原因。
我做了这么多年嵌入式开发,见过因为注释缺失导致项目延期,也见过因为注释错误导致线上事故。注释这件事,看似简单,其实挺考验工程师的责任心。
记住一句话:注释不是代码的附属品,而是代码的说明书。没有说明书的代码,就像没有图纸的电路板——能跑,但没人敢动。