第五章 多文件结构_第1页
第五章 多文件结构_第2页
第五章 多文件结构_第3页
第五章 多文件结构_第4页
第五章 多文件结构_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

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

文档简介

数据的共享与保护作用域与可见性对象的生存期数据与函数静态成员共享数据的保护友元编译预处理命令多文件结构和工程5-1-1标识符作用域1.函数原型作用域例如,以下函数原型编译器认为是相同的:

doublefunPrototype(double,double); doublefunPrototype(doublea,doubleb); doublefunPrototype(doublex,doubley);函数原型形式参数表中的标识符具有函数原型作用域

作用域指标识符能够被使用的范围。只有在作用域内标识符才可以被访问(称为可见)。函数原型中的参数,其作用域始于

"(",结束于")"。例如,设有下列原型声明:doubleArea(doubleradius);radius的作用域仅在于此,不能用于程序正文其他地方,因而可有可无。2.块作用域在语句块中声明的标识符具有块作用域//例

不同作用域的同名变量#include<iostream>usingnamespacestd;intmain(){inta=1; //外层的a{inta=1; //内层的aa++;cout<<"insidea="<<a<<endl;} //内层的a作用域结束cout<<"outsidea="<<

a

<<endl;} //外层的a作用域结束2.块作用域在语句块中声明的标识符具有块作用域//例3-25不同作用域的同名变量#include<iostream>usingnamespacestd;intmain(){int

a

=1; //外层的a{int

a

=1;

//内层的a

a

++;cout<<"insidea="<<

a

<<endl;} //内层的a作用域结束cout<<"outsidea="<<

a

<<endl;} //外层的a作用域结束insidea=2outsidea=1内层的a覆盖了外层的a3.函数作用域语句标号(后面带冒号的标识符)是惟一具有函数作用域的标识符语句标号用于switch结构中的case标号,goto语句转向入口的语句标号标号可以在函数体中任何地方使用,但不能在函数体外引用类作用域作用于特定的成员名。类X的成员M具有类作用域,对M的访问方式如下:如果在X的成员函数中没有声明同名的局部作用域标识符,那么在该函数内可以访问成员M。通过表达式x.M或者X::M访问。通过表达式prt->M4.类作用域5.文件作用域任何在函数之外声明的标识符具有文件作用域这种标识符从声明处起至文件尾的任何函数都可见//例

使用文件作用域变量#include<iostream>usingnamespacestd;inta=1,b=1;voidf1(intx){a=x*x;b=a*x;}intc;voidf2(intx,inty){a=x>y?x:y;b=x<y?x:y;c=x+y;}intmain(){f1(4); cout<<"callfunctionf1:\n";cout<<"a="<<a<<",b="<<b<<endl;f2(10,23);cout<<"callfunctionf2:\n";cout<<"a="<<a<<",b="<<b<<",c="<<c<<endl;}//例

使用文件作用域变量#include<iostream>usingnamespacestd;inta

=1,

b

=1;

voidf1(intx) {a=x*x;

b=a*x;}intc; voidf2(intx,inty) {a=x>y?x:y;b=x<y?x:y;

c=x+y;}intmain(){f1(4); cout<<"callfunctionf1:\n";cout<<"a="<<a<<",b="<<b<<endl;f2(10,23);cout<<"callfunctionf2:\n";cout<<"a="<<a<<",b="<<b<<",c="<<c<<endl;}//

a,b的作用域从这里开始//f1函数可以访问a,b//f2函数可以访问a,b//main函数可以访问a,b//例

使用文件作用域变量#include<iostream>usingnamespacestd;inta

=1,

b

=1;

voidf1(intx) {a=x*x;

b=a*x;}intc; voidf2(intx,inty) {a=x>y?x:y;b=x<y?x:y;

c=x+y;}intmain(){f1(4); cout<<"callfunctionf1:\n";cout<<"a="<<a<<",b="<<b<<endl;f2(10,23);cout<<"callfunctionf2:\n";cout<<"a="<<a<<",b="<<b<<",c="<<c<<endl;}//

a,b的作用域从这里开始//f1函数可以访问a,b//f2函数可以访问a,b//main函数可以访问a,b//

c

的作用域从这里开始,默认初始值为0//f2函数可以访问a,b,c//main函数可以访问a,b,c6.全局变量和局部变量具有文件作用域的变量称为全局变量;具有函数作用域或块作用域的变量称为局部变量全局变量声明时默认初始值为0

