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

下载本文档

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

文档简介

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

2、型形式参数表中的标识符具有函数原型作用域函数原型形式参数表中的标识符具有函数原型作用域 作用域作用域指标识符能够被使用的范围。只有在作用域内标识符才可以被指标识符能够被使用的范围。只有在作用域内标识符才可以被访问(称为可见)。访问(称为可见)。 函数原型中的参数,其作用域始于函数原型中的参数,其作用域始于(,结束于,结束于)。 例如,设有下列原型声明:例如,设有下列原型声明:double Area(double radius);double Area(double radius);radius 的作用域仅在于此,不能用于程序正文其他地方,因而可有可无。2块作用域块作用域 在语句块中声明的标识符

3、具有块作用域在语句块中声明的标识符具有块作用域 / 例例 不同作用域的同名变量不同作用域的同名变量#includeusing namespace std ;int main() int a = 1;/ 外层的外层的a int a = 1 ;/ 内层的内层的a a + ; cout inside a = a endl ; / 内层的内层的a作用域结束作用域结束cout outside a = a endl ;/ 外层的外层的a作用域结束作用域结束2块作用域块作用域 在语句块中声明的标识符具有块作用域在语句块中声明的标识符具有块作用域 / 例例3-25 不同作用域的同名变量不同作用域的同名变量#i

4、ncludeusing namespace std ;int main() int = 1;/ 外层的外层的a int a = 1 ;/ 内层的内层的a a + ; cout inside a = a endl ; / 内层的内层的a作用域结束作用域结束cout outside a = M4类作类作用域用域 5文件作用域文件作用域 任何在函数之外声明的标识符具有文件作用域任何在函数之外声明的标识符具有文件作用域 这种标识符从声明处起至文件尾的任何函数都可见这种标识符从声明处起至文件尾的任何函数都可见 / 例例 使用文件作用域变量使用文件作用域变量#include using namespace

5、 std ;int a = 1, b = 1 ;void f1( int x ) a = x * x ; b = a * x ;int c ; void f2( int x, int y ) a = x y ? x : y ; b = x y ? x : y ; c = x + y ; int main() f1( 4 ) ; cout call function f1 :n ; cout a = a , b = b endl ; f2 (10, 23 ) ; cout call function f2 :n ; cout a = a , b = b , c = c endl ;/ 例例 使用

6、文件作用域变量使用文件作用域变量#include using namespace std ;int a = 1, b = 1 ;void f1( int x ) a = x * x ; b = a * x ;int c ; void f2( int x, int y ) a = x y ? x : y ; b = x y ? x : y ; c = x + y ; int main() f1( 4 ) ; cout call function f1 :n ; cout a = a , b = b endl ; f2 (10, 23 ) ; cout call function f2 :n ;

7、cout a = a , b = b , c = endl ;/ a, b的作用域从这里开始的作用域从这里开始/ f1函数可以访问函数可以访问a,b/ f2函数可以访问函数可以访问a, b/ main 函数可以访问函数可以访问a, b/ 例例 使用文件作用域变量使用文件作用域变量#include using namespace std ;int a = 1, b = 1 ;void f1( int x ) a = x * x ; b = a * x ;int c ; void f2( int x, int y ) a = x y ? x : y ; b = x y ? x : y ; c =

8、x + y ; int main() f1( 4 ) ; cout call function f1 :n ; cout a = a , b = b endl ; f2 (10, 23 ) ; cout call function f2 :n ; cout a = a , b = b , c = endl ;/ a, b的作用域从这里开始的作用域从这里开始/ f1函数可以访问函数可以访问a,b/ f2函数可以访问函数可以访问a, b/ main 函数可以访问函数可以访问a, b/ 的作用域从这里开始,默认初始值为的作用域从这里开始,默认初始值为0/ f2函数可以访问函数可以访问a, b, /

9、main 函数可以访问函数可以访问a, b, 6全局变量和局部变量全局变量和局部变量 具有文件作用域的变量称为全局变量;具有函数作用域具有文件作用域的变量称为全局变量;具有函数作用域 或块作用域的变量称为局部变量或块作用域的变量称为局部变量 全局变量声明时默认初始值为全局变量声明时默认初始值为0 0 当局部量与全局量同名,在块内当局部量与全局量同名,在块内全局量全局量 为了在块内访问全局量,可以用域运算符为了在块内访问全局量,可以用域运算符 : : 6全局变量和局部变量全局变量和局部变量 / 在函数体内访问全局变量在函数体内访问全局变量#includeusing namespace std ;

