算法第一章作业 代码规范

代码规范的本质是降低阅读成本、减少低级错误、方便团队协作。也让我们编程时减少出错。
所以我利用AI大模型和结合了自己编程经历总结了以下笔记:

一、命名规范

核心原则:见名知意,宁长勿短。
类型 风格 示例
变量 / 函数(C++、Java 常用) 小驼峰 camelCase studentScore、getUserInfo()

类 / 结构体 / 类型名 大驼峰 PascalCase StudentManager、LinkedList

常量 / 宏 全大写下划线 MAX_SIZE、PI

成员变量(可选前缀) m_ 或 _ m_count、_name

命名空间 / 包 全小写 namespace utils

布尔变量 is/has/can/should 开头 isValid、hasPermission

要点:

避免 a、b、tmp、data1、flag2 这类无意义命名;循环计数器 i/j/k 是例外,可以用。
函数名用动词或动宾结构:calculateTotal()、loadConfig();返回值语义明确的可用名词:isEmpty()。
不要和标准库/关键字重名(如 count、size、new、class),容易混淆甚至冲突。
缩写只用公认缩写:msg、idx、cfg、num;生僻缩写(usrPrfMgr)反而增加理解成本。
名字长度和作用域成正比:作用域越大,名字越要完整清晰。

二、格式规范

