嵌入式开发命名约定

11 篇文章 0 订阅

c/c++程序风格约定

文/Mike

往往我们做单片机程序开发的时候,很少去注意程序的架构和命名规范,然而只要是涉及到代码开发,这都是不可回避的问题,很多小公司做嵌入式的开发,在技术上没有传承性,项目总是因人而异。很多较大型的代码写到最后总是捂不住各种冒出来的bug,其实最大的问题是根基没有打牢。当然,主要是程序架构的问题,架构的清晰性,程序的可读性,可维护性,模块化都是需要设计和约定的。复杂的事,困难的事都是可以分解为简单的小事的。
本文档,简要约定C/C++的相关命名规范,参照了《google开源项目风格指南》,然而文档全面的而庞杂的命名规则,很容易让人记不住,其实在嵌入式开发的过程中,我们只需要记住几个最核心的,代码风格就会立马转变。用20%的内容可以提高80%的代码质量。主要是变量命名、结构体命名、文件命名、函数命名、枚举命名等。

1、命名规则

总述

函数命名, 变量命名, 文件命名要有描述性,少用缩写。
尽可能使用描述性的命名, 别心疼空间, 毕竟相比之下让代码易于新读者理解更重要. 不要用只有项目开发者能理解的缩写, 也不要通过砍掉几个字母来缩写单词。

示例

  • 示例(好):
int price_count_reader;    // 无缩写
int num_errors;            // "num" 是一个常见的写法
int num_dns_connections;   // 人人都知道 "DNS" 是什么

  • 示例(差):
int n;                     // 毫无意义.
int nerr;                  // 含糊不清的缩写.
int n_comp_conns;          // 含糊不清的缩写.
int wgc_connections;       // 只有贵团队知道是什么意思.
int pc_reader;             // "pc" 有太多可能的解释了.
int cstmr_id;              // 删减了若干字母.

1.1、 文件命名

总述

文件名要全部小写, 可以包含下划线 。

示例

my_useful_class.cc
my-useful-class.cc
myusefulclass.cc
myusefulclass_test.cc // _unittest 和 _regtest 已弃用.

C++ 文件要以 .cc 结尾, 头文件以 .h 结尾. 专门插入文本的文件则以 .inc 结尾, 参见 头文件自足.

不要使用已经存在于 /usr/include 下的文件名 (Yang.Y 注: 即编译器搜索系统头文件的路径), 如 db.h.

通常应尽量让文件名更加明确. http_server_logs.h 就比 logs.h 要好. 定义类时文件名一般成对出现, 如 foo_bar.h 和 foo_bar.cc, 对应于类 FooBar.

内联函数必须放在 .h 文件中. 如果内联函数比较短, 就直接放在 .h 中.

1.2、变量命名

总述

变量 (包括函数参数) 和数据成员名一律小写, 单词之间用下划线连接. 类的成员变量以下划线结尾, 但结构体的就不用, 如:

a_local_variable, a_struct_data_member, a_class_data_member_.

说明

  • 普通变量命名

举例:

string table_name;  // 好 - 用下划线.
string tablename;   // 好 - 全小写.

string tableName;  // 差 - 混合大小写
  • 类数据成员

不管是静态的还是非静态的, 类数据成员都可以和普通变量一样, 但要接下划线.

class TableInfo {
  ...
 private:
  string table_name_;  // 好 - 后加下划线.
  string tablename_;   // 好.
  static Pool<TableInfo>* pool_;  // 好.
};
  • 结构体变量

不管是静态的还是非静态的, 结构体数据成员都可以和普通变量一样, 不用像类那样接下划线:

struct UrlTableProperties {
  string name;
  int num_entries;
  static Pool<UrlTableProperties>* pool;
};

结构体与类的使用讨论, 参考 结构体 vs. 类.

1.3、常量命名

总述

声明为 constexpr 或 const 的变量, 或在程序运行期间其值始终保持不变的, 命名时以 “k” 开头, 大小写混合. 例如:

const int kDaysInAWeek = 7;

说明

所有具有静态存储类型的变量 (例如静态变量或全局变量, 参见 存储类型) 都应当以此方式命名. 对于其他存储类型的变量, 如自动变量等, 这条规则是可选的. 如果不采用这条规则, 就按照一般的变量命名规则.

1.4、 函数命名

总述

常规函数使用大小写混合, 取值和设值函数则要求与变量名匹配:

MyExcitingFunction(), 
MyExcitingMethod(), 
my_exciting_member_variable(), 
set_my_exciting_member_variable().

说明

一般来说, 函数名的每个单词首字母大写 (即 “驼峰变量名” 或 “帕斯卡变量名”), 没有下划线. 对于首字母缩写的单词, 更倾向于将它们视作一个单词进行首字母大写 (例如, 写作 StartRpc()而非 StartRPC()).

AddTableEntry()
DeleteUrl()
OpenFileOrDie()

(同样的命名规则同时适用于类作用域与命名空间作用域的常量, 因为它们是作为 API 的一部分暴露对外的, 因此应当让它们看起来像是一个函数, 因为在这时, 它们实际上是一个对象而非函数的这一事实对外不过是一个无关紧要的实现细节.)

取值和设值函数的命名与变量一致. 一般来说它们的名称与实际的成员变量对应, 但并不强制要求. 例如 int count()void set_count(int count).

1.5、 枚举命名

总述

枚举的命名应当和 常量 或 宏 一致: kEnumName 或是 ENUM_NAME.

说明

单独的枚举值应该优先采用 常量 的命名方式. 但 宏 方式的命名也可以接受. 枚举名 UrlTableErrors (以及 AlternateUrlTableErrors) 是类型, 所以要用大小写混合的方式.

enum UrlTableErrors {
    kOK = 0,
    kErrorOutOfMemory,
    kErrorMalformedInput,
};
enum AlternateUrlTableErrors {
    OK = 0,
    OUT_OF_MEMORY = 1,
    MALFORMED_INPUT = 2,
};

2009 年 1 月之前, 我们一直建议采用 宏 的方式命名枚举值. 由于枚举值和宏之间的命名冲突, 直接导致了很多问题. 由此, 这里改为优先选择常量风格的命名方式. 新代码应该尽可能优先使用常量风格. 但是老代码没必要切换到常量风格, 除非宏风格确实会产生编译期问题.

1.6. 宏命名

总述

你并不打算 使用宏, 对吧? 如果你一定要用, 像这样命名: MY_MACRO_THAT_SCARES_SMALL_CHILDREN.

说明

参考 预处理宏; 通常 不应该 使用宏. 如果不得不用, 其命名像枚举命名一样全部大写, 使用下划线:

#define ROUND(x) ...
#define PI_ROUNDED 3.0

2、总结

更多程序风格和命名规范请移步Google开源项目风格指南

针对第一结里面提到的命名规则,总结一下,记住下面的几句话就好了:

文件和变量命名全小写,结构体变量统一小写加 _
函数命名首字母大写(驼峰命名);
枚举名驼峰命名,枚举值统一大写;

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值