第二章:变量命名规范

变量命名这事儿,看着简单,其实坑不少。我见过太多项目因为命名混乱,后期维护时让人抓狂。今天咱们就聊聊全局变量、局部变量、静态变量和常量该怎么命名。

2.1 全局变量:名字要醒目

全局变量作用域大,谁都能改。所以命名必须一眼就能看出来——这是个全局的!

核心原则:全局变量加前缀 g_g

// 好的做法
int g_system_tick;          // 系统滴答计数
uint32_t g_adc_value;       // ADC采样值
char g_log_buffer[256];     // 日志缓冲区

// 不好的做法
int tick;                   // 这是全局还是局部?
uint32_t adc;               // 完全看不出作用域

我个人习惯用 g_ 前缀。为什么?因为下划线让变量名更清晰。你想想看,g_system_tickgsystemtick 哪个好读?

小技巧:全局变量名要完整,别偷懒。比如 g_timer_countg_tmr_cnt 好得多。我在项目中吃过缩写太短的亏,后来查代码时自己都看不懂了。

2.2 局部变量:短小精悍

局部变量作用域小,命名可以短一些。但也不能太随意。

// 好的做法
void uart_send_data(uint8_t *data, uint16_t len)
{
    uint16_t i;              // 循环变量,短点没问题
    uint8_t temp;            // 临时变量
    uint16_t bytes_sent;     // 已发送字节数
}

// 不好的做法
void func(void)
{
    int a;                   // 这是干啥的?
    int b;                   // 完全没意义
}

局部变量命名有个原则:一眼能看出用途。循环用 ijk 没问题,但其他变量最好有含义。

注意:别在局部变量里用匈牙利命名法。比如 int nCount 这种,在嵌入式里反而显得多余。类型信息看定义就行,没必要写进名字里。

2.3 静态变量:区分文件内和函数内

静态变量分两种:文件内静态和函数内静态。命名规则也不一样。

类型 前缀 示例
文件内静态 s_static_ s_buffer_size
函数内静态 无前缀,按局部变量处理 call_count
// 文件内静态变量
static int s_device_count;          // 设备数量
static uint8_t s_rx_buffer[128];    // 接收缓冲区

// 函数内静态变量
void timer_isr(void)
{
    static uint32_t overflow_count = 0;  // 溢出次数
    overflow_count++;
}

嗯,这里要注意:函数内静态变量虽然作用域小,但生命周期长。命名时最好体现它的「持久性」。比如 call_countcnt 好,因为一看就知道是累计值。

2.4 常量:全大写加下划线

常量命名最简单,也最容易统一。全大写,单词间用下划线分隔。

// 宏定义常量
#define SYSTEM_CLOCK_HZ     72000000
#define UART_BAUD_RATE      115200
#define BUFFER_SIZE         256

// const 常量
const uint16_t ADC_REF_VOLTAGE = 3300;  // 单位mV
const float PI_VALUE = 3.14159f;

我曾经在项目里见过有人把常量写成小写,结果和变量混在一起,调试时找半天才发现是常量被改了。所以,常量命名必须和变量区分开。

我的习惯:枚举常量也用全大写。比如:

typedef enum {
    STATE_IDLE = 0,
    STATE_RUNNING,
    STATE_ERROR
} system_state_t;

这样在代码里看到 STATE_IDLE,一眼就知道是常量,不是变量。

2.5 命名风格统一:选一种,坚持用

嵌入式里常见的命名风格有三种:

  • 下划线风格: uart_send_datag_system_tick
  • 驼峰风格: uartSendDatagSystemTick
  • 匈牙利风格: nCountpBuffer(不推荐)

我个人推荐下划线风格。为什么?因为嵌入式代码里经常有寄存器名、硬件缩写,下划线风格更自然。比如 USART1_DRGPIOA_ODR,用驼峰反而别扭。

避坑指南:我曾经在一个项目里看到三种风格混用,结果查个bug要来回猜变量含义。团队必须统一风格,没有商量余地。

2.6 实战建议:命名检查清单

每次写代码前,问自己几个问题:

  1. 这个变量是全局的吗?加 g_ 了吗?
  2. 局部变量名能看出用途吗?
  3. 静态变量加 s_ 了吗?
  4. 常量全大写了吗?
  5. 风格和项目统一了吗?

说白了,命名规范不是为了好看,是为了让代码可维护。你想想看,半年后你自己回来看代码,如果命名清晰,能省多少时间?

总结一句话:变量名是代码的注释。好的命名,让代码自己说话。