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

下载本文档

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

文档简介

存储类别和作用域第1页,共32页,2023年,2月20日,星期一4.6存储类别和作用域变量的作用域:是指变量在程序中有效的空间范围,变量的作用域与定义变量的位置有关;变量的生存期:指的是变量生成到变量空间释放的时间范围,变量的生存期与变量的存储类别相关。

C++可将作用域分为五种:块作用域、文件作用域、函数原型作用域、函数作用域和类作用域。第2页,共32页,2023年,2月20日,星期一1.块作用域块:就是用花括号括起来的那部分程序。在块内说明的标识符只能在该块内引用,即其作用域在块内。所有函数体内定义的变量都具有块作用域。在一个函数内或块内定义的变量被称为局部变量;对于块中嵌套其他块的情况,如果嵌套块中有同名局部变量,服从局部优先原则,即在内层块中屏蔽外层块中的同名变量。在函数原型作用域和函数作用域内定义的变量都属于局部变量;第3页,共32页,2023年,2月20日,星期一【例4.12】局部变量的屏蔽。#include<iostream.h>voidmain(){ inti=5; { cout<<"i1="<<i<<'\n'; //A inti; i=7; cout<<"i2="<<i<<'\n'; //B } cout<<"i3="<<i<<'\n'; //C return;}运行结果是:i1=5i2=7i3=5第4页,共32页,2023年,2月20日,星期一2.文件作用域在所有函数外定义的变量称为全局变量,全局变量的作用域称为文件的作用域;当局部变量与全局变量同名时,局部变量(块作用域内的变量)优先。它与块作用域不同的是:在块作用域内可通过域运算符“::”来引用与局部变量同名的全局变量。第5页,共32页,2023年,2月20日,星期一【例4.13】在块作用域内引用文件作用域中的同名全局变量。#include<iostream.h>inti=0; //Avoidmain(){ inti=5; //B { cout<<i; //C inti=7; //D cout<<i;//E cout<<::i;//F }}程序运行后结果为:570第6页,共32页,2023年,2月20日,星期一4.6.2变量的存储类别操作系统为一个C++程序的运行所分配的内存分为4个区域,如图4.2所示。代码区:存放程序代码,即程序中各个函数的代码块静态数据区:存放程序的全局数据和静态数据栈区:存放程序中的局部变量,如函数中的局部变量等堆区:存放动态分配的数据。堆区(动态数据)栈区(函数局部数据)main()函数局部数据静态数据区(全局变量、静态变量)代码区(程序代码)图4.2程序在内存中的区域第7页,共32页,2023年,2月20日,星期一C++使用四种说明符auto(自动类型)、register(寄存器类型)、static(静态类型)和extern(外部类型)来确定变量的存储类型。加上变量的作用域的不同,在C++中变量共有下列5种存储形式:局部变量、全局变量、外部变量、静态变量、寄存器变量;第8页,共32页,2023年,2月20日,星期一

在函数或块内部说明的变量称为局部变量(如形参变量),由于建立和撤消这些变量是由系统自动完成,因此这类变量又称为自动型变量。注意:a:局部变量仅由说明它的函数或块的内部语句所访问;换言之,局部变量在定义自己的函数或块之外是不可见的。b:局部变量在进入函数时生成,退出时消亡。因此局部变量的生存期仅存在于被定义的函数或块中。1、自动存储变量(局部变量,属于auto型)第9页,共32页,2023年,2月20日,星期一#include<iostream.h>voidfunc1();voidfunc2();voidfunc1(){ intx; x=10; cout<<x<<‘\t’;}voidmain(void){ intx=20; func1(); func2(); cout<<x;}voidfunc2(){ intx; x=-199; cout<<x<<‘\t’;}第10页,共32页,2023年,2月20日,星期一程序说明:整形变量x被说明了3次,一次在func1中,另一次在func2和main中,func1和func2中的x互不相关,也就是说,局部变量的值不能在两次调用之间保持。在C语言中,必须在函数或语句块的开头先于其它任何语句说明所有的局部变量。但在C++中,只需在变量使用之前说明就可以了。(结果为:10-19920)第11页,共32页,2023年,2月20日,星期一