当局部量与全局量同名,在块内屏蔽全局量为了在块内访问全局量,可以用域运算符"::"6.全局变量和局部变量//在函数体内访问全局变量#include<iostream>usingnamespacestd;intx;intmain(){intx=256;cout<<"globalvariablex="<<::x<<endl;cout<<"localvariablex="<<x<<endl;}6.全局变量和局部变量//在函数体内访问全局变量#include<iostream>usingnamespacestd;intx

;intmain(){intx=256;cout<<"globalvariablex="<<::x<<endl;cout<<"localvariablex="<<x<<endl;}访问全局量6.全局变量和局部变量//在函数体内访问全局变量#include<iostream>usingnamespacestd;intx;intmain(){intx=256;cout<<"globalvariablex="<<::x<<endl;cout<<"localvariablex="<<x<<endl;}访问局部量6.全局变量和局部变量//在函数体内访问全局变量#include<iostream>usingnamespacestd;intx;intmain(){intx=256;cout<<"globalvariablex="<<::x<<endl;cout<<"localvariablex="<<x<<endl;}7命名空间

命名空间是类、函数、对象、类型和其他名字的集合。命名空间令软件组件之间不会产生命名冲突。

std是C++的标准名空间,包含了标准头文件中各种名字的声明。标准名空间

C++标准头文件没有扩展名。

iostreamiomaniplimitfstreamstringtypeinfostdexcept

使用标准类库的组件时,需要指定名空间。

C++标准名空间std//方法一:#include<iostream> usingnamespacestd; intmain(){inta,b;cin>>a; cin>>b; cout<<"a+b="<<a+b<<'\n'; }使用标准名空间//方法一:#include<iostream> usingnamespacestd; intmain(){inta,b;cin>>a; cin>>b; cout<<"a+b="<<a+b<<'\n'; }使用标准名空间//包含头文件//方法一:#include<iostream>

usingnamespacestd;

intmain(){inta,b;cin>>a; cin>>b; cout<<"a+b="<<a+b<<'\n'; }使用标准名空间//包含头文件//使用标准名空间std//方法一:#include<iostream>

usingnamespacestd; intmain(){inta,b;cin>>a;

cin>>b; cout<<"a+b="<<a+b<<'\n'; }使用标准名空间//包含头文件//使用标准名空间std//使用std的元素cin//方法一:#include<iostream>

usingnamespacestd; intmain(){inta,b;cin>>a;

cin>>b;

cout<<"a+b="<<a+b<<'\n'; }使用标准名空间//包含头文件//使用标准名空间std//使用std的元素cin//使用std的元素cout//方法一:#include<iostream> usingnamespacestd; intmain(){inta,b;cin>>a; cin>>b; cout<<"a+b="<<a+b<<'\n'; }使用标准名空间//包含头文件//指定使用名空间std//使用std的元素cin//使用std的元素cin//使用std的元素cout//方法二:#include<iostream>usingstd::cin;usingstd::cout;intmain(){inta,b;cin>>a; cin>>b; cout<<"a+b="<<a+b<<'\n';}使用标准名空间//方法二:#include<iostream>usingstd::cin;usingstd::cout;intmain(){inta,b;cin>>a; cin>>b; cout<<"a+b="<<a+b<<'\n';}使用标准名空间//指定使用std的元素cin//方法二:#include<iostream>usingstd::cin;

usingstd::cout;intmain(){inta,b;cin>>a; cin>>b; cout<<"a+b="<<a+b<<'\n';}使用标准名空间//指定使用std的元素cin//指定使用std的元素cout//方法二:#include<iostream>usingstd::cin;

usingstd::cout;intmain(){inta,b;

cin>>a;

cin>>b; cout<<"a+b="<<a+b<<'\n';}使用标准名空间//指定使用std的元素cin//指定使用std的元素cout//使用std的元素cin//方法二:#include<iostream>usingstd::cin;

usingstd::cout;intmain(){inta,b;cin>>a; cin>>b;

cout<<"a+b="<<a+b<<'\n';}使用标准名空间//指定使用std的元素cin//指定使用std的元素cout//使用std的元素cin//使用std的元素cout//方法二:#include<iostream>usingstd::cin;usingstd::cout;intmain(){inta,b;cin>>a; cin>>b; cout<<"a+b="<<a+b<<'\n';}使用标准名空间//指定使用std的元素cin//指定使用std的元素cout//使用std的元素cin//使用std的元素cout//方法三:#include<iostream>intmain(){inta,b;std::cin>>a;std::cin>>b;std::cout<<"a+b="<<a+b<<'\n';}使用标准名空间//方法三:#include<iostream>intmain(){inta,b;std::cin>>a;std::cin>>b;

