




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第三讲
生存期和作用域
变量的作用域即变量的作用范围(或有效范围)。表现为变量有的可以在整个程序或其它程序中进行引用,有的则只能在局部范围内引用。
变量的生存期变量从被生成到被撤消的这段时间。实际上就是变量占用内存的时间。作用域和生存期是从空间和时间的角度来体现变量的特性。按照变量的作用域分:全局变量和局部变量按照变量的生存期分:动态变量和静态变量2作用域及生存期局部变量的3
定义在函数内作定义说明的变量,也称为内部变量
。
作用域仅限于函数内,离开函数后不可再引用。
生存期从函数被调用的时刻到函数返回调用处的时刻(静态局部变量除外)。intf1(intx,inty){
intz;z=x>y?x:y;return(z);}voidf2(){printf("%d\n",z);}局部变量
变量x、y、z的作用域引用错误!4
说明(1)主函数main()中定义的变量也是局部变量,它只能在主函数中使用,其它函数不能使用。同时,主函数中也不能使用其它函数中定义的局部变量。
intf3(intx);voidmain(){inta=2,b;b=a+y;printf("%d\n",b);}intf3(intx){inty;y=a+5;return(y);}局部变量
变量a、b的作用域变量x、y的作用域局部变量
错误!错误!5(2)形参变量属于被调用函数的局部变量;实参变量则属于调用函数的局部变量。(3)允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。#include<stdio.h>voidsubf();voidmain(){
inta,b;
a=3,b=4;printf("main:a=%d,b=%d\n",a,b);subf();printf("main:a=%d,b=%d\n",a,b);}voidsubf(){inta,b;a=6,b=7;printf("subf:a=%d,b=%d\n",a,b);}运行结果:main:a=3,b=4subf:a=6,b=7main:a=3,b=4变量名相同
6(4)在复合语句中定义的变量也是局部变量,其作用域只在复合语句范围内。其生存期是从复合语句被执行的时刻到复合语句执行完毕的时刻。
#include<stdio.h>voidmain(){
inta=2,b=4;
{intk,b;k=a+5;b=a*5;printf("k=%d\n",k);printf("b=%d\n",b);}printf("b=%d\n",b);a=k+2;}main中的局部变量
复合语句中的局部变量
main中变量a、b的作用域
复合语句中变量k、b的作用域输出k=7
输出b=10
输出b=4
错误!7作用域及生存期全局变量的8
定义在函数外部作定义说明的变量,也称为外部变量
。它不属于哪一个函数,而属于一个源程序文件。
作用域从定义变量的位置开始到本源文件结束,及有extern说明的其它源文件。
生存期与程序相同。即从程序开始执行到程序终止的这段时间内,全局变量都有效。
#include<stdio.h>#include<math.h>intsign();floatsqr(){if(n>0)return(sqrt(n));elsereturn(-1);}floatn=0;voidmain(){ints;floatt;scanf("%f",&n);s=sign();t=sqr();printf("s=%dt=%f",s,t);}intsign(){intr=0;if(n>0)r=1;if(n<0)r=-1;return(r);}定义全局变量,并赋初值局部变量全局变量n的作用域
局部变量s、t的作用域局部变量局部变量r的作用域错误!9
说明(1)应尽量少使用全局变量。
全局变量在程序全部执行过程中始终占用存储单元降低了函数的独立性、通用性、可靠性及可移植性降低程序清晰性,容易出错(2)若全局变量与局部变量同名,则全局变量被屏蔽。#include<stdio.h>inta=10;
//全局变量voidmain(){
inta=100;
//局部变量(与全局变量同名)
printf("locala=%d\n",a);}运行结果:locala=100注意:局部变量与全局变量同名极易导致程序员犯逻辑错误。10(3)全局变量定义必须在所有的函数之外,且同一全局变量名只能定义一次,并可赋初值。全局变量定义的一般形式为:
[extern]类型说明符全局变量名1[=初始值1],…,全局变量名n[=初始值n];可缺省!charch='Y';voidmain(){……}charch;voidfunc(){……}定义全局变量ch错误!ch只能定义一次例:inta=2,b=4;externinta=2,b=4;11extern类型说明符全局变量名1,…,全局变量名n;(4)对全局变量进行说明,可扩展全局变量的作用域。全局变量说明的一般形式为:用于扩展作用域时,不可缺省!不可赋初值!voidgx(),gy();voidmain(){externintx,y;printf("1:x=%d\ty=%d\n",x,y);y=246;gx();gy();}externintx,y;voidgx(){x=135;printf("2:x=%d\ty=%d\n",x,y);}intx=0,y=0;voidgy(){printf("3:x=%d\ty=%d\n",x,y);}全局变量定义未说明前的作用域全局变量说明说明后的作用域全局变量说明说明后的作用域运行结果:
1:x=0y=02:x=135y=2463:x=135y=24612(5)全局变量定义与全局变量的说明的区分
externinta;
voidfunc1(){……//引用变量a}externinta=2;
voidfunc2(){……//引用变量a}谁是定义?谁是说明?全局变量定义(因为赋了初值)全局变量说明13定义说明次数只能1次可说明多次位置所以函数之外函数内或函数外分配内存分配内存可初始化不分配内存不可初始化14(6)全局变量定义时如果不初始化,则系统对其自动赋值为0或者空字符’\0’(7)全局变量可加强函数模块间的联系,通过函数调用,改变全局变量的值,可以影响主调函数,得到意想不到的结果。#include<stdio.h>inta,b;//全局变量定义voidswap(){intt;t=a;a=b;b=t;}voidmain(){a=10,b=20;//全局变量赋值swap();printf(“%d,%d”,a,b)}#include<stdio.h>inti;//全局变量定义voidmain(){voidprt();for(i=0;i<5;i++)//使用全局变量prt();}voidprt(){for(i=0;i<5;i++)printf(“%c”,’*’);printf(“\n”);}#include<stdio.h>charcolor=‘B’;voidfirst(void);voidsecond(void);intmain(void){printf(“colorinmain()is%c\n”,color);first();printf(“colorinmain()is%c\n”,color);second();printf(“colorinmain()is%c\n”,color);return0;}voidfirst(void){charcolor;color=‘R’;printf(“colorinfisrt()is%c\n”,color);}voidsecond(void){color=‘G’;printf(“colorinsecond()is%c\n”,color);}15存储类型变量的16程序区静态存储区动态存储区内存用户区将数据存放在此区1、全局变量;2、静态(static)局部变量1、函数形式参数;2、函数中定义的没有用关键字static声明的变量;程序编译后即分配存储区,程序执行完毕就释放。在程序执行过程中始终占据固定的存储单元函数调用开始时分配,函数结束时释放。在程序执行过程中,这种分配和释放是动态的变量的生存期由变量的存储类型决定CPU寄存器register型数据的存放位置数据读取速度快,存储空间小;空间分配和释放是动态的变量的存储类型
概述
变量是对程序中数据的存储空间的抽象变量的属性①数据类型:变量所持有的数据的性质(操作属性)。规定了它们的取值范围和可参与的运算。
②存储类型:
规定了变量占用内存空间的方式,也称为存储方式。
存储器类型:寄存器、静态存储区、动态存储区
auto---------自动型
register-----寄存器型
static-------静态型
extern-------外部型动态存储静态存储存储类型说明符数据类型说明符变量名1,变量名2,…,变量名n;变量定义的完整形式应为:
例如:
auto
charc1,c2;//c1,c2为自动字符变量
register
inti;//i为寄存器型变量
static
inta,b;//a,b为静态整型变量
extern
intx,y;//x,y为外部整型变量181、自动变量(auto型变量)[auto]数据类型说明符变量名1,变量名2,…,变量名n;
定义格式
说明
存储类型说明符auto可以省略。自动变量只能在函数内或复合语句中定义,它属于局部变量。voidfunc(){
inti,j,k;
……}等价于autointi,j,k;autointk;
voidfunc(){……}错误!自动变量不可定义在函数外
注意:在函数外部定义的没有带存储类型说明符的全局变量是外部变量,属于静态存储类型。如:intk;//k为外部变量,属静态存储类型
voidfunc(){……}19外部变量和全局变量是对同一类变量的两种不同角度的提法。全局变量是从它的作用域提出的,外部变量从它的存储方式提出的,表示了它的生存期。它属于静态存储类型。例:引用其它文件中的外部变量原文件prg1.cinta,b;
//外部变量定义voidmain(){intc;
a=4,b=5;c=max();printf("max=%d\n",c);}原文件prg2.cexterninta,b;
//外部变量说明intmax(){return(a>b?a:b);}编译、链接、运行运行结果:
max=52、外部变量(extern型变量)20
静态变量与静态存储类型
静态变量的类型说明符是static。静态变量属于静态存储类型。外部变量虽属于静态存储类型但不一定是静态变量,必须由static加以定义后才能成为静态外部变量,或称静态全局变量。
自动变量可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。
静态局部变量
在局部变量的说明前加上static就构成静态局部变量
例如:
staticinta,b;staticfloatarray[5]={1,2,3,4,5};3、静态变量(static型变量)21
静态局部变量与自动变量比较
静态局部变量与自动变量均属于局部变量
静态局部变量生存期长,为整个源程序。自动变量生存期短。静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同voidfunc();voidmain()
{inta;a=s+5;……}voidfunc(){staticints;……}定义静态局部变量s错误!s的作用域22
静态局部变量与自动变量比较
静态局部变量若在定义时未赋初值,则系统自动赋初值0
静态局部变量赋初值只一次,而自动变量赋初值可能多次#include<stdio.h>voidmain(){inti;voidfunc();for(i=1;i<=5;i++)func();}voidfunc(){
autointj=0;++j;printf("%d",j);}#include<stdio.h>voidmain(){inti;voidfunc();for(i=1;i<=5;i++)func();}voidfunc(){
staticintj=0;++j;printf("%d",j);}自动变量静态变量运行结果:11111
运行结果:12345
23可继承性
静态全局变量全局变量(外部变量)的说明之前再冠以static就构成了静态全局变量。全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。当一个源程序由多个源文件组成时,非静态的全局变量可通过外部变量说明使其在整个源程序中都有效。而静态全局变量只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能通过外部变量说明来使用它。
prg1.c
inta,b;staticcharch;
voidmain(){……}
prg2.c
externinta,b;externcharch;
intfunc(intx,inty){……}
外部(全局)变量定义静态全局变量定义错误!244、寄存器变量(register型变量)这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,这样可提高效率。寄存器变量的说明符是register,属于动态存储类型。
voidmain(){
registerinti,s=0;for(i=1;i<=100;i++)s=s+i;printf("s=%d\n",s);}说明:只有局部自动变量和形式参数才可以定义为寄存器变量。2526局部变量默认为auto型register型变量个数受限,且不能为long,double,float型局部static变量具有全局寿命和局部可见性局部static变量具有可继承性extern作为声明,可扩展外部变量作用域静态动态存储方式程序整个运行期间函数调用开始至结束生存期编译时赋初值,只赋一次每次函数调用时赋初值自动赋初值0或空字符不确定未赋初值静态存储区动态区存储区寄存器局部变量外部变量作用域定义变量的函数或复合语句内本文件其它文件registerstaticautostaticextern存储类别27练习1:如何改正以下程序?void
main(){x=2;printf(“%d\n”,x);}intx;法1:将intx;放到主函数之内法2:将intx;放到主函数之上法3:在主函数之内加一语句
externintx;法4:在主函数之上加一语句
externintx;练习2:以下程序运行结果是:fun3(intx){staticinta=3;a+=x;returna;}voidmain(){intk=2,m=1,n;n=fun3(k);n=fun3(m);printf("%d\n",n);}外部函数及内部函数281、内部函数如果在一个源文件中定义的函数只能被本文件中的函数调用,而不能被同一源程序其它文件中的函数调用,这种函数称为内部函数。static类型说明符函数名(形参表)例如:staticintfunc(inta,intb){return(a>b?a:b);}内部函数也称为静态函数。但此处静态static的含义已不是指存储类型,而是指对函数的作用域只局限于本文件。因此在不同的源文件中定义同名的静态函数不会引起混淆。2、外部函数外部函数在整个源程序中都有效,其定义的一般形式为extern类型说明符函数名(形参表)缺省时,隐含为externprg1.cexternintfunc2();voidmain(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论