第11章 文件结构
第11章 方便调试移植的多个文件——多文件结构
在第9章中可以看出,凡是解决通用性问题的程序,就把它编写成子函数,以便能灵活方便地互换套用。例如,求解长方形的面积,数学上可以用,房地产商计算房间面积可以用,丈量土地时也可以用……这个问题就具有通用性,所以,可将求解长方形面积的程序编写成子函数。
但是,这些子函数是在一个有复合功能的程序中的,如果房地产商需要使用某个子函数,但由于该子函数是在一个大程序中,所以必须把整个程序拿去用,而其中有些内容显然是不需要的,这就带来了某个程序移植到另一个程序时不方便的问题。C++有好办法,即把这些具有通用性的子函数制作成子文件,要移植或要拿为己用时就将整个文件拿去,像堆积木一样把多个文件架构起来,形成一个多文件结构的文件。下面就来看个究竟。
11.1 求长方形面积和半圆形面积的例题详解
【例 11-1】将例 9-1 编写成一个计算长方形面积和半圆形面积的多文件结构的程序。编程时请注意如下几点。
1)将要计算的长方形面积和半圆形面积编写成两个子函数,并分别作为两个子文件。
2)还有包含主函数 main() 的主文件。
3)再编写一个头文件,关联主文件和子文件。
4)该文件的功能同例9-1。
1. 用心分析人想通,机随人行写提纲
因为此题的功能与例 9-1 相同,所以人的做法、流程图及函数都是一样的,故可以转入下一步了。
2. 对号入座写文章,头脑运行改文章
此题是要把单文件变成多文件,函数还是多函数,只是原来例9-1的多个函数是放在一个文件中,现在要把多个函数分别放在多个文件中。这还是把一个大家庭分成多个小家庭的分家问题,读者只要遵照一个萝卜一个坑的原则,就很容易分家了。此题的分家按以下方法进行。
1)把子函数分到各子文件中,即把 rectangle 子函数分到 ex11-1-1.cpp 子文件中,把 circular 子函数分到 ex11-1-2.cpp 子文件中。
2)把这两个子函数的声明语句和常量pi的声明语句放到头文件head11-1.h中。
3)剩下的按兵不动,作为主文件。
4)还要在各个文件中(除了头文件外)留下导游 head11-1.h 的电话号码——#include"head11-1.h",以起到联系整个团队(工程文件)中的各个人员(各个文件)的作用。分完家后,编写程序如下:
#include"head11-1.h"
void main()
{
double l,w,r;
cout<<"Please input l,w and r"<<endl;
cin>>l;
cin>>w;
cin>>r;
while(!=0)
{
cout<<"the rectangle area is:"<<rectangle(l,w)<<endl;
cout<<"the half circular area is:"<<circular(r)<<endl;
cout<<"Please input l,w and r"<<endl;
cin>>l;
cin>>w;
cin>>r;
}
子文件 1//ex11-1-1.cpp
#include"head11-1.h"
double rectangle(double l,double w)
{
double V1;
V1=l*w;
return V1;
}
子文件 2 //ex11-1-2.cpp
#include"head11-1.h"
double circular(double r)
{
double V2;
V2=pi*r*r/2;
return V2;
}
头文件//head11-1.h
#include<iostream>
using namespace std;
double rectangle(double l,double w);
double circular(double r);
const double pi=3.1415926;
读者可能注意到了这一句:#include"head11-1.h",这种用双引号括起头文件名的方法
是用于包含用户自定义的头文件。而用尖括号括起头文件名的方法是用于包含 C++ 提供的头文件。
分好家了,就可以进入下一步了。
3. C++帮助且裁判,人定胜机凯歌扬
按照第2章讲的添加文件的方法或本章讲的多文件结构的工程文件的建立方法,先输入并建立工程文件,再编译各个源文件,然后连接整个工程文件,如果没有错误,则可以运行了(注意:不要对头文件进行编译和连接)。
程序的执行顺序同例9-1,只是通过头文件找到了子文件,再调用子函数而已。
运行结果:
Please input 1, w and r
53
2
the rectangle area is:15
the half circular area is:6.28319
Please input 1, w and r
63.52.5
the rectangle area is:21
the half circular area is:9.81748
Please input 1, w and r
031
结果正确。
11.2 勤奋实践,总结评分
11.2.1 习题
将第8章习题的第1~10题采用多文件结构的方式编写程序。
11.2.2 思考题
- 编写一个工程文件,在主文件中任意输入一个正整数,再调用子文件,将子文件写成用递归函数将该整数按反序输出,然后用一个头文件联系上述两个文件。
- 将第9章思考题的第2题采用多文件结构的方式编写程序。
11.2.3 总结评分,继续提高
浏览、体验了例题、习题和思考题之后,说说自己的体会和收获,并认真总结,然后按表11-1给自己评判一下可以得多少分。
| 成绩 | A | B | C | D | 不足的原因 | 改进的方法 | 备注 |
| C++知识 | 完全理解和会用 | 基本理解和会用 | 肤浅理解和会用 | 基本不理解和不会用 | |||
| 程序原创(独立编程)的比例(%) | ≥90 | 80~89 | 60~79 | <60 |
不论得分多少,大家都要总结经验,扬长避短,勤奋努力,不断提高。
最后浏览一下本章的第4节,可以先考考自己,然后再浏览,以便使重点知识掌握得更牢固。
11.3 多文件结构知识
在这章之前的章节中,所编写的程序都是用一个文件来保存的,而多文件结构,顾名思义,是由多个文件组成了一个文件结构(与第8章的结构是两个截然不同的概念,第8章的结构是指数据类型的结构,而这一章的结构是指文件的结构)。不管是单个文件的程序还是由多个文件组成的程序,在编译时,C++都要把它们构造在一个工程文件中,只不过以前都是单文件的工程文件,而这一章讲的是多文件的工程文件罢了。本章的亮点就是把单文件的工程文件转变成多文件的工程文件,学习了本章知识后,就可以建造多文件的工程文件了。
11.3.1 在什么情况下用到多文件结构
在以下一些情况下用多文件结构。
1)当程序中有通用性的问题要处理解决时。
2)当程序中有一个以上的相对较独立的问题要处理解决时。
11.3.2 关于多文件结构
1. 什么是多文件结构
多文件结构是由3个及3个以上的文件组成的工程文件,其中含有唯一的一个主文件,子文件和头文件至少各有一个。
2. 多文件结构的构成成分是什么
多文件结构(又称为多文件结构的工程文件,以下简称为多文件)的构成成分如下。
1)唯一的一个主文件。其中有唯一的一个主函数 main,可能还有其他函数。
2)至少有一个子文件,将具有通用性功能或相对独立的程序编写成子函数,并存放在子文件中。
3)至少有一个头文件,它起到导游的作用,带着主文件和子文件找到它们所需要的数据和子函数,它将主文件及子文件联系起来,用团队(工程文件)的力量来处理问题。
3. 多文件结构的工程文件的编写方法
先按照函数的分家原则,分好各个函数,再写出各个函数的提纲或流程图,然后编写
各个函数的程序,再为这些具有通用性或独立性功能的各个函数(各个源文件)配备相应的头文件,而且最好源文件名与头文件名相同(扩展名不同),以便提高程序的可读性、可维护性、可移植性(方便将某功能的子文件和配套的头文件一起移植),最后通过将单文件的工程文件(以下简称为单文件)分家来建立多文件的工程文件;也可以用分家的设计思想直接建立多文件的工程文件。上述即为多文件结构的工程文件的编写方法。
分家的设计思想是:一个萝卜一个坑,该种哪个坑就种哪个坑。
分家的原则是:
| 单文件的工程文件 | 搬家到 | 多文件的工程文件 |
| 原来的子函数或数据定义 | 搬家到 | 子文件 |
| 原来的子函数声明句 | 搬家到 | 头文件 |
| 原来的常量定义句 | 搬家到 | 头文件 |
| 原来的包含指令(如#include) | 搬家到 | 头文件 |
| 原来的宏定义 | 搬家到 | 头文件 |
| 原来的类型声明 | 搬家到 | 头文件 |
| 原来的内联函数定义 | 搬家到 | 头文件 |
| 原来的数据声明 | 搬家到 | 头文件 |
| 原来的枚举 | 搬家到 | 头文件 |
| 原来的注释 | 搬家到 | 头文件 |
| ...... | ||
| 但原来的子函数和数据定义 | 不搬家到 | 头文件 |
| 搬完上述后剩下原来的主函数 | 搬家到 | 主文件 |
注意:不论是主文件还是子文件,凡是用到头文件中声明及定义的子函数、数据和指令等的,都一定要在文件的头部加上包括指令:#include"文件名.h"(自定义的头文件用一对双引号引起来,而不用一对尖括号括住),但要切记,头文件中不要有包括自己的头文件名的包括指令。
例如,参照例11-1的分家方法来编写多文件的工程文件,一开始,可能头脑会比较乱,但先别管这些,就按照分家原则去做,编写好多文件的程序后,还按以前的方法调试,因为现在的多文件与以前的单文件相比,只是文件分块不同而已。如果实在觉得乱,每种文件就参照例11-1的一头一尾的写法,中间的函数体换成为解决问题而编写的语句即可,慢慢地,你就会有所体会。
4. 多文件的工程文件中各种文件的命名方法
多文件的工程文件中各种文件的命名方法是:文件名.扩展名。即与所有文件的命名方法相同,但要注意 C++对扩展名的规定:主文件和子文件的扩展名为cpp,头文件的扩展名为h,这是绝对要遵守的规定。
5. 多文件的工程文件在计算机上建立、编译、连接和调试的方法
(1)多文件的工程文件在计算机上的建立方法
与 2.3.6 节中的 1、5、7 所介绍的方法相同,读者可根据各种情况选用,因为以前所编写的是单文件的工程文件,现在的多文件只不过多添加了一些文件而已。
(2) 编译、连接和调试的方法
同上理,编译、连接和调试的方法也与2.3.6节中所介绍的方法相同,即都在扩展名为cpp的文件中进行,而且是逐个进行编译、连接和调试,或在工作区窗口的FileView中选中首行的工程文件名,再连接,然后修改和调试。
注意:绝对不能对头文件(扩展名为 h)的文件进行编译和连接。那么头文件错了怎么办?当在.cpp 的源文件中编译时,如果有错,同以前的方法,双击错误信息行,光标就指向相应的错误行;如果是头文件错,光标就指向头文件的某错误,然后可以分析错误,找出错误原因,修改头文件或源文件,再用上述方法编译和连接源文件,直到对每个源文件的编译、连接均没有错误时,就成功一半了——可以运行了。直到运行得到正确的结果,才是真正大功告成了(其间也可用 debug 等调试方法进行调试)。
11.3.3 如何运用多文件结构
按照前述的方法分析题意,把通用性的问题或相对较独立的问题安排在子文件中处理。
编写程序时先按分家原则练习,切记:一个萝卜一个坑。如果熟练以后,就随你用什么方法都可以了。
11.4 多文件结构的亮点
1. 在什么情况下用多文件结构的亮点
在以下一些情况下用多文件结构。
1)当程序中有通用性的问题要处理解决时。
2)当程序中有一个以上的相对较独立的问题要处理解决时。
2. 多文件结构具体知识的亮点
1)多文件结构是由3个及3个以上的文件组成的工程文件。
2)多文件结构(又称为多文件结构的工程文件)的构成成分如下。
① 唯一的一个主文件,其中有唯一的一个主函数 main,可能还有其他函数。
② 至少有一个子文件,将具有通用性功能或相对独立的程序编写成子函数,并存放在子文件中。
③ 至少有一个头文件。
3. 运用多文件结构的亮点
1)按照前述的方法分析题意,把通用性的问题或相对较独立的问题安排在子文件中处理。
2)按照多文件的知识,运用分家原则把单文件分为多文件。