std::cout<<"a+b="<<a+b<<'\n';}使用标准名空间//指定使用std的元素cin//方法三:#include<iostream>intmain(){inta,b;

std::cin>>a;std::cin>>b;std::cout<<"a+b="<<a+b<<'\n';}使用标准名空间//指定使用std的元素cin//指定使用std的元素cout//方法三:#include<iostream>intmain(){inta,b;std::cin>>a;std::cin>>b;std::cout<<"a+b="<<a+b<<'\n';}使用标准名空间//指定使用std的元素cin//指定使用std的元素cout定义名空间

定义命名空间语法:namespace<标识符>{<语句序列>}namespaceA{voidf();voidg();}namespaceB{voidh();namespaceC //嵌套命名空间

{voidi();}}namespaceA //为namespaceA追加说明

{voidj();}定义名空间定义命名空间语法:

usingnamespace

名空间;或

using

名空间::元素;//例

演示命名空间的使用#include<iostream>usingnamespacestd;namespaceA{voidf(){cout<<"f():fromnamespaceA\n";}voidg(){cout<<"g():fromnamespaceA\n";}namespaceB{voidf(){cout<<"f():fromnamespaceB\n";}namespaceC{voidf(){cout<<"f():fromnamespaceC\n";}}}}voidg(){cout<<"g():fromglobalnamespace“<<endl;}intmain(){g();usingnamespaceA;f();B::f();B::C::f();A::g();}调用非命名空间函数g()使用命名空间A调用命名空间函数A::g()调用函数A::B::f()调用函数A::B::C::f()调用函数A::g()可见性

可见性从另一个角度说明标识符的有效性,可见性与作用域具有一定的一致性。标识符的作用域包含可见范围,可见范围不会超过作用域。可见性在理解同名标识符的作用域嵌套时十分直观。对于外层块与内层块定义了同名标识符的,在外层作用域中,内层所定义的标识符是不可见的,即外层引用的是外层所定义的标识符;同样,在内层作用域中,外层的标识符将被内层的同名标识符屏蔽,变得不可见,即外层中同名标识符的可见范围为作用域中挖去内层块的范围。可见性

下面的程序段和图示显示作用域与可见性。

intm=1;floatx;{floatm=3.5;X=5.5;}m++;

intm,floatx作用域intm可见floatm不可见x可见floatm作用域floatm可见intm不可见x可见

5-2

生命期

(1)静态生命期

(2)局部生命期

(3)动态生命期

生命期(Lifetime)也叫生存期。生命期与存储区域相关,存储区域分为代码区、静态数据区、栈区和堆区,相应地,生命期分为静态生命期、局部生命期和动态生命期。(1)静态生命期

静态生命期指的是标识符从程序开始运行时存在,即具有存储空间,到程序运行结束时消亡,即释放存储空间。具有静态生命期的标识符存放在静态数据区,属于静态存储类型,如全局变量、静态全局变量、静态局部变量。具有静态生命期的标识符在未被用户初始化的情况下,系统会自动将其初始化为全0。

函数驻留在代码区,也具有静态生命期。所有具有文件作用域的标识符都具有静态生命期。(2)局部生命期

在函数内部或块中定义的标识符具有局部生命期,其生命期开始于执行到该函数或块的标识符声明处,结束于该函数或块的结束处。具有静态生命期的标识符存放在栈区。具有局部生命期的标识符如果未被初始化,其内容是随机的,不可用。具有局部生命期的标识符必定具有局部作用域;但反之不然,静态局部变量具有局部作用域,但却具有静态生命期。(3)动态生命期

具有动态生命期的标识符由特定的函数调用或运算来创建和释放,如调用malloc()或用new运算符为变量分配存储空间时,变量的生命期开始,而调用free()或用delete运算符释放空间或程序结束时,变量生命期结束。具有动态生命期的变量存放在堆区。关于new运算和delete运算将在指针一章中介绍。#include<iostream.h>voidfun();intmain(){fun();fun();}voidfun(){staticinta=1;inti=5;

a++;

