目 录第1章文件结构.41.1 版权和版本的声明.41.2 头文件的结构.41.3 定义文件的结构.51.4 头文件的作用.61.5 目录结构.6第2章程序的版式.72.1 空行.72.2 代码行.72.3 代码行内的空格.82.4 对 齐.92.5 长行拆分.102.6 修饰符的位置.112.7 注 释.112.8 类的版式.12第3章命名规则.143.1 共性规则.143.2 简单的WINDOWS应用程序命名规则.153.3 简单的UNIX应用程序命名规则.17第4章 表达式和基本语句.184.1 运算符的优先级.184.2 复合表达式.184.3 IF 语 句.194.4 循环语句的效率.214.5 FOR语句的循环控制变量.224.6 SWITCH 语句.224.7 GOTO 语 句.23第5章常量.255.1 为什么需要常量.255.2 CONST 与#DEFINE 的比较.255.3 常量定义规则.255.4 类中的常量.26第6章 函数设计.286.1 参数的规则.286.2 返回值的规则.296.3 函数内部实现的规则.316.4 其它建议.326.5 使用断言.336.6 引用与指针的比较.34第 7 章 内 存 管 理.367.1 内存分配方式.3672/1J 367.3 指针与数组的对比.377指针参数 如何传递内存的 37.5 FREE和 DELETE把指针怎么啦?.417.6 内彳/1=1 27.7 杜 绝“野指针”.437.8 有了 MALLOC/FREE 为什么还要 NEW/DELETE?.437.9 内存耗尽怎么办?.457.10 MALLOC/FREE 的使用要点.467.11 NEW/DELETE 的使用要点.477.12 一些心得体会.48第 8 章 C+函数的高级特性.498.1 函数重载的概念.498.2 成员函数的重载、覆盖与隐藏.528.3 参数的缺省值.558.4 运算符重载.568.5 函数内联.578.6 一些心得体会.60第 9 章 类的构造函数、析构函数与赋值函数.619.1 构造函数与析构函数的起源.619.2 构造函数的初始化表.629.3 构造和析构的次序.649.4 示例:类 STRING的构造函数与析构函数.649.5 不要轻视拷贝构造函数与赋值函数.659.6 示例:类 STRING的拷贝构造函数与赋值函数.659.7 偷懒的办法处理拷贝构造函数与赋值函数.679.8 如何在派生类中实现类的基本函数.679.9 一些心得 体 会.69第 10章 类 的 继 承 与 组 合.7010.1 继 承.7010.2 组 合.72第 11章 其它编程经验.7411.1 使 用 CONST提高函数的健壮性.7411.2 提高程序的效率.7611.3 一些有益的建议.77参考文献.79附 录 A:C+/C代码审查表.80附 录 B;C+/C试 题.86附 录 C:C+/C试题的答案与评分标准.90第 1 章文件结构每 个C+/C程序通常分为两个文件。一个文件用于保存程序的声明(declaration),称为头文件。另一个文件用于保存程序的实现(implementation),称 为 定 义(definition)文件。C+/C程序的头文件以“.h”为后缀,C程序的定义文件以“.c”为后缀,C+程序的定义文件通常以“.cpp”为 后 缀(也有一些系 统 以“.cc”或“.cxx”为后缀)。1.1 版权和版本的声明版权和版本的声明位于头文件和定义文件的开头(参 见 示 例1-1),主要内容有:(1)版权信息。(2)文件名称,标识符,摘要。(3)当前版本号,作者/修改者,完成II期。(4)版本历史信息。/*C o p y r i g h t (c)*A l l r i g h t s r e s e r ve d.*文件名称:filename,h*文件标识:*摘 要:简要描述本文件的内容*当前版本:*作 者:输 入 作 者(或修改者)名字*完成口期:20 0 1.年7月2 0 n*取代版本:1.0*原 作 者:输 入 原 作 者(或修改者)名字*完成日期:20 0 5年*/示例1 T版权和版本的声明1.2 头文件的结构头文件由三部分内容组成:(1)头文件开头处的版权和版本声明(参 见 示 例1-1)。(2)预处理块。(3)函数和类结构声明等。假设头文件名称为graphics,h,头文件的结构参见示例1-2。【规贝IJ1-2-1】为了防止头文件被重复弓|用,应 当 用ifndef/define/endif结构产生预处理块。【规 则1-2-2】用include 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。【规 则1-2-3用ttinclude“filename.h”格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。令 【建 议1-2-11头文件中只存放“声明”而 不 存 放“定义”在C+语法中,类的成员函数可以在声明的同时被定义,并且自动成为内联函数。这虽然会带来书写上的方便,但 却造成了风格不致,弊大于利。建议将成员函数的定义与声明分开,不论该函数体有多么小。令 【建 议1-2-2不提倡使用全局变量,尽量不要在头文件中出现象extern int value这类声明。版 权 和 版 本 声 明 见 示 例1-1,此处省略。#ifndef GRAPHICS H 防止 graphics.h 被重复引用#define GRAPHICSttinclude /引用标准库的头文件ttinclude myheader.h/引用非标准库的头文件void Functionl();/全局函数声明class Box/类结构声明;ttendif示 例1-2 C+/C头文件的结构1.3定义文件的结构定义文件有三部分内容:(1)定义文件开头处的版权和版本声明(参 见 示 例1-1)。(2)对一些头文件的引用。(3)程 序 的 实 现 体(包括数据和代码)。假设定义文件的名称为graphics.c p p,定义文件的结构参见示例1-3。/版权和版本声明见示例1-1,此处省略。ttinclude graphics.h/引用头文件/全局函数的实现体void Functionl(,)()/类成员函数的实现体void Box:Draw(,)()示 例 1-3 C+/C定义文件的结构1.4 头文件的作用(1)通过头文件来调用库功能。在很多场合,源 代 码 不 便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。(2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。1.5 目录结构如果一个软件的头文件数目比较多(如超过十个),通常应将头文件和定义文件分别保存于不同的目录,以便于维护。例如可将头文件保存于include目录,将定义文件保存于source目 录(可以是多级目录)。如果某些头文件是私有的,它不会被用户的程序直接引用,则没有必要公开其“声明”。为了加强信息隐藏,这些私有的头文件可以和定义文件存放于同一个目录。第 2章程序的版式可以把程序的版式比喻为“书法”。好 的“书法”可让人对程序一目了然,看得兴致勃勃。差 的 程 序“书法”如螃蟹爬行,让人看得索然无味,更令维护者烦恼有加。2.1 空行空行起着分隔程序段落的作用。空行得体(不过多也不过少)将使程序的布局更加清晰。空行不会浪费内存,虽然打印含有空行的程序是会多消耗一些纸张,但是值得。所以不要舍不得用空行。【规 则 2-1-1 在每个类声明之后、每个函数定义结束之后都要加空行。参见示例2-1(a)【规 则 2-1-2 在一个函数体内,逻揖上密切相关的语句之间不加空行,其它地方应加空行分隔。参见示例2-1(b)示 例 2-1(a)函数之间的空行 示 例 2 T(b)函数内部的空/空行void Functionl(,)(/空行void Function2(,)()/空行void Functions(,)()/空行while(condition)(statementl;/空行if(condition)(statement2;)else(statements;)/空行statement4;)行2.2 代码行【规 则 2-2-1 1 一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,并且方便于写注释。【规 则 2-2-2】if、for while,d o 等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加 L这样可以防止书写失误。示 例 2-2(a)为风格良好的代码行,示 例 2-2(b)为风格不良的代码行。int width;/宽度int height;/高度int depth;/深度in t width,height,depth;/宽度高度深度x=a+b;y=c+d;z=e+f;X=a+b;y=c+d;z=e+f;if(width height)(dosomething();if(width inline c a se 等关键字之后至少要留一个空格,否则无法辨析关键字。象 if、for、while等关键字之后应留一个空 格 再 跟 左 括 号 (,以突出关键字。【规 则 2-3-2】函数名之后不要留空格,紧 跟 左 括 号 (,以与关键字区别。【规 则 2-3-3 1 (向后紧跟,向前紧跟,紧跟处不留空格。【规 则 2-3-41 ,之后要留空格,如F u n c t i o n s,y,z)。如 果;不是一行的结束符号,其后要留空格,如 f o r (i n i t i a l i z a t i o n;c o n d i t i o n;u p d a t e)【规 则 2-3-5赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=、+=”“I I、等二元操作符的前后应当加空格。【规贝I J 2-3-61 一元操作符如“一”、(地址运算符)等前后不加空格。【规 则 2-3-7象这类操作符前后不加空格。令 【建 议 2-3-1】对于表达式比较长的f o r语 句 和i f语句,为了紧凑起见可以适当地去掉一些空格,如 f o r (i=0;i =2 0 0 0)/良好的风格i f (y e a r =2 0 0 0)/不良的风格i f (a =b)&(c =b&c =d)/不良的风格f o r (i=0;i 1 0;i+)/良好的风格f o r(i=0;i 1 0;i+)/不良的风格f o r (i =0;I 1 0;i +)/过多的空格x =a b?a :b;/良好的风格x=a Fun c t i o n ();/不要写成 b -Fun c t i o n();2.4对齐【规 则 2-4-1】程 序 的 分 界 符 和 应独占一行并且位于同列,同时与引用它们的语句左对齐。【规 则 2-4-2 之内的代码块在 右边数格处左对齐。示 例2-4(a)为风格良好的对齐,示 例2-4(b)为风格不良的对齐。void Function(int x)(/program code)void Function(int x)/program code)if(condition)(/program code)else(/program code)if(condition)/program code)else /program code)for(in itializatio n;update)(/program codecondition;for(in itializatio n;update)/program codecondition;While(condition)(/program code)while(condition)/program code如果出现嵌套的 ,则使用缩进