C08作用域和存储类别_第1页
C08作用域和存储类别_第2页
C08作用域和存储类别_第3页
C08作用域和存储类别_第4页
C08作用域和存储类别_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1C08作用域和存储类别第八章 用户标识符的作用域和存储类 教学目标教学目标掌握作用域与的概念;了解动态存储区与静态存储区的概念;掌握4种存储类别(auto,register,static,extern);掌握局部变量的作用域、及其使用特点;掌握的作用域、及其使用特点;了解函数的存储分类(extern ,static)。 基本要求基本要求 能够熟练地阅读有关的应用程序,能够利用不同的存储属性来灵活地编写有关的应用程序。2C08作用域和存储类别8.1 局部变量、全局变量和存储分类 在C语言中,由用户命名的标识符都有一个有效的作用域。所谓“作用域”是指程序中的某一部分,只有在这一部分中,该标识符才

2、是有定义的,即只有在这个域中才能使用该标识符。 例如,在某一函数内定义的变量,只能在该函数内进行使用。显然,变量的作用域与其定义语句在程序中出现的位置有直接的关系,由此可以将变量划分为局部变量和全局变量。1. 用户标识符的作用域作用域3C08作用域和存储类别定义:在函数内定义的变量, 只在本函数内有效。说明:在main函数中定义的变量只能在main函数内有效;不同函数中的同名变量,占不同的内存单元。函数的形参属于局部变量;可以定义只在某个复合语句内有效的局部变量。float f1(int a) int b,c; .char f2(int x,int y) int i,j; main() int

3、 m,n; .a,b,c有效x,y,i,j有效m,n有效2. 局部变量(也称内部变量)4C08作用域和存储类别例 不同函数中同名变量main() int a,b; a=3; b=4; printf(main:a=%d,b=%dn,a,b); sub(); printf(main:a=%d,b=%dn,a,b);sub() int a,b; a=6; b=7; printf(sub:a=%d,b=%dn,a,b);例 复合语句中的变量#define N 5main() int i; int aN=1,2,3,4,5; for(i=0;iN/2;i+) int temp;temp=ai;ai=aN

4、-i-1;aN-i-1=temp; for(i=0;iN;i+) printf(%d ,ai);局部变量示例5C08作用域和存储类别 若要在本文件中使用同一程序的其它文件中定义的全局变量,必需要对该变量进行外部变量声明。 外部变量声明的方法声明的方法: extern 数据类型 变量表;定义:在函数外定义,可为本文件内的所有函数共用。有效范围:从定义变量的位置开始到本源文件结束,及有extern声明的其它源文件。3.3.全局变量全局变量( (也称外部变量也称外部变量) ) 外部变量定义 外部变量声明u次数: 只能1次 可说明多次u位置: 所有函数之外 函数内或函数外u分配内存: 分配内存,可初始

5、化 不分配内存,不可初始化外部变量定义与外部变量声明的区别声明的区别:6C08作用域和存储类别全全局变量示例int a , b;main() a=3; b=4; printf(main:a=%d,b=%dn,a,b); sub(); printf(main:a=%d,b=%dn,a,b);sub() int a ; a=6; b=7; printf(sub:a=%d,b=%dn,a,b); 若外部变量与局部变量同名,则外部变量被屏蔽。 尽量少用全局变量Y全局变量在程序全部执行过程中始终占用存储单元;Y降低了函数的通用性、可靠性,可移植性;Y降低了程序清晰性,容易出错。 运行结果: main:a

6、=3,b=4 sub:a=6,b=7 main:a=3,b=77C08作用域和存储类别变量的属性变量的属性 数据类型:变量所持有的数据的性质(操作属性) 存储属性存储属性:存储器类型:寄存器、静态存储区、动态存储区生存期:变量在某一时刻存在-静态变量与动态变量作用域:变量在某区域内有效-局部变量与全局变量指定变量的存储类型时所要用的关键字 auto -自动型(缺省值缺省值) register-寄存器型 static -静态型 extern -外部型变量定义格式: 存储类型 数据类型 变量表;如: int sum; auto int a,b,c; register int i; static f

7、loat x,y;4. 变量的存储属性变量的存储属性8C08作用域和存储类别 静态存储静态存储:程序运行期间分配固定地存储空间 动态存储动态存储:程序运行期间根据需要动态地分配存储空间 寄存器寄存器:程序运行期间动态地占用CPU的内部寄存器5. 变量的存储类型变量的存储类型程序代码区静态存储区动态存储区全局变量、静态局部变量形参变量动态局部变量(auto、register)函数调用现场保护和返回地址等计算机内存分系统区和用户区计算机内存分系统区和用户区操作系统区9C08作用域和存储类别静态变量的生存期生存期: 从程序程序开始执行到整个程序运行结束程序运行结束。动态变量的生存期生存期: 从包含该