i++;cout<<"i="<<i<<",a="<<a<<endl;}运行结果:i=6,a=2i=6,a=3i是动态生存期a是静态生存期例5-2变量的生存期与可见性#include<iostream.h>inti=1;//i为全局变量,具有静态生存期。intmain(){staticinta;//静态局部变量,有全局寿命,局部可见。

intb=-10;//b,c为局部变量,具有动态生存期。

intc=0;voidother(void);cout<<"---MAIN---\n";cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;c=c+8;other();cout<<"---MAIN---\n";cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;

i=i+10;other();}voidother(void){staticinta=2;staticintb;//a,b为静态局部变量,具有全局寿命,局部可见。

//只第一次进入函数时被初始化。

intc=10;//C为局部变量,具有动态生存期,

//每次进入函数时都初始化。

a=a+2;i=i+32;c=c+5;cout<<"---OTHER---\n";cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl;b=a;}17运行结果:---MAIN---i:1a:0b:-10c:0---OTHER---i:33a:4b:0c:15---MAIN---i:33a:0b:-10c:8---OTHER---i:75a:6b:4c:1518例5-3具有静态、动态生存期对象的时钟程序#include<iostream.h>classClock //时钟类声明{public: //外部接口

Clock(); voidSetTime(intNewH,intNewM,intNewS);//三个形参均具有函数原型作用域

voidShowTime(); ~Clock(){}private: //私有数据成员

intHour,Minute,Second;};//时钟类成员函数实现Clock::Clock()//构造函数{ Hour=0; Minute=0; Second=0;}voidClock::SetTime(intNewH,intNewM,intNewS){ Hour=NewH; Minute=NewM; Second=NewS;}voidClock::ShowTime(){ cout<<Hour<<":"<<Minute<<":"<<Second<<endl;}20ClockglobClock;//声明对象globClock,

//具有静态生存期,文件作用域intmain() //主函数{ cout<<"Firsttimeoutput:"<<endl; //引用具有文件作用域的对象:

globClock.ShowTime();//对象的成员函数具有类作用域

globClock.SetTime(8,30,30); ClockmyClock(globClock);//声明具有块作用域的对象myClock cout<<"Secondtimeoutput:"<<endl; myClock.ShowTime(); //引用具有块作用域的对象}21程序的运行结果为:Firsttimeoutput:0:0:0Secondtimeoutput:8:30:3022多文件程序结构

一个C++程序称为一个工程(.dsp)一个工程由一个或多个文件组成一个文件可以包含多个函数定义,但一个函数的定义必须完整地存在于一个文件中一个文件可以被多个应用程序共享多文件结构

一个好的软件系统应当分解为各种同构逻辑文件头文件A头文件B头文件C实现文件A.cpp实现文件B.cpp实现文件C.cpp 主文件M.cpp 例

计算圆面积和矩形面积myAreamyCircle.cppmyRect.cpp

myMain.cpp 例计算圆面积和矩形面积constdoublepi=3.14;doublecircle(doubleradius){returnpi*radius*radius;}myCircle.cppdoublerect(doublewith,doublelength){returnwith*length;}myRect.cppdoublecircle(doubleradius);doublerect(doublewidth,doublelength);myArea例3-27计算圆面积和矩形面积#include<iostream>usingnamespacestd;#include"myArea"intmain(){doublewidth,length;cout<<"Pleaseentertwonumbers:\n";cin>>width>>length;cout<<"Areaofrecttangleis:"<<rect(width,length)<<endl;doubleradius;cout<<"Pleaseenteraradius:\n";cin>>radius;cout<<"Areaofcircleis:"<<circle(radius)<<endl;}

myMain.cpp预处理指令源程序预处理器词法分析语法分析代码生成错误处理程序目标程序符号表错误信息C++编译器工作过程预处理器

改善程序的组织和管理预处理指令

所有编译指令以#

开头,每条指令单独占一行预处理指令1.文件包含include指令在编译之前把指定文件包含到该命令所在位置

#

include

<文件名>或 #

include

"文件名"

形式为:系统头文件预处理指令1.文件包含include指令在编译之前把指定文件包含到该命令所在位置

#

include

<文件名>或 #

include

"文件名"

形式为:自定义头文件预处理指令2.条件编译形式1#if

常量表达式程序段#endif形式2#if

常量表达式程序段1#else程序段2#endif形式3#if

常量表达式1程序段1

#elif

常量表达式2程序段2…#elif

常量表达式n

温馨提示

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

评论

0/150

提交评论