高质量C++/C编程指南 页码,11/101 第1章文件结构 每个C+/C程序通常分为两个文件。一个文件用于保存程序的声明(declaration),称为头文件。 另一个文件用于保存程序的实现(implementation),称为定义(definition)文件。 C+C程序的头文件以“h”为后缀,C程序的定义文件以“.c”为后缀,C+程序的定义文件通常 以“.cpp”为后缀(也有一些系统以“.cc”或“cxx”为后缀)。 1.1版权和版本的声明 版权和版本的声明位于头文件和定义文件的开头(参见示例1-1),主要内容有: (1)版权信息。 (2)文件名称,标识符,摘要。 (3)当前版本号,作者/修改者,完成日期。 (4)版本历史信息。 /* *Copyright(c)2001,上海贝尔有限公司网络应用事业部 All rights reserved. *文件名称:filename.h *文件标识:见配置管理计划书 *摘 要:简要描述本文件的内容 米 *当前版本:1.1 *作 者:输入作者(或修改者)名字 *完成日期:2001年7月20日 米 *取代版本:1.0 *原作者:输入原作者(或修改者)名字 *完成日期:2001年5月10日 */ 示例1-1版权和版本的声明 1.2头文件的结构 头文件由三部分内容组成: (1)头文件开头处的版权和版本声明(参见示例1-1)。 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
第1章 文件结构 每个C++/C 程序 通常分为两个 文件 。一个文件用 于保存程序的声明 (declaration ),称为头文件 。 另一个文件用 于保存程序的 实现(implementation ),称为定义(definition )文件。 C++/C 程序的头文件 以“.h”为后缀,C程序的定义文件 以“.c”为后缀,C++程序的定义文件 通常 以“.cpp”为后缀(也有一些 系统以“.cc”或“.cxx”为后缀)。 1.1 版权和版本的声明 版权和版本的声明位 于头文件和定义文件的 开头(参见示例1-1),主要内容有: (1)版权信息。 (2)文件名称,标识符, 摘要。 (3)当前版本 号,作者 /修改者,完成日期 。 (4)版本历史 信息。 示例1-1 版权和版本的声明 1.2 头文件的结构 头文件 由三部分内容组成: (1)头文件 开头处的版权和版本声明 (参见示例1-1)。 /* * Copyright (c) 2001, 上海贝尔有限公司网 络应用事业部 * All rights reserved. * * 文件名称:filename.h * 文件标识: 见配置管理计划书 * 摘 要:简要描述本文件的内容 * * 当前版本: 1.1 * 作 者:输入作者(或修改者)名字 * 完成日期: 2001年7月20日 * * 取代版本: 1.0 * 原作者 :输入原作者(或修改者)名字 * 完成日期: 2001年5月10日 */ 高质量C++/C编程指南 页码,11/101 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
高质量C++/C编程指南 页码,12/101 (2)预处理块。 (3)函数和类结构声明等。 假设头文件名称为graphics.h,头文件的结构参见示例1-2。 ● 【规则l-2-1】为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块。 ● 【规则1-2-2】用#include〈filename..h>格式来引用标准库的头文件(编译器将从标准库目录开 始搜索)。 ●【规则1-2-3】用#include“filename.h”格式来引用非标准库的头文件(编译器将从用户的工作 目录开始搜索)。 【建议1-2-1】头文件中只存放“声明”而不存放“定义” 在C+语法中,类的成员函数可以在声明的同时被定义,并且自动成为内联函数。这虽然会带来 书写上的方便,但却造成了风格不一致,弊大于利。建议将成员函数的定义与声明分开,不论该函数 体有多么小。 【建议1-2-2】不提倡使用全局变量,尽量不要在头文件中出现象extern int value这类声明。 /版权和版本声明见示例1-1,此处省略。 #ifndef GRAPHICS_H ∥防止graphics.h被重复引用 #define GRAPHICS_H #include <math.h> ∥引用标准库的头文件 … #include“myheader.h”∥引用非标准库的头文件 void Functionl(.):/全局函数声明 class Box 类结构声明 { … }: #endif 示例1-2C+/C头文件的结构 1.3定义文件的结构 定义文件有三部分内容: (1)定义文件开头处的版权和版本声明(参见示例1-1)。 (2) 对一些头文件的引用。 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
(2)预处理块。 (3)函数和类结构声明 等。 假设头文件 名称为 graphics.h ,头文件的结构参 见示例1-2。 l 【规则 1-2-1 】为了防止头文件 被重复引 用,应当用 ifndef/define/endif 结构产生预处理块。 l 【规则 1-2-2 】用 #include < filename.h> 格式 来引用标 准库的头文件 (编译器将从 标准库目录 开 始搜索)。 l 【规则 1-2-3 】用 #include “filename.h ” 格式 来引用非标准库的头文件 (编译器将从 用户的工作 目录开始搜索)。 ² 【建议 1-2-1 】头文件中 只存放“声明”而不存放“定义” 在C++ 语法中,类的成 员函数 可以在 声明的 同时被定义, 并且 自动 成为内联函数 。这 虽然会带来 书写上的方便,但却 造成了风格不一致,弊大于利。建议 将成员函数 的定义与声明分 开,不论该函数 体有多么小。 ² 【建议 1-2-2 】不提倡使用全局变量,尽量不要在头文件中 出现象extern int value 这类声明 。 示例1-2 C++/C 头文件的结构 1.3 定义文件的结构 定义文件 有三部分内容: (1) 定义文件 开头处的版权和版本声明 (参见示例1-1)。 (2) 对一些头文件的 引用。 // 版权和版本声明 见示例1-1,此处省略。 #ifndef GRAPHICS_H // 防止graphics.h 被重复引 用 #define GRAPHICS_H #include <math.h> // 引用标准库的头文件 … #include “myheader.h ” // 引用非标准库的头文件 … void Function1( …); // 全局函数声明 … class Box // 类结构声明 { … }; #endif 高质量C++/C编程指南 页码,12/101 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
高质量C+/C编程指南 页码,13/101 (3)程序的实现体(包括数据和代码)。 假设定义文件的名称为graphics.cpp,定义文件的结构参见示例l-3。 /版权和版本声明见示例1-1,此处省略。 #include“graphics.h”∥引用头文件 … /全局函数的实现体 void Functionl(...) } /类成员函数的实现体 void Box:Draw(...) 示例1-3C+/C定义文件的结构 1.4头文件的作用 早期的编程语言如Basic、Fortran没有头文件的概念,C+/C语言的初学者虽然会用使用头文件, 但常常不明其理。这里对头文件的作用略作解释: (1)通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头 文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实 现的。编译器会从库中提取相应的代码。 (2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一 致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。 1.5目录结构 如果一个软件的头文件数目比较多(如超过十个),通常应将头文件和定义文件分别保存于不同 的目录,以便于维护。 例如可将头文件保存于include目录,将定义文件保存于source目录(可以是多级目录)。 如果某些头文件是私有的,它不会被用户的程序直接引用,则没有必要公开其“声明”。为了加 强信息隐藏,这些私有的头文件可以和定义文件存放于同一个目录。 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
(3) 程序的 实现体 (包括数据和代码 )。 假设定义文件的 名称为 graphics.cpp ,定义文件的结构参 见示例1-3。 示例1-3 C++/C 定义文件的结构 1.4 头文件的作用 早期的编程 语言如 Basic 、Fortran 没有头文件的 概念 ,C++/C 语言 的初学者虽然会用使用头文件, 但常常不明其理。这 里对头文件的作用 略作解释: (1)通过头文件 来调用库功能。在很多场合,源代码 不便(或不准)向用户公布,只要向用户提供头 文件和 二进制的库即可。用户只需要 按照头文件中的 接口声明 来调用库功能 ,而不 必关心接口怎么实 现的。编译器会从库中提取相应的代码 。 (2)头文件 能加强类型安全检查。如果某个接口被实现 或被使 用时,其方 式与头文件中的声明 不一 致,编译器就会指出错误, 这一简单的规则 能大大减轻程序员调试、改错的 负担。 1.5 目录结构 如果一个软 件的头文件 数目比较 多(如超过十个),通常应将头文件和定义文件分 别保存于不同 的目录, 以便于维护。 例如可将头文件 保存于include 目录, 将定义文件 保存于source 目录(可以是多级目录)。 如果某些头文件 是私有的,它不会被 用户的程序 直接 引用,则 没有必要公开其“声明 ”。为了 加 强信息隐藏,这些私有的头文件 可以和定义文件 存放于同一个目录。 // 版权和版本声明 见示例1-1,此处省略。 #include “graphics.h ” // 引用头文件 … // 全局函数的实现体 void Function1( …) { … } // 类成员函数 的实现体 void Box::Draw( …) { … } 高质量C++/C编程指南 页码,13/101 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
高质量C++/C编程指南 页码,14/101 第2章程序的版式 版式虽然不会影响程序的功能,但会影响可读性。程序的版式追求清晰、美观,是程序风格的重 要构成因素。 可以把程序的版式比喻为“书法”。好的“书法”可让人对程序一目了然,看得兴致勃勃。差的 程序“书法”如螃蟹爬行,让人看得索然无味,更令维护者烦恼有加。请程序员们学习程序的“书 法”,弥补大学计算机教育的漏洞,实在很有必要。 2.1空行 空行起着分隔程序段落的作用。空行得体(不过多也不过少)将使程序的布局更加清晰。空行不 会浪费内存,虽然打印含有空行的程序是会多消耗一些纸张,但是值得。所以不要舍不得用空行。 ● 【规则2-1-1】在每个类声明之后、每个函数定义结束之后都要加空行。参见示例2-1(a) ● 【规则2-1-2】在一个函数体内,逻揖上密切相关的语句之间不加空行,其它地方应加空行分隔。 参见示例2-1(b) /1空行 //空行 void Functionl(...) while (condition) { … statementl; //空行 11空行 if (condition) void Function2(...) { statement2; } else /1空行 void Function3(...) statement3; { } /1空行 statement4; 示例2-1(a)函数之间的空行 示例2-1(b)函数内部的空行 2.2代码行 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
第2章 程序的版式 版式 虽然不会影响 程序的 功能 ,但会影响 可读性。程序的版式 追求清晰 、美观,是程序 风格的 重 要构成因素。 可以把程序的版式 比喻为“书法 ”。好的“书法 ”可让人对程序 一目了然,看得兴致勃勃 。差的 程序 “书法 ”如螃蟹 爬行,让人看得索然无味,更 令维护 者烦恼 有加。请 程序 员们学习程序的 “书 法”,弥补大学计算机教育的漏洞,实在很有必要。 2.1 空行 空行起 着分隔程序 段落的作用 。空行 得体 (不过多 也不过 少)将使程序的 布局更加清晰 。空行 不 会浪费内存,虽然打印含有空行的程序 是会多消耗一些 纸张,但是值得 。所以不要舍不得用空行 。 l 【规则 2-1-1 】在每个类声明 之后、每个函数定义结 束之后都要加空行。参见示例2-1(a) l 【规则 2-1-2 】在一个函数体 内,逻揖 上密切相关 的语句 之间不加空行, 其它 地方应加空行分 隔。 参见示例2-1(b ) 示例2-1(a) 函数之间 的空行 示例2-1(b) 函数内部的空行 2.2 代码行 // 空行 void Function1( …) { … } // 空行 void Function2( …) { … } // 空行 void Function3( …) { … } // 空行 while (condition) { statement1; // 空行 if (condition) { statement2; } else { statement3; } // 空行 statement4; } 高质量C++/C编程指南 页码,14/101 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
高质量C++/C编程指南 页码,15/101 ● 【规则2-2-1】一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅 读,并且方便于写注释。 ●【规则2-2-2】if、for、while、do等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少 都要加{}。这样可以防止书写失误。 示例2-2(a)为风格良好的代码行,示例2-2(b)为风格不良的代码行。 int width; 11宽度 int width,height,,depth:/宽度高度深度 int height; /1高度 int depth; /川深度 x a +b; X a+b:y=c d:z e f y =c+d; z e+f; if (width height) if (width height)dosomething(: { dosomething(): } for (initialization;condition:update) for (initialization:condition:update) { dosomething(): dosomething () otherO; } 1空行 other ( 示例2-2(a)风格良好的代码行 示例2-2(b)风格不良的代码行 【建议2-2-1】尽可能在定义变量的同时初始化该变量(就近原则) 如果变量的引用处和其定义处相隔比较远,变量的初始化很容易被忘记。如果引用了未被初始化 的变量,可能会导致程序错误。本建议可以减少隐患。例如 int width=10:/定义并初绐化width int height=l0://定义并初绐化height int depth=l0:/定义并初绐化depth 2.3代码行内的空格 ●【规则2-3-l】关键字之后要留空格。象const、virtual、inline、case等关键字之后至少要留一个空 格,否则无法辨析关键字。象if、for、while等关键字之后应留一个空格再跟左括号‘(’,以突 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30
l 【规则 2-2-1 】一行代码 只做一件事情,如只定义 一个变量,或只写一条语句。这样的代码 容易阅 读,并且方便于写注释。 l 【规则 2-2-2 】if、for、while 、do等语句自 占一行,执行语句不得紧跟其后。不论执行语句有 多少 都要加{}。这样可以防止书写失误。 示例2-2(a)为风格良好的代码行, 示例2-2(b)为风格不良的代码行 。 示例2-2(a) 风格良好 的代码行 示例2-2(b) 风格不良 的代码行 ² 【建议 2-2-1 】尽可能在定义变量的同时初始化 该变量(就近原则) 如果变量的 引用处和其定义 处相隔比较 远,变量的 初始化 很容易 被忘记 。如果引用了未被初始化 的变量,可能会导致程序错误 。本建议可以减少隐患。例如 int width = 10; // 定义并初绐化width int height = 10; // 定义并初绐化height int depth = 10; // 定义并初绐化depth 2.3 代码行内的空格 l 【规则 2-3-1 】关键字之后要留空格。象const 、virtual 、inline 、case 等关键字之后至少要留一个空 格,否则无法辨析关键字。象if、for、while 等关 键字之后 应留一个空格 再跟左 括号 ‘(’,以突 int width; // 宽度 int height; // 高度 int depth; // 深度 int 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 < height) dosomething(); for (initialization; condition; update) { dosomething(); } // 空行 other(); for (initialization; condition; update) dosomething(); other(); 高质量C++/C编程指南 页码,15/101 http://man.chinaunix.net/develop/c&c++/c/c.htm 2006-3-30