多文件工程和编译预处理命令_第1页
多文件工程和编译预处理命令_第2页
多文件工程和编译预处理命令_第3页
多文件工程和编译预处理命令_第4页
多文件工程和编译预处理命令_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

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

文档简介

第七章

多文件工程和编译预处理命令清华大学郑莉学习目标掌握多文件工程的组织和应用方法;掌握外部变量和外部函数的定义与使用;了解各种预编译指令的功能。2目录7.1多文件工程7.2外部变量与外部函数7.3标准C++库和命名空间7.3.1标准C++库7.3.2什么是命名空间7.3.3命名空间的定义7.3.4命名空间的使用7.3.5命名空间的嵌套3目录(续)7.4编译预处理7.4.1在程序中包含头文件7.4.2程序中的置换7.4.3条件预编译4本章主要考点多文件工程的基本组成外部函数及外部变量的基本概念无参宏定义及带参宏定义7.1多文件工程多文件结构(对于比较复杂的程序)一个源程序可以划分为多个源文件:类声明文件(.h文件)类实现文件(.cpp文件)类的使用文件(main()所在的.cpp文件)利用工程来组合各个文件。图解:用VC建立多文件的工程向工程中添加文件多文件工程的好处将类和函数的定义与对它们的使用分离将类的声明和类的实现分离便于分工合作便于软件的维护16例7-1:

设计一个圆类,并计算圆的面积和周长//文件1,类的定义,Circle.h#include<iostream>usingnamespacestd;classCircle{private: floatradius;//圆半径public:

Circle(floatr);//构造函数 floatCircumference(

);//计算圆周长 floatArea(

);//计算圆面积

};177.1多文件工程Circle.h:Circle类的定义文件,定义了类的使用接口例7-1(续)//文件2,类的实现,Circle.cpp#include”Circle.h”Circle::Circle(floatr):radius(r){}floatCircle::Circumference(){ return2.0*3.14*radius;}

floatCircle::Area(){ return3.14*radius*radius;}187.1多文件工程Circle.cpp:Circle类成员函数的具体实现例7-1(续)//文件3,主函数,7_1.cpp#include"Circle.h"intmain(){ Circlecr(5.0);

cout<<"Circumference="<<cr.Circumference()<<endl;

cout<<"Area="<<cr.Area()<<endl; return0;}197.1多文件工程使用Circle类的源程序文件//文件3,主函数,7_1.cpp#include"Circle.h"intmain(){ Circlecr(5.0);

cout<<"Circumference="<<cr.Circumference()<<endl;

cout<<"Area="<<cr.Area()<<endl; return0;}运行结果:Circumference=31.4Area=78.51、#include<文件名>

例如:#include<iostream>

表示按照标准方式搜索要包含的文件,该文件位于C++系统目录的include子目录下,一般要包含系统提供的标准文件时采用这种方式。2、#include“文件名”例如:#include“Circle.h”表示在当前目录下搜索要包含的文件,如果没有再按标准方式搜索,用户自己编写的文件一般采用这种方式。注意include有两种书写方式:7.1多文件工程自测题:在文件包含预处理语句(#include)的使用形式中,当之后的文件名用""(双括号)括起时,寻找被包含文件的方式是

()。A.先在源程序所在目录搜索,再按系统设定的标准方式搜索

B.仅仅搜索源程序所在目录

C.仅仅搜索当前目录

D.直接按系统设定的标准方式搜索目录

