本文以车企嵌入式软件(C/C++)开发为背景,系统介绍代码命名的原则、原理与最佳实践。
一、命名的核心原则
1.1 清晰性原则 (Clarity)
原理:代码被阅读的次数远多于编写的次数。命名的首要目标是让读者快速理解代码意图。
cpp
// ❌ 不清晰:需要猜测含义
int x;
int val;
void proc();
// ✅ 清晰:一目了然
int engineRpm;
int batteryVoltage;
void StartEngine();
认知科学依据:人脑处理有意义的信息比处理抽象符号更高效。有意义的命名利用了"语义记忆",而非"工作记忆"。
1.2 一致性原则 (Consistency)
原理:相同的概念使用相同的命名模式,降低认知切换成本。
cpp
// ❌ 不一致:同一概念多种表达
int getSpeed();
int FetchRpm();
int retrieve_torque();
// ✅ 一致:统一风格
int GetSpeed();
int GetRpm();
int GetTorque();
心理学依据:一致性利用了"模式识别"能力,读者形成命名模式后可快速推断新代码含义。
1.3 简洁性原则 (Brevity)
原理:在保证清晰的前提下,尽量精简。过长的名字增加阅读负担。
cpp
// ❌ 过长:冗余信息
int theCurrentEngineRotationSpeedInRevolutionsPerMinute;
// ❌ 过短:信息丢失
int rpm;
// ✅ 适中:简洁且清晰
int engineRpm;
int m_EngineRpm; // 成员变量
黄金法则:名字长度与作用域成正比
- 循环变量:
i,j(作用域小) - 局部变量:
speed,count(中等作用域) - 成员变量:
m_EngineState,m_pCanBus(较大作用域) - 全局常量:
MAX_ENGINE_RPM,CAN_ID_ENGINE_STATUS(全局作用域)
1.4 无歧义原则 (Unambiguity)
原理:一个名字只有一种理解方式,避免多义词和容易混淆的缩写。
cpp
// ❌ 有歧义
int temp; // temperature 还是 temporary?
void check(); // 检查什么?返回什么?
int state; // 哪个状态?
// ✅ 无歧义
int coolantTemp; // 冷却液温度
bool IsEngineRunning(); // 检查引擎是否运行
EEngineState engineState; // 引擎状态
1.5 可搜索原则 (Searchability)
原理:好的命名应该便于在代码库中进行全局搜索和定位。避免使用过于通用或过于简短的名字。
cpp
// ❌ 难以搜索
int e; // 搜索 "e" 会匹配所有包含 e 的单词
int data; // 太通用,匹配过多
int 7; // 魔法数字,无法搜索其含义
// ✅ 易于搜索
int errorCount; // 搜索 "errorCount" 精确定位
int engineTemperature; // 搜索 "engineTemperature" 唯一匹配
const int MAX_RETRY_COUNT = 7; // 搜索 "MAX_RETRY_COUNT" 找到定义和所有使用
实践要点:
- 避免单字母变量 (循环变量
i,j,k除外)
cpp
// ❌ 单字母难以搜索
int s = GetSpeed();
int t = GetTemperature();
// ✅ 有意义的短名
int speed = GetSpeed();
int temp = GetCoolantTemperature();
- 使用命名常量替代魔法数字
cpp
// ❌ 魔法数字无法搜索其含义
if (rpm > 6000) { LimitFuel(); }
sleep(5000);
// ✅ 命名常量可搜索
#define ENGINE_RPM_REDLINE 6000
#define STARTUP_DELAY_MS 5000
if (rpm > ENGINE_RPM_REDLINE) { LimitFuel(); }
sleep(STARTUP_DELAY_MS);
- 模块前缀增强搜索精度
cpp
// ❌ 通用名称,搜索结果杂乱
int GetStatus();
void Reset();
// ✅ 模块前缀,搜索结果精确
int Engine_GetStatus();
void Engine_Reset();
int Battery_GetStatus();
void Battery_Reset();
- 避免过度缩写
cpp
// ❌ 过度缩写难以猜测和搜索
int engTmpSnsrVal;
void prcDtcEvt();
// ✅ 适度缩写,仍可搜索
int engineTempSensorValue;
void ProcessDtcEvent();
搜索友好度检验:命名完成后,问自己"如果我需要找到所有使用这个变量/函数的地方,搜索词是什么?能精确定位吗?"
二、匈牙利命名法与变体
2.1 匈牙利命名法原理
历史背景:由微软程序员 Charles Simonyi 发明,通过前缀表达变量的类型或用途。
分类:
- 系统匈牙利 (Systems Hungarian):前缀表示数据类型(如
iCount,szName) - 应用匈牙利 (Apps Hungarian):前缀表示语义类型(如
rwPosition表示行号,colPosition表示列号)
2.2 车企嵌入式常用前缀
| 前缀 | 含义 | 示例 |
|---|---|---|
m_ |
成员变量 (member) | m_EngineState, m_CurrentRpm |
m_p |
成员指针 | m_pCanBus, m_pSensorArray |
m_n |
成员整数 | m_nRetryCount, m_nErrorCode |
m_Is/Has/Can |
成员布尔 | m_IsRunning, m_HasFault, m_CanShift |
g_ |
全局变量 | g_SystemConfig, g_CanBusInstance |
s_ |
静态变量 | s_InstanceCount, s_DefaultConfig |
p |
指针 | pEngine, pCanFrame |
n |
整数/计数 | nWheelCount, nErrorCode |
b |
布尔值 | bIsValid, bHasData |
sz |
零结尾字符串 | szVehicleName, szErrorMsg |
arr |
数组 | arrSensorValues, arrCanFrames |
e |
枚举值 | eEngineState, eDriveMode |
cpp
// 成员变量示例
class Engine
{
private:
// 指针成员
ICanBus *m_pCanBus; // CAN总线接口指针
ISensor *m_pThrottleSensor; // 油门传感器指针
// 整数成员
int m_nCurrentRpm; // 当前转速
int m_nTargetRpm; // 目标转速
// 布尔成员
bool m_IsRunning; // 是否运行中
bool m_HasFault; // 是否有故障
// 枚举成员
EEngineState m_State; // 引擎状态
// 结构体/类成员
TEngineConfig m_Config; // 配置信息
};
三、变量命名规范
3.1 成员变量
规范 :m_ 前缀 + 帕斯卡命名
cpp
class Chassis
{
private:
// 基本类型
int m_CurrentSpeed; // 当前车速
double m_SteeringAngle; // 转向角度
// 指针类型:m_p 前缀
ICanBus *m_pCanBus;
IBrakeController *m_pBrakeCtrl;
// 布尔类型:m_Is/Has/Can 前缀
bool m_IsMoving;
bool m_HasAbsActive;
bool m_CanAccelerate;
// 容器类型
std::vector<TWheelInfo> m_WheelInfoList;
std::map<int, TSensorData> m_mapSensorById;
};
3.2 局部变量
规范:小写驼峰或匈牙利前缀
cpp
int ProcessCanFrame(const TCanFrame *pFrame)
{
// 简短局部变量
int ret = SYS_RET_OK;
int canId = pFrame->canId;
// 带类型提示的局部变量
int nFrameCount = 0;
bool bIsValid = false;
unsigned char *pData = pFrame->data;
// 迭代器
std::map<int, TEcuInfo>::iterator it;
std::map<int, TEcuInfo>::iterator itFound;
return ret;
}
3.3 全局变量与静态变量
规范 :g_ 或 s_ 前缀,谨慎使用
cpp
// 全局配置(只读)
static const TSystemConfig g_DefaultConfig = { /* ... */ };
// 模块级静态变量
static int s_InstanceCount = 0;
static TCanBus *s_pCanBusInstance = NULL;
// 全局变量(尽量避免)
TSystemContext g_SystemContext;
3.4 函数参数命名
规范:语义清晰,输入在前输出在后
cpp
// 输入参数
int Engine_SetThrottle(TEngineContext *pCtx, int throttlePercent);
// 输出参数:指针
int Sensor_ReadValue(int sensorId, int *pValue);
// 输入输出参数
int Buffer_Process(TCanBuffer *pBuffer); // pBuffer 被修改
// const 修饰只读参数
int CanFrame_Validate(const TCanFrame *pFrame);
四、常量与枚举命名规范
4.1 宏常量
规范:全大写 + 下划线分隔
cpp
// 数值常量
#define MAX_ENGINE_RPM 8000
#define MIN_BATTERY_VOLTAGE 9000 // mV
#define CAN_FRAME_MAX_DLC 8
// CAN ID 定义
#define CAN_ID_ENGINE_STATUS 0x100
#define CAN_ID_CHASSIS_CMD 0x200
#define CAN_ID_BATTERY_INFO 0x300
// 超时定义
#define TIMEOUT_ENGINE_START_MS 5000
#define TIMEOUT_CAN_RESPONSE_MS 100
// 模块前缀区分
#define ENGINE_MAX_CYLINDERS 12
#define CHASSIS_MAX_WHEELS 4
#define BATTERY_CELL_COUNT 96
4.2 枚举类型与值
规范 :类型用 E 前缀 + 帕斯卡,值用类型名前缀 + 全大写
cpp
// 引擎状态枚举
typedef enum
{
ENGINE_STATE_OFF = 0, // 关闭
ENGINE_STATE_CRANKING, // 启动中
ENGINE_STATE_IDLE, // 怠速
ENGINE_STATE_RUNNING, // 运行
ENGINE_STATE_STALL, // 熄火
ENGINE_STATE_FAULT, // 故障
ENGINE_STATE_COUNT // 计数(边界检查用)
} EEngineState;
// 驾驶模式枚举
typedef enum
{
DRIVE_MODE_ECO = 0, // 经济模式
DRIVE_MODE_COMFORT, // 舒适模式
DRIVE_MODE_SPORT, // 运动模式
DRIVE_MODE_RACE, // 赛道模式
DRIVE_MODE_COUNT
} EDriveMode;
// 仪表盘命令枚举
typedef enum
{
DASHBOARD_CMD_GET_SPEED = 0x01,
DASHBOARD_CMD_GET_RPM = 0x02,
DASHBOARD_CMD_SET_TRIP = 0x10,
DASHBOARD_CMD_RESET = 0xFF
} EDashboardCmd;
4.3 const 常量(C++)
规范 :与宏常量相同风格,或使用 k 前缀
cpp
// 命名空间内的常量
namespace EngineConstants
{
const int MAX_RPM = 8000;
const int IDLE_RPM = 800;
const double FUEL_FACTOR = 0.001;
}
// 类内静态常量
class Engine
{
public:
static const int MAX_THROTTLE = 100;
static const int MIN_THROTTLE = 0;
private:
static const char *MODULE_NAME;
};
const char *Engine::MODULE_NAME = "Engine";
五、函数命名规范
5.1 命名模式
规范:动词 + 宾语,帕斯卡命名法
| 操作类型 | 命名模式 | 示例 |
|---|---|---|
| 获取值 | Get + 名词 |
GetEngineRpm(), GetBatteryVoltage() |
| 设置值 | Set + 名词 |
SetThrottlePosition(), SetTargetSpeed() |
| 判断状态 | Is/Has/Can + 形容词/名词 |
IsEngineRunning(), HasDtcFault(), CanShiftGear() |
| 执行动作 | 动词 + 宾语 | StartEngine(), ApplyBrake(), SendCanFrame() |
| 计算值 | Calculate/Compute + 名词 |
CalculateFuelRate(), ComputeSteeringAngle() |
| 初始化 | Init/Initialize |
InitCanController(), InitializeSensorArray() |
| 创建/销毁 | Create/Destroy |
CreateEngineContext(), DestroyCanBuffer() |
| 验证 | Validate/Check |
ValidateCanFrame(), CheckSensorRange() |
| 转换 | Convert/Parse |
ConvertRpmToSpeed(), ParseDtcCode() |
| 注册/注销 | Register/Unregister |
RegisterCallback(), UnregisterObserver() |
5.2 模块化函数命名(C风格)
规范:模块前缀 + 下划线 + 操作名
cpp
// Engine 模块
int Engine_Create(TEngineContext **ppCtx);
int Engine_Destroy(TEngineContext *pCtx);
int Engine_Initialize(TEngineContext *pCtx, const TEngineConfig *pConfig);
int Engine_Start(TEngineContext *pCtx);
int Engine_Stop(TEngineContext *pCtx);
int Engine_GetRpm(TEngineContext *pCtx);
int Engine_SetThrottle(TEngineContext *pCtx, int percent);
bool Engine_IsRunning(TEngineContext *pCtx);
// Chassis 模块
int Chassis_Create(TChassisContext **ppCtx);
int Chassis_ApplyBrake(TChassisContext *pCtx, int force);
int Chassis_GetSpeed(TChassisContext *pCtx);
int Chassis_SetSteeringAngle(TChassisContext *pCtx, double angle);
// CanBus 模块
int CanBus_Open(TCanBusContext **ppCtx, const TCanConfig *pConfig);
int CanBus_Close(TCanBusContext *pCtx);
int CanBus_Send(TCanBusContext *pCtx, const TCanFrame *pFrame);
int CanBus_Receive(TCanBusContext *pCtx, TCanFrame *pFrame, int timeoutMs);
5.3 回调函数命名
规范 :On + 事件名 或 PFN_ + 描述
cpp
// 回调函数类型定义
typedef void (*PFN_OnCanFrameReceived)(const TCanFrame *pFrame, void *pUserData);
typedef void (*PFN_OnDtcFault)(int dtcCode, int severity, void *pUserData);
typedef int (*PFN_TimeoutHandler)(int timerId, void *pUserData);
// 回调函数实现
void OnEngineStateChanged(EEngineState oldState, EEngineState newState, void *pUserData);
void OnCanFrameReceived(const TCanFrame *pFrame, void *pUserData);
void OnBatteryLowVoltage(int voltage, void *pUserData);
5.4 事件处理函数命名
规范 :On + 事件源 + 事件类型
cpp
// 事件处理函数
void OnTimerExpired(int timerId);
void OnCanMessageReceived(const TCanFrame *pFrame);
void OnSensorDataReady(int sensorId, const TSensorData *pData);
void OnEngineStartComplete(EEngineState state);
void OnFaultDetected(const TDtcInfo *pFault);
六、类与结构体命名规范
6.1 类名
规范:帕斯卡命名,名词或名词短语
cpp
// 业务类
class Engine;
class Chassis;
class BatteryManager;
// 管理器类
class BrakeCtrlManager;
class SensorManager;
class CanBusManager;
// 事件类
class TimerExpiredEvent;
class CanMessageEvent;
class FaultEvent;
// 实现类
class RadarDefaultImpl;
class DashboardDefaultImpl;
6.2 接口类
规范 :I 前缀 + 帕斯卡命名
cpp
// 接口定义
class IEngine
{
public:
virtual ~IEngine() {}
virtual int Start() = 0;
virtual int Stop() = 0;
virtual int GetRpm() const = 0;
virtual bool IsRunning() const = 0;
};
class ICanBus
{
public:
virtual ~ICanBus() {}
virtual int Send(const TCanFrame *pFrame) = 0;
virtual int Receive(TCanFrame *pFrame, int timeoutMs) = 0;
};
class ISensor
{
public:
virtual ~ISensor() {}
virtual int ReadValue(int *pValue) = 0;
virtual bool IsOnline() const = 0;
};
6.3 结构体
规范 :T 前缀 + 帕斯卡命名
cpp
// 数据传输结构
typedef struct
{
int speed;
int rpm;
int gear;
} TWheelSpeed;
typedef struct
{
unsigned char status;
int errorCode;
} TEngStatus;
typedef struct
{
uint32_t canId;
uint8_t dlc;
uint8_t data[8];
} TCanFrame;
// 配置结构
typedef struct
{
int maxRpm;
int idleRpm;
int cylinders;
} TEngineConfig;
// 事件类型
typedef CEvent<TReqThrottleAdj> TReqThrottleAdjEvent;
七、常用数据结构命名规范
7.1 数组与向量
规范 :arr 前缀或 List 后缀,使用复数名词
cpp
// 固定数组
int arrSensorValues[MAX_SENSOR_COUNT];
TWheelInfo arrWheelInfo[4];
// 动态向量
std::vector<TEcuInfo> ecuInfoList;
std::vector<TCanFrame> pendingFrameList;
// 成员变量
class VehicleManager
{
private:
std::vector<TSensorInfo> m_SensorList;
int m_arrPriorities[8];
};
7.2 映射表与集合
规范 :map 前缀 + ByKey 后缀,或 set 前缀
cpp
// 映射
std::map<int, TSensorInfo> m_mapSensorById;
std::map<std::string, IHandler *> m_mapHandlerByName;
std::map<int, std::string> ecuNameById;
// 集合
std::set<int> m_setRegisteredEcuIds;
std::set<std::string> m_setActiveSensors;
7.3 栈与队列
规范 :stack 或 queue 前缀,体现数据结构特性
cpp
// 栈
std::stack<TGearAction> m_stackUndoOps;
std::stack<int> m_stackStateHistory;
// 队列
std::queue<TCanFrame> m_queuePendingFrames;
std::queue<TDiagTask> m_queueDiagTasks;
// 优先队列
std::priority_queue<TFaultEvent> faultEventQueue;
7.4 数据结构命名速查表
| 数据结构 | 成员变量前缀 | 局部变量风格 | 示例 |
|---|---|---|---|
| 数组 | m_arr |
arrXxx / 复数名词 |
m_arrPriorities, sensorValues |
| 向量 | m_ + List 后缀 |
复数名词 / XxxList |
m_SensorList, frameList |
| 映射表 | m_map |
xxxByKey |
m_mapSensorById, ecuNameById |
| 集合 | m_set |
uniqueXxx / xxxSet |
m_setRegisteredIds, validStates |
| 栈 | m_stack |
xxxStack |
m_stackUndoOps, stateStack |
| 队列 | m_queue |
xxxQueue |
m_queuePendingFrames, taskQueue |
八、文件命名规范
8.1 头文件与源文件
规范:帕斯卡命名,与主类名一致
✅ 正确示例
├── Engine.h // 类 Engine 的声明
├── Engine.cpp // 类 Engine 的实现
├── EngFsm.h // 类 EngFsm 的声明
├── EngFsm.cpp // 类 EngFsm 的实现
├── BrakeCtrlManager.h
└── BrakeCtrlManager.cpp
❌ 错误示例
├── engine.h // 应帕斯卡
├── eng_fsm.h // 应帕斯卡无下划线
└── brakeCtrl.cpp // 应完整
8.2 Include Guard
规范:全大写 + 下划线,与路径对应
cpp
// 文件: Module/Business/Chassis/Chassis.h
#ifndef MODULE_BUSINESS_CHASSIS_H_
#define MODULE_BUSINESS_CHASSIS_H_
// ... 内容 ...
#endif /* MODULE_BUSINESS_CHASSIS_H_ */
8.3 目录命名
规范:帕斯卡命名
/
├── Module/
│ ├── Engine/
│ └── Chassis/
├── Units/
│ ├── ECU/
│ ├── CAN/
│ └── OBD/
└── ...
九、命名的认知科学原理
9.1 工作记忆限制
原理:人类工作记忆容量约 7±2 个项目
应用:
- 名字长度适中(3-5 个单词)
- 使用有意义的缩写减少认知负担
cpp
// ✅ 适中长度
m_pCanBus // 4 个语义单元
m_EngFsm // 3 个语义单元
// ❌ 过长
m_pInternalCanBusForEngine // 太长
9.2 模式识别
原理:人脑善于识别模式,一致的命名模式降低认知成本
应用:
cpp
// 一致的模式便于识别
m_IsReady → 布尔成员
m_pProxy → 指针成员
OnEvent() → 事件处理
Initialize() → 初始化方法
9.3 上下文推断
原理:名字含义依赖上下文,适当的冗余提高独立可读性
cpp
// 类上下文中,适度简化
class Engine
{
void Start(); // ✅ 上下文明确:启动引擎
};
// 全局函数,需要更明确
void StartEngine(); // ✅ 无上下文需完整
十、命名反模式(Anti-Patterns)
10.1 避免的命名方式
| 反模式 | 问题 | 正确做法 |
|---|---|---|
data, info, temp |
语义模糊 | 描述具体内容 |
flag, status |
不够具体 | m_IsConnected, m_EngState |
doSomething |
太宽泛 | 具体描述操作 |
handle1, handle2 |
数字后缀 | 使用语义区分 |
myVariable |
my 无意义 |
去掉 my |
theManager |
the 冗余 |
直接用 Manager |
10.2 缩写使用原则
允许的缩写(广泛认可):
| 缩写 | 全称 | 示例 |
|---|---|---|
Eng |
Engine | EngFsm, m_EngMode |
Fsm |
Finite State Machine | BuildFsm() |
Msg |
Message | TReqThrottleAdjMsg |
Ptr |
Pointer | m_pCanBus |
Id |
Identifier | m_TimerId |
Evt |
Event | evt, TimerExpEvt |
Rpm |
Revolutions Per Minute | GetRpm() |
Cfg |
Configuration | LoadCfg() |
Ret |
Return | ret = SYS_RET_OK |
Err |
Error | m_LastErr |
Cmd |
Command | DASHBOARD_CMD_GET_INFO |
Ctx |
Context | pCtx, TEngineContext |
Dtc |
Diagnostic Trouble Code | TDtcInfo |
Ecu |
Electronic Control Unit | TEcuStatus |
禁止的缩写(造成歧义):
cnt→ 用countflg→ 用flag或更具体名称val→ 用value或具体含义btn→ 用button
十一、总结:命名检查清单
11.1 变量命名检查
- 成员变量是否有
m_前缀? - 指针成员是否有
m_p前缀? - 布尔成员是否有
m_Is/Has/Can前缀? - 局部变量是否简短但有意义?
- 指针星号是否贴近类型?
11.2 常量命名检查
- 宏常量是否全大写下划线分隔?
- 枚举常量是否有类型前缀?
- 常量名是否能表达其用途?
11.3 函数命名检查
- 函数名是否为帕斯卡命名?
- 函数名是否以动词开头?
- 布尔函数是否用
Is/Has/Can?
11.4 类型命名检查
- 类名是否为帕斯卡命名?
- 接口类是否有
I前缀? - 结构体是否有
T前缀? - 枚举类型是否有
E前缀?
11.5 文件命名检查
- 文件名是否与主类名一致?
- Include Guard 是否与路径对应?
- 目录名是否为帕斯卡命名?
十二、如何起一个好名字
12.1 起名的思维过程
第一步:明确"它是什么"
cpp
// ❌ 先写代码再起名
int x = calculate();
// ✅ 先思考再命名
// 问:这个值代表什么?答:剩余重试次数
int remainingRetryCount = CalculateRemainingRetries();
第二步:选择合适的词汇
| 场景 | 推荐词汇 | 避免词汇 |
|---|---|---|
| 获取值 | Get, Fetch, Retrieve, Query |
Take, Grab |
| 设置值 | Set, Update, Assign, Configure |
Put, Change |
| 创建对象 | Create, Build, Make, Generate |
New, Produce |
| 销毁对象 | Destroy, Delete, Remove, Clear |
Kill, Erase |
| 检查条件 | Is, Has, Can, Should, Check |
Test, Verify |
| 转换类型 | Convert, Transform, Parse, Format |
Change, Make |
| 计算值 | Calculate, Compute, Evaluate |
Do, Process |
第三步:组合成完整名称
名称 = [前缀] + [形容词/修饰语] + [核心名词/动词] + [后缀]
示例分解:
cpp
m_pCanBusProxy
├── m_ → 成员变量前缀
├── p → 指针前缀
├── CanBus → 修饰语(CAN 总线)
└── Proxy → 核心名词(代理)
12.2 好名字的特征
| 特征 | 说明 | 好例子 | 坏例子 |
|---|---|---|---|
| 准确 | 精确描述用途 | m_EngineState |
m_state |
| 具体 | 避免模糊词汇 | sensorCount |
data |
| 简洁 | 不冗余啰嗦 | SendFrame |
SendFrameToReceiver |
| 一致 | 风格统一 | GetX, GetY, GetZ |
GetX, fetchY, retrieve_z |
| 可发音 | 能读出来 | customerName |
cstmrNm |
| 可搜索 | 便于全局搜索 | MAX_RETRY_COUNT |
MRC |
| 无歧义 | 只有一种理解 | isEngineRunning |
check |
12.3 命名的黄金法则
法则一:用业务语言,不用技术语言
cpp
// ❌ 技术语言
std::map<int, std::string> intStringMap;
// ✅ 业务语言
std::map<int, std::string> sensorNameById;
法则二:让代码读起来像英文句子
cpp
// ✅ 读起来流畅
if (engine.IsRunning() && battery.HasSufficientCharge())
{
chassis.EnableCruiseControl();
}
// ❌ 难以理解
if (engine.Check() && battery.Val(1))
{
chassis.Do();
}
法则三:名字长度与作用域成正比
cpp
// 循环变量:短
for (int i = 0; i < 10; i++) { }
// 局部变量:适中
int retryCount = 0;
// 成员变量:完整
ICanBus *m_pCanBus;
// 全局常量:完整 + 前缀
#define CONFIG_MAX_CONNECTION_RETRY_COUNT 3
法则四:避免否定命名
cpp
// ❌ 双重否定难理解
if (!isNotReady) { }
// ✅ 使用肯定形式
if (isReady) { }
法则五:使用对称命名
| 操作 | 对称词 |
|---|---|
Open |
Close |
Start |
Stop |
Begin |
End |
Create |
Destroy |
Add |
Remove |
Insert |
Delete |
Push |
Pop |
Get |
Set |
Read |
Write |
Lock |
Unlock |
Show |
Hide |
Enable |
Disable |
Attach |
Detach |
Connect |
Disconnect |
总结
好的命名是代码的灵魂!这份专为嵌入式C/C++开发打造的命名规范,核心围绕清晰、一致、简洁、无歧义、可搜索五大原则,从变量、常量、函数到类 / 文件命名,给出全套最佳实践:
✅ 匈牙利命名法变体:m_/g_/s_前缀区分变量作用域,p/n/b 前缀标识类型
✅ 命名黄金法则:长度与作用域成正比,用业务语言、肯定式命名,避免魔法数字和过度缩写
✅ 反模式避坑:拒绝 data/temp/flag 等模糊命名,统一帕斯卡 / 驼峰风格
✅ 认知科学支撑:贴合人脑模式识别、工作记忆特性,让代码易读、易搜、易维护
好命名让代码自解释,这份规范值得嵌入式开发者收藏践行!