50、代码风格:命名规范、缩进风格与注释规范的一致性

说实话,代码风格这事儿,我年轻的时候觉得特别虚。

那时候我心想:能跑不就行了?管你变量叫 a 还是叫 b,编译器又不挑。直到有一次,我接手了一个离职同事的项目——好家伙,那代码写得跟加密文件似的。函数名全是 f1、f2、f3,缩进一会儿用空格一会儿用 Tab,注释倒是不少,但全是「// 这里加1」「// 这里减1」这种废话。

我花了整整三天才理清楚一个模块的逻辑。从那以后,我再也不敢小看代码风格了。

核心观点:代码风格不是给机器看的,是给人看的。而人,最怕的就是不一致。

命名规范:名字就是最好的注释

我个人习惯,命名要遵循三个原则:见名知意、风格统一、团队共识

什么叫见名知意?你看这个:

// 糟糕的命名
int a;
int b;
int c;
void func1(void);
void func2(void);

// 好的命名
int led_status;
int temperature_value;
int error_code;
void led_turn_on(void);
void temperature_read(void);

嗯,差别很明显吧?

我见过最离谱的命名,是一个全局变量叫 g_abc。我追了三个文件才搞清楚,原来「abc」是「Analog Battery Check」的缩写。你想想看,这种命名除了原作者,谁能猜得出来?

常见的命名风格

风格 示例 适用场景
蛇形命名法(snake_case) led_status 变量、函数(C语言主流)
驼峰命名法(camelCase) ledStatus 部分嵌入式库、C++
帕斯卡命名法(PascalCase) LedStatus 类型名、结构体、枚举
全大写加下划线 LED_STATUS_OK 宏定义、枚举常量

我的建议:在一个项目中,只选一种风格,从头用到尾。混用是最要命的。我曾经在一个项目里看到 snake_case 和 camelCase 混着用,同一个文件里变量叫 motor_speed,函数却叫 motorSpeedGet()——你说这代码能好维护吗?

缩进风格:别让 Tab 和空格打架

缩进这事儿,说白了就是「视觉对齐」。但就是这点小事,能让团队吵翻天。

我经历过最经典的场景:一个同事用 Tab 缩进,另一个用 4 个空格。两个人改了同一个文件,提交之后,代码全乱了。为什么?因为不同编辑器对 Tab 的解析不一样。有的 Tab 等于 4 个空格,有的等于 8 个。

警告:永远不要在一个项目中混用 Tab 和空格。要么全用 Tab,要么全用空格。我个人推荐用 4 个空格,因为它在任何编辑器里看起来都一样。

常见的缩进风格

  • K&R 风格:大括号跟在语句后面,不换行。C 语言最主流。
  • Allman 风格:大括号单独占一行。可读性更好。
  • GNU 风格:缩进更深,代码层次更清晰,但占空间。

看个对比:

// K&R 风格(我常用的)
if (condition) {
    do_something();
    do_another();
}

// Allman 风格
if (condition)
{
    do_something();
    do_another();
}

两种风格没有绝对的好坏。关键是——团队统一。我在一个项目里见过两种风格混着写,那感觉就像看一本书,前半本是宋体,后半本是楷体,别扭得很。

注释规范:写给人看的,不是写给编译器看的

注释这件事,我踩过不少坑。

刚入行的时候,我觉得注释越多越好。每个变量都写注释,每行代码都写注释。结果呢?代码改了,注释没改,反而误导人。

后来我明白了:好的代码自己会说话,注释是用来解释「为什么」的,不是用来解释「是什么」的。

注释的黄金法则

  1. 解释意图,而不是重复代码
  2. 更新代码时同步更新注释
  3. 不要写废话注释

看个例子:

// 糟糕的注释
i = i + 1;  // 把 i 加 1

// 好的注释
i = i + 1;  // 跳过 CRC 校验字节,因为硬件自动填充了

看出区别了吗?好的注释告诉你「为什么这么做」,而不是「做了什么」。

避坑指南:我曾经在一个驱动文件里看到这样的注释:「以下代码不要删,删了会报错。」——你猜后来怎么着?没人敢动那段代码,结果里面藏了一个 bug,整整藏了两年。所以,注释要写清楚原因,而不是写一句吓人的话。

文件头注释模板

我个人习惯,每个源文件和头文件都要加文件头注释,格式如下:

/**
 * @file    led_driver.c
 * @brief   LED 驱动模块,控制板载指示灯
 * @author  张三
 * @date    2024-01-15
 * @note    依赖 gpio.h,使用前需调用 led_init()
 */

这种注释的好处是:别人一看就知道这个文件是干嘛的,谁写的,什么时候写的,有什么依赖。

一致性:风格统一才是王道

说了这么多,其实核心就一句话:一致性比风格本身更重要。

你想想看,一个团队里,有人用 K&R 风格,有人用 Allman 风格,有人用 2 空格缩进,有人用 4 空格缩进,变量命名有的用 snake_case,有的用 camelCase——这代码还能看吗?

我建议的做法是:

  • 项目启动前,先定好编码规范文档
  • 用 clang-format 或类似工具自动格式化代码
  • Code Review 时把风格问题作为检查项

小技巧:很多团队会用 .clang-format 配置文件,把它放在项目根目录。这样每个人用 IDE 格式化代码时,结果都是一样的。省去了很多扯皮的功夫。

知识体系结构图

下面这张图,帮你理清代码风格的几个核心维度:

代码风格一致性 命名规范 缩进风格 注释规范 蛇形命名法(snake_case) 驼峰命名法(camelCase) 帕斯卡命名法(PascalCase) 全大写 + 下划线(宏/枚举) K&R 风格(大括号不换行) Allman 风格(大括号换行) GNU 风格(深层缩进) Tab vs 空格(统一即可) 解释意图,而非重复代码 文件头注释(作者/日期/功能) 函数注释(参数/返回值/说明) 代码修改时同步更新注释

总结一下

代码风格这件事,说白了就是「约定」。没有绝对的对错,只有统一与混乱的区别。

我见过最舒服的代码,是那种打开文件一看,命名风格统一、缩进整齐、注释恰到好处的代码。读这种代码,就像跟一个思路清晰的人聊天,顺畅得很。

反过来,那种风格混乱的代码,读起来就像在迷宫里找路,每一步都提心吊胆。

所以,我的建议很简单:定好规矩,用工具执行,Code Review 把关。 做到这三点,代码风格就不会成为团队的痛点。

最后说一句:代码是写给人看的,顺便给机器执行。别让你的代码变成「一次性加密文本」——因为总有一天,你自己也要回来读它。


公众号:蓝海资料掘金营,微信deep3321