自测题:在文件包含预处理语句(#include)的使用形式中,当之后的文件名用<>(尖括号)括起时,寻找被包含文件的方式是

()。A.仅仅搜索源程序所在目录

B.直接按系统设定的标准方式搜索目录

C.仅仅搜索当前目录

D.先在源程序所在目录搜索,再按系统设定的标准方式搜索

补充小知识:1、一个C++源文件如何生成exe可执行文件?一个C++源文件翻译临时文件目标文件objexe可执行文件预处理编译连接2、多个C++源文件如何生成一个exe可执行文件?一个C++源文件翻译临时文件目标文件objexe可执行文件预处理编译连接一个C++源文件翻译临时文件目标文件obj预处理编译7.2外部变量与外部函数外部变量与外部函数对于大型复杂程序一般采用多文件工程,也就是一个工程由多个文件构成,但有时候我们在一个文件中定义的变量或函数,希望能够被其他文件共享,这时候我们就要把该变量或函数定义为外部变量或外部函数。声明外部变量和外部函数具体格式如下:外部变量:extern变量名;外部函数:extern函数名;26例7-2:

外部变量和外部函数的声明和使用//A.hclassA{private: doublenValue;public: A(); doubleGetValue(){returnnValue;}};277.2外部变量与外部函数A.h:A类的定义文件//A.cpp#include"A.h"#include<iostream>usingnamespacestd;doublenInitValue=10.0;voidShowMessage(){

cout<<"TheShowMessagefunctionhasbeencalled"<<endl;}A::A(){

nValue=nInitValue;

ShowMessage();}

287.2外部变量与外部函数A.cpp:A类类成员函数的具体实现注意这里例7-2(续)//B.hclassB{private: doublenValue;public: B(); doubleGetValue(){returnnValue;}};297.2外部变量与外部函数B.h:B类的定义文件例7-2(续)//B.cpp#include"B.h"externdoublenInitValue;externvoidShowMessage();B::B(){

nValue=nInitValue;

ShowMessage();}307.2外部变量与外部函数B.cpp:B类类成员函数的具体实现注意这里例7-2(续)//7-2.cpp#include"A.h"#include"B.h"#include<iostream>usingnamespacestd;voidmain(){ Aa; Bb;

cout<<"nValueofAis:"<<a.GetValue()<<endl;

cout<<"nValueofBis:"<<b.GetValue()<<endl;}317.2外部变量与外部函数运行结果:TheShowMessagefunctionhasbeencalledTheShowMessagefunctionhasbeencallednValueofTest1is:10nValueofTest2is:10外部存储类型小结问题的提出:一个文件如何使用另一个文件中的变量、函数?inta=199;1.cpp文件#include<iostream.h>externinta;voidf(){

cout<<"f:"<<a;

cout<<endl;}3.cpp文件#include<iostream.h>externinta;externvoidf();intmain(){

cout<<"main:"<<a;

cout<<endl;f();}2.cpp文件定义变量a编译器遇到externinta;它会在这三个文件中找变量a的定义,在1.cpp文件中找到了。自测题:关于外部变量的下列说法错误的是

()。A.函数外定义的变量,其前若用static修饰,则不能作为外部变量

B.外部变量只需要在一个文件中定义一次,但可以其他文件中多次声明

C.只要在主函数外面定义的变量就一定是外部变量

D.外部变量在其他文件中被使用时需要用extern进行事先声明

7.4编译预处理编译预处理编译预处理是把C++代码编译为机器指令之前执行的一个过程。文件包含程序中的置换条件预编译C++预处理指令集407.4编译预处理预处理指令功能#include包含头文件#if#else#elif#endif#ifdefined(或#ifdef)#if!defined(或#ifnedf)条件编译#define#undef符号定义和宏定义#line重新定义当前行和文件名#error产生编译时错误消息#pragma提供机器专用特性,同时保证与C++的完全兼容7.4.1在程序中包含头文件(文件包含)头文件是外部文件,通常存储在磁盘上,其内容可以通过#include预处理指令包含的程序中。

例如:#include<iostream>文件包含一般形式如下#include<标准库头文件>把自己的源文件包含在程序中,此时文件名要放在双引号中例如:#include”Circle.h”417.4编译预处理文件包含是怎么一回事?1、#include<文件名>

例如:#include<iostream>

表示按照标准方式搜索要包含的文件,该文件位于C++系统目录的include子目录下,一般要包含系统提供的标准文件时采用这种方式。2、#include“文件名”例如:#include“Circle.h”表示在当前目录下搜索要包含的文件,如果没有再按标准方式搜索,用户自己编写的文件一般采用这种方式。复习:注意include有两种书写方式7.1多文件工程7.4.2程序中的置换程序中的置换包括符号置换和宏置换。C语言中,常用符号置换定义符号常量,宏定义常用来实现简单的函数计算。447.4编译预处理符号置换符号常量定义格式为:

