为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

变量作用域的问题

2013-10-19 6页 doc 26KB 10阅读

用户头像

is_392628

暂无简介

举报
变量作用域的问题Chapter1C语言中的变量,按照作用域的范围可分为两种,即局部变量和全局变量。一、局部变量局部变量也称为内部变量,自由变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。例如: intf1(inta)/*函数f1*/{intb,c;……} intf2(intx)/*函数f2*/{inty,z;;……} f1内定义了三个变量,a为形参,b,c为一般变量。在f1的范围内a,b,c有效,或者说a,b,c变量的作用域限于f1内。 f...
变量作用域的问题
Chapter1C语言中的变量,按照作用域的范围可分为两种,即局部变量和全局变量。一、局部变量局部变量也称为内部变量,自由变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。例如: intf1(inta)/*函数f1*/{intb,c;……} intf2(intx)/*函数f2*/{inty,z;;……} f1内定义了三个变量,a为形参,b,c为一般变量。在f1的范围内a,b,c有效,或者说a,b,c变量的作用域限于f1内。 f2内定义了三个变量,x为形参,y,z为一般变量。在f2的范围内x,y,z有效,或者说x,y,z变量的作用域限于f2内。关于局部变量的作用域还要说明以下几点:主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用。同时,主函数中也不能使用其它函数中定义的变量。因为主函数也是一个函数,它与其它函数是平行关系。形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量。允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。。二、全局变量 inta,b;/*外部变量*/voidf1()/*函数f1*/{……} floatx,y;/*外部变量*/intfz()/*函数fz*/{……}全局变量也称为外部变量,它是在所有函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。例如:从上例可以看出a、b、x、y都是在函数外部定义的外部变量,都是全局变量。对于全局变量还有以下几点说明:对于局部变量的定义和说明,可以不加区分。而对于外部变量则不然,外部变量的定义和外部变量的声明并不是一回事。(1)外部变量定义必须在所有的函数之外,且只能定义一次。其一般形式为:[extern]类型说明符变量名,变量名…其中方括号内的extern可以省去不写。例如:inta,b;等效于:externinta,b;(2)外部变量声明出现在要使用该外部变量的各个函数内,在整个程序内,可能出现多次,外部变量说明的一般形式为:extern类型说明符变量名,变量名,…;外部变量在定义时就已分配了内存单元,外部变量定义可作初始赋值,外部变量声明不能再赋初始值,只是表明在函数内要使用某外部变量。外部变量可加强函数模块之间的数据联系,但是又使函数要依赖这些变量,因而使得函数的独立性降低。从模块化程序设计的观点来看这是不利的,因此在不必要时尽量不要使用全局变量。在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量不起作用。intvs(intl,intw){externinth;intv;v=l*w*h;returnv;}main(){externintw,h;intl=5;printf("v=%d",vs(l,w));}intl=3,w=4,h=5;本例程序中,外部变量在最后定义,因此在前面函数中对要用的外部变量必须进行说明。外部变量l,w和vs函数的形参l,w同名。外部变量都作了初始赋值,main函数中也对l作了初始化赋值。执行程序时,在printf语句中调用vs函数,实参l的值应为main中定义的l值,等于5,外部变量l在main内不起作用;实参w的值为外部变量w的值为4,进入vs后这两个值传送给形参l,wvs函数中使用的h为外部变量,其值为5,因此v的计算结果为100,返回主函数后输出。变量的存储类型决定了各种变量的作用域不同。变量的存储方式可分为“静态存储”和“动态存储”两种。静态存储变量通常是在变量定义时就分定存储单元并一直保持不变,直至整个程序结束。动态存储变量是在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放。例如函数的形式参数,在函数定义时并不给形参分配存储单元,只是在函数被调用时,才予以分配,调用函数完毕立即释放。如果一个函数被多次调用,则反复地分配、释放形参变量的存储单元。静态存储变量是一直存在的,而动态存储变量则时而存在时而消失。把这种由于变量存储方式不同而产生的特性称变量的生存期。生存期表示了变量存在的时间。生存期和作用域是从时间和空间这两个不同的角度来描述变量的特性,这两者既有联系,又有区别。一个变量究竟属于哪一种存储方式,并不能仅从其作用域来判断,还应有明确的存储类型说明。Chapter2在C语言中,对变量的存储类型说明有以下四种:自动变量(auto)、寄存器变量(register)、外部变量(extern)、静态变量(static)。   变量的存储方式可分为:自动变量和寄存器变量属于动态存储方式,外部变量和静态变量属于静态存储方式。所以,变量定义的完整形式应为:存储类型说明符数据类型说明符变量名,变量名…;eg:staticinta,b;     //说明a,b为静态类型变量[auto]charc1,c2;   //说明c1,c2为自动字符变量,auto可以省略staticinta[5]={1,2,3,4,5};//说明a为静整型数组externintx,y;     //说明x,y为外部整型变量下面分别介绍以上四种存储类型:一、自动变量的类型说明符为auto这种存储类型是C语言程序中使用最广泛的一种类型。自动变量可省去说明符auto。函数内凡未加存储类型说明的变量均视为自动变量,例如:{inti,j,k;charc;}等价于:{autointi,j,k;autocharc;}自动变量具有以下特点:1.自动变量的作用域:仅限于定义该变量的个体内。在函数中定义的自动变量,只在该函数内有效。在复合语句中定义的自动变量只在该复合语句中有效。例如:intkv(inta){autointx,y;{autocharc;/*c的作用域*/}/*a,x,y的作用域*/}2.自动变量存储方式:属于动态存储方式,只有定义该变量的函数被调用时才给它分配存储单元,开始它的生存期。函数调用结束,释放存储单元,结束生存期。因此函数调用结束之后,自动变量的值不能保留。在复合语句中定义的自动变量,在退出复合语句后也不能再使用,否则将引起错误。例如以下程序:Eg1:intmain(){autointa,s,p;printf("/ninputanumber:/n");scanf("%d",&a);if(a>0){s=a+a;p=a*a;}printf("s=%dp=%d/n",s,p);}Eg2:intmain(){autointa;printf("/ninputanumber:/n");scanf("%d",&a);if(a>0){autoints,p;s=a+a;p=a*a;}printf("s=%dp=%d/n",s,p);//会出错}Eg2中,s,p是在复合语句内定义的自动变量,只能在该复合语句内有效。而程序的第10行却是退出复合语句之后用printf语句输出s,p的值,这显然会引起错误。3.自动变量在不同的个体中可以同名:这是由自动变量的作用域和生存期决定的(函数或复合语句内)。即在函数内定义的自动变量也可与该函数内部的复合语句中定义的自动变量同名。下例表明了这种情况。intmain(){autointa,s=100,p=100;printf("/ninputanumber:/n");scanf("%d",&a);if(a>0){autoints,p;//在复合语句中,//允许定义与局部变量同名的量s=a+a;p=a*a;printf("s=%dp=%d/n",s,p);}printf("s=%dp=%d/n",s,p);}本程序在main函数中和复合语句内两次定义了变量s,p为自动变量。在复合语句内,应由复合语句中定义的s,p起作用,故s的值应为a+a,p的值为a*a。退出复合语句后的s,p应为main所定义的s,p,其值在初始化时给定,均为100。从输出结果可以出两个s和两个p虽变量名相同,但却是两个不同的变量。二、外部变量的类型说明符为extern外部有两个含义:一是指这些变量定义在任何函数的外部,二是指这些变量可以被同一源程序的外部文件使用1.外部变量和全局变量是对同一类变量的两种不同角度的提法。全局变量是从它的作用域提出的,外部变量从它的存储方式提出的,属于静态存储方式。2.生存期:当一个源程序由若干个源文件组成时,在一个源文件中定义的外部变量在其它的源文件中也有效。例如有一个源程序由源文件F1.C和F2.C组成:F1.Cinta,b;/*外部变量定义*/charc;/*外部变量定义*/main(){……}F2.Cexterninta,b;/*外部变量说明*/externcharc;/*外部变量说明*/func(intx,y){……}在F1.C文件中把a,b,c都定义为外部变量。在F2.C文件中用extern把三个变量说明为外部变量,表示这些变量已在其它文件中定义,编译系统不再为它们分配内存空间。对构造类型的外部变量,如数组等可以在说明时作初始化赋值,若不赋初值,则系统自动定义它们的初值为0。三、静态变量的类型说明符为static静态变量当然是属于静态存储方式,必须由static加以定义后才能成为静态外部变量,或称静态全局变量。对于自动变量,它属于动态存储方式,可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。一个变量(局部变量)可由static进行再说明,并改变其原有的存储方式。1.静态局部变量在局部变量的说明前再加上static说明符就构成静态局部变量。Eg:staticinta,b;staticfloatarray[5]={1,2,3,4,5};静态局部变量属于静态存储方式,它具有以下特点:(1)生存期:静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。(2)作用域:静态局部变量的作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它。(3)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。根据静态局部变量的特点,可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值。因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。main(){inti;voidf();/*函数声明*/for(i=1;i<=5;i++)f();/*函数调用*/}voidf()/*函数定义*/{autointj=0;++j;printf("%d/n",j);}main(){inti;voidf();for(i=1;i<=5;i++)f();}voidf(){staticintj=0;++j;printf("%d/n",j);}左例中,程序中定义了函数f,其中的变量j说明为自动变量并赋予初始值为0。当main中多次调用f时,j均赋初值为0,故每次输出值均为1。右例中,把j改为静态局部变量,由于j为静态变量,能在每次调用后保留其值并在下一次调用时继续使用,所以输出值成为累加的结果。2.静态全局变量全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量。静态全局变量同全局变量存储方式一样,也属于静态存储方式。两者区别在于作用域范围。非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。静态全局变量则只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。优点:静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。总结:(1)局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。(2)全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static这个说明符在不同的地方所起的作用是不同的。四、寄存器变量的说明符是register上述各类变量都存放在存储器内,因此当对一个变量频繁读写时,必须要反复访问内存储器,从而花费大量的存取时间。寄存器变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,这样可提高效率。对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量。求∑200i=1intmain(){registeri,s=0;for(i=1;i<=200;i++)s=s+i;printf("s=%d/n",s);}本程序循环200次,i和s都将频繁使用,因此可定义为寄存器变量。对寄存器变量还要说明以下几点:1.存储方式:寄存器变量属于动态存储方式。只有局部自动变量和形式参数才可以定义为寄存器变量。凡需要采用静态存储方式的量不能定义为寄存器变量。2.在TurboC,MSC等微机上使用的C语言中,实际上是把寄存器变量当成自动变量处理的。因此速度并不能提高。而在程序中允许使用寄存器变量只是为了与标准C保持一致。即使能真正使用寄存器变量的机器,由于CPU中寄存器的个数是有限的,因此使用寄存器变量的个数也是有限的。
/
本文档为【变量作用域的问题】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索