版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第六章 C+程序的结构6.1 变量的类型 除了按数据类型区分变量外,根据变量定义的位置,可以把变量分成全局变量与局部变量。全局变量是指定义在函数体外部的变量,它能被所有函数使用。局部变量是指定义在函数或复合语句中的变量,只能在函数或复合语句中使用。 电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型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; coutsum(x,y)+gendl;12345
2、678910111213g为全局变量sum()中 x、y为局部变量main()中的 x、y为局部变量6.1.2 变量的存储类型 C+中变量有auto 、extern、register、static四种存储类型。1.auto说明符 auto说明符说明定义的是一个局部变量。局部变量默认存储类型为auto, 所以在程序中很少使用auto说明符说明。2. register说明符 register说明符在定义变量时说明此变量存储在CPU中的寄存器中,以加快存取速度。一般编译器自己选择几个变量采用寄存器存储,不需要在程序中声明。3. extern说明符 如果一个完整的计算机程序很大,分成多个模块,放在不同
3、的文件中,分开编译成目标文件,最后连接成一个完整的可执行代码。对于所有模块共同使用的全局变量,如果在所有的模块中都定义,在连接时就会出错。 解决办法是只在一个模块中定义全局变量,在其他模块中用extern说明这是一个“外来”的全局变量。电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型/* p6_1_p.cpp * 主程序 */#include using namespace std;extern void p1dispG();extern void p2dispG();extern void p2d
4、ispg();int G=0,g=0;void main() p1dispG();p2dispG();p2dispg();coutin p 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 p
5、2dispG() G=22; coutin p2 G=Gendl;void p2dispg() g=222; coutin p2 g=gendl; 123456789101112131415运行结果:in p1 G=11in p2 G=22in p2 g=222in p G=22in p g=222 6.1.2 变量的存储类型 4. static说明符 static说明符用于在定义变量时将变量声明为成static(静态)变量。 其格式为: static可用来声明全局静态变量和局部静态变量。当声明全局静态变量时,全局静态变量只能供本模块使用,不能被其它模块再声明为extern变量。 例如:将程序
6、p6_1_p.cpp中的全局变量声明为: static int G=0; 那么在其他模块中就不能声明为: extern int G; /错误,G已经是一个static变量; 电子科技大学计算机学院 软件学院static 数据类型 变量名=初值; C+语言程序设计教程 第6章构造数据类型注意: 当一个局部变量声明为static变量,它既具有局部变量的性质:只能在函数体局部存取;又具有全局变量的性质:函数多次进入,变量的值只初始化一次。因此静态局部变量实质是一个供函数局部存取的全局变量。 6.1.2 变量的存储类型 static型变量电子科技大学计算机学院 软件学院/* 6_2.cpp * 静态局
7、部变量的使用 */#includeusing namespace std;void fun() static int n; int m=0; n+; m+; coutm=m, n=nendl;void main() for (int i=0;i4;i+) fun(); 12345678910111213141516171819 C+语言程序设计教程 第6章构造数据类型运行结果:m=1 n=1m=1 n=2m=1 n=3m=1 n=4 静态局部变量n只是在函数fun()第一次进入时初始化0,随后每次进入不再赋初值 6.1.3 变量在内存中的存储 当一个程序准备运行时,操作系统会为程序分配一块内存
8、空间,C+程序的内存通常被分为四个区: 全局数据区(data area) 代码区(code area) 栈区(stack area) 堆区(heap area) 全局变量、静态变量、字符串常量、常变量存放在全局数据区;所有的函数和代码存放在代码区;为运行函数而分配的函数参数、局部变量、返回地址存放在栈区;堆区用于动态内存分配。 变量的生存期为从产生到消失的时期。全局变量、静态变量、常变量生存周期为整个程序的生存周期,因此称为静态生存期;局部变量的生存周期起于函数调用,结束于函数调用结束,其生存期是动态的,因此称为动态生存期。电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类
9、型注意: 堆空间不是系统为程序自动分配的,它是程序执行过程中由new语句为变量分配的。即使指向堆空间的指针变量消失,new语句分配的空间也不会消失。new语句分配的空间由delete语句释放。 6.1.3 变量在内存中的存储 常变量(常量)、全局变量、局部静态变量、字符串常量在程序运行前在数据区进行分配。并且依次按照常变量、全局变量、局部静态变量的顺序从低地址向高地址分配。常变量按定义的先后次序分配,全局变量、局部变量也一样。 电子科技大学计算机学院 软件学院/* p6_3.cpp * 显示各类变量的内存分配 */ #include using namespace std;int k=300;
10、const 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;mn;m+) pm=A+m; pm=0; coutAdddress of parameter variable:endl; 12345678910111213141516171819 C+语言程序设计教程 第6章构造数据类型6.1.2 变量的存储类型 电子科技大学计算机学院 软件学院 cout&i=&it&j=&jendl; coutAddd
11、ress of local variable:endl; cout&k=&kt&p=&pt&m=&mendl; coutAdddress of static local variable:endl; cout&l=&lendl; coutAddress of heap: (void *)pendl; coutbefore delete p=pendl; delete p; coutafter delete: (void *)pendl; coutp=pendl;void main() L1:fun(); L2:coutAdddress of global variable:endl;cout&
12、i=&it&j=&jt&k=&kendl; coutAddress of function:endl;cout&fun=&funt&main&mainendl; 20212223 2425262728293031323334353637 39C+语言程序设计教程 第6章构造数据类型运行结果:Adddress of parameter variable:&i=0013FF2C&j=0013FF30Adddress of local variable:&k=0013FF20&p=0013FF1C&m=0013FF18Adddress of static local variable:&l=0047
13、773CAddress of heap: 00480410 /释放堆空间前指针的值before delete p=ABCDEFGHIJ /释放堆空间前堆中的内容after delete: 00480410 /释放堆空间后指针的值不变p=葺葺葺葺葺葺葺? /释放堆空间后,堆中的内容无意义Adddress of global variable:&i=0046C01C&j=0046C020&k=00474DC0Address of function:&fun=004010A0&main=0040123F 6.1.2 变量的存储类型电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类
14、型解释 :当函数被调用时才为函数的形参、返回代码地址、局部变量分配空间。由于空间在栈中,所以从栈底开始依次按形参、返回代码地址、局部变量的顺序从高地址向低地址分配。其中,在分配形参地址时,按从右向左的顺序;分配各局部变量的地址时,按定义的先后次序。当函数调用结束,该函数占用的栈空间收回。收回的顺序(即各变量消失的顺序)与分配的顺序相反。程序运行时,系统为各个函数的执行代码在代码段中分配空间,然后将代码调入内存。各函数在代码区的排列次序按函数定义的先后次序。程序运行结束,程序占用的代码段空间收回。常变量(常量)、全局变量、局部静态变量、字符串常量在程序运行前在数据区进行分配。并且依次按照常变量、
15、全局变量、局部静态变量的顺序从低地址向高地址分配。常变量按定义的先后次序分配,全局变量、局部变量也一样。当程序运行结束后,各全局变量的空间被系统收回,收回的顺序与分配的顺序相同,即:先分配先收回。堆空间不是系统为程序自动分配的,它是程序执行过程中由new语句为变量分配的。即使指向堆空间的指针变量消失,new语句分配的空间也不会消失。New语句分配的空间由delete语句释放。变量的生存期为从产生到消失的时期。全局变量、静态变量、常变量生存周期为整个程序的生存周期,因此称为静态生存期;局部变量的生存周期起于函数调用,结束于函数调用结束,其生存期是动态的,因此称为动态生存期。 电子科技大学计算机学
16、院 软件学院6.2 标识符的作用域与可见性 标识符的作用域是标识符在程序源代码中的有效范围,从小到大分为函数原型作用域、块作用域(局部作用域),文件作用域(全局作用域)。1. 函数原型作用域 函数原型作用域是C+程序中最小作用域。函数原型声明时形式参数的作用范围就是函数原型的作用域。 例如:有下列函数声明: fun(int i, int j); 标识符i、j的作用域为函数原型,即函数fun形参的两个括号之间,在其他地方不能引用这些标识符。2. 块作用域 所谓的块就是用括起来的一段程序,在块中定义的标识符,作用域从声明处开始,一直到块的大括号为止。其中有下列情况属于一个块: (1) 函数的形参与
17、函数体属于一个块; (2) for()语句中,括号()中属于一个块; 电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型6.2 标识符的作用域与可见性电子科技大学计算机学院 软件学院/* p6_4.cpp * * 标识符作用域 */ #include using namespace std;int i=100,j=200;void fun(int i=2) coutL2: i=iendl; int i=3; coutL3: i=iendl; for(int i=4;i5;coutL6:i=iendl,i+) 123456789101112131415C+语言程序设计教程
18、第6章构造数据类型i=5i=4i=3i=2 6.2 标识符的作用域与可见性电子科技大学计算机学院 软件学院 coutL4: i=iendl; int i=5 i+; coutL5: i=iendl; void main() fun(); 16171819 20212223 2425262728C+语言程序设计教程 第6章构造数据类型运行结果:L2: i=2L3: i=3L4: i=4L5: i=6L6: i=4 6.2 标识符的作用域与可见性 4. 可见性 程序运行到某一处,能够引用到的标识符,称为该处可见到的标识符。可见性表示从某处能看到什么。可见性的一般规则是: (1) 块内层可以看到外层
19、定义的各种标识符。 (2) 如果内、外层块定义的标识符同名,实质代表不同的实体,内层只能看到与 之最近的标识符,相当于外层标识符被内层同名的标识符隐藏了。 (3) 内层标识符的作用域不能覆盖(作用)到外层,所以外层看不到内层的标识符。 (4) 同层中,后面语句定义的标识符作用域不能作用到前面语句和块。因此,前 面语句看不到后面语句定义的标识符。 (5) 作用域作用的方向为从外向内、从前向后;可见性的方向则从内向外、从后 向前。电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型6.3 程序的文件结构与编译预处理命令 一个高级语言源程序在计算机上运行,必须先用编译程序将其翻译
20、为机器语言。在编译之前还要做某些预处理工作,如去掉注释,变换格式等。 C+源程序中以#开头、以换行符结尾的行称为预处理命令。预处理命令不是C+语言的语法成分,在编译前由预处理器执行,在目标程序中,不含预处理指令对应的机器码。因此,预处理命令不以分号结尾。 许多预处理命令更适合程序员,但为了处理C遗留的代码,C+编程者也应该熟悉预处理命令。 电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型6.3 程序的文件结构与编译预处理命令 1. 文件包括 # include命令 文件包含是指在一个C+源程序中通过#include命令将另一个文件(通常是.h、.c或.cpp为后缀的文件
21、)的全部内容包含进来。 文件包含处理命令的一般格式为: 编译时预编译器将被包含文件的内容插入到源程序中#include命令的位置,以形成新的源程序。 电子科技大学计算机学院 软件学院 #include 或 #include 被包含文件名C+语言程序设计教程 第6章构造数据类型电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型/* p6_5.cpp * 主程序 */#include using namespace std;#include mymath.hvoid main() coutmax(5,6)endl; 12345678910/* mymath.h * 一些自定义
22、的数学函数 */#include using namespace std;int max(int x,int y) return xy?x:y; 12345678910#include using namespace std;#include using namespace std;int max(int x,int y) return xy?x:y;void main() coutmax(5,6)endl;1234567891011 对主程序p6_5.cpp编译时预处理程序执行#includemymath.h, 将p6_5.cpp变成: 6.3 程序的文件结构与编译预处理命令 2. 不带参数
23、的宏定义 宏定义分为两种:不带参数的宏定义和带参数的宏定义。 #define 命令定义一个标识符来代表一个字符串(表达式),在源程序中发现该标识符时,都用该字符串替换,以形成新的源程序。这种标识符称为宏名(macro name),将程序中出现的与宏名相同的标识符替换为字符串的过程称为宏替换或宏代换(macro substitulition)。 不带参数的宏定义的一般形式是: 其中:#define是宏定义命令名称。标识符(宏名)被定义用来代表后面的单词串。单词串是宏的内容文本,也称为宏体,可以是任意以回车换行结尾的文字。单词串一般不用分号结尾。电子科技大学计算机学院 软件学院 #define 标
24、识符 单词串 C+语言程序设计教程 第6章构造数据类型电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型 源程序#include using namespace std;#define SIZE 10#define NEWLINE n#define TAB tvoid main() int aSIZE, i; for (i = 0; i SIZE; i+) coutaiTAB; coutNEWLINE;123456789101112预编译处理(宏替换)后的源程序#include using namespace std;#define SIZE 10#define NEWL
25、INE n#define TAB tvoid main() int a 10 , i; for (i = 0; i 10 ; i+) coutai t; cout (y) ) ? (x) : (y) )void main() float a = -2.5, b = -3.2; coutMAX(a,b)endl; 123456预编译处理(宏替换)后的新源程序 void main() float a = 2.5, b = -3.2; cout (b) ) ? (a) : (b) ) (b) ) ? (a) : (b) ),然后将MAX(a,b)替换成( ( (a) (b) ) ? (a) : (b
26、) )。6.3 程序的文件结构与编译预处理命令4. 条件编译 一般情况下,源程序中所有的语句都参加编译,但有时也希望根据一定的条件去编译源文件的不同部分,这就是条件编译。条件编译使得同一源程序在不同的编译条件下得到不同的目标代码。 条件编译有几种常用的形式,现分别介绍如下: (1) #if #endif形式 #if #endif形式的条件编译的格式为: 其中:elif是else if的缩写,但不可写成else if。#elif和#else可以省略,但#endif不能省略,它是#if命令的结尾。#elif命令可以有多个。if后面的条件必须是一个常量表达式,通常会用到宏名,条件可以不加括号() 电
27、子科技大学计算机学院 软件学院#if 条件1 程序段1#elif 条件2 程序段2 .#else 程序段n#endifC+语言程序设计教程 第6章构造数据类型电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型 源程序#define USA 0#define CHINA 1#define ENGLAND 2#define ACTIVE_COUNTRY USA#if ACTIVE_COUNTRY = = USAchar *currency = dollar; #elif ACTIVE_COUNTRY = = ENGLANDchar *currency = pound;#els
28、echar *currency = yuan;#endifvoid main ( ) float money; cinmoney; coutmoneycurrencymoney; coutmoneycurrencyendl; 123456789101112131415161718注意: #if和#elif常常与defined命令配合使用 6.3 程序的文件结构与编译预处理命令(2) #ifdef #endif #ifdef #endif形式的条件编译的格式为: 其中:#else可以省略,#endif不能省略,它是#if命令的结尾。在#ifdef和#else之间可以加多个#elif命令。“#if
29、def 宏名”的含义是判断是否定义了宏,它等价于“#if defined(宏名)”。其作用是:如果宏名已被#define行定义,则编译程序段1,否则编译程序段2。 电子科技大学计算机学院 软件学院#ifdef 宏名 程序段1#else 程序段2#endifC+语言程序设计教程 第6章构造数据类型6.3 程序的文件结构与编译预处理命令(3) #ifndef #endif #ifndef #endif形式的条件编译的格式为: 条件编译呢主要用于下列几种场合: (1) 避免重复包含引起变量函数的重复定义引起的冲突。如果某个程序的头文件中已定义了某个常量,用条件编译进行判断后,就不再重新定义该常量,避
30、免造成不一致;如果在头文件中如果包含某个模块,用条件编译进行判断后,就可不再重复包含此模块,避免变量、函数重名冲突。 电子科技大学计算机学院 软件学院#ifndef 宏名 程序段1#else 程序段2#endifC+语言程序设计教程 第6章构造数据类型注意: 与第2种形式的区别仅在于:如果宏名没有被#define定义,则编译程序段1,否则编译程序段2。电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型 源程序/* mymath.h */#include using namespace std;#define INTMAXint max(int x,int y) retur
31、n xy?x:y; /* 主程序 */#include using namespace std;#include mymath.h#ifndef INTMAXint max(int x,int y) return xy?x:y;#endifvoid main() coutmax(5,6)endl; 1234567891011121314151617181920212223242526预编译处理后的新源程序 #include using namespace std;#include using namespace std;#define INTMAXint max(int x,int y) re
32、turn xy?x:y;void main() coutmax(5,6)endl;解释:主程序中定义的int max(int,int)在预处理时被过滤掉,没有进入编译,避免了与mymath.h中的int max(int,int)冲突。123456789101112136.3 程序的文件结构与编译预处理命令 (2) 便于程序的移植。 如在PC机上,最常用的C+有BC+、VC+、Linux GNU C+,三者在实现上有一些不同之处,如果我们希望自己的源程序能够适应这种差异,可以在有差异的地方插入选择判断: #ifdef VC+ /visual C+独有的内容 #endif #ifdef BC+ /
33、Borland C+独有的内容 #endif #ifdef GC+ /Linux Gnu C+独有的内容 #endif 如果希望这个程序在Borland C+环境下编译运行,可在程序的前面写上: #define BC+ 这样一个源程序只要修改一句就可以适应三种C编译,商业软件经常就是这样编写的。再比方说商业软件的版本中经常出现的单机版、网络版,其实网络版只是在单机版的基础上增加了相应的一些网络功能,功能上大体相同,所以在同一软件程序中将单机版的功能和网络版的功能通过条件编译就可得到相应的版本。电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型6.4 名字空间 一个软件往往
34、由多个模块(组件)组成,这些模块由不同程序员(软件商)提供,不同模块可能使用了相同的标识符。简单说就是同一个名字在不同模块中代表不同的事物。当这些模块用到同一个程序中,同名标识符就引起冲突。C+提供名字空间(namespace) 将相同的名字放在不同空间中来防止命名冲突。 定义一个名字空间的格式如下: 其中:namespace 为关键字。名称为名字空间标识符。成员为函数、变量、常量、自定义类型等。 电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型namespace 名称 成员; 6.4 名字空间例如: 一个名为TsingHua的软件公司为自己的组件建立了一个名字空间。将
35、它存入头文件:TsingHua.h电子科技大学计算机学院 软件学院/*TsingHua.h*/namespace TsingHua int year=2005; char name=TsingHua Software; ShowName() coutnameendl; C+语言程序设计教程 第6章构造数据类型6.4 名字空间(1)个别使用声明方式,格式如下:其中:为作用域分辨符。成员使用形式包括函数调用式、变量名、常量名、类型名等 电子科技大学计算机学院 软件学院C+语言程序设计教程 第6章构造数据类型名字空间名:成员使用形式 /* p6_6.cpp * 名字空间的使用 */#include using namespace std;#include TsingHua.hvoid main() TsingHua:ShowName();/个别声明方式 12345678910116.4 名字空间(2)全局声明方式: 这种方式表明此
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《立定跳远》的教学反思
- 《快乐英语》第三册教案
- 体育场馆电缆网络顶管施工协议
- 城市绿化钻孔桩施工合同
- 环保产业园项目招投标资料
- 建筑工人休息室空调节能办法
- 公共交通枢纽防火门招投标资料
- 物业公司医疗保健人员合同模板
- 招投标合同变更法律风险
- 研发项目招投标实施细则
- Module1 Unit3 Period 3 A thirsty bird (教学设计)-2024-2025学年沪教牛津版(深圳用)英语四年级上册
- 《心系国防 强国有我》 课件-2024-2025学年高一上学期开学第一课国防教育主题班会
- Unit1 单元整体教学设计 2024-2025学年人教版(2024)七年级英语上册
- 2024年秋季新华师大版七年级上册数学教学课件 4.1.1对顶角
- 《创伤失血性休克中国急诊专家共识(2023)》解读课件
- 论网络交易违法行为监管地域管辖权的确定
- 酒店连锁突发事件处理考核试卷
- 2024发电企业安全风险分级管控和隐患排查治理管理办法
- 2024-2030年中国甲硫基乙醛肟行业市场行情监测及发展前景研判报告
- 运用PBL教学法探讨如何教会患者正确使用吸入剂
- 第四章运动和力的关系单元教学设计
评论
0/150
提交评论