与局部变量不同,全局变量在任何函数之外说明,包括main函数,并且可被任何一个函数使用。全局变量将在整个程序运行期间保持有效,同时可被函数内的任何表达式访问。说明全局变量的最佳位置在程序的一开始。2、全局变量第12页,共32页,2023年,2月20日,星期一#include<iostream.h>intcount;voidfunc1();voidfunc2();voidfunc1(){inttemp;temp=count;func2();cout<<“countis:”<<temp;}voidmain(void){count=100;func1();exit(0);}voidfunc2(){intcount;for(count=1;count<10;count++)cout.put(‘。’);}第13页,共32页,2023年,2月20日,星期一

全局变量count既不在main()中说明,也不在func1()中说明,但可以在两者中被访问。函数func2中也说明了一个同名的局部变量count,但func2访问count时,仅访问自己说明的局部变量count,而不是那个全局变量count。注意:全局变量和某一函数的局部变量同名时,在函数内对该名的访问权仅针对局部变量,对全局变量无任何影响。程序执行结果为:。。。。。。。。。countis100//9个“。”程序分析:第14页,共32页,2023年,2月20日,星期一使用全局变量应注意的几点:不论是否需要,全局变量在整个程序执行期间均占用固定的内存空间。在使用局部变量就可以达到其功能时,应避免使用全局变量,这样可以提高函数的通用性。大量使用全局变量时,可能导致不期望的副作用。例如,变量值在程序其它地点的偶然改变,将在程序的整个生存期内有效。第15页,共32页,2023年,2月20日,星期一

由于C++语言支持分离编译,既一个完整的C++语言程序可以由多个独立的文件组成,每个文件可以分别单独编译,然后再由链接程序完成程序组装。因此必须将程序需要的所有全局变量通过某种方法告诉所有的独立文件。方法就是在一个文件中说明所有全局变量,在其它文件中用extern再次描述它们。因此外部变量定义是:由extern说明的全局变量称为外部变量。3、外部变量第16页,共32页,2023年,2月20日,星期一文件1intx,y;charch;Voidmain(void){...........}文件2externintx,y;externcharch;voidfunc22(){x=y/10;}voidfunc1(){x=123;}voidfunc23(){y=10;}程序分析:在文件2中,全局变量表是从文件1中复制过来的,并将分类符extern加在说明之前。extern告诉编译程序,如下变量的类型和名字已在别处说明过了。第17页,共32页,2023年,2月20日,星期一稳定的具有固定的内存地址的变量称为静态变量;

或:用static修饰的变量);

静态变量不象动态变量是在程序执行过程中被动态建立、动态撤消的。静态变量的定义格式为:static变量类型变量列表;静态变量又可分为静态局部变量和静态全局变量。静态局部变量:是指定义在模块内部的静态变量。它与局部变量的共同点是:都是局限于某个模块内部;仅在该模块内是有效的;4、静态变量第18页,共32页,2023年,2月20日,星期一

局部变量仅存在于该模块被调用时,函数退出后,该变量就消失了。因此,它没有连续性,在末赋初值时,其值不定;而静态局部变量是始终存在的,即使退出该模块,变量仍然有效。这是因为它在内存中占有固定的单元,在多次调用该模块时,可以保持此变量的连续性。它们的不同点是:第19页,共32页,2023年,2月20日,星期一#include<iostream.h>voidabc(intx,inty,intz);voidmain(void){ inti,j,k; i=5;j=10; for(k=1;k<=5;k++) abc(i,j,k);}voidabc(intx,inty,intz){ intm; staticintn; if(z==1) {m=0;n=0;} else { m+=x+y; n+=x+y; } cout<<"m="<<m<<",n="<<n<<'\n';}例:说明静态局部变量与局部变量的区别;第20页,共32页,2023年,2月20日,星期一在上例中,函数abc()中的if语句if(z==0) {m=0;n=0;}是为了同时给m,n赋值。然而多次调用函数abc(),n的初值在起作用,保持了连续性。而m初值没有起作用,没有连续性。语句m+=x+y;在z!=1以后的多次调用中,结果为不确定(因为没有被赋值)。程序运行结果: m=0,n=0; m=*,n=15 m=*,n=30; m=*,n=45; m=*,n=60;其中*表示不确定值。程序说明:第21页,共32页,2023年,2月20日,星期一

