版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C语言中局部变量和全局变量 变量的存储类别(static,extern,auto,register) 8.8 局部变量和全局变量在讨论函数的形参变量时曾经提到,形参变量只在被调用期间才分配内存单元,调用结束立即释放。这一点表明形参变量只有在函数内才是有效的,离开该函数就不能再使用了。这种变量有效性的范围称变量的作用域。不仅对于形参变量,语言中所有的量都有自己的作用域。变量说明的方式不同,其作用域也不同。语言中的变量,按作用域范围可分为两种,即局部变量和全局变量。8.8.1 局部变量 局部变量也称为内部变量。局部变量是在函数内作定义说明
2、的。其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。例如: int f1(int a) /*函数f1*/ int b,c; a,b,c有效 int f2(int x) /*函数f
3、2*/ int y,z; x,y,z有效 main() int m,n; m,n有效在函数f1内定义了三个变量,a为形参,b,c为一般变量。在 f1的范围内a,b,c有效,或者说a,b,c变量的作用域限于f1内。同理,x,y,z的作用域限于f2内。m,n的作用域限于main函数内。关于局部变量的作用域还要说明以下几点:1) 主函数中定义的变量
4、也只能在主函数中使用,不能在其它函数中使用。同时,主函数中也不能使用其它函数中定义的变量。因为主函数也是一个函数,它与其它函数是平行关系。这一点是与其它语言不同的,应予以注意。2) 形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量。3) 允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。如在前例中,形参和实参的变量名都为n,是完全允许的。4) 在复合语句中也可定义变量,其作用域只在复合语
5、句范围内。例如: main() int s,a; int b; s=a+b; /*b作用域*/
6、60; /*s,a作用域*/【例8.12】main() int i=2,j=3,k; k=i+j; int k=8;
7、; printf("%dn",k); printf("%dn",k);本程序在main中定义了i,j,k三个变量,其中k未赋初值。而在复合语句内又定义了一个变量k,并赋初值为8。应该注意这两个k不是同一个变量。在复合语句外由main定义的k起作用,而在复合语句内则由在复合语句内定义的k起作用。因此程序第4行的k为main所定义,其值应为5。第7行输出k值,该行在复合语句内,由复合语句内定义的k起作用,其初值为8,故输出值为8,第9行输出i,k值。i是在整个程序中有效的,
8、第7行对i赋值为3,故以输出也为3。而第9行已在复合语句之外,输出的k应为main所定义的k,此k值由第4 行已获得为5,故输出也为5。8.8.2 全局变量全局变量也称为外部变量,它是在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。例如: int a,b;
9、0; /*外部变量*/ void f1() /*函数f1*/ float x,y; /*外部变量*/ int fz()
10、60; /*函数fz*/ main() /*主函数*/ 从上例可以看出a、b、x、y 都是在函数外部定义的外部
11、变量,都是全局变量。但x,y 定义在函数f1之后,而在f1内又无对x,y的说明,所以它们在f1内无效。a,b定义在源程序最前面,因此在f1,f2及main内不加说明也可使用。【例8.13】输入正方体的长宽高l,w,h。求体积及三个面x*y,x*z,y*z的面积。int s1,s2,s3;int vs( int a,int b,int c) int v; v=a*b*c; s1=a*b; s2=b*c; s3=a*c;
12、 return v;main()int v,l,w,h;printf("ninput length,width and heightn");scanf("%d%d%d",&l,&w,&h);v=vs(l,w,h);printf("nv=%d,s1=%d,s2=%d,s3=%dn",v,s1,s2,s3);【例8.14】外部变量与局部变量同名。int a=3,b=5; /*a,b为外部变量*/max(int a,int b) /*
13、a,b为外部变量*/int c;c=a>b?a:b;return(c);main()int a=8;printf("%dn",max(a,b);如果同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即它不起作用。8.9 变量的存储类别8.9.1 动态存储方式与静态动态存储方式前面已经介绍了,从变量的作用域(即从空间)角度来分,可以分为全局变量和局部变量。从另一个角度,从变量值存在的作时间(即生存期)角度来分,可以分为静态存储方式和动态存储方式。静态存储方式:是指在程序运行期间分配固定的存储空间的方式。动态存储
14、方式:是在程序运行期间根据需要进行动态的分配存储空间的方式。用户存储空间可以分为三个部分:1) 程序区;2) 静态存储区;3) 动态存储区;全局变量全部存放在静态存储区,在程序开始执行时给全局变量分配存储区,程序行完毕就释放。在程序执行过程中它们占据固定的存储单元,而不动态地进行分配和释放;动态存储区存放以下数据:1)
15、160; 函数形式参数;2) 自动变量(未加static声明的局部变量);3) 函数调用实的现场保护和返回地址;对以上这些数据,在函数开始调用时分配动态存储空间,函数结束时释放这些空间。在c语言中,每个变量和函数有两个属性:数据类型和数据的存储类别。8.9.2 auto变量函数中的局部变量,如不专门声明为static存储类别,都是动态地分配存储空间的,数据存储在动态存储区中。函数中的形参和在函数中定义的变量(包括在复合语句中定义的变量),都属此类,在调
16、用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。这类局部变量称为自动变量。自动变量用关键字auto作存储类别的声明。例如:int f(int a) /*定义f函数,a为参数*/auto int b,c=3; /*定义b,c自动变量*/a是形参,b,c是自动变量,对c赋初值3。执行完f函数后,自动释放a,b,c所占的存储单元。关键字auto可以省略,auto不写则隐含定为“自动存储类别”,属于动态存储方式。8.9.3 用sta
17、tic声明局部变量有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,这时就应该指定局部变量为“静态局部变量”,用关键字static进行声明。【例8.15】考察静态局部变量的值。f(int a)auto b=0;static c=3;b=b+1;c=c+1;return(a+b+c);main()int a=2,i;for(i=0;i<3;i+)printf("%d",f(a);对静态局部变量的说明:1) 静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局
18、部变量)属于动态存储类别,占动态存储空间,函数调用结束后即释放。2) 静态局部变量在编译时赋初值,即只赋初值一次;而对自动变量赋初值是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。3) 如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量)。而对自动变量来说,如果不赋初值则它的值是一个不确定的值。【例8.16】打印1到5的阶乘值。int fac(int n)static int f=1;f=f*n;return(f)
19、;main()int i;for(i=1;i<=5;i+)printf("%d!=%dn",i,fac(i);8.9.4 register变量为了提高效率,C语言允许将局部变量得值放在CPU中的寄存器中,这种变量叫“寄存器变量”,用关键字register作声明。【例8.17】使用寄存器变量。int fac(int n)register int i,f=1;for(i=1;i<=n;i+)f=f*ireturn(f);main()int i;for(i=0;i<=5;i+)printf("%d!=%dn",i,fac(i);说明:1)
20、160; 只有局部自动变量和形式参数可以作为寄存器变量;2) 一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量;3) 局部静态变量不能定义为寄存器变量。8.9.5 用extern声明外部变量外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用
21、该外部变量,则应该在引用之前用关键字extern对该变量作“外部变量声明”。表示该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量。【例8.18】用extern声明外部变量,扩展程序文件中的作用域。int max(int x,int y)int z;z=x>y?x:y;return(z);main()extern A,B;printf("%dn",max(A,B);int A=13,B=-8;说明:在本程序文件的最后1行定义了外部变量A,B,但由于外部变量定义的位置在函数main之后,因此本来在main函数中不能引用外部变量A,B。
22、现在我们在main函数中用extern对A和B进行“外部变量声明”,就可以从“声明”处起,合法地使用该外部变量A和B。对于malloc而来的变量存储在堆(heap)中,局部变量都存储在栈(stack)中。堆和栈的区别: 堆和栈的区别 一个由c/C+编译的程序占用的内存分为以下几个部分 1、栈区(stack) 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 3、全局区(静态区)(static),全局变量和
23、静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 4、文字常量区 常量字符串就是放在这里的。 程序结束后由系统释放 5、程序代码区存放函数体的二进制代码。在全局变量和全局静态变量有什么区别: 在全局变量和全局静态变量有什么区别变量可以分为:全局变量、静态全局变量、静态局部变量和局部变量。 按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。 按作用域分,全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它
24、的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。 全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。 静态全局变量,只本文件可以用。 全局变量是没有定义存储类型的外部变量,其作用域是从定义点到程序结束.省略了存储类型符,系统将默认为是自动型. 静态全局变量是定义存储类型为静态型的外部变量,其作用域是从定义点到程序结束,所不同的是存储类型决定了存储地点,静态型变量是存放在内存的数据区中的,它们在程序开始运行前就分配了固定的字节,在程序运行过程中被分配的字节大小是不改变的.只有程序运行结束后,才释放所
25、占用的内存. 自动型变量存放在堆栈区中.堆栈区也是内存中一部分,该部分内存在程序运行中是重复使用的.声明变量与定义变量有什么区别声明是向编译器介绍名字标识符。它告诉编译器“这个函数或变量在某处可找到,它的模样象什么”。而定义是说:“在这里建立变量”或“在这里建立函数”。它为名字分配存储空间。无论定义的是函数还是变量,编译器都要为它们在定义点分配存储空间。对于变量,编译器确定变量的大小,然后在内存中开辟空间来保存其数据,对于函数,编译器会生成代码,这些代码最终也要占用一定的内存。 在C和C中,可以在不同的地方声明相同的变量和函数,但只能有一个定义(有时这称为ODR,单一定义规则)。 定义也可以是
26、声明,如果有int x;,之前编译器未发现标识符x,编译器则把这一标识符看成是定义并立即为它分配存储空间。 。 对“变量声明”的解释向来模糊且自相矛盾。 函数声明包括函数类型、函数名、参数列表和一个分号,这些信息足以编译器认出它是一个函数声明并可识别出这个函数的外部特征。由此推断,变量声明应是类型标识后面跟一个标识符。如int a;但这产生了一个矛盾,这段代码有足够的信息让编译器为之分配存储空间,而且编译器也确实给之分配了存储空间。要解决这个问题,对于C和C需要一个关键字来说明“这是一个声明,它的定义在别的地方”,这个关键字就是extern,它表示变量是在文件以外定义的,或在文件后面定义的。 在变量定义前加ex
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 经营酒吧合同
- 股份制改革流程文书模板与指导
- 汽车美容店合作协议书年
- 委托培训协议书
- 质量管理体系培训指导书
- 2025年青海货运从业资证孝试模似题库
- 小学三年级数学加减乘除混合口算
- 2025年黔东南道路货运驾驶员从业资格证考试题库
- 2025年上海货车丛业资格证考试题
- 2025年汕头货运从业资格证怎么考试
- 中储棉直属企业招聘笔试真题2024
- 2024年长沙卫生职业学院高职单招职业技能测验历年参考题库(频考版)含答案解析
- 2025届高考数学一轮专题重组卷第一部分专题十四立体几何综合文含解析
- 福建省泉州市南安市2024-2025学年九年级上学期期末考试语文试题(无答案)
- 医疗器材申请物价流程
- 人教PEP版2025年春季小学英语三年级下册教学计划
- 华为研发部门绩效考核制度及方案
- 2025年蛇年年度营销日历营销建议【2025营销日历】
- 摄影入门课程-摄影基础与技巧全面解析
- 冀少版小学二年级下册音乐教案
- 【龙集镇稻虾综合种养面临的问题及优化建议探析(论文)13000字】
评论
0/150
提交评论