8、变量定义的函数函数开始执行至该函该函数执行结束。数执行结束。6. 变量的生存期变量的生存期10C08作用域和存储类别int a;main( ) . . f2; . f1; .f1( ) auto int b; f2; .f2( ) static int c; c作用域b作用域a作用域mainf2f1mainf1f2maina生存期:b生存期:例:例:变量的作用域与生存期c生存期:11C08作用域和存储类别静态动态存储方式程序整个运行期间函数调用开始至结束生存期编译时赋初值,只赋一次每次函数调用时赋初值自动赋初值0或空字符不确定未赋初值静态存储区动态区存储区寄存器局部变量外部变量作用域定义变量的

9、函数或复合语句内本文件多个文件局部变量默认为auto型register型变量个数受限,且不能为long, double, float型static局部变量具有全局寿命和局部可见性static局部变量具有可继承性extern不是变量定义,可扩展外部变量作用域registerstatic局部autostatic外部外部存储类别小结:变量的存储类型、作用域与生存期12C08作用域和存储类别8.2 局部变量及其作用域和生存期 1. auto变量 在函数内部(或复合语句内)定义变量时,若使用auto(或缺省) ,称为“动态局部变量” 内。 如在一函数中有定义:auto int a; 或 int a; 则

10、整型变量a是一个自动类的局部变量。 auto变量的特点:1. 由于自动类局部变量的存储单元是在进入这些局部变量所在的函数体(或复合语句)时分配,退出所在的函数体(或复合语句)时释放,所以这些变量的生存期是“短期” 。2. 多次进入同一函数体(或复合语句)时,自动类局部变量所分配的存储位置可能不同。所以,未赋初值的自动变量其值为一个随机值。3不同函数中使用同名变量不会相互影响。 13C08作用域和存储类别main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);auto变

11、量的应用示例(1/8) void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);内存.main:a20002001200220032004200520062007动动态态存存储储区区main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b14C08作用域和存储类别内存.main: a20002001200220032004200520062007动动态态存存储储区区main()vo

12、id f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);auto变量的应用示例(2/8)15C08作用域和存储类别内存.main: a2000200120022003200420052006200720082009动动态态存存储储区区main()void f(int x,int y); int a , b; a=10;b=20; f(

13、a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);f: xf: yf: tauto变量的应用示例(3/8)16C08作用域和存储类别内存.main: a2000200120022003200420052006200720082009动动态态存存储储区区main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=

14、t; f(a,b);main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);102030f: xf: yf: tx=10,y=20,x+y=30auto变量的应用示例(4/8)17C08作用域和存储类别内存.main: a2000200120022003200420052006200720082009动动态态存存储储区区main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b)

15、;main: b1020void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);x=10,y=20,x+y=30main: tauto变量的应用示例(5/8)18C08作用域和存储类别内存.main: a2000200120022003200420052006200720082009动动态态存存储储区区main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b2010void f(i

16、nt x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);x=10,y=20,x+y=3010main: tauto变量的应用示例(6/8)19C08作用域和存储类别内存.main: a2000200120022003200420052006200720082009动动态态存存储储区区main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab) int t; t=a; a=b;b=t; f(a,b);main: b1020void f(int x,int y)int t;

17、t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);f: xf: yf: tx=10,y=20,x+y=30auto变量的应用示例(7/8)20C08作用域和存储类别void f(int x,int y)int t; t=x+y; printf(x=%d,y=%d,x+y=%dn,x,y,t);x=10,y=20,x+y=30内存.main: a2000200120022003200420052006200720082009动动态态存存储储区区main()void f(int x,int y); int a , b; a=10;b=20; f(a,b); if(ab)

18、 int t; t=a; a=b;b=t; f(a,b);main: b1020201030f: xf: yf: tx=10,y=20,x+y=30 x=20,y=10,x+y=30主函数运行结束时,内存中所有的变量均被释放auto变量的应用示例(8/8)21C08作用域和存储类别 寄存器变量也是自动类变量。这种变量的值是保留在CPU内部的寄存器中。 特点:程序运行速度快。主要针对过去的计算机速度慢。2. register变量说明1一个计算机系统中的寄存器数目是有限的,因此只能定义少量的寄存器变量。当程序中的寄存器变量较多时,或编译程序认为指定的变量不适合放在寄存器中时,将自动按auto变量来

