1、大连理工大学软件学院大连理工大学软件学院第七章第七章第1页本章关键点大连理工大学软件学院大连理工大学软件学院第2页按按作用域(能引用该变量区域)作用域(能引用该变量区域)不一样可分为两类:不一样可分为两类:局部变量局部变量(local variable)(local variable)在一个函数内部定义变量是在一个函数内部定义变量是内部变量内部变量只在只在本函数本函数范围内有效范围内有效:只有在本函数内才能使用,在此只有在本函数内才能使用,在此函数以外是不能使用它们。在函数以外是不能使用它们。在复合语句复合语句中定义变量只在本中定义变量只在本复合语句范围内有效。复合语句范围内有效。全局变量全局
2、变量(global variable)global variable)在函数之外定义变量是在函数之外定义变量是外部变量外部变量有效范围为从定义变量位置开始到根源文件结束。有效范围为从定义变量位置开始到根源文件结束。7.8 变量作用域-局部变量和全局变量大连理工大学软件学院大连理工大学软件学院第3页float f1(int a)/*函数函数f1*/int b,c;a、b、c有效有效 char f2(int x,int y)/*函数函数f2*/int i,j;x、y、i、j有效有效 void main()/*主函数主函数*/int m,n;m、n有效有效 局部变量大连理工大学软件学院大连理工大学软
3、件学院第4页局部变量注意注意:(1)(1)主函数主函数mainmain中定义变量只在主函数中有效中定义变量只在主函数中有效,也也不能使用其它函数中定义变量。不能使用其它函数中定义变量。(2)(2)不一样函数中能够使用不一样函数中能够使用同名变量同名变量,它们它们代表不一代表不一样对象样对象,互不干扰。互不干扰。void main()int a=1,b=2;int c=max(a,b);int max(int x,int y)int a =xy?x:y;return a;大连理工大学软件学院大连理工大学软件学院第5页局部变量(3)(3)复合语句中定义变量只在本复合语句中有效复合语句中定义变量只在
4、本复合语句中有效,复合语句也称为复合语句也称为块块。void bubble_sort(int a,int size)int pass,k;for(pass=0;passsize-1;pass+)int t,num=0;for(k=0;k=ak+1)t=ak;ak=ak+1;ak+1=t;大连理工大学软件学院大连理工大学软件学院第6页局部变量(4)(4)形参为局部变量形参为局部变量;(5)(5)在函数申明中出现参数名,其作用范围只在本在函数申明中出现参数名,其作用范围只在本行内。行内。int max(int a,int b);/函数申明中出现函数申明中出现a、b,可省略,可省略 int max(
5、int x,int y)/函数定义,形参是函数定义,形参是x、y int sum=x+y;/正当,正当,x、y在函数体中有效在函数体中有效 sum=a+b;/非法,非法,a、b在函数体中无效在函数体中无效编译时认为编译时认为maxmax函数体中函数体中a a和和b b未经定义。未经定义。大连理工大学软件学院大连理工大学软件学院第7页#include int f(int);void main()int n=2;n=f(n)+1;printf(n=%dn,n);int f(int m)int n;n=m*m;return n;void Mul_table(int a9)int i;for(i=1;
6、i10;i+)int j;for(j=1;j=i;j+)aij=i*j;局部变量大连理工大学软件学院大连理工大学软件学院第8页int q=5;void f1()q=q*2;int p=1;void main()p=p-1;f1();全局变量大连理工大学软件学院大连理工大学软件学院第9页例例:全局变量与局部变量同名全局变量与局部变量同名#include int a=3,b=5;void main()int a=8;printf(“%d”,max(a,b);max(int a,int b)int c;c=ab?ab;return(c);运行结果为运行结果为 8 定义全局变量时定义全局变量时默认初始
7、值为默认初始值为0 0;大连理工大学软件学院大连理工大学软件学院第10页#include int a=1,b=1;void f1(int x)a=x*x;b=a*x;int c;void f2(int x,int y)a=x y?x:y;b=x y?x:y;c=x+y;void main()f1(4);printf(call function f1:n”);printf(a=%d,b=%dn,a,b);f2(10,23);printf(call function f2:n);printf(“a=%d,b=%d,c=%d”,a,b,c);例例:不一样函数修改全局变量不一样函数修改全局变量大连理工
8、大学软件学院大连理工大学软件学院第11页#include int a=1,b=1;void f1(int x)a=x*x;b=a*x;int c;void f2(int x,int y)a=x y?x:y;b=x y?x:y;c=x+y;void main()f1(4);printf(call function f1:n”);printf(a=%d,b=%dn,a,b);f2(10,23);printf(call function f2:n);printf(“a=%d,b=%d,c=%d”,a,b,c);/a,b作用域从这里开始作用域从这里开始/f1函数能够访问函数能够访问a,b/f2函数能够
9、访问函数能够访问a,b/main 函数能够访问函数能够访问a,b例例:不一样函数修改全局变量不一样函数修改全局变量大连理工大学软件学院大连理工大学软件学院第12页#include int a=1,b=1;void f1(int x)a=x*x;b=a*x;int c c;void f2(int x,int y)a=x y?x:y;b=x y?x:y;c c =x+y;void main()f1(4);printf(call function f1:n”);printf(a=%d,b=%dn,a,b);f2(10,23);printf(call function f2:n);printf(“a=
10、%d,b=%d,c=%d”,a,b,c);/a,b作用域从这里开始作用域从这里开始/f1函数能够访问函数能够访问a,b/f2函数能够访问函数能够访问a,b,c c/main 函数能够访问函数能够访问a,b,c c/c c 作用域从这里开始,默认初始值为作用域从这里开始,默认初始值为0例例:不一样函数修改全局变量不一样函数修改全局变量大连理工大学软件学院大连理工大学软件学院第13页设全局变量作用是增加函数间数据联络渠道设全局变量作用是增加函数间数据联络渠道提议不在必要时不要使用全局变量提议不在必要时不要使用全局变量 全局变量在程序全部执行过程中都占用存放单元,而不是仅在需要时才开辟单元。使用全局
11、变量过多,会降低程序清楚性。在各个函数执行时都可能改变外部变量值,程序轻易犯错。降低函数通用性,因为函数在执行时要依赖于其所在外部变量。普通要求把程序中函数做成一个封闭体,除了能够经过“实参形参”渠道与外界发生联络外,没有其它渠道。全局变量大连理工大学软件学院大连理工大学软件学院第14页 7.变量存放方式和生存期 从变量从变量作用域作用域(即从空间)角度来分,能够分(即从空间)角度来分,能够分为为全局变量和局部变量全局变量和局部变量。从变量值从变量值生存期生存期(即存在时间)角度来分,又(即存在时间)角度来分,又能够分为能够分为静态存放方式和动态存放方式静态存放方式和动态存放方式。大连理工大学
12、软件学院大连理工大学软件学院第15页静态存放方式静态存放方式是指在程序运行期间由系统分配固定是指在程序运行期间由系统分配固定存放空间方式。存放空间方式。动态存放方式动态存放方式则是在程序运行期间依据需要进行动则是在程序运行期间依据需要进行动态分配存放空间方式。态分配存放空间方式。在语言中每一个变量和函数有两个属性:在语言中每一个变量和函数有两个属性:数数据类型据类型和和数据存放类别数据存放类别。例:例:static int a;static int a;7.变量存放方式和生存期 大连理工大学软件学院大连理工大学软件学院第16页程序内存区域程序内存区域程序区程序区(code area)静态存放区
13、静态存放区(data area)动态存放区动态存放区存放程序代码存放程序代码存放程序全局数据和静态数据存放程序全局数据和静态数据存放程序局部数据存放程序局部数据 7.变量存放方式和生存期 存放空间能够分为三部分:存放空间能够分为三部分:1.1.程序区程序区 2.2.静态存放区静态存放区 3.3.动态存放区动态存放区 大连理工大学软件学院大连理工大学软件学院第17页7.9.1 局部变量存放类别分类分类自动变量自动变量静态局部变量静态局部变量存放器变量存放器变量大连理工大学软件学院大连理工大学软件学院第18页1 1自动存放类自动存放类autoauto 自动存放变量存放在自动存放变量存放在动态存动态
14、存放区放区 进入定义块时生成,在结束进入定义块时生成,在结束块时删除块时删除 函数函数形式参数和(非静态)形式参数和(非静态)局部变量局部变量都是自动存放类都是自动存放类 自动存放是变量默认状态自动存放是变量默认状态 int max(int a,int b,int c)auto int t;t=max(a,b);return max(t,c);7.9.1 局部变量存放类别大连理工大学软件学院大连理工大学软件学院第19页2.2.静态局部变量静态局部变量staticstatic当函数中局部变量值在函数调用结束后不消失当函数中局部变量值在函数调用结束后不消失而保留原值时,该变量称为静态局部变量。而保
15、留原值时,该变量称为静态局部变量。7.9.1 局部变量存放类别大连理工大学软件学院大连理工大学软件学院第20页例例:考查静态局部变量值考查静态局部变量值#include void main()int f(int);int a=2,i;for(i=0;i3;i+)printf(“%d”,f(a);int f(int a)auto int b=0;static c=3;b=b+1;c=c+1;return(a+b+c);不对自动变量初始化不对自动变量初始化静态变量默认初始化值为静态变量默认初始化值为 0输出结果:输出结果:789b=34大连理工大学软件学院大连理工大学软件学院第21页对静态局部变量
16、说明:对静态局部变量说明:1.1.静态局部变量属于静态存放类别,在静态存放区内静态局部变量属于静态存放类别,在静态存放区内分配存放单元。分配存放单元。在程序整个运行期间都不释放。在程序整个运行期间都不释放。而而自动变量(即动态局部变量)属于动态存放类别,自动变量(即动态局部变量)属于动态存放类别,占动态存放区空间而不占静态存放区空间,占动态存放区空间而不占静态存放区空间,函数调函数调用结束后即释放。用结束后即释放。2.2.对静态局部变量是在编译时赋初值对静态局部变量是在编译时赋初值,即只赋初值,即只赋初值一次,在程序运行时它已经有初值。以后每次调用一次,在程序运行时它已经有初值。以后每次调用函
17、数时不再重新赋初值而只是保留上次函数调用结函数时不再重新赋初值而只是保留上次函数调用结束时值。束时值。7.9.1 局部变量存放类别大连理工大学软件学院大连理工大学软件学院第22页3.3.如在定义局部变量时不赋初值话,则对静态局部如在定义局部变量时不赋初值话,则对静态局部变量来说,变量来说,编译时自动赋初值(对数值型变量)编译时自动赋初值(对数值型变量)或空字符(对字符变量)。或空字符(对字符变量)。而对自动变量来说,假而对自动变量来说,假如不赋初值则它值是一个不确定值。如不赋初值则它值是一个不确定值。4.4.即使静态局部变量在函数调用结束后依然存在,即使静态局部变量在函数调用结束后依然存在,但
18、但其它函数不能引用其它函数不能引用它。(作用域仍是局部)它。(作用域仍是局部)7.9.1 局部变量存放类别大连理工大学软件学院大连理工大学软件学院第23页例:输出到阶乘值例:输出到阶乘值#include void main()()int fac(int);int;for(;)(;)printf(%!=,fac();int fac(int)static int;*;return();();用静态局部变量用静态局部变量,以免每次调用以免每次调用时重新赋值。时重新赋值。但用静态存放要多占内存,而且但用静态存放要多占内存,而且降低了程序可读性,降低了程序可读性,大连理工大学软件学院大连理工大学软件学院
19、第24页 3.3.存放器变量存放器变量registerregister 放在放在CPUCPU中存放器中,需要用时直接从存放器取出参加中存放器中,需要用时直接从存放器取出参加运算,无须再到内存中去存取。因为对存放器存取速度远运算,无须再到内存中去存取。因为对存放器存取速度远高于对内存存取速度,所以这么做能够提升执行效率。高于对内存存取速度,所以这么做能够提升执行效率。程序中定义存放器变量对编译系统只是提议性。当今优化程序中定义存放器变量对编译系统只是提议性。当今优化编译系统能够识别使用频繁变量,自动地将这些变量放在编译系统能够识别使用频繁变量,自动地将这些变量放在存放器中。存放器中。7.9.1
20、局部变量存放类别 int fac(int n)register int i,f=1;for(i=1;i=n;i+)f=f*i;return f;大连理工大学软件学院大连理工大学软件学院第25页7.9.1 局部变量存放类别说明说明:三种局部变量存放位置是不一样:三种局部变量存放位置是不一样:自动局部变量自动局部变量存放在动态存放区;存放在动态存放区;静态局部变量静态局部变量存放在静态存放区;存放在静态存放区;存放器局部变量存放器局部变量存放在存放在CPUCPU中存放器中。中存放器中。大连理工大学软件学院大连理工大学软件学院第26页全局变量都是存放在全局变量都是存放在静态存放区中。所以它静态存放区
21、中。所以它们生存期是固定,存在们生存期是固定,存在于程序整个运行过程于程序整个运行过程。程序内存区域程序内存区域代码区(code area)静态存放区动态存放区7.9.2 全局变量存放类别大连理工大学软件学院大连理工大学软件学院第27页v外部外部变变量是在函数外部定量是在函数外部定义义全局全局变变量。量。v它作用域是从它作用域是从变变量定量定义处义处开始,到本程序文件末开始,到本程序文件末尾。尾。v在此作用域内,全局在此作用域内,全局变变量可量可认为认为程序中各个函数程序中各个函数所引用。所引用。v但有但有时时程序程序设计设计人人员员希望能希望能扩扩展外部展外部变变量作用域,量作用域,方法有以
22、下几个:方法有以下几个:v1.在一个文件内在一个文件内扩扩展外部展外部变变量作用域量作用域(extern)v2.将外部将外部变变量作用域量作用域扩扩展到其他文件展到其他文件(extern)v3.将外部将外部变变量作用域限制在本文件中量作用域限制在本文件中(static)7.9.2 全局变量存放类别大连理工大学软件学院大连理工大学软件学院第28页1.1.在一个文件内扩展外部变量作用域在一个文件内扩展外部变量作用域#include int max(int,int);/函数申明函数申明void main()extern int a,b;/对全局变量对全局变量a,b作提前引用申明作提前引用申明 pri
23、ntf(“%dn”,max(a,b);int a=15,b=-7;/定义全局变量定义全局变量a,bint max(int x,int y)int z;z=xy?x:y;return z;7.9.2 全局变量存放类别大连理工大学软件学院大连理工大学软件学院第29页2.2.将外部变量作用域扩展到其它文件将外部变量作用域扩展到其它文件 filefile.中内容为:中内容为:#include int A;/*定义外部变量定义外部变量*/void main()int power(int);/*函数申明函数申明*/int b=3,c,d,m;printf(“enter the number a and i
24、ts power m:n”);scanf(“%d%d”,&A,&m);c=A*b;printf(“%d*%d=%d n”,A,b,c);d=power(m);printf(“%d*%d=%dn,A,m,d);7.9.2 全局变量存放类别大连理工大学软件学院大连理工大学软件学院第30页 extern A;/*申明A为一个已定义外部变量*/int power(int);int,y=1;for(i1;i=n;i+)y*=A;return();7.9.2 全局变量存放类别 file2.file2.中内容为:中内容为:2.2.将外部变量作用域扩展到其它文件将外部变量作用域扩展到其它文件 大连理工大学软件
25、学院大连理工大学软件学院第31页/Ch7_1.cpp/Ch7_1.cppint num=3;int num=3;./Ch7_2.cpp/Ch7_2.cppextern int num;extern int num;编译系统依据编译系统依据externextern知道知道numnum是一个已在别处定义外部变量:是一个已在别处定义外部变量:先先在本文件中找在本文件中找有没有外部变量有没有外部变量numnum,假如有,则将其作用域,假如有,则将其作用域扩展到本行开始。扩展到本行开始。假如本文件中无另外部变量,则在程序连接时假如本文件中无另外部变量,则在程序连接时从其它文件中从其它文件中找找有没有外部
26、变量有没有外部变量numnum,假如有,则把在另一文件中定义外部,假如有,则把在另一文件中定义外部变量变量numnum作用域扩展到本文件。作用域扩展到本文件。假如还没有,假如还没有,报错报错。7.9.2 全局变量存放类别2.2.将外部变量作用域扩展到其它文件将外部变量作用域扩展到其它文件 大连理工大学软件学院大连理工大学软件学院第32页 3.3.将外部变量作用域限制在本文件中将外部变量作用域限制在本文件中 在程序设计中,一些外部变量只限于被本文件引用,而不能被其它文件引用。这时能够在定义外部变量时加一个static申明。比如:比如:file1.c file2.cstatic int A;ext
27、ern int A;/Error!void main()void fun(int n)A=A*n;7.9.2 全局变量存放类别大连理工大学软件学院大连理工大学软件学院第33页 用用static 申明一个变量作用是:申明一个变量作用是:(1)(1)对对局局部部变变量量用用static申申明明,把把它它分分配配在在静静态态存存放放区区,该该变变量量在在整整个个程程序序执执行行期期间间不不释释放放,其其所分配空间一直存在。所分配空间一直存在。(2)(2)对对全全局局变变量量用用static申申明明,则则该该变变量量作作用用域域只限于本文件模块只限于本文件模块(即被申明文件中即被申明文件中)。注意:注
28、意:用用auto、register、static申明变量时,是在定义变量申明变量时,是在定义变量基础上加上这些关键字,不能单独使用。基础上加上这些关键字,不能单独使用。int a;int a;static a;static a;错误错误 7.9.2 全局变量存放类别大连理工大学软件学院大连理工大学软件学院第34页 变量属性小结v一个变量除了数据类型以外,还有一个变量除了数据类型以外,还有3 3种属性:种属性:(1)(1)作用域作用域:指程序中能够引用该变量区域。指程序中能够引用该变量区域。(2)(2)存放类别存放类别 :auto,staticauto,static,registerregist
29、er。(3)(3)生存期生存期 :指变量在内存存放期限。指变量在内存存放期限。v变量定义位置决定作用域变量定义位置决定作用域v变量定义存放类别决定生存期。变量定义存放类别决定生存期。大连理工大学软件学院大连理工大学软件学院第35页变量属性小结(1 1)从作用域角度分类)从作用域角度分类 局部变量局部变量v自动变量自动变量,即动态局部变量即动态局部变量(离开函数离开函数,值就消失值就消失)v静态局部变量静态局部变量(离开函数离开函数,值仍保留值仍保留)v存放器变量存放器变量(离开函数离开函数,值就消失值就消失)形式参数能够定义为自动变量或存放器变量形式参数能够定义为自动变量或存放器变量 全局变量
30、全局变量v静态外部变量静态外部变量(只限本文件引用只限本文件引用)v非静态外部变量(允许其它文件引用非静态外部变量(允许其它文件引用)大连理工大学软件学院大连理工大学软件学院第36页(2 2)从生存期角度分类)从生存期角度分类l动态存放:动态存放:自动变量自动变量存放器变量存放器变量形式参数形式参数l静态存放:静态存放:静态局部变量静态局部变量静态外部变量静态外部变量(非静态)外部变量(非静态)外部变量变量属性小结大连理工大学软件学院大连理工大学软件学院第37页(3)(3)从变量值存放位置来区分从变量值存放位置来区分l内存内存中静态存放区:中静态存放区:静态局部变量静态局部变量静态外部变量静态
31、外部变量(非静态)外部变量(非静态)外部变量l内存内存中动态存放区:中动态存放区:(自动)局部变量(自动)局部变量形式参数形式参数lCPUCPU中中存放器存放器:存放器变量:存放器变量变量属性小结大连理工大学软件学院大连理工大学软件学院第38页变量变量作用域作用域生存期生存期修饰符修饰符(自动自动)局部变量局部变量函数或块函数或块函数或块函数或块autoauto静态局部变量静态局部变量函数或块函数或块单个文件单个文件 staticstatic 形形 参参函数体内函数体内函数中函数中auto/auto/registerregisterv存放器存放器变变量量函数或块函数或块函数或块函数或块regi
32、sterregister静态全局变量静态全局变量程序文件程序文件单个文件单个文件staticstatic(非静态)全局变量(非静态)全局变量 多文件多文件工程中工程中externextern存放类别小结大连理工大学软件学院大连理工大学软件学院第39页7.10 关于变量申明和定义需要建立存放空间需要建立存放空间(如:如:int a;)int a;),称为,称为“定义性定义性申明申明”(defining declaration)(defining declaration),或简称,或简称定义。定义。不需要建立存放空间(如:不需要建立存放空间(如:extern aextern a;),称为;),称为
33、“引用性申明引用性申明”(referencing declaration)(referencing declaration),或简称,或简称申明申明。大连理工大学软件学院大连理工大学软件学院第40页 7.11 内部函数和外部函数 依据函数能否被其它源文件调用,将函数区分为内部内部函数函数和外部函数外部函数。1 1、内部函数、内部函数 假如一个函数只能被本文件中其它函数所调用,它称为内部函数。在定义内部函数时,在函数名和函数类型前面加static。即static 类型标识符 函数名(形参表)比如比如:static int fun(int a,int b)大连理工大学软件学院大连理工大学软件学院第41页2 2、外部函数、外部函数(1)定义函数时,假如在函数首部最左端加关键字extern,则表示此函数是外部函数,可供其它文件调用。比如,extern int fun(int a,int b)假如在定义函数时省略extern,则隐含为外部函数。(2)在需要调用此函数文件中,用extern对函数作申明,表示该函数是在其它文件中定义外部函数 7.11 内部函数和外部函数 大连理工大学软件学院大连理工大学软件学院第42页