版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第19章生存,范围和可视区域,有时是写大页面的程序,编译链接没有定义特定变量,如果找不到特定函数,你可能会想,这个函数肯定在这里,那不是特定变量吗?编译器有问题吗?阅读本章后,编译器会发现函数、变量的范围、寿命和可见字段工作正常。可以包含的程序元素包括变量(一般类型的变量、结构变量和共享变量的统称)、常量、函数和结构以及共享的定义。19.1内存分配、变量名、函数名等都必须在内存的一个区域中。这些实体如何保存在内存中,程序如何使用这些变量,首先从c程序内存分配开始逐步回答这些问题。19.1.1内存分区,c编译程序占用的内存很大程度上包括堆栈区域:编译器自动取消分配,函数的参数值,本地变量的值等。
2、堆(heap):通常,如果程序员取消分配(动态内存请求和释放),而程序员不释放,则程序退出时可能会从操作系统中收回。全局区域(静态区域):全局变量和静态变量的存储库放在一起,初始化的全局变量和静态变量放在一个区域中,未初始化的全局变量和未初始化的静态变量放在程序结束后由操作系统释放的相邻区域中。常数区域:程序退出时由操作系统释放的字符串常数和其他常数的存储位置。程序代码区:存储函数主体的二进制代码。19.1.2变量的存储类。在c语言中,变量的存储类别主要分为四种:auto(自动)、register(寄存器)、static(静态)和extern(外部)。其中,auto和register变量属于自
3、动分配方法,static和extern变量属于静态分配方法。变量寿命、范围和可见域取决于分布方式。范围可以分为局部变量和全局变量。局部变量是在函数内部定义的变量,局部变量仅在定义它们的函数内有效,其范围限定在函数内。也就是说,变量从定义的位置开始,在函数体中结束。通常,编译器不会将内存单位分配给本地变量,而是在程序运行时调用具有本地变量的函数时,系统根据需要临时将内存分配给该变量。函数运行结束时,局部变量将取消,占用内存将被回收。在函数外部定义的变量有时称为全局变量,有时称为外部变量。全局变量的范围更广,全局变量不属于该函数之一,并且该函数内的所有函数都可以从理论上访问全局变量,因此,函数之间
4、的数据连接提供了函数之间数据连接的多种方式,从而使函数之间的数据连接不仅限于传递参数和return语句。定义全局变量后,编译器将分配固定的内存设备。在程序运行之前,此内存单元始终有效,直到操作系统收回相应的块内存。19.1.3寿命,通常为程序运行期间从生成到撤消的变量持续时间。寿命的长度取决于上述存储方法,在自动分配(堆栈分配)中,变量与相应的代码块一起保留。对于静态分配(编译器预分配),变量与程序一起工作,在程序开始执行时存在,直到程序结束执行后才会执行。对于动态存储的内存块(注:不是指向该内存块的指针),程序员将确定其寿命。对于程序代码区域中的函数、常量区域中的字符串常量和其他常量、结构和
5、共享体的定义等,都与程序一起生存,因此对生存的讨论没有意义。,19.1.4范围和可视域,程序代码中变量有效范围(源区域)为范围、变量、标识符的合法访问范围(源区域)称为可视域。这样,范围就是变量理论上有效的区域,可见域是变量实际上有效的区域,可见域是域的子集。c语言范围可分为以下几类:(1)块范围自动变量(auto,register)和内部静态变量(static)在块范围(即开始于声明点,结束于块结束的块)中声明的变量。与在其它函数中声明的同名变量不同,如果函数定义中声明的正式参数、在其它函数中声明的相同变量名允许,编译器会为这些变量分配不同的存储单位,而不会混淆。(2)文件范围外的静态变量(
6、static)具有从声明点开始到文件结束的文件范围。此处提到的文件是编译的基本单位c文件。(3)全局(程序)域全局变量(extern)具有全局域,只要在使用之前声明它,全局变量就可以用于程序中由多个文件组成的所有位置。19.2 auto变量、函数的几何参数和代码块中定义的变量属于auto变量。此变量是c语言中使用最广泛的变量,可以分配堆栈和动态分配存储空间。例如,函数参数可以在调用函数时为参数分配存储空间,并在函数调用结束时自动释放存储空间。对于代码块中定义的变量(包括函数中定义的变量),当变量声明运行时,系统会为这些auto变量分配空间,当程序进程离开代码块时,系统会自动取消并释放所占用的内
7、存空间。19.2.1定义格式,自动变量表示auto数据类型变量1=初始化表达式,变量2=初始化表达式,其中方括号表示可以省略。其中,变量不仅指常规内置类型的变量,还指数组、结构和指针等复合结构。默认情况下为c语言定义的变量是auto变量,在上一个示例中,函数和代码块中的局部变量没有使用关键字auto。这实际上是遵循c语言的基本规则。例如,在函数中,int a;Float b:由c编译器自动解释。auto int a;自动浮点b;19.2.2范围和寿命、auto变量的范围和寿命均限制为定义它们的代码块。换句话说,是指用两个大括号括起来的代码行的代码块。函数只是代码块的一种,典型的代码块具有if结
8、构、for结构等,即使包含两个大括号,也可以构造单个代码块。此外,除了“声明后使用”的原则外,您还可以看到auto变量的范围和寿命对应于此时空区域,该时空区域以定义中的代码块结束。请查看以下函数:1int func(int m,int n)2 3int x;/*与auto int x相同;*/4 5int a、b、c;/* auto int a、b、c;*/6 7 8int y,z;/*与auto int y,z相同;*/9 10 return 0;11,19.2.3屏蔽,代码块可以嵌套以形成一定的层次结构。是否可以在内部和外部代码块中定义同名变量?如果可能,这些同名变量有什么关系?例如,19
9、.2.4重复定义,auto变量不能重复定义。重复是指在同一代码块中出现两个同名变量。这里提到的相同代码块不包含屏蔽。下列程式码会产生重复定义错误,例如if() int x,y:双x、y;并行层次结构中的代码块可以显示同名变量,而不会引起混淆。最常见的例子是,所有函数(包括main函数)都在外部定义,因此在函数a内定义的auto变量在函数b内完全不可见,编译器很容易区分这两个函数中定义的同名变量,因此编写函数非常方便。,19.2.5初始化,编译器不会自动初始化auto变量。此操作必须由程序员在定义变量时显式执行。否则,变量的值不是随机确定的。不管是指针还是一般变量,总是提醒初始化,可以有效地防止
10、奇怪的错误。由于19.3 register变量(通常CPU访问内部寄存器的速度比访问内存的速度快得多),因此,建议将某些经常应用的变量放在CPU的通用寄存器中,这样在使用该变量时,如果直接从寄存器中取出(而不访问内存),程序执行效率将大大提高,因此在c语言中引入了register变量(称为寄存器变量)。19.3.1定义格式,寄存器变量定义如下:register数据类型变量1=初始化表达式,变量2=初始化表达式;与Auto变量一样,register变量也属于局部变量。register变量只能在函数中定义,CPU使用寄存器数据的速度要比使用寄存器数据的速度快得多,因此,应用CPU中的寄存器可以大大
11、提高程序的执行效率和速度。但是,由于CPU中寄存器的数量有限,因此经常将常用变量定义为寄存器变量。19.3.2使用范例,以计算的近似值为例,解决了以下近似值公式:为了实现高精度,需要更多的迭代,为了提高效率,可以将循环控制变量定义为寄存器变量,如下所示:19.4 extern变量、exeten变量(也称为全局变量)、exeten变量(放置在静态存储库中)(即全局)可以在整个程序代码范围内使用,这与auto变量的不同之处在于定义和声明了extern变量。19.4.1全局变量定义,全局变量定义的默认格式为:extern类型变量名称=初始化表达式;不能省略初始化表达式,此命令通知编译器在静态存储中打
12、开指定类型的内存区域以存储变量。以下语句创建初始值为100的基于int的全局变量m:extern int m=100;c语言是外部(即,函数中未定义的变量)时,编译器会将其视为全局变量,而不管变量定义之前是否有extern说明符。也就是说,在函数外部,以int m=100的形式写。如果定义了全局变量,则仅在省略extern时才能省略初始化表达式;默认情况下,初始化为0;对于定义的全局数组或结构,编译器将每个元素或成员的所有位初始化为0。19.4.2全局变量声明全局变量与程序协同工作,因此全局变量的生存不是关注的焦点,而是经常讨论其范围和可见域。全局变量的范围取决于程序由多少个文件组成,理论上,
13、您可以在程序中的任何位置使用定义的全局变量,但在特定位置是否合理声明了全局变量。没有声明时,全局变量的可视域将从定义扩展到此文件的结尾,即通过示例代码(19.4.3可视域和声明)扩展全局变量的可视域,但可视域扩展到什么程度?实际上,是否可以很大程度上确定声明的位置可见的域,并测试读者是否可以在的基础上从main函数输出x和y?编译链接时,在main函数中仅声明全局变量z,而不声明全局变量x和y,因此会报告找不到x和y的错误。在块中声明全局变量时,仅限制该块的可见性,当在块外部访问全局变量时,编译器会显示未定义变量的错误提示,以查看以下部分:19.4.4屏蔽,在自动变量部分,内部代码块中声明的变
14、量屏蔽外部代码块中声明的同名变量,屏蔽指令同样适用于全局变量。范例:请参阅19.4.5的优点和缺点。全局变量的好处很明显。(1)提供了函数之间数据传输的新方法,函数返回值只能有一个,多数情况下不符合要求,全局变量可用于更多的处理结果。(2)使用全局变量可以减少几何参数和实际参数的数量,从而消除函数调用的时间和空间开销,提高程序执行效率。但是,全局变量在程序运行时有效,它在调用执行过程中暂时占用内存(例如局部变量),并始终占用存储单元,而不是在退出函数时释放。最大的问题是减少函数的封装和共同性,因为函数具有全局变量,如果要在其他文件中重用函数,则必须与相关的全局变量一起迁移,并且容易出现各种问题
15、,因此程序不可靠。全局变量降低函数之间的独立性,提高结合度,降低可移植性和可靠性。总之,如果可以不使用全局变量,建议尽量不要使用全局变量。19.5静态变量(也称为静态变量)是一种接近折衷点的特殊变量。这些变量也保存在静态存储库中,一旦分配了内存,在整个程序运行过程中,分配的内存将固定不变。与Extern变量不同,static变量只有定义,没有声明。定义19.5.1格式。static变量定义为static数据类型变量1=初始化表达式,变量2=初始化表达式。与extern变量(具有静态全局变量和静态局部变量之间的区别)不同,静态局部变量与可视域和常规auto变量相同,只是前者是整个程序执行期间(与
16、程序一起生存)。静态全局变量和exeten变量之间的区别在于,exeten域是程序的所有源代码文件,在一个文件中定义,并在另一个文件中使用时,只需声明它们。静态全局变量只有定义,没有声明,范围从定义位置限制到此文件的结尾,不能用于其他文件中的函数。静态全局变量实际上是对extern变量的封装和可靠性的改进。如果省略初始化表达式,编译器会自动将静态变量初始化为0。对于数组或结构,编译器将其中每个元素或成员的所有位初始化为零。19.5.2静态局部变量,在函数中定义的静态局部变量可以用作显示域、范围与常规自动变量完全匹配的未取消的自动变量。在函数调用中,通常使用静态局部变量间歇性存储特定变量的值,如
17、19.5.3静态全局变量、常规extern全局变量和静态全局变量,如所示。静态存储库与程序生存一起分配。两个变量的区别在于exeten变量的范围是整个源程序。如果源程序由多个文件组成,则exeten全局变量在单个文件中有效,而静态全局变量的作用域仅在定义该变量的源文件中有效,不能在同一源程序的其他源文件中使用。19.5.4 extern变量和static变量的初始化在编译时会静态分配内存给extern变量和static变量,因此,如果程序员没有显式初始化它们,编译器将默认使用0填充变量结构。如果要显式初始化变量,则只能使用常量表达式初始化extern变量和static变量。常量表达式包含直接常量、const常量、枚举常量和sizeof()运算符,以下初始化代码都有效:int num/*编译器自动将num初始化为0 */int
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 短诗5首课件教学课件
- 短撇课件教学课件
- 盗墓笔记教学课件
- 2026年环保工程师环境监测与治理技术测试题
- 2026年大数据处理与算法题库数据处理方法与技术前沿问题探索
- 2026年机械工程师职称考试复习资料机械原理与制造工艺综合题
- 2026年PMP项目管理专业考试项目范围管理模拟试题
- 2026年旅游管理与服务技能旅游行业从业者进阶考试
- 2026年机械设计制造与自动化考试题库及答案详解
- 2026年法学考试精讲法律知识要点试题库
- 中等长度导管维护流程与健康宣教
- 渔船合伙投资协议书
- 7下英语单词表人教版
- 涉密人员保密培训
- 攻坚克难追求卓越主题班会
- (八省联考)2025年高考综合改革适应性演练 英语试卷(含答案详解)+听力音频+听力原文
- 新媒体运营全年规划
- 国防装备全寿命周期管理
- 2024年江西省中考生物·地理合卷试卷真题(含答案)
- 国家开放大学《理工英语4》机考参考答案(第1-3套)
- 医院护士护理用药安全管理培训
评论
0/150
提交评论