这篇文章整理了一份适合项目协作的 C/C++ 代码规范,内容以现有团队规范为基础,并参考 Google C++ Style Guide。文末补充了统一的 Git 提交规范,方便在日常开发里直接套用。
一、命名规范
1. 变量
局部变量
1int i_am_a = 0;2static std::string i_am_b = "";全局变量
1int g_i_am_a = 0;2std::string g_i_am_b = "";类成员变量
1int _i_am_a;2static std::string _i_am_b;结构体成员变量
1int i_am_a;2static std::string i_am_b;2. 常量
1const int kIamConst = 1;2const int kUbuntu_20_04 = 1;说明:
- 常量使用
k前缀。 - 多单词采用大驼峰。
- 带版本或数字的命名可以直接保留数字段。
3. 枚举
1enum IamEnum2{3 kIamEnumA = 0,4 kIamEnumB,5};6
7enum class IamEnum8{9 kIamEnumA = 0,10 kIamEnumB,11};12
13enum class IamEnum : int14{15 kIamEnumA = 0,2 collapsed lines
16 kIamEnumB,17};4. 宏
1#define I_AM_MACRO_A 102#define I_AM_MACRO_B "i am b"3#define I_AM_MACRO_C(x) ...说明:
- 宏名全部大写。
- 单词之间使用下划线分隔。
- 能用
const、constexpr、内联函数替代时,优先不要用宏。
5. 结构体
1struct IamStruct2{3 int i_am_a;4 std::string i_am_b;5};6. 类
1class IamClass2{3public:4 IamClass(void);5 ~IamClass(void);6
7 int IamFuncA(int arg_a);8
9protected:10 std::string _i_am_a;11
12private:13 int _i_am_b;14 static std::string _i_am_c;15};7. 函数
1int IamFuncA(int i_am_a, const string& i_am_b);说明:
- 函数名使用大驼峰。
- 参数名使用小写加下划线。
- 引用或指针参数要能从命名和类型上体现输入输出语义。
8. 函数指针与回调
1typedef void (*FP_{FUNCTION_NAME})(int i_am_a, const string& i_am_b);2FP_{FUNCTION_NAME} fp_ptr; // Local variable3FP_{FUNCTION_NAME} _fp_ptr; // Member variable4FP_{FUNCTION_NAME} g_fp_ptr; // Global variable5
6typedef std::function<void(int i_am_a, const string& i_am_b)> FN_{FUNCTION_NAME};7FN_{FUNCTION_NAME} fn_ptr; // Local variable8FN_{FUNCTION_NAME} _fn_ptr; // Member variable9FN_{FUNCTION_NAME} g_fn_ptr; // Global variable9. 命名空间
1namespace mynamespace2{3...4namespace mysubnamespace5{6
7} // namespace mynamespace::mysubnamespace8...9} // namespace mynamespace10. 头文件保护
1#ifndef __[SYSTEM_NAME_ACRONYM]_[MOUDLE_NAME]_[HEADER_NAME]_H__2#define __[SYSTEM_NAME_ACRONYM]_[MOUDLE_NAME]_[HEADER_NAME]_H__3...4#endif // __[SYSTEM_NAME_ACRONYM]_[MOUDLE_NAME]_[HEADER_NAME]_H__二、注释规范
1. 文件头注释
1/** @file module_api.h2 * @brief Module API.3 * A module must implement the following APIs and be compiled as a shared library.4 * @author Ermazi Wang5 * @version 1.06 * @date 2012-01-017 * @copyright Heli Co., Ltd. All rights reserved.8 */2. 接口注释
外部调用接口,或者逻辑复杂的接口,尽量补充接口注释。
1/** @fn bool Init(const char* arg1, int& arg2)2 * @brief This function is the first one to be called before other APIs.3 * Module initialization should be completed in this function.4 * @param [in] arg1 Argument 1.5 * @param [in,out] arg2 Argument 2.6 * @return Result of module initialization.7 */8
9/** @fn void Uninit()10 * @brief This function will be called to perform module uninitialization11 * before exiting the module. It is a good chance to clean all data12 * structures here.13 * @return None14 */三、代码目录结构
1ExampleProject/2|-- src3|-- conf4|-- bin5|-- lib6|-- build7|-- doc8|-- CMakeLists.txt9`-- README.md建议:
src放源码。conf放配置。lib放第三方库或内部库。doc放文档。- 构建产物与源码分离,避免目录混乱。
四、编码建议
- 代码文件尽量不超过 1000 行。
- 函数尽量不超过 100 行。
- 函数参数个数尽量不超过 5 个。
- 圈复杂度尽量不超过 5。
- 统一使用 4 个空格缩进。
- 尽可能处理所有编译告警。
- 宁用组合,慎用继承。
- 不要堆叠过深的继承链。
- 不要写技巧性过强的代码。
- 能简单就不要复杂。
- 如非必要,不要增加新的抽象实体。
- 不要过度设计。
- 在可读性和扩展性之间做平衡。
- 可读性是代码质量的重要指标。
- 好的命名是可读性的核心组成部分。
- 及时重构,消除异味代码。
五、Git 提交规范
提交信息统一采用下面的格式:
1类型: 描述1. 类型定义
| 类型 | 含义 |
|---|---|
feat | 新功能 |
fix | 修复问题 |
refactor | 代码重构 |
docs | 文档修改 |
chore | 其他修改 |
2. 提交示例
1feat: 新增底盘控制2fix: 修复校验错误3refactor: 优化协议解析4docs: 更新说明文档5chore: 调整构建脚本3. 使用建议
- 一次提交尽量只做一类事情。
- 描述直接写结果,不写无意义词汇,例如“修改了一下”。
- 优先使用能体现业务变化或技术动作的短语。
- 文档、脚本、配置类调整不要混进功能提交。
六、落地建议
如果项目准备长期维护,这份规范至少要在三个位置保持一致:
- 仓库根目录的开发文档。
- 新成员入项说明。
- Code Review 和 Git 提交检查流程。
规范本身不是目的,降低协作成本、减少理解偏差、提升可维护性才是目的。只要团队已经约定,就要稳定执行,而不是每个模块各写一套风格。