10、int x ;int main() int x = 256 ; cout global variable x = :x endl ; cout local variable x = x endl ;6全局变量和局部变量全局变量和局部变量 / 在函数体内访问全局变量在函数体内访问全局变量#includeusing namespace std ;int ;int main() int x = 256 ; cout global variable x = endl ; cout local variable x = x endl ;访问全局量访问全局量6全局变量和局部变量全局变量和局部变量 / 在函

11、数体内访问全局变量在函数体内访问全局变量#includeusing namespace std ;int x ;int main() int = 256 ; cout global variable x = :x endl ; cout local variable x = endl ;访问局部量访问局部量6全局变量和局部变量全局变量和局部变量 / 在函数体内访问全局变量在函数体内访问全局变量#includeusing namespace std ;int x ;int main() int x = 256 ; cout global variable x = :x endl ; cout l

12、ocal variable x = x endl ;7 命命名空间名空间 命名空间是类、函数、对象、类型和其他名字的集合。命名空间是类、函数、对象、类型和其他名字的集合。 命名空间令软件组件之间不会产生命名冲突。命名空间令软件组件之间不会产生命名冲突。 std是是C+的标准名空间,包含了标准头文件中各种名字的声明。的标准名空间,包含了标准头文件中各种名字的声明。 标标准名空间准名空间 C+标准头文件没有扩展名。标准头文件没有扩展名。iostream iomanip limit fstream string typeinfo stdexcept 使用标准类库的组件时,需要指定名空间。使用标准类库

13、的组件时,需要指定名空间。 C+标准名空间标准名空间 std/方法一:方法一:#includeusing namespace std;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /方法一:方法一:#includeusing namespace std;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /包含头文件包含头文件/方法一:方法一:#includeusing namespace std;int main() int a, b; cin

14、a; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /包含头文件/使用标准名空间使用标准名空间std/方法一:方法一:#includeusing namespace std;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /包含头文件/使用标准名空间std/使用使用std的元素的元素cin/方法一:方法一:#includeusing namespace std;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /包含头文件

15、/使用标准名空间std/使用std的元素cin/使用使用std的元素的元素cout/方法一:方法一:#includeusing namespace std;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /包含头文件包含头文件/指定使用名空间指定使用名空间std/使用使用std的元素的元素cin/使用使用std的元素的元素cin/使用使用std的元素的元素cout/方法二:方法二:#includeusing std:cin; using std:cout;int main() int a, b; cina; cinb;

16、 couta+b=a+bn; 使用标准名空间使用标准名空间 /方法二:方法二:#includeusing std:cin; using std:cout;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /指定使用指定使用std的元素的元素cin /方法二:方法二:#includeusing std:cin; using std:cout;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /指定使用std的元素cin /指定使用指定使用std的元素

17、的元素cout /方法二:方法二:#includeusing std:cin; using std:cout;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /指定使用std的元素cin /指定使用std的元素cout /使用使用std的元素的元素cin/方法二:方法二:#includeusing std:cin; using std:cout;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /指定使用std的元素cin /指定使用std的元素

18、cout /使用std的元素cin/使用使用std的元素的元素cout/方法二:方法二:#includeusing std:cin; using std:cout;int main() int a, b; cina; cinb; couta+b=a+bn; 使用标准名空间使用标准名空间 /指定使用指定使用std的元素的元素cin /指定使用指定使用std的元素的元素cout /使用使用std的元素的元素cin/使用使用std的元素的元素cout/方法三:方法三:#includeint main() int a, b; std:cina; std:cinb; std:couta+b=a+bn;

19、使用标准名空间使用标准名空间 /方法三:方法三:#includeint main() int a, b; std:cina; std:cinb; std:couta+b=a+bn; 使用标准名空间使用标准名空间 /指定使用指定使用std的元素的元素cin /方法三:方法三:#includeint main() int a, b; std:cina; std:cinb; std:couta+b=a+bn; 使用标准名空间使用标准名空间 /指定使用指定使用std的元素的元素cin /指定使用指定使用std的元素的元素cout /方法三:方法三:#includeint main() int a, b

20、; std:cina; std:cinb; std:couta+b=a+bn; 使用标准名空间使用标准名空间 /指定使用指定使用std的元素的元素cin /指定使用指定使用std的元素的元素cout 定定义名空间义名空间 定义命名空间语法:定义命名空间语法:namespace namespace A void f(); void g(); namespace B void h(); namespace C /嵌套命名空间嵌套命名空间 void i(); namespace A /为为namespace A追加说明追加说明 void j(); 定义名空间定义名空间定义命名空间语法:定义命名空间语

21、法:using namespace 名空间名空间 ;或或using 名空间名空间:元素元素 ;/例例 演示命名空间的使用演示命名空间的使用 #includeusing namespace std;namespace A void f() cout f() : from namespace An; void g() cout g() : from namespace An ; namespace B void f() cout f() : from namespace Bn ; namespace C void f() cout f() : from namespace Cn ; void g(

