C/C++编码规范
以下编码规则仅适用于王新晓的 C/C++代码
一、文件结构
头文件规范
- 一个头文件需要 #define保护,命名格式为:
_<PROJECT>_<PATH>_<FILE>_H_
如:项目xzpt中,头文件xzpt\Classes\xzpt\xzptGameSence.h应定义如下:(需要写全路径)(宏定义 #endif 后须加注释)
|
|
#include
的顺序(每种头文件间应空行)- 当前文件的对应头文件
- C系统文件
- C++系统文件
- 其他库的头文件
- 本项目的头文件
二、命名规范
文件命名
使用小驼峰法命名如:
xzptGameSence.cpp
xzptGameSence.h
类型命名
class 开头为 C, struct开头为S, interface开头为I
大驼峰法
例如:
CXzptGameSence
SXzptUserInfo
IXzptLogin
变量命名
指针需在结尾添加_ptr,若为常量指针(我这里的意思是指针不能改变指向的东西,但是可以改变这个指向的东西的内容)需在结尾添加_cPtr
局部变量
以下划线开头,第一个单词代表变量的类型(STL中的情况使用小驼峰法命名),第二个单词为项目名称,第三个单词为变量意义(使用小驼峰法),每个单词之间加下滑线,例如:
Sprite* _sprite_xzpt_up_leaves_ptr;
int _int_xzpt_Level;
std::vector<Sprite> _vectorSprite_xzpt_listMoveShape;
std::list<xzptSprite*> _listXzptSpritePtr_xzpt_listShape;
全局变量
以g_开头,第一个单词代表变量的类型(STL中的情况使用小驼峰法命名),第二个单词为项目名称,第三个单词为变量意义(使用小驼峰法),每个单词间添加下滑线,例如:
char* g_char_xzpt_userInfoData_ptr;
int g_int_xzpt_version;
成员变量
以m_开头,第一个单词代表变量的类型(STL中的情况使用小驼峰法命名),第二个单词为项目名称,第三个单词为变量意义(使用小驼峰法),每个单词间添加下滑线,例如:
Sprite* m_sprite_xzpt_hand_ptr;
int m_int_xzpt_actionNum;
函数中的参数
- 直接写变量含义,例如:
calMinDistanceLineWithShape(Vec2 pointX, Vec2 pointY, Vec2 pointM);
- 函数中的参数如果是传出数据使用,再开头添加out,使用小驼峰法,例如:
calMaxTwoNumber(int num0, int num1, int& outResultNumber)
其他补充规则
- for循环中括号内的局部循环标记量可直接定义为字母,使用字母顺序如下
i
j
m
n
x
y
z
,之后的不做顺序规定 - 其中基础类型名称在对象名中体现可以只写首字母,例如:
int _i_xzpt_level;
- 单例对象用大写A开头,整体采用大驼峰法
常量命名
以c_开头,第一个单词代表变量的类型(STL中的情况使用小驼峰法命名),第二个单词为项目名称,第三个单词为变量意义(使用小驼峰法),每个单词间添加下滑线,例如:
const char* c_char_xzpt_direction_ptr;
注意:常量与变量相同拥有全局常量,局部常量等情况,故规定如下
1. 局部常量为 _c_开头
2. 其他情况可直接与开头字母合并,如下(若为全局变量)
const char* const cg_char_xzpt_hurdleInfoData_cPtr = "123.txt";
或
const char* const gc_char_xzpt_hurdleInfoData_cPtr = "123.txt";
此处gc与cg皆可
静态量命名
以s_开头,第一个单词代表变量的类型(STL中的情况使用小驼峰法命名),第二个单词为项目名称,第三个单词为变量意义(使用小驼峰法),每个单词间添加下滑线,例如:
static bool s_bool_xzpt_firstTimeGetDesign;
此处注意与常量注意相同,若遇到常量,静态,全局等因素组合,除局部因素将_s加在开头外,其他因素皆可直接组合例如:
static cont bool scg_bool_xzpt_firstTimeGetDesign = true;
scg可任意排列组合
函数命名
- 函数名必须直观,并且能正确表达其内在功能
- 对于函数参数中的引用和指针类型视情况以const修饰
- 对于不修改数据成员的类成员函数,以const修饰
- 函数名以小写开头,使用小驼峰法
- 返回值为布尔型的一些检测函数,正确的要返回true,错误的返回false,不要调转含义
宏命名规范
- 尽量不使用宏定义
- 如果使用宏需全部大写,每个单词以下滑线分割
typedef类型命名规范
typedef std::vector<int> SeqInt;
//vector的全部都在前面加Seq。
typedef ::std::map<int, int> DictIntInt;
//map在cdl中加前缀Dict,在代码中用Map
- 必须以大写开头。
- 命名翻译的是内部的组成,例如SeqInt,一看就是vector
。不能改为PlayerId这种具有确切意义的命名,缺乏通用性。具体含义应该在变量名上反映出来。
代码风格
空格放置
- 循环后加空格再加括号,例:
for (int i = 0; i < 10; ++i)
- 函数名后不需要加空格,紧跟
(
)
(
后紧跟与)
后紧跟不加空格- 嵌套
(
)
与(
)
之间加空格如:if ( (x == 1) && (x == 2) )
;
不是结尾加空格- 除
[ ]
、.
、->
、::
外,双目操作符, 如=
、+=
、>=
、<=
、+
、*
、%
、&&
、||
、<<
、^
等两侧各留一个空格。 - 单目操作符如
!
、~
、++
、--
、&
(地址运算符)与操作数之间不留空格。 - 当一个函数的返回值是指针变量或引用变量时,类型与操作符(
*
或&
)之间不留空格,操作符之后留一个空格; - 定义指针时,
*
放在对象前,与对象中间无空格,当作为函数入参时,*
放在类后,与类中间无空格 {
}
用于初始化时不换行,在中间加空格
布局规范
- 每个函数,成员函数声明之间保留一个空格
- 同一个函数体内,有语义转换时,保留一个空行
{
}
会换行++
--
前后可选择时,放在前面{
}
用于初始化时不换行,在中间加空格
注释规范
- 块注释使用
/* */
, 行注释使用//
- 函数声明前需注释函数含义(除非特别简单能从函数命名推测出来)(若函数功能简单,无需介绍返回值与参数也可以使用
//
直接写注释)具体格式如下:
|
|
- 代码的注释放在该行代码上
- 函数实现的开头需要写函数实现的大致步骤(特别简单的可不写)
- 每个文件最前面需写注释,格式如下(可适当删除不需要的项)):
|
|
其他规范
- 符合表达式需要使用小括号,不要使用默认优先级
- 判断指针是否为空,如:
if (ptr == nullptr)
- 判断是否为某个值时,值放在前面,如:
if (0 == i)
- 判断
bool
时,如:if (flag)
与if (!flag)