《四章节C程序结构》由会员分享,可在线阅读,更多相关《四章节C程序结构(24页珍藏版)》请在金锄头文库上搜索。
1、四章节C程序结构Stillwatersrundeep.流静水深流静水深,人静心深人静心深Wherethereislife,thereishope。有生命必有希望。有生命必有希望本章主要内容变量的类型变量的类型作用域与可见性作用域与可见性文件结构与编译预处理命令文件结构与编译预处理命令名字空间名字空间26.1 变量的作用域变量的作用域 除除了了按按数数据据类类型型区区分分变变量量外外,根根据据变变量量定定义义的的位位置置,可可以以把把变变量量分分成成全全局局变变量量与与局局部部变变量量。全全局局变变量量是是指指定定义义在在函函数数体体外外部部的的变变量量,它它能能被被所所有有函函数数使使用用。局
2、局部部变变量量是是指指定定义义在在函函数数或或复复合合语语句句中中的的变变量量,只能在函数或复合语句中使用。只能在函数或复合语句中使用。 int g=100000;int sum(int x, int y) int sum = 0; for (int i=x; i=y; i+) sum = sum + i; return sum;void main() int x = 1, y = 100; cout sum(x, y) + g endl;12345678910111213g为全局变量sum()中 x、y为局部变量main()中的 x、y为局部变量变量的存储类型auto存储类存储类q属于一时性
3、存储,其存储空间可以被若干变量多次覆盖使用。register存储类存储类q存放在通用寄存器中。extern存储类存储类q在所有函数和程序段中都可引用。static存储类存储类q在内存中是以固定地址存放的,在整个程序运行期间都有效。4/* p6_1_p.cpp * 主程序 */#include using namespace std;extern void p1dispG();extern void p2dispG();extern void p2dispg();int G=0, g=0;void main() p1dispG(); p2dispG(); p2dispg(); coutin p
4、G=Gendl; coutin p g=gendl;123456789101112131415161718 / p6_1_p1.cpp#include using namespace std;extern int G;void p1dispG() G=11; coutin p1 G=Gendl; 123456789/ p6_1_p2.cpp#include using namespace std;extern int G;extern int g;void p2dispG() G=22; coutin p2 G=Gendl;void p2dispg() g=222; coutin p2 g=g
5、endl; 123456789101112131415运行结果运行结果运行结果运行结果:in p1 G=11in p2 G=22in p2 g=222in p G=22in p g=222 /* 6_2.cpp * 静态局部变量的使用 */#includeusing namespace std;void fun() static int n; int m=0; n+; m+; cout m=“ m , n=“ n endl;void main() for (int i=0; i4; i+) fun(); 12345678910111213141516171819 运行结果运行结果运行结果运行结
6、果:m=1 n=1m=1 n=2m=1 n=3m=1 n=4 6.1.2 变量的存储类型变量的存储类型 static型变量静态局部变量静态局部变量n只是在只是在函数函数fun()第一次进入时第一次进入时初始化初始化0,随后每次进,随后每次进入不再赋初值入不再赋初值 可执行程序的结构代码区(text segment)q存放CPU执行的机器指令(machine instructions)q代码区是只读的q规划了局部变量的相关信息全局数据区静态数据区q包含了程序中已初始化的全局变量、全局变量、已初始化的静态变量(全局、静态变量(全局、局部)局部)常量数据(如字符串常量)(如字符串常量)常变量7 进程
7、的结构如果将某个可执行文件加载到内存运行,如果将某个可执行文件加载到内存运行,则将成为一个进程则将成为一个进程栈区堆区已初始化全局变量静态变量和常量数据数据区可执行代码代码区初始化全局变量静态变量和常量数据可执行代码可执行文件结构可执行文件结构数据区代码区进程结构进程结构86.1.3 变量在内存中的存储变量在内存中的存储 当当一一个个程程序序准准备备运运行行时时,操操作作系系统统会会为为程程序序分分配配一一块块内内存存空空间间,C+C+程程序序的的内存通常被分为四个区:内存通常被分为四个区: 全局数据区(全局数据区(data areadata area) 代码区(代码区(code areaco
8、de area) 栈区(栈区(stack areastack area) 堆区(堆区(heap areaheap area) 全全局局变变量量、静静态态变变量量、字字符符串串常常量量、常常变变量量存存放放在在全局数据区;所所有有的的函函数数和和代代码码存存放放在在代码区;为为运运行行函函数数而而分分配配的的函函数数参参数数、局局部部变变量量、返返回回地地址址存放在存放在栈区;堆区用于动态内存分配。用于动态内存分配。 变量的生存期为为从从产产生生到到消消失失的的时时期期。全全局局变变量量、静静态态变变量量、常常变变量量生生存存周周期期为为整整个个程程序序的的生生存存周周期期,因因此此称称为为静态
9、生存期;局局部部变变量量的的生生存存周周期期起起于于函数调用,结束于函数调用结束,其生存期是动态的,因此称为函数调用,结束于函数调用结束,其生存期是动态的,因此称为动态生存期。F注意注意: : 堆空间不是系统为程序自动分配的,它是程序执行过程中由new语句为变量申请的。即使指向堆空间的指针变量消失,newnew语句语句申请的空间也不会消失。new语句申请的空间由deletedelete语句语句释放。对应于C语言的mallocmalloc语句语句 /* p6_3.cpp * 显示各类变量的内存分配*/ #include using namespace std;int k = 300;const
10、int i = 100;#define N 10const int j = 200;void fun( int i=1, int j=2 ) int k=3; static int l = 0; char *p = new charN+1; for (int m = 0; m N; m+) pm = A+m; pm = 0; cout Adddress of parameter variable:“ endl; 12345678910111213141516171819 6.1.3 变量在内存中的存储变量在内存中的存储 常变量常变量( (常量常量) )、全局变量、局部静、全局变量、局部静 态变
11、量、字符串常量在程序运行前态变量、字符串常量在程序运行前 在数据区进行分配。并且依次按照在数据区进行分配。并且依次按照 常变量、全局变量、局部静态变量常变量、全局变量、局部静态变量 的顺序从低地址向高地址分配。常的顺序从低地址向高地址分配。常 变量按定义的先后次序分配,全局变量按定义的先后次序分配,全局 变量、局部变量也一样。变量、局部变量也一样。 Adddress of parameter variable:&i=0013FF2C&j=0013FF30Adddress of local variable:&k=0013FF20&p=0013FF1C&m=0013FF18Adddress of
12、 static local variable:&l=0047773CAddress of heap: 00480410 /释放堆空间前指针的值before delete p=ABCDEFGHIJ /释放堆空间前堆中的内容after delete: 00480410 /释放堆空间后指针的值不变p=葺葺葺葺葺葺葺? /释放堆空间后,堆中的内容无意义void main() L1:fun(); L2:cout Adddress of global variable:“ endl;cout &i=“ &i t“ &j=“ &j t“ &k=“ &k endl; cout Address of funct
13、ion:“ endl;cout &fun=“ &fun t“ &main“ &main b;if (b 0)int c;. c的作用域b的作用域作用域与可见性13类和文件作用域类作用域类作用域作用于特定的成员名,类及其作用于特定的成员名,类及其对象有特殊的访问和作用域规则。对象有特殊的访问和作用域规则。不在前述各个作用域中出现的声明,具不在前述各个作用域中出现的声明,具有有文件作用域文件作用域,这样声明的标识符的作,这样声明的标识符的作用域用域开始于声明点,结束于文件尾开始于声明点,结束于文件尾。作用域与可见性程序实例程序实例14可见性的概念可见性是从对标识符的引用的角度来谈的概念。可见性是从
14、对标识符的引用的角度来谈的概念。可见性表示从可见性表示从内层作用域内层作用域向向外层作用域外层作用域“看看”时能看见什么。时能看见什么。如果标识在某处可见,则就可以在该处引用此如果标识在某处可见,则就可以在该处引用此标识符。标识符。块作用域类作用域文件作用域作用域与可见性15可见性的一般规则标识符应标识符应声明在先,引用在后声明在先,引用在后。在同一作用域中,不能声明在同一作用域中,不能声明同名同名的标识符。的标识符。对于两个嵌套的作用域对于两个嵌套的作用域,如果某个标识符在,如果某个标识符在外层外层中声明,且在中声明,且在内层内层中没有同一标识符的中没有同一标识符的声明,则该标识符在声明,则
15、该标识符在内层可见内层可见。对于两个嵌套的作用域对于两个嵌套的作用域,如果在内层作用域,如果在内层作用域内声明了与外层作用域中同名的标识符,则内声明了与外层作用域中同名的标识符,则外层作用域的标识符在外层作用域的标识符在内层不可见内层不可见。作用域与可见性16例#includeint i i; /文件作用域int main() i i = 5; int i;/块作用域i = 7;cout i=“ i endl; /输出7cout i=“ i i ;/输出5return 0;作用域与可见性返返 回回17例2 块作用域对象的生存期#includevoid fun();void main() fun
16、(); fun();void fun() static int a = 1;int i =5;a+;i+;cout i=“ i ,a=“ a endl;i,a均为块作用域均为块作用域 i是动态生存期是动态生存期 a是静态生存期是静态生存期运行结果:运行结果:i=6, a=2i=6, a=3对象的生存期18变量的生存期与可见性全局变量全局变量q具有静态生存期。静态局部变量静态局部变量q有全局寿命,局部可见。q只第一次进入函数时被初始化。一般局部变量一般局部变量q具有动态生存期。q每次进入函数时都初始化。对象的生存期19数据与函数数据存储在局部对象中,通过参数传数据存储在局部对象中,通过参数传递实
17、现共享递实现共享函数间的参数传递。函数间的参数传递。数据存储在全局对象中。数据存储在全局对象中。将数据和使用数据的函数封装在类中。将数据和使用数据的函数封装在类中。20模块化程序设计将一个程序分解成若干模块,分别放在几个源将一个程序分解成若干模块,分别放在几个源文件中,形成一个项目(文件中,形成一个项目(Project)可以对每个源文件单独进行编译,再将它们的可以对每个源文件单独进行编译,再将它们的目标代码连同标准函数库中的函数链接在一起,目标代码连同标准函数库中的函数链接在一起,形成可执行文件形成可执行文件q 当一个文件中的代码被修改后,不必对所有程序重新编译,从而节省了程序的编译时间q 使
18、程序更易于维护,给多个程序员共同编制一个大型项目提供了方便22 模块模块的构成模块的构成q扩展名为.h的头文件函数的原型声明,函数的原型声明,功能接口的描述功能接口的描述全局变量的声明全局变量的声明, 加上加上extern关键字,说明这个变量的内存关键字,说明这个变量的内存是在其他模块分配的。是在其他模块分配的。宏定义宏定义q扩展名为.cpp的源文件定义全局变量并进行相应的初始化定义全局变量并进行相应的初始化定义函数,定义函数,功能的实现细节功能的实现细节q模块之间通过相互调用函数和共享全局变量联系起来,头文件是联系的纽带。q模块全局变量,仅供本模块的调用者使用的函数和全局变量,需要在定义它们时加上static关键字23 实例用用scanf( )可以读入用户输入的整数或浮点数。可以读入用户输入的整数或浮点数。但是在输入时,它并不限制字符类型。在输入但是在输入时,它并不限制字符类型。在输入整数时,如果用户输入了字母或符号,整数时,如果用户输入了字母或符号,scanf( )将报错。将报错。如果设计一个模块,限制在输入整数和浮点数如果设计一个模块,限制在输入整数和浮点数时只可以输入合法的数字、正负号和小数点,时只可以输入合法的数字、正负号和小数点,其余的字符都忽略。其余的字符都忽略。这个模块就可应用于所有需要输入整数和浮点这个模块就可应用于所有需要输入整数和浮点数的程序。数的程序。24