22、) cout g() : from global namespace“ endl ;int main() g() ; using namespace A; f() ; B:f() ; B:C:f() ; A:g() ;调用非命名空间调用非命名空间函数函数g() 使用命名空间使用命名空间A调用命名空间调用命名空间函数函数A:g() 调用函数调用函数A:B:f() 调用函数调用函数A:B:C:f() 调用函数调用函数A:g() 2可见性可见性 可见性可见性从另一个角度说明标识符的有效性,可见性与作用域具从另一个角度说明标识符的有效性,可见性与作用域具有一定的一致性。有一定的一致性。标识符的作用域包

23、含可见范围,可见范围不标识符的作用域包含可见范围,可见范围不会超过作用域会超过作用域。可见性在理解同名标识符的。可见性在理解同名标识符的作用域嵌套作用域嵌套时十分时十分直观。直观。对于外层块与内层块定义了同名标识符的,在外层作用域中,对于外层块与内层块定义了同名标识符的,在外层作用域中,内层所定义的标识符是不可见的,即外层引用的是外层所定义内层所定义的标识符是不可见的,即外层引用的是外层所定义的标识符;同样,的标识符;同样,在内层作用域中,外层的标识符将被内层的在内层作用域中,外层的标识符将被内层的同名标识符屏蔽,变得不可见同名标识符屏蔽,变得不可见,即外层中同名标识符的可见范,即外层中同名标

24、识符的可见范围为作用域中挖去内层块的范围。围为作用域中挖去内层块的范围。2可见性可见性 下面的程序段和图示显示作用域与下面的程序段和图示显示作用域与可见性。可见性。 int m=1;float x; float m=3.5; X=5.5;m+; int m, float x作用域作用域int m可见可见float m不可见不可见x可见可见float m作用域作用域float m可见可见int m不可见不可见x可见可见 5-2 生命期生命期 生命期(生命期(Life timeLife time)也叫生存期。生命期与存储区域相关,)也叫生存期。生命期与存储区域相关,存储区域分为代码区、静态数据区、

25、栈区和堆区,相应地,存储区域分为代码区、静态数据区、栈区和堆区,相应地,生命期分为生命期分为静态生命期、局部生命期和动态生命期静态生命期、局部生命期和动态生命期。(1)静态生命期静态生命期 静态生命期静态生命期指的是标识符从程序开始运行时指的是标识符从程序开始运行时存在,即具有存储空间,到程序运行结束时消亡,存在,即具有存储空间,到程序运行结束时消亡,即释放存储空间。具有静态生命期的标识符存放即释放存储空间。具有静态生命期的标识符存放在静态数据区,属于静态存储类型,如全局变量、在静态数据区,属于静态存储类型,如全局变量、静态全局变量、静态局部变量。静态全局变量、静态局部变量。具有静态生命期具有

26、静态生命期的标识符在未被用户初始化的情况下,系统会自的标识符在未被用户初始化的情况下,系统会自动将其初始化为全动将其初始化为全0 0。 函数驻留在代码区,也具有静态生命期。所函数驻留在代码区,也具有静态生命期。所有具有文件作用域的标识符都具有静态生命期。有具有文件作用域的标识符都具有静态生命期。(2)局部生命期局部生命期 在函数内部或块中定义的标识符具有局部生命在函数内部或块中定义的标识符具有局部生命期,其生命期开始于执行到该函数或块的标识符声期,其生命期开始于执行到该函数或块的标识符声明处,结束于该函数或块的结束处。具有静态生命明处,结束于该函数或块的结束处。具有静态生命期的标识符存放在栈区

27、。期的标识符存放在栈区。具有局部生命期的标识符具有局部生命期的标识符如果未被初始化,其内容是随机的,不可用如果未被初始化,其内容是随机的,不可用。 具有局部生命期的标识符必定具有局部作用域;具有局部生命期的标识符必定具有局部作用域;但反之不然,但反之不然,静态局部变量具有局部作用域,但却静态局部变量具有局部作用域,但却具有静态生命期具有静态生命期。(3)动态生命期动态生命期 具有动态生命期的标识符由特定的函数调具有动态生命期的标识符由特定的函数调用或运算来创建和释放用或运算来创建和释放,如调用,如调用mallocmalloc()()或用或用newnew运算符为变量分配存储空间时,变量的生命运算

28、符为变量分配存储空间时,变量的生命期开始,而调用期开始,而调用free()free()或用或用deletedelete运算符释放运算符释放空间或程序结束时,变量生命期结束。具有动空间或程序结束时,变量生命期结束。具有动态生命期的变量存放在堆区。关于态生命期的变量存放在堆区。关于newnew运算和运算和deletedelete运算将在指针一章中介绍。运算将在指针一章中介绍。 #includevoid fun();int main() fun(); fun();void fun() static int a=1; int i=5; a+; i+; couti=i,a=aendl;运行结果:i=6,