用static修饰全局变量称为静态全局变量。静态全局变量与全局变量在形式上类似,但意义不同。静态全局变量只在它被定义的源文件中是有效的(该文件可以有几个函数),而在任何别的源文件中则是无效的。而全局变量通过extern修饰后可以作用于一个程序的多个源文件中。静态全局变量:第22页,共32页,2023年,2月20日,星期一例:文件1staticinti=5;intj=10;voidmain(void){ intk1,k2; k1=f1(i,j); k2=f2(i,j); cout<<"k1="<<k1<<",k2="<<k2<<endl;}f1(intx,inty){ intz; z=x+y+i; return(z);}文件2externintj;f2(inta,intb){ intc; c=a*b+j; return(c);}运行结果:k1=20,k2=60;第23页,共32页,2023年,2月20日,星期一程序说明:这个程序有三个函数:main,f1,f2。其中函数f2单独作为一个文件,main和f1为另一个文件。程序中用一个静态全局变量i和一个全局变量j。因此变量j既可以在文件1中使用,也可以在文件2中通过extern说明使用。然而,变量i是静态全局变量,它只能在文件1中使用,即在函数main和函数f1中使用。第24页,共32页,2023年,2月20日,星期一C++语言提供了一种仅用于int和char类型变量的存储分类符register,(因为通常寄存器是16位或32位字长)。它的定义是:用register修饰的局部变量称为寄存器变量。几点注意:分类符register要求编译系统将它所说明的变量值保存在CPU寄存器中,而不是象普通变量那样存放在内存单元中,此时由于对变量的存取不必访问内存,因此运算速度大大快于普通变量的运算。这一类变量常用于循环控制部分;分类符register仅可用于局部变量和函数的形式参数,因为这些变量都是缺省的自动变量。全局的register变量是不允许的;5、寄存器变量第25页,共32页,2023年,2月20日,星期一因为register变量存放在CPU的寄存器中,所以它没有地址,也就是说,不能用地址操作符&对register变量进行地址操作;一个函数中所允许的寄存器变量的数目取决于处理器类型以及所指定的C++编译系统。若程序中寄存器变量的数量超过极限时,编译系统可能自动将它们转换成自动变量,从而保证了程序的可移植性;第26页,共32页,2023年,2月20日,星期一int_pwr(intm,registerinte){ registerinttemp; temp=1; for(;e;e--) temp=temp*m; return(temp);}程序说明:其中e和temp因用在循环中而又都说明为register变量,由于register变量可以提高速度,因此它是最理想的循环控制变量。例:求M的e次幂。第27页,共32页,2023年,2月20日,星期一最后总结:全局变量和静态变量只在程序的开始一次生成;局部变量和寄存器变量在进入定义它们的程序块和每个入口多次生成;没有赋值的局部变量和寄存器变量在第一个赋值语句之前是末知的。例1:不同存储类变量的应用;例2:自动类与局部静态类变量的应用;例3:由多个文件组成的程序中变量的作用域;第28页,共32页,2023年,2月20日,星期一#include<iostream.h>#include<iomanip.h>inti=1;voidother(void);voidmain(void){ staticinta; registerintb=-10; intc=0; cout<<"i: "<<"a: "<<"b: "<<"c: "<<endl; cout<<i<<setw(8)<<a<<setw(8)<<b<<setw(8)<<c<<endl;//例:不同存储类型变量的应用 c+=8; other(); cout<<i<<setw(8)<<a<<setw(8)<<b<<setw(8)<<c<<endl; i+=10; other();}voidother(void){ staticinta=2; staticintb; intc=10; a+=2; i+=32; c+=5; cout<<i<<setw(8)<<a<<setw(8)<<b<<setw(8)<<c<<endl; b=a;}

温馨提示

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

评论

0/150

提交评论