#define标识符字符序列如:#definePI3.14159265C++中,定义符号常量更好的办法是用const来定义,

如:constdoublepi=3.14159265;457.4编译预处理宏置换宏定义格式

#define标示符(参数列表)替换字符串如:#defineMAX(a,b)(a>b?a:b)

当程序中出现如下语句:

c=MAX(a,b);预编译过程会把它替换为:

c=(a>b?a:b);C++中这一功能已被内联函数取代。#undef

用于取消对标识符和宏的定义。467.4编译预处理取消置换#undef

用于取消对标识符和宏的定义。#undefPI#undefMAX477.4编译预处理例7-8:简单宏替换预处理指令(#define)#include<iostream>usingnamespacestd;#defineYES1#definePI3.1415926#defineRADPI/180#defineMESG“Thisisastring”#definePRINT(k)cout<<(k)<<endl#defineMAX(a,b)(a>b?a:b)#defineCC(a,b)a*b#defineCCC(a,b)(a)*(b)487.4编译预处理——7.4.2程序中的置换符号置换宏置换intmain(){

cout<<”YES=”<<YES<<endl;if(YES)cout<<”PI=”<<PI<<endl;

cout<<”RAD=”<<RAD<<endl;

cout<<MESG<<endl;

inta=0,b=2,c;c=MAX(a,b);

PRINT(c); c=CC(2+3,4+5);

PRINT(c); c=CCC(2+3,4+5);

PRINT(c); return0;}497.4编译预处理——7.4.2程序中的置换运行结果:YES=1PI=3.14159RAD=0.0174533Thisisastring21945自测题:对于以下宏定义: #defineM(x)x*x #defineN(x,y)M(x)+M(y)宏调用N(2,2+5)执行后,值为

()。A.21

B.19

C.53

D.51

以下for语句构成的循环执行了

()次。#include<iostream>usingnamespacestd;#defineN2#defineMN+1#defineNUM(M+1)*M/2intmain(){inti,n=0;for(i=1;i<=NUM;i++){n++;cout<<n<<"";}cout<<endl;return0;}A.5

B.9

C.6

D.8

7.4.3条件预编译条件编译:程序中的某些语句仅在满足某种条件时,才要编译程序对其编译;否则不被编译。条件编译命令可以出现在程序的任何位置。527.4编译预处理自测题:关于编译预处理,下列说法正确的是

()。A.用户自定义头文件时前后加条件编译指令可以避免重复包含。

B.#include“头文件名”这种格式的包含,预处理程序最后到当前目录查找文件

C.#include<头文件名>这种格式的包含,预处理程序直接到标准目录查找文件

D.含有函数原型的头文件可以出现在任何模块中,函数定义可出现在多个模块中。

例7-10:预编译指令的应用,防止类的重复定义//Point.h#ifndefPOINTCLASS#definePOINTCLASSclassPoint{private:doubleX,Y,Z;public:Point(double_X=0,double_Y=0,double_Z=0);Point(Point&);~Point(){}doubleGetX(){returnX;}doubleGetY(){returnY;}doubleGetZ(){returnZ;}};#endif597.4编译预处理——7.4.3条件预编译//Point.cpp#include"Point.h"#include<iostream>Usingnamespacestd;Point::Point(double_X,double_Y,double_Z){X=_X;Y=_Y;Z=_Z;

cout<<"Point("<<X<<","<<Y<<","<<Z<<")“<<"hasbeenconstructed."<<endl;}Point::Point(Point&point){X=point.GetX();Y=point.GetY();Z=point.GetZ();}607.4编译预处理——7.4.3条件预编译//Line.h#include“Point.h”#include<iostream>Usingnamespacestd;classLine{private:PointptStart;

温馨提示

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

评论

0/150

提交评论