29、 a=2i=6, a=3i是动态生存期a是静态生存期例5-2 变量的生存期与可见性#includeint i=1; / i 为全局变量,具有静态生存期。int main() static int a;/ 静态局部变量,有全局寿命,局部可见。 int b=-10; / b, c为局部变量,具有动态生存期。 int c=0; void other(void); cout-MAIN-n; cout i: i a: a b: b c: cendl; c=c+8; other(); cout-MAIN-n; cout i: i a: a b: b c: cendl; i=i+10; other(); v

30、oid other(void) static int a=2; static int b; / a,b为静态局部变量,具有全局寿命,局部可见。 /只第一次进入函数时被初始化。 int c=10; / C为局部变量,具有动态生存期, /每次进入函数时都初始化。 a=a+2; i=i+32; c=c+5; cout-OTHER-n; cout i: i a: a b: b c: cendl; b=a;17运行结果:-MAIN- i: 1 a: 0 b: -10 c: 0-OTHER- i: 33 a: 4 b: 0 c: 15-MAIN- i: 33 a: 0 b: -10 c: 8-OTHER-

31、 i: 75 a: 6 b: 4 c: 1518例5-3具有静态、动态生存期对象的时钟程序#includeclass Clock/时钟类声明public:/外部接口Clock();void SetTime(int NewH, int NewM, int NewS); /三个形参均具有函数原型作用域void ShowTime();Clock()private:/私有数据成员int Hour,Minute,Second;/时钟类成员函数实现Clock:Clock() /构造函数 Hour=0;Minute=0;Second=0;void Clock:SetTime(int NewH,int New

32、M,int NewS) Hour=NewH;Minute=NewM;Second=NewS;void Clock:ShowTime() coutHour:Minute:Secondendl;20Clock globClock;/声明对象globClock, /具有静态生存期,文件作用域int main()/主函数coutFirst time output:endl;/引用具有文件作用域的对象:globClock.ShowTime();/对象的成员函数具有类作用域globClock.SetTime(8,30,30);Clock myClock(globClock); /声明具有块作用域的对象my

33、ClockcoutSecond time output:endl;myClock.ShowTime();/引用具有块作用域的对象21程序的运行结果为:First time output:0:0:0Second time output:8:30:3022多多文件程序结构文件程序结构 一个一个C+C+程序称为一个工程(程序称为一个工程(.dsp.dsp) 一个工程由一个或多个文件组成一个工程由一个或多个文件组成 一个文件可以包含多个函数定义,但一个函数的定义必须一个文件可以包含多个函数定义,但一个函数的定义必须 完整地存在于一个文件中完整地存在于一个文件中 一个文件可以被多个应用程序共享一个文件可

34、以被多个应用程序共享多多文件结构文件结构 一个好的软件系统应当分解为各种同构逻辑文件一个好的软件系统应当分解为各种同构逻辑文件头文件头文件A头文件头文件B头文件头文件C实现文件实现文件A.cpp实现文件实现文件B .cpp实现文件实现文件C .cpp主主 文文 件件 M.cpp例例 计算圆面积和矩形面积计算圆面积和矩形面积myAreamyCircle.cppmyRect.cppmyMain.cpp例计例计算圆面积和矩形面积算圆面积和矩形面积const double pi = 3.14 ;double circle ( double radius ) return pi * radius * r

35、adius ; myCircle.cppdouble rect ( double with, double length ) return with * length ; myRect.cppdouble circle( double radius ) ;double rect( double width, double length ) ; myArea例例3-27 计算圆面积和矩形面积计算圆面积和矩形面积#includeusing namespace std ;#include myAreaint main() double width, length ; cout width lengt

36、h ; cout Area of recttangle is: rect( width, length ) endl ; double radius ; cout radius ; cout Area of circle is: circle( radius ) endl ; myMain.cpp预预处理指令处理指令 源程序源程序预处理器预处理器词法分析词法分析语法分析语法分析代码生成代码生成 错误处理程序错误处理程序 目标程序目标程序 符号表符号表 错误信息错误信息C+编译器工作过程编译器工作过程预处理器预处理器 改善程序的组织和管理改善程序的组织和管理预处理指令预处理指令 所有编译指令以所

37、有编译指令以 # 开头,每条指令单独占一行开头,每条指令单独占一行预预处理指令处理指令 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程序段程序段n# else程序段程序段n+1# endif预预处理指令处理指令 3宏定义指令宏定义指令 用指定正文替

温馨提示

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

评论

0/150

提交评论