19、处理。因此,register说明只是对编译程序的一种建议。2由于register变量的值是放在寄存器内而不是放在内存中,因此register变量没有地址,也就不能对它进行求地址运算。3为了提高寄存器的利用率,register变量应尽量做到即定义即使用,用完就释放。4有些编译程序不理采寄存器变量的定义,直接将其当auto变量来处理。 运算速度慢、访问内存速度慢22C08作用域和存储类别3. 静态存储的局部变量 说明:1.静态局部变量的作用域仍是从定义点到函数体(或复合语句)结束。即仍具有作用域的局部特性。2.在整个程序运行期间,静态局部变量在内存的静态存储区中将长期占用存储单元并保留其值(即便是

20、函数运行结束),其生存期为“长期”,一直到程序运行结束。但要注意此变量及其值不能被其它函数使用。3.静态局部变量的初值是在编译期间赋予的(一次性的),在程序运行期间不再赋予初值。 对未赋初值的静态局部变量,C编译程序自动给它赋初值0。 在函数体(或复合语句)内部,用static说明的变量,称为静态局部变量,存放在内存的静态存储区。23C08作用域和存储类别例8.2 静态局部变量与动态局部变量的比较 f()auto int b=0; /*或int b=0; */ b+; return b;g()static int c=0;/*或static int c;*/ c+; return c;main

21、()int i; for(i=1;i4;i+) printf(%d%d%dn,i,f(),g();运行结果为:111212313 内存.20002001200220032004动动态态存存储储区区main: if: b静态存静态存储区储区g: c24C08作用域和存储类别静态局部变量使用的情形(例8.3) 需要保留函数上一次调用结束时的变量值。 注意:使用静态局部变量要长期占用存储空间,而且当调用次数多时,难以确定静态局部变量的当前值。并且,不同的编译系统对静态局部变量的处理方法不尽相同。因此,如不必要,尽量不要使用静态局部变量。 例8.3 在函数中使用静态局部变量来计算1到5的阶乘值。int

22、 fac(int n)static int f=1; f=f*n; return f; main()int i; for(i=1;i=5;i+) printf(%d!=%dn,i,fac(i);程序运行结果为:1!=12!=23!=64!=245!=12025C08作用域和存储类别8.3 全局变量及其作用域和生存期 全局变量只有静态一种类别,放在静态存储区。1. 全局变量的作用域和生存期 全局变量是可以在函数外部任意位置上定义的变量,它的作用域是从定义点到整个源文件结束。 说明: (1)全局变量为函数之间的数据传递提供了一条通道。由于同一文件的所有函数都能引用全局变量的值,如果在一个函数中改变

23、了某全局变量的值,就能影响使用该全局变量的其它函数,相当于各个函数间有了直接传递的通道。(2)全局变量的生存期是整个程序的运行期间,即“长期”。(3)若全局变量与某一函数中的局部变量同名,则在该函数中,全局变量被屏蔽,使用局部变量。 26C08作用域和存储类别int max,min;float f(int a10) int i,sum=a0; float aver; max=a0; min=a0; for(i=1;imax) max=ai; if(aimin) min=ai); aver=sum/10.0; return aver; main()int x10,j; float average

24、; for(j=0;j10;j+) scanf(%d,&xj); average=f(x);printf(max=%d,min=%d,average=%fn,max,min,average); 例例8.4 编一函数求出编一函数求出10个整数的最大值、最小值和平均值。个整数的最大值、最小值和平均值。27C08作用域和存储类别int i;main() void prt(); for(i=0;i5;i+) prt();void prt() for(i=0;i5;i+) printf( %c, *); printf(n);运行结果:*例例 外部变量副作用外部变量副作用28C08作用域和存储类别2. 全

25、局变量作用域的扩展 (1) 当全局变量定义在后,引用它的函数在前时,应该在引用它的函数中用extern对此全局变量进行声明,使其作用域从extern声明处起,延伸到该函数末尾。也可将extern写在函数之外,使其作用域延伸至文件末尾。 (2) 当一个程序由多个文件组成时,每个文件都是一个独立的编译单位。如果多个文件中都需要用同一个全局变量,这时若在每个文件中都定义一个同名的全局变量,则单独编译各个文件时不会产生错误,编译程序将按定义分别为它们分配存储空间;但当连接时,将产生同一变量的重复定义的错误。 解决办法是:在其中一个文件中定义的全局变量,在其它文件中用extern进行说明,说明这些全局变

26、量已在某一编译单位中定义过,通知编译程序不必再为它们开辟存储单元,只是将作用域进一步扩展到本编译单位中。 29C08作用域和存储类别main( )void gx(),gy(); extern int x,y; gx();gy(); void gx( )int x,y;void gy( ) x,y的原作用域扩展后新增的作用域extern int x,y; main() void gx() int x,y; void gy() x,y的作用域扩展后 x,y的作用域例:在同文件中扩展全局变量的作用域30C08作用域和存储类别/*/int x,y;main( )f1();f2(); f3(); f1( ) x=111; x,y的作用域/*/extern int x;f2( ) printf(%dn,x); /*111*/ f3( ) x+; printf(%dn,x); /*112*/ 例:在不同文件中扩展全局变量的作用域扩展后x的作用域31C08作用域和存储类别/*xt10210a.c*/#include int x=10;int y=10;void add(void) y=x+10; x*=2;void main() extern void sub(); x+=5; add(); sub();prin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论