




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
函数中的变量第一页,共三十八页,2022年,8月28日12.1生存期和作用域C程序中的所有变量都有一定的生存期和作用域。生存期是指程序运行时,变量占有内存的时间。变量作用域是指在程序中,变量可以被使用的有效代码区域。本节将讨论变量的生存期和作用域的相关概念,并且介绍全局变量的使用,以及同名变量和变量屏蔽的问题。第二页,共三十八页,2022年,8月28日12.1.1生存期生存期是指程序运行时变量占有内存的整个时期。当程序运行到变量的定义语句时,编译器为其分配内存,这是它的生存期的开始;当变量占用的内存被释放时,则标志着生存期的结束。第三页,共三十八页,2022年,8月28日12.1.1生存期第四页,共三十八页,2022年,8月28日12.1.2作用域作用域是指变量可以被使用的代码区域。只有在变量的有效作用域内,变量才是可以被访问的。在变量作用域之外使用变量是非法操作,编译器会对这种行为报告错误。变量可以在main函数内定义,可以在自定义的函数内定义(包括形参),也可以定义在所有函数的外部,还可以在各个函数内部的复合语句中定义。不同位置定义的变量作用域是不一样的。变量作用域的大小由它所在的程序块决定。如前所述,程序块就是复合函数,也就是在C语言中使用花括号对({})分隔出来的代码块。为了便于讨论变量的作用域,按程序块间的关系将程序块分为4类:本层程序块、上层程序块、下层程序块和外部程序块。分别定义如下。第五页,共三十八页,2022年,8月28日12.1.2作用域本层程序块:即程序块本身。上层程序块:如果程序块A放在程序块B内部,那么B为A的上层程序块;同时,B的所有上层程序块也为A的上层程序块。下层程序块:如果程序块A内部含有B程序块,那么B为A的下层程序块;同时,B的所有下层程序块都为A的下层程序块。外部程序块:如果程序块B不是程序块A的以上三种程序块的任何一种,那么B就是A的外部程序块。第六页,共三十八页,2022年,8月28日12.2局部变量和全局变量在C语言中,根据变量的作用范围,可以将变量分为局部变量和全局变量两种。两种变量在使用特点和应用中都有很多差别,本章将详细讲解。第七页,共三十八页,2022年,8月28日12.2.1局部变量局部变量是指作用域无法涵盖整个代码区的变量。在C语言中,函数体中定义的变量,即函数的内部变量也是局部变量之一。需要注意的是,由于局部变量的生存期在函数调用完成后就结束,因此每次调用时的局部变量都是新生成的、并拥有不同内存空间的变量。像这种只是临时有效的变量,也称为“临时变量”。作为一个临时变量,局部变量的主要优点是仅在需要时编译器才为之分配内存。这是因为临时变量仅在程序执行到它们被定义的程序块内时才进入生存期。第八页,共三十八页,2022年,8月28日12.2.2全局变量与局部变量相对应的,在所有函数外部定义的变量,即所有函数的外部变量,则被称为“全局变量”。实际上,整个C程序可以视为一个程序块,而且是其余所有程序块的上层程序块,而全局变量就是在这个程序块中定义的。因此,全局变量在整个C程序中都是有效力了,作用域为从被定义开始直到整个C程序结束。例如:第九页,共三十八页,2022年,8月28日12.2.2全局变量第十页,共三十八页,2022年,8月28日12.2.3初始化全局变量在C语言中,编译器对全局变量的初始化处理与其余变量不一样。如果局部变量没有被显式地初始化,编译器不会自动为其清理内存;如果全局变量没有为其显式初始化,编译器则会自动初始化,将其内存空间清除归零。内存空间清零的效果相当于:如果变量为int型,则赋值为0;如果变量为float型,则赋值为0.0;如果为int型数组,则将每一个数组元素赋值为0……第十一页,共三十八页,2022年,8月28日12.2.4合理使用全局变量当程序需要在不同的程序块、不同的函数间传递数值信息时,最简单最有效的方式就是使用作用域可以覆盖整个程序的全局变量。但与此同时,大作用域也是全局变量的一大缺点,会导致全局变量的一些使用隐患。第十二页,共三十八页,2022年,8月28日12.2.4合理使用全局变量1.过渡使用全局变量会导致资源浪费全局变量一旦被定义后,就会在整个程序执行过程中一直占有内存空间。而局部变量则只是在一段程序块中占有内存空间。如果毫无顾忌地把所有变量都定义为全局变量,会导致内存资源严重浪费。因为并非所有变量都需要把生存周期放大到整个程序执行过程,完全可以把它们定义为局部变量,在需要用到的地方才使用,使用结束后便释放内存。第十三页,共三十八页,2022年,8月28日12.2.4合理使用全局变量2.不宜对全局变量做过多操作由于全局变量可以在程序中所有程序块中访问,如果访问该变量的操作过多,那么就会给编程和调试带来很大的难度,因为程序员很难确保过多的操作全在控制范围之内。对全局变量进行过多的操作常常是一些程序Bug的源头。第十四页,共三十八页,2022年,8月28日12.2.4合理使用全局变量3.不利于模块化设计过多地使用全局变量有悖于模块化编程思想。模块化编程的基本思想是要将程序划分为功能单一、相互独立的多个模块,而过多使用全局变量必然会使不同模块操作同一变量,加强了模块间的耦合度,使模块间通过一些变量相互影响,削弱了模块功能的独立性。第十五页,共三十八页,2022年,8月28日12.2.4合理使用全局变量4.破坏信息封装性一些只需定义为局部变量的变量如果被提升为全局变量,不仅仅浪费了内存,而且还破坏了模块的信息封装性。在模块化编程过程中,划分模块时,不仅要使各个模块的功能单一,还要使模块间相互独立,同时对信息进行有效的封装。信息封装的意思就是如果只需在模块内处理的信息,应当只放在模块内,外部不应该看到除模块接口(例如函数声明)之外的所有模块信息。第十六页,共三十八页,2022年,8月28日12.2.5同名变量和变量屏蔽当互为外部程序块的多个程序块内存在同名变量时,由于所有外部程序块的变量在本层程序块中都是无效的,可以工作的只有本层程序块定义的变量,那么访问该名字的变量,使用的只能是本层定义的变量。这种情况下的同名变量不会导致命名冲突。由于函数之间互为外部程序块,一个函数的变量在另一个函数中肯定是无效的,因此当存在同名变量时,函数访问的肯定是本函数定义的变量。第十七页,共三十八页,2022年,8月28日12.3变量的存储类别C语言中的变量都有两个属性:数据类型和存储类别。数据类型在第2章已经详细讨论过,本节将讨论变量的存储类别。C语言中定义了4个关键字作为变量的存储类别的修饰词,分别为:auto、static、register和extern。变量的存储类别决定了变量在内存中的存储区域。本节首先将介绍C语言中内存存储区的划分以及各个存储区的概念,接着将介绍各种存储类别的变量的概念和使用。第十八页,共三十八页,2022年,8月28日12.3.1内存存储区在C语言中,内存存储区可以分为4种不同的存储区:栈、堆、静止存储区和常量存储区。1.栈栈是由编译器管理的动态存储区域,用于存储临时变量,即只在需要时才被分配内存,不需要时编译器会自动回收。可存放的数据包括以下几项。函数形参:其只在函数执行期内有效。局部变量(不包括static修饰的局部变量):只在它定义的程序块及其下层程序块的执行期内有效。其他临时变量(例如,a++语句中产生的临时变量):函数返回时产生的临时变量。第十九页,共三十八页,2022年,8月28日12.3.1内存存储区2.堆堆是由程序管理的动态存储区域,用于分配由程序使用malloc函数申请的内存空间,需要由程序自行释放。在内存管理一章中将讨论这块存储区域的使用。堆上分配的内存也是未经初始化的,需要程序显式地初始化。第二十页,共三十八页,2022年,8月28日12.3.1内存存储区3.静态存储区静态存储区用于存储全局变量,该区域的内存在程序开始时就已固定分配完毕,直到程序结束由编译器自动释放,在该区域分配的内存在整个程序执行过程中都是有效的。全局变量全部存放在静态存储区中。静态存储区的内存分配时由编译器自动初始化。第二十一页,共三十八页,2022年,8月28日12.3.1内存存储区4.常量存储区常量存储区用于存储程序中的常量,同时经编译器优化后的const常量也可能占用该区域内存。第二十二页,共三十八页,2022年,8月28日12.3.2auto变量存储类别auto的作用是声明变量的生存期为自动型,auto变量的内存由编译器自动从栈上分配,因此auto变量都是临时变量。使用auto声明变量的形式十分简单,如下所示。auto数据类型变量名;或数据类型auto变量名:第二十三页,共三十八页,2022年,8月28日12.3.2auto变量如果变量还有const和volatile修饰词,它们的摆放次序可以相互任意调换,只要保证这些修饰词都在变量名之前即可。下面是一些auto变量声明的实例。constautointamount=1;autovolatilefloatrpg=0;intconstautobb=2;这个声明顺序的规则对于后面介绍的存储类别static、register和extern都适用,后面不再赘述。第二十四页,共三十八页,2022年,8月28日12.3.2auto变量所有的局部变量的声明中如果不含存储类别,那么都默认为auto型变量。如下函数中的两种声明方式是等效的。/*声明方式1*/intfun(autointarg1,autodoublearg2){autointa=1;autointb=1;……}/*声明方式1*/intfun(intarg1,doublearg2){inta=1;intb=1;……}第二十五页,共三十八页,2022年,8月28日12.3.3static局部变量储存类型static的作用是将变量声明为static型,即静止型,该类别变量的内存均从静止存储区分配,生存期为整个程序的执行过程。static的使用形式也非常简单,形式如下:static数据类型名变量名;static可以修饰局部变量,也可以修饰全局变量。本节先讨论static局部变量的使用。第二十六页,共三十八页,2022年,8月28日12.3.3static局部变量由于函数内的auto局部变量每次函数结束后都会被释放,因此不能将本次函数调用的信息保留。但是,当函数功能需要在多次调用中传递信息时,就需要一个变量能在函数结束时保留住内存而不释放,这时就需要使用static局部变量。例如:01 voidfunc(void){02 staticinta=2;03 ++a;04 }第二十七页,共三十八页,2022年,8月28日12.3.3static局部变量该函数中的a为static局部变量,第2行的定义语句只会在第一次调用时执行,在后面的函数调用中该语句相当于空语句。变量a存储在静止存储区,其生存期包括了程序的整个执行过程,在每次函数结束时,其内存不会被释放。下一次调用该函数时,a的值等于上一次函数结束时的值。例如,有如下调用语句:01 func();02 func();03 func();上述语句执行过程中,变量a的变化右表所示。第二十八页,共三十八页,2022年,8月28日
12.3.4register变量所有变量的值都是存储在内存中的,而计算机的直接操作对象是寄存器。寄存器是CPU内部的元件,寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快。当程序访问变量时,计算机要先从内存中将变量值提取到寄存器中。;运算结束后,如果该变量值发生改变,则还需要把寄存器中的值重新送回到内存存放。第二十九页,共三十八页,2022年,8月28日
12.3.4register变量C语言中提供了一种存储类别register,这种存储类别的变量的值会被要求直接存储在寄存器中。访问该变量无需从内存中获取它的值,存储该变量时也无需再存回内存,都直接在寄存器上进行操作。由于寄存器的存取速度要远快于内存的存取数度,因此,如果一个该变量在程序中被频繁使用,那么将其声明为register变量,将大大提高程序的执行效率。register型的变量声明如下所示。register数据类型名变量名;第三十页,共三十八页,2022年,8月28日
12.3.4register变量register变量的使用要注意以下几点。register只能修饰函数内的变量,包括局部变量和形式参数。例如:voidfunction(registerintx,registerinty){registerinta=1;}第三十一页,共三十八页,2022年,8月28日
12.3.4register变量一个变量只能声明为一种存储类别。下列3个变量声明是错误的。voidfunction(void){registerstaticinta; /*函数内的变量声明*/registerautointb; /*函数内的变量声明*/}registerintc; /*函数外的变量声明*/以上三个声明都将变量同时声明为两种存储类别。其中,函数外的变量本身就是全局变量。第三十二页,共三十八页,2022年,8月28日
12.3.4register变量不能对register变量进行取地址操作。下列两种用法都是错误的。registerinta;scanf(“%d”,&a);printf(“%x”,&a);声明为register的变量未必都会存放在寄存器内,该声明的作用只是要求把该变量放在寄存器中处理。因为寄存器的数量是有限的,同时还因为各个系统允许使用的寄存器也不同,有的系统只允许部分类型的变量可以存放在寄存器中。注意:若函数参数在函数中被操作的次数超过3次,便可以考虑将其声明为register变量。第三十三页,共三十八页,2022年,8月28日12.3.5extern变量关键字extern用于声明全局变量时,可以扩展全局变量的作用域。在节中已介绍了该关键字的使用形式,并讨论了若要在变量定义前使用变量时,可以借助extern来进行声明。在这种情况下,extern的作用是在一个文件中扩展了全局变量的作用域。除此之外,extern还可以使全局变量的作用域扩展到其他文件中。第三十四页,共三十八页,2022年,8月28日12.3.5extern变量当一个程序含有多个源文件
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 拆迁安置房产权交易合同及产权登记与过户服务协议
- 小升初备考试题及答案
- 植物人喉管护理
- 设备人员面试题及答案
- 家具项目投标方案
- 2026版《全品高考》选考复习方案生物0505 第16讲 基因在染色体上、伴性遗传和人类遗传病 含答案
- 化工园区封闭检查方案
- 伤口造口压疮护理
- 铁路职工培训大纲
- 企业门口硬化改造方案
- (TCSEB 0011-2020)《露天爆破工程技术设计规范》
- 政审表模板打印版
- 医院检验科设备管理与维护制度
- T∕DZJN165-2023工业建筑布线系统工程技术标准
- 西藏山南市完全中学2023-2024学年七年级下学期期末测试历史试题
- 手电钻使用安全培训
- 中国汽车行业ESG评价指南
- DB43T 876.5-2014 高标准农田建设 第5部分:灌溉排水
- 装饰装修工程施工方案完整版
- while循环 教学课件
- 市场营销人员劳动合同指南
评论
0/150
提交评论