[逼死强迫症 - C&C++设计风格选择.1] : 命名规范

1.命名规范

  本系列的第一篇,命名风格本就是有关艺术审美,没有美与丑的绝对标准,本文难免带有主观选择倾向,但是会尽量保持客观的态度归纳几种主流的命名风格,仅供参考。制定规范是为了方便团队沟通和利于代码维护,虽然并不能符合每个艺术家的胃口。对于独立开发者,花点时间设计自己的编码风格也是有助于提高能力的,至少可以在看到自己代码的时候感觉美美哒~~。本文参考了< Google C++ 风格指南>,< Qt 编码风格>,当然还有维基百科,以后不累述。

1.1.常见命名法

蛇形命名法 [ snake_case]:
  like_this,常见于Linux内核,C++标准库,Boost以及Ruby,Rust等语言。
驼峰命名法 [ camelCase]:
  likeThis,为了和帕斯卡命名法区分,本文特指小驼峰式命名法,常见于Qt以及Java。
帕斯卡命名法[ PascalCase]:
  LikeThis,又名大驼峰式命名法,常见于Windows API函数以及C#。
匈牙利命名法[ Hungarian notation]:
  dwWidth,系统匈牙利命名法是被黑的最多的,主要认为在有类型检查的语言里发现类型错误编译器比人更可靠;在有IDE的情况下,找到一个变量的类型也不是一件难事;通常我们看到一个陌生的变量的时候,如果不知道它是干什么的,知道它的类型好像也并没有什么用;并且在重构的时候,如果你要改变一个变量的类型,尽管其功能并没有变,你还是要去修改变量名。所以除非是Windows系统开发,不建议使用系统匈牙利命名法。
  rwPosition,匈牙利应用命名法不表示变量的类型,而是用前缀表示变量的目的,或者它代表了什么。这种变量命名方法在帮助程序员理解变量的用途上是很有帮助的。但是建议前缀不要使用缩写,除非所用的缩写是普遍共识。

1.2.文件命名

文件名后缀:
 1 # C语言不纠结
 2 file.h & file.c
 3 # C++ Group.1(注意C是大写)
 4 file.h & file.C
 5 # C++ Group.2
 6 file.hh & file.cc
 7 # C++ Group.3
 8 file.hpp & file.cpp
 9 # C++ Group.4
10 file.hxx & file.cxx
tip.1:c语言没有选择,以下仅讨论c++;
tip.2:各组合可以混搭,比如常见的file.cpp搭配file.h和Google风格的file.cc搭配file.h;
tip.3:强迫症可以选择不混搭的各组,这样看起来有对称感;
tip.4:不要选择第1组大写C的后缀,特别是在Windows这样不区分大小写的操作系统上;
tip.5:一些后缀名可能不被某些较老的编译器或IDE所默认支持,例如vs2005默认没有扩展.hh后缀;
tip.6:如果需要跨平台,推荐选择第3组,至少boost是这么选的;
 
文件名命名:
 1 # Teddy项目UserLog文件为例:
 2 # Group.1
 3 UserLog.c & TedUserLog.c
 4 # Group.2
 5 userlog.c & teduserlog.c
 6 # Group.3
 7 userlog.c & ted_userlog.c
 8 # Group.4
 9 user_log.c & ted_user_log.c
10 # Group.5
11 user-log.c & ted-user-log.c
tip.1:如果需要将源码直接发布,可以使用项目名做前缀,防止链接时文件名冲突(msvc好像能自动重命名冲突的.obj文件,但是跨平台程序不能依赖这个特性);
tip.2:各组文件名风格都没有明显的缺点,但要注意在区分大小写的系统上UserLog.c和userlog.c是两个文件;

1.3.类型命名

 1 /*
 2 ** 基本数据类型的重定义,小写比首字母大写更有利于延长Shift寿命,
 3 ** 但也更容易产生命名冲突。
 4 */
 5 typedef unsigned char byte;
 6 typedef unsigned char byte_t;
 7 typedef unsigned char Byte;
 8 typedef unsigned char Byte_t;
 9 
