第二章:变量命名规范
变量命名这事儿,看着简单,其实坑不少。我见过太多项目因为命名混乱,后期维护时让人抓狂。今天咱们就聊聊全局变量、局部变量、静态变量和常量该怎么命名。
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_tick 和 gsystemtick 哪个好读?
小技巧:全局变量名要完整,别偷懒。比如 g_timer_count 比 g_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; // 完全没意义
}
局部变量命名有个原则:一眼能看出用途。循环用 i、j、k 没问题,但其他变量最好有含义。
注意:别在局部变量里用匈牙利命名法。比如 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_count 比 cnt 好,因为一看就知道是累计值。
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_data、g_system_tick - 驼峰风格:
uartSendData、gSystemTick - 匈牙利风格:
nCount、pBuffer(不推荐)
我个人推荐下划线风格。为什么?因为嵌入式代码里经常有寄存器名、硬件缩写,下划线风格更自然。比如 USART1_DR、GPIOA_ODR,用驼峰反而别扭。
避坑指南:我曾经在一个项目里看到三种风格混用,结果查个bug要来回猜变量含义。团队必须统一风格,没有商量余地。
2.6 实战建议:命名检查清单
每次写代码前,问自己几个问题:
- 这个变量是全局的吗?加
g_了吗? - 局部变量名能看出用途吗?
- 静态变量加
s_了吗? - 常量全大写了吗?
- 风格和项目统一了吗?
说白了,命名规范不是为了好看,是为了让代码可维护。你想想看,半年后你自己回来看代码,如果命名清晰,能省多少时间?
总结一句话:变量名是代码的注释。好的命名,让代码自己说话。