缩进统一:4 个空格(或统一用 Tab,但全项目只能一种),禁止空格与 Tab 混用。建议配 .editorconfig。
括号风格一致:for ( / while ( 左括号前加空格、不换行;if 条件后空格。

for (int i = 0; i < n; ++i) {
sum += arr[i];
}

空行分隔逻辑块:不同职责的代码段之间空一行;函数之间空一行;文件末尾留一个空行。
行宽限制:一般 80~120 字符,超长表达式换行并保持对齐缩进。
运算符两侧加空格:a = b + c、x < y;函数调用括号内侧不加空格:foo(a, b)。
一行一个语句,不要 int a = 1; int b = 2; 挤在一行。
用 clang-format / checkstyle 等工具自动格式化,别靠手工和争论。

三、注释规范

注释解释 Why(为什么这么做),而不是 What(这行在干什么)。

// 好:说明原因和约束
// 这里必须用稳定排序,否则相同分数的学生顺序会与上一次查询不一致
std::stable_sort(v.begin(), v.end(), cmp);

公共接口、类、复杂算法必须有文档注释(C++ 用 Doxygen 风格 /// 或 /** */),说明参数含义、返回值、异常、时间复杂度。
TODO / FIXME 要带责任人和说明:// TODO(zhangsan): 支持并发写入,2026-11 前完成。
注释要与代码同步更新,过期注释比没有注释更害人;被废弃的代码直接删除(有 Git 历史),不要注释掉一大片。
避免"翻译式注释"和无信息量的分隔线装饰。

四、函数与类设计规范

单一职责:一个函数只做一件事。函数名里出现 "and"、"or" 通常说明该拆了。
控制长度:函数建议 20~50 行内,超过 80 行考虑拆分;圈复杂度过高(大量嵌套 if/for)要重构。
参数尽量少(建议 ≤ 4 个),多参数用结构体封装;输出参数优先用返回值。
避免副作用:不要偷偷修改全局变量或入参(除非语义明确,如 swap)。
提前返回(guard clause)减少嵌套:

int divide(int a, int b) {
if (b == 0) return -1; // 先处理异常分支
return a / b;
}

DRY:重复三次以上的逻辑抽成函数或模板;但不要为了复用而过度抽象。
类设计遵循 SOLID,优先组合而非继承;成员尽量 private,通过接口暴露能力。
避免"上帝类"和超长工具类;模块间通过明确接口通信,减少循环依赖。

五、C++ 特有的规范与注意点

C++ 灵活但也最容易踩坑,以下建议参考 Google C++ Style Guide 与 C++ Core Guidelines:

  1. 头文件
    每个头文件加 include guard 或 #pragma once。
    include 顺序:本文件对应头文件 → C 标准库 → C++ 标准库 → 第三方库 → 项目内头文件,各组之间空行。
    不要在头文件中 using namespace std;,会污染所有包含者。

  2. 内存与资源
    优先用智能指针和标准容器,不要裸 new/delete:std::unique_ptr(独占)、std::shared_ptr(共享,慎用)、std::vector/std::string 代替裸数组和 C 字符串。
    遵循 RAII:资源在构造时获取、析构时释放(锁、文件句柄、socket 同理)。
    需要自定义析构时,考虑 Rule of Five / Zero(析构、拷贝构造、拷贝赋值、移动构造、移动赋值)。
    注意悬垂引用/指针:不要返回局部变量的引用或指针。

  3. 传参与 const
    小对象(int、指针、小 struct)按值传;大对象用 const T&;需要转移所有权用 T&& + std::move。
    不修改成员的函数标 const;不抛异常的标 noexcept(对性能与容器行为有影响)。

  4. 初始化与类型
    变量声明即初始化,使用 {} 列表初始化避免窄化转换。
    少用 C 风格强制转换,优先 static_cast / dynamic_cast / reinterpret_cast(最后者极少用);避免 const_cast。
    尽量用 auto 简化冗长类型,但不要牺牲可读性;注意 auto 会推导掉引用和 const。
    用 nullptr 而不是 NULL/0;用 enum class 而不是裸 enum。

  5. 其他易错点
    整数除法、有符号/无符号比较(int 与 size_t 比较会有警告和隐患)。
    数组越界、迭代器失效(容器扩容后原迭代器失效)。
    未初始化变量、= 与 == 混淆、switch 忘写 break。
    全局对象的初始化顺序问题,避免跨编译单元的全局依赖。
    多线程下共享数据必须加锁或使用原子类型,注意死锁(用 std::lock_guard/std::scoped_lock)。

  6. 现代特性
    在团队允许的 C++ 标准内(如 C++17/20)优先使用 std::optional、std::string_view、结构化绑定、constexpr、范围 for 等,减少手写易错代码。

六、错误处理与健壮性

明确错误传递方式:返回值 + 错误码、异常或 std::expected,一个项目内保持一致,不要混用。
异常只用于"真正异常"的情况,不要用异常做流程控制;捕获时捕获具体类型,不要 catch (...) 后什么都不做。
所有外部输入(用户输入、文件、网络、数据库)都要校验和边界检查。
关键操作失败要有日志(含上下文信息),便于排查;日志分级:DEBUG / INFO / WARN / ERROR。
不要吞掉错误,也不要向用户暴露内部堆栈或敏感信息。

七、开发流程中的注意事项

先设计再编码:明确需求、数据结构、接口和边界条件,画一下流程,比边写边改省时间。
小步提交:Git 提交粒度小、信息清晰(如 fix: 修复除零导致的崩溃),一个提交只做一件事;提交前自查 diff。
写测试:至少覆盖核心逻辑和边界情况(空输入、0、负数、极大值、重复数据);重构前先有测试兜底。
善用工具:clang-tidy / cppcheck 做静态检查,AddressSanitizer / Valgrind 查内存问题,编译器开 -Wall -Wextra -Werror。
Code Review:既看正确性也看可读性;评论对事不对人,被 review 时不要 defensive。
性能优化要有依据:先测量(profiler)再优化,避免过早优化;算法复杂度通常比微优化更重要。
安全底线:不硬编码密码密钥,防注入(SQL 参数化)、防越界(不用 strcpy/scanf 裸用),依赖库定期更新。
文档与可读性优先:代码主要给人读,顺便给机器执行;命名 + 结构清晰,比大量注释更有效。

八、一份自查清单
命名见名知意,风格与项目一致
缩进、括号、空行、行宽统一(已跑格式化工具)
注释解释"为什么",且与代码同步

一句话总结:命名让人看懂意图,格式让人快速扫读,注释解释决策原因,函数保持单一职责;在 C++ 中额外守住"资源管理(RAII + 智能指针)、const 正确性、避免未定义行为"这三条底线,再用格式化工具、静态检查和测试把规范固化下来,代码质量就会稳定提升。

posted @ 2026-10-01 20:51  Lssss177  阅读(3)  评论(0)    收藏  举报