10 /*
11 ** 类与结构体常见的风格是采用PascalCase,不推荐使用camelCase
12 ** 这种怪异的风格。
13 */
14 class HashTable { ...
15 class hash_table { ...
16 struct FileInfo { ...
17 struct file_info { ...
18 
19 /* C语言常见到的风格还有结构体名称加'_t'后缀 */
20 struct fileinfo_t { ...
21 struct FileInfo_t { ...
22 
23 /* 枚举命名常见PascalCase风格 */
24 enum FileFlags { ...
25 enum file_flags { ...
tip.1:c语言没有命名空间,为防止命名冲突,常见做法是将项目名或其缩写作为类型名称前缀;
tip.2:类,结构体,枚举的命名风格尽量保持一致;

1.4.命名空间命名

1 /* 一般使用项目名称,风格看喜好。 */
2 namespace my_project { ...
3 namespace MyProject { ...

tip.1:确保命名空间不会和常用的库冲突;

1.5.函数和变量命名

 1 /*
 2 ** 在函数和变量命名风格上PascalCase,camelCase,
 3 ** snake_case三足鼎立,选择凭喜好。
 4 */
 5 void FunctionName(void) { ...
 6 void functionName(void) { ...
 7 void function_name(void) { ...
 8 
 9 long VarName;
10 long varName;
11 long var_name;
12 
13 /*
14 ** tip.1:snake_case在名称比较长时可读性较好;
15 */
16 long variable_names_in_snake_case;
17 long VariableNamesInPascalCase;
18 long variableNamesInCamelCase;
19 
20 /*
21 ** tip.2:PascalCase和camelCase在函数中的区分度较好,
22 ** 在快速扫描代码逻辑的时候不易被其它符号所干扰。
23 */
24 long FabonacciFunction(long rabbitNums)
25 {
26     if (rabbitNums < 2) {
27         return rabbitNums;
28     }
29     long resultOne = FabonacciFunction(rabbitNums - 1);
30     long resultTwo = FabonacciFunction(rabbitNums - 2);
31     return resultOne + resultTwo;
32 }
33 
34 long fabonacci_function(long rabbit_nums)
35 {
36     if (rabbit_nums < 2) {
37         return rabbit_nums;
38     }
39     long result_one = fabonacci_function(rabbit_nums - 1);
40     long result_two = fabonacci_function(rabbit_nums - 2);
41     return result_one + result_two;
42 }

tip.3:如果类需要兼容标准库迭代器或是要支持range for,begin()和end()函数会破坏PascalCase风格的一致性;

1.6.类成员变量和全局变量命名

 1 /*
 2 ** 类成员变量和全局变量的命名风格和局部变量的命名风格
 3 ** 并没有更多的区别。唯一的问题是,是否要加前缀或后缀
 4 ** 以方便和局部变量区分开来。
 5 */
 6 class UserInfo {
 7     ...
 8 private:
 9     std::string user_name_; /* Google style */
10     std::string m_userName; /* Hungarian notation */
11     /* 不推荐前缀'_'的风格,可能会和标准库命名冲突 */
12 };
13 
14 /* 全局变量要少用,推荐加前缀用于区分 */
15 extern "C" long g_commonCount;

tip.1:在有IDE提示时,前缀"m_"的类成员变量能够很快被找到,如果不喜欢这种风格,"this->"同样也很便利;

1.7.常量和枚举值命名

 1 /*
 2 ** 常量和枚举值的命名风格建议和局部变量的命名风格区分开,
 3 ** 常见的有全字母大写加'_'的风格,PascalCase风格,以及
 4 ** Google加'k'前缀的风格。
 5 */
 6 static const int DAYS_IN_WEEK = 7;
 7 static const int kDaysInWeek  = 7;
 8 
 9 enum FileOpenMode {
10     ReadOnly, WriteOnly, ReadWrite
11 };
12 
13 enum FileOpenMode {
14     READ_ONLY, WRITE_ONLY, READ_WRITE
15 };

 tip.1:如果可以使用c++11特性,推荐enum class,否则可以在有歧义的枚举值中重复枚举类型的名字;

1.8.宏命名

 1 /* 宏命名推荐使用全字母大写加'_'分隔的风格 */
 2 #define OS_UNIX
 3 #define OS_LINUX
 4 #define OS_WINNT
 5 
 6 /* 除非你想用条件编译将某些功能变为可选项 */
 7 #ifdef  USE_TCMALLOC
 8 #define my_malloc tcmalloc
 9 #else
10 #define my_malloc malloc
11 #endif

tip.1:能用常量替代宏的地方尽量使用常量吧;

你可能感兴趣的:([逼死强迫症 - C&C++设计风格选择.1] : 命名规范)