编程规范的介绍.ppt_第1页
编程规范的介绍.ppt_第2页
编程规范的介绍.ppt_第3页
编程规范的介绍.ppt_第4页
编程规范的介绍.ppt_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

科技的实力、创新的活力、服务的诚信力 编程规范的介绍 An Introduction to C / C+ Coding Conventions 广东天讯电信科技有限公司 2007.4 编写的参考依据 1, Logiscope RuleChecker对代码规 范作说明 2, C+ 编码规范(陈世忠 Motorola ) 3, Write Solid Code(编程精粹) 4, Manual of CVS 2 编程规范的作用 提高代码的质量 提高编程的效率 便于项目的管理 如果一个项目坚持共同规范,那么会有下面这些好处: 程序员可以理解任何代码,并知道正在做什么 新使用C+的人可以很快驶入正轨 新使用C+的人不必发展自己的风格并一直守着它 新使用C+的人不会一遍又一遍地反复犯相同的错误 在一致的环境里大家可以少犯错误 3 一流代码的特性 鲁棒 - Solid and Robust Code 简洁 - Maintainable and Simple Code 高效 - Fast Code 简短 - Small Code 复用/共享 - Re-usable Code 可测试 - Testable Code 可移植 - Portable Code (“写好代码的10个秘诀”微软,林斌) 4 1.命名规范 2.代码风格与版式 3.有关注释 4.函数 5.类/结构 6.变量、常量 7.类型转换 8.程序组织 9.代码的管理 主要内容 5 1.命名规范 变量命、函数、类、宏、常量、类型 、模版名和文件名等都需要命名 命名工作很重要 命名的一些方法和原则 my_name myName cMyName 6 1.1变量命名规则 变量的命名 一般变量遵从 变量名=作用域+变量类 型+变量含义 静态变量遵从 变量名=”s_”+变量类型+ 变量含义 7 1.1.1作用域的表示: g_ 全局变量,如:g_lpImageInfo; m_ 类成员变量,如:m_strColorBuffer; sg_ 全局静态变量,如:sg_ucIteration sm_ 类成员静态变量,如: sm_pLengthEdit s_ 类方法中静态变量,如:s_ pLengthEdit 局部变量省略作用域,如:pLengthEdit 8 1.1.2变量类型 前缀类型前缀类型 b Booleanlp长指针(long pointer) c字符型(char)a数组(array) uc无符号字符e枚举(enum) s短整数(short)sz零结尾的字符串 ptr记录指针(pointer to record)w短无符号整数(WORD) str字符串(string pointer)l长整数(long) dw长无符号整数(DWORD)f浮点类型(float) d长浮点类型(double)p短指针(pointer) ar结构数组(array of record) af 浮点数组(array of float) 9 1.1.3 变量名字的含义 接近变量含义的英文单词,本着简单清 楚、简单的原则,如Device表示设备, Name表示名字。若用多个单词表示各个单 词应用大写字母打头,如DeviceName表 示设备名。根据以上命名规则,我们对变 量m_szCallingNumber应知道该变量是一个 类的数据成员,该成员是零结尾的字符串 ,存储的是呼叫号码。这样我们就能望文 生义,知道该变量的作用域、类型和含义 ,便于以后的维护和实际的编程。 10 1.1.4注意事项 全局变量可在头文件中定义,并尽量减 少全局变量的使用。 对于多文件共享的全局变量尽量定义在 独立的一个头文件中 。 全局变量会增大模块间的耦合。 11 1.2 函数命名规则 全局函数:Dll或引出模块缩写”+“具体含 义”,避免导出的全局函数与别人的重名;如 Display_InitEditor()。 类成员函数: 省略作用域,直接用具体含义 表示。以前缀 OnMsg作为类中针对消息的 响应函数的前缀,前缀OnNotify作为对 Notify消息的响应函数的前缀。 12 1.3类的命名规则 遵从:类名 = “C”+类的含义,类的含义应为 易于理解英文单词、术语或其简写,例如: class CClipCompileDlg : public CDYDialog 为便于界定,每个单词的首字母要大写。 类的命名推荐用“名词“或“形容词名词“的形 式,例如:“CAnalyzer“, “CFastVector“ 13 1.4宏 所有的宏在头文件中定义。 宏名由英文单词和下划线组成,字母皆大写。 例如: #defineSET_MOUSE_POS 对于宏的展开部分,在宏的参数出现的地方要加括号“( )”。 保证宏替换的安全,同时提高代码的可读性。 举例: / 不要这样写 #define GET_NAME(obj,ind) obj-nameind / 应该这样写 #define GET_NAME(obj,ind) (obj)-name(ind) 14 1.5 常量 常量名由类型前缀全大写字母组 成,单词间通过下划线来界定 a. 全局常量 全局常量在cpp中定义,如其他库需要使用时,在头文件中用extern.声明,保证 只有一个实例。 常量名“G_”+常量含义,其他同函数内常量,如: #define G_FilePath“C:My documentspic.jpg” b. 类成员常量 常量名“M_”+常量含义,其他同函数内常量 由英文单词和下划线组成。全部字母大写。 例如:M_SCREEN_WIDTH, C. 原则上函数内不定义常量 15 1.6类型(自定义) 类型名由英文单词组成(不用下划线),每个单 词首字母大写。指针类型名前冠以“P” 。 typedef struct tagStructName int iType; LPCSTR pszCatName; LPCSTR pszITName; LPCSTR pszITDescription; STRUCTNAME, *PSTRUCTNAME; 16 1.7关于定义struct、union变量 禁止在程序中直接定义结构体(struct)、联合体(union)变量。 要使用typedef为自定义的结构体、联合体重新命名后,再使用这个名字来 定义变量。 理由: 使代码更容易理解。 举例: / 不要这样写 struct . varName; / 应该这样写 typedef struct . typeName; typeName varName; 17 2.代码风格与版式 一段稍长一点的无格式代码基 本上是不可读的。 一定形成良好的风格(style) 18 2.1空行的使用 空行起着分隔程序段落的作用,提高代码的 可读性。 空行得体(不过多也不过少)将 使程序的布局更加清晰。空行不会浪费内 存,虽然打印含有空行的程序是会多消耗 一些纸张,但是值得。所以不要舍不得用 空行。 在每个类声明之后、每个函数定义结束之 后都要加空行。 在一个函数体内,逻揖上密切相关的语句 之间不加空行,其它地方应加空行分隔。 19 2.2语句与代码行 一行代码只做一件事情,如只定义一个变 量,或只写一条语句。这样的代码容易阅 读,并且方便于写注释。 “if”、“for”、“while”、“do”、“try”、 “catch” 等语句自占一行,执行语句不得紧 跟其后。不论执行语句有多少都要加 “ ” 。这样可以防止书写失误。 20 2.3缩进和对齐 TAB和空格的问题 程序的分界符 “ 和 “ 应独占一行并且位于 同一列,同时与引用它们的语句左对齐。 “ “ 之内的代码块在 “ 右边一个制表符处 左对齐。如果出现嵌套的 “ “,则使用缩进 对齐。 如果一条语句会对其后的多条语句产生影响 的话,应该只对该语句做半缩进,以突出该 语句。 21 2.3.1例如: Void Function(int x) CSessionLock iLock(*m_psemLock); for (初始化; 终终止条件; 更新) / . try / . catch (const exception i= 2000) / 良好的风格 if(year=2000) / 不良的风格 if (a=b) / 不要写成 b - Function(); 27 2.7 建议在表达式中使用括号 对于一个表达式,在一个二元、三 元操作符操作的操作数的两边,应该 放置“(”和“)”。 避免出现不明确的运算、赋值顺序 。 举例: / 下面这行代码: result = fact / 100 * number + rem; /最好写成这样 result = (fact / 100) * number) + rem; 28 2.8 不在条件判断语句中赋值 不要在控制语句if, while, for 和 switch的条件表达式 中使用赋值操作符。赋值操作符包括:=, +=, -=, *=, /=, %=, =, =, VSTR; public: / 构造、析构、初始化 CXXX(); CXXX(); 61 public: / 公共方法 / 功能组1 void Function1(void) const; long Function2(IN int n); / 功能组1 / 功能组2 void Function3(void) const; bool Function4(OUT int / 功能组2 private: / 属性 / . private: / 禁用的方法 / 禁止复制 CXXX(IN const CXXX CXXX ; 62 5.10初始化列表 应当尽可能通过构造函数的初始化列表来初始化成员和 基类。初始化列表至少独占一行,并且与构造函数的定 义保持一个制表符的缩进。 例如: CXXX:CXXXX(IN int nA, IN bool bB) : m_nA(nA), m_bB(bB) / . ; 初始化列表的书写顺序应当与对象的构造顺序一致,即 :先按照声明顺序写基类初始化,再按照声明顺序写成 员初始化。 如果一个成员 “a“ 需要使用另一个成员 “b“ 来初始化, 则 “b“ 必须在 “a“ 之前声明,否则将会产生运行时错误 (有些编译器会给出警告)。 63 例如: / . class CXXXX : public CAA, public CBB / . CYY m_iA; CZZ m_iB; / m_iA必须在m_iB之前声明 ; CXXX:CXXXX(IN int nA, IN int nB, IN bool bC) : CAA(nA), CBB(nB), m_iA(bC), m_iB(m_iA) / 先基 类,后成员, / 分别按照声明顺序书写 / . ; 64 5.11明确指明派生类与基类的关系 在由基类派生子类时,要明确指明派生类对基类的访问控制( public, protected, private)。 理由: 明确子类、基类的继承关系。 举例: / 不要这样写 class inherclass1 : public Base1, Base2 /等价于 public Base1, private Base2 . class inherclass2 : Base1 /等价于private Base1 . / 应该这样写, class inherclass : public Base1, private Base2 . class inherclass2 : private Base1 . 65 6 变量、常量 变量、常量的声明格式如下: 存储方式 类型 变量名; 其中: 以 “ “ 括住的为可选项目。 “存储方式“ 的说明见下文 66 6.1变量、常量的定义 变量、常量的定义格式如下: 存储方式 类型 变量名 = 初始值; 其中: 以 “ “ 括住的为可选项目。 “存储方式” 的说明见下文 变量必须在使用前初始化(并不是每个编译 器赋相同的初始值) 67 6.2存储方式 除 “auto“ 类型以外,诸如 “extern“, “static“, “register“, “volatile“ 等存储方式 均不可省略,且必须在声明和定义中一致地 使用(即:不允许仅在声明或定义中使用) 。 68 7类型转换 禁止使用C风格的 “(类型)“ 格式转换,应当优先使用C+的 “xxx_cast“ 风格的类型转换。C+风格的类型转换可以提供 丰富的含义和功能,以及更好的类型检查机制,这对代码的阅 读、修改、除错和移植有很大的帮助。其中 static_cast static_cast用于编译器认可的,安全的静态转换,比如将 “char“ 转为 “int“ 等等。该操作在编译时完成 reinterpret_cast reinterpret_cast用于编译器不认可的,不安全的静态转换,比 如将 “int*“ 转为 “int“ 等等。这种转换有可能产生移植性方面 的问题,该操作在编译时完成 const_cast const_cast用于将一个常量转化为相应类型的变量,比如将 “const char*“ 转换成 “char*“ 等等。这种转换通常伴随潜在 的错误。该操作在编译时完成 69 7类型转换 dynamic_cast dynamic_cast是C+RTTI机制的重要体现,用于在类层次结构 中漫游。dynamic_cast可以对指针和引用进行自由度很高的 向上、向下和交叉转换。被正确使用的dynamic_cast操作将 在运行时完成. 此外,对于定义了 单参构造函数 或 类型转换操作 的类来说,应 当优先使用构造函数风格的类型转换,如:“string(“test“)“ 等等。 通常来说,“xxx_cast“ 格式的转换与构造函数风格的类型转换 之间,最大的区别在于:构造函数风格的转换通常会生成新的 临时对象,可能伴随相当的时间和空间开销。 而 “xxx_cast“ 格式的转换只是告诉编译器,将指定内存中的数 据当作另一种类型的数据看待,这些操作一般在编译时完成, 不会对程序的运行产生额外开销。当然,“dynamic_cast“ 则 是一个例外。 70 8.程序组织 8.1一个头文件中只声明一个类 在一个头文件中,只应该包含对一个类的声 明(嵌套类的情况除外)。头文件是指以 .h、.hh、.H、.hxx、.hpp为后缀的文件。 理由: 提高代码的可读性。 72 8.2 一个源文件中只实现一个类 在一个源文件中定义的每一个函数,都应该 属于同一个类,即对一个类的实现描述要 独占一个文件。源文件指以*.cc, *.cxx, *.cpp, *.C or *.c为后缀的代码文件。 理由: 提高代码的可读性。 73 8.3 头文件中只包含声明,不应包含定义 在头文件中只包含声明,不要包含全局变 量和函数的定义 内联函数的情况除外。 74 8.4 源文件中不要有类的声明 在源文件中只应该包含对类的实现,不应 该包含任何类的声明。类声明应该统一放 到头文件中去。源文件指以*.cc, *.cxx, *.cpp, *.C or *.c为后缀的代码文件。 75 8.5 可被包含的文件 为改善程序代码的组织结构 ,只允许头

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论