您好,欢迎访问三七文档
第八章变量的存储类型本章介绍变量的存储类型。变量的存储类型确定了变量的存储方式、生命期、作用域。介绍自动变量、静态变量、外部变量和寄存器变量,及它们之间的区别。程序在系统中运行时,操作系统为其分配的存储空间可划分为如下的四个区域,每个区域存放不同的数据。函数调用是在公共数据区stackarea中建栈完成的。动态内存分配是在heaparea中进行分配的。程序代码全局数据,静态数据动态数据局部数据CodeareaDataareaheapareaStackarea数据区——全局生命期及作用域、静态生命期及作用域栈区——局部生命期及作用域堆区——动态生命期当数据存放在不同区域时,具有不同的生命期和作用域。生命期也称为生存期,即标识符在程序运行中的时限。全局生命期指标识符在程序运行的全过程中存在。局部生命期指标识符在程序运行的局部阶段存在。作用域是指标识符在程序中的有效范围。作用域开始于标识符的说明处。可见性是分析在某一位置标识符的有效性,即表示该标识符在该位置是否可以被调用。它是从另一角度表现标识符的有效性。标识符的生命期和作用域与标识符在内存中的存储方式密切相关。自动变量在函数(模块)内部定义的变量称为自动变量,也称为局部变量。其生命期和作用域均为局部的。即在函数(模块)内可见,作用域为函数内部。局部变量存放在栈区中,函数被调用时,局部变量在栈区被分配存储空间,函数调用结束时,局部变量随之消失,其值不能保存。生命期是在函数调用期间。局部变量在C中没有缺省初值,未被显式初始化,其值不确定。自动变量使用关键字auto表示,通常auto可以省略。迄今为止,在前面已讨论过的程序中,如无特殊说明,使用的变量都是自动变量。不同函数可以使用同名的局部变量,便于大型软件开发中的分任务分模块的编程。例如:voidmain(){intn;/*等价于autointn;同名的局部变量*///……}voidfunc(){intn;/*等价于autointn;同名的局部变量*///……}外部变量外部变量是在函数之外定义的变量,也称为全局变量。具有全局生命期和作用域,程序中的每个函数都是可见的。外部变量存放在内存的全局数据区。定义外部变量时,若无显示初始化,编译器将外部变量初始化为0。外部变量通常在main()函数之前定义,一旦被定义可被后面函数访问。尽管外部变量是可以在程序任何函数之外定义,但定义点之前的函数是不可知的。例如:intfunc();intn=5;voidmain(){intm=n;pritf(“m=%d”,m);pritf(“n=%d”,n);pritf(“n=%d”,func());}intfunc(){ints=10;n=s;return(n);}结果:m=5n=5n=10则main()函数中语句m=n;无意义,编译错。若将全局变量n定义在两函数之间:intn=5;静态变量包括:静态局部变量及静态外部变量。1.静态局部变量静态局部变量也是在函数(模块)内部定义的变量,其作用域与局部变量类似,仅在函数内部可见,但由于存放在dataarea有固定的存储单元,函数调用结束后,其值得以保存。关键字为static静态局部变量与外部变量一样,若未初始化,其值为0。编译器对静态局部变量仅初始化一次,重复调用保留原值,不再进行初始化。下面是使用外部变量、静态局部变量、局部变量的例子。();intn=1;/*外部变量*/main(){staticinta;/*静态局部变量*/intb=-10;/*局部变量*/printf(”a:%db:%dn:%d”,a,b,n);b+=4;func();printf(”a:%db:%dn:%d”,a,b,n);n+=10;func();}voidfunc(){staticinta=2;/*静态局部变量多次函数调用仅初始化1次*/intb=5;/*局部变量,每次调用都初始化。*/a+=2;n+=12;b+=5;printf(”a:%db:%dn:%d”,a,b,n);}静态外部变量在函数之外定义的静态变量称为静态外部变量。静态外部变量与外部变量的作用域和生命期都是全局的。其主要区别是:前者作用域为定义该静态外部变量的源程序文件,后者作用域为组成程序的所有源程序文件。结果:a:0b:-10n:1a:4b:10n:13a:0b:-6n:13a:6b:10n:35语言中,还定义了另一种局部变量——寄存器变量定义形式:registerintindex;registercharc;其中,register是关键字。由于寄存器变量是存放在CPU中,而不是通常存放在内存中,因而加快了操作速度。用于使用频度高的变量。由于寄存器长度和个数的限制,寄存器变量只能用于整型和字符型,如果定义的寄存器变量过多,编译器会将超过寄存器数目的寄存器变量变为自动变量处理。寄存器变量的生命期和作用域与自动变量相同。变量的初始化变量初始化规定:第一,未显示初始化,按缺省约定。外部变量和静态变量的初值为0,自动变量和寄存器变量的初值不确定。第二,外部变量和静态变量的初始化在编译时一次完成,只赋一次初值;自动变量和寄存器变量的初始化是每当调用函数时都要重新进行一次初始化。第三,自动变量和寄存器变量的初值可以是常量,也可以是有效表达式,而外部变量和静态变量的初始值只能用常量。例如:intheight=30,width=25,slant=0;intpix=640*350;intline_style=1;inta[5]={10,20,30,40,50};floatinc=200.0;staticintmain_select=1;char*colarry=”red”;charmsg[]={”Filenametoputscreen:”,””};Main(){….}函数调用采用栈结构实现。栈是一种后进先出的数据结构。函数调用的整个过程就是栈空间操作过程。调用过程:建立被调用函数的栈空间保留调用函数的运行状态和返回地址传递参数将控制权转交给被调用的函数返回过程:函数返回时,如果有返回值保留在临时变量空间中恢复调用函数的运行状态释放栈空间按保存的返回地址,返回到调用函数8.6函数调用机制例如:voidfunca(int,int);main(){inta=6,b=12;funca(a,b);//……}voidfunca(intaa,intbb){intn=5;//……}栈区……nbbfunca(c)aa5126返回地址调用函数运行状态bamain()126参数返回地址操作系统运行状态例中函数调用机制中的栈结构程序是由函数构成,一个源程序文件通常包括若干个函数。C程序可以由一个或多个包括若干函数的源程序文件构成,其中只有一个源程序文件包括main()函数。C编译器和连接器把构成一个程序的若干源程序文件有机地联系在一起,最终产生可执行程序。8.7程序结构在多文件程序中的全局及静态类型在多文件程序中,外部变量通常在含有main()函数的源程序文件中的开始位置定义,其他要使用外部变量的源程序文件,必须用extern加以说明。例如:externintn;表示使用在其他源程序文件中定义的外部变量。外部变量只能定义一次,在定义外部变量的源程序文件内,可直接使用,不加使用说明。静态外部变量的作用域为定义它的源程序文件,其他源程序文件不能使用,可保证数据的安全。函数定义在缺省情况下均为全局函数,在多文件程序中,要使用在其他源程序文件中定义的函数,可以在该源程序文件的开始位置使用extern关键字说明。例如:externvoidfn1();externvoidfn2(intchar);通常extern都被省略。当要使某个函数只在一个源程序文件中有效时,可说明为静态函数,例如:staticvoidstaticfn();//……voidstaticfn(){cout“Thisisstaticfn()\n”;}由于不能被其他源程序文件中的函数调用,保证数据的安全。多程序文件例子:/*mfile1.prj*/mfile1.c/*两个源程序文件*/mfile2.c/*mfile1.c*/#includestdio.hintn;/*外部变量定义*/voidfn();/*被调函数说明,extern省略*/main(){n=20;printf(”%d\n”,n);fn()/*调用mfile2.c中的函数*/}*mfile2.c*/#includestdio.hstaticintn;/*静态外部变量定义*/voidfn(){n++/*屏蔽外部变量n*/printf(”%d”,n);结果201注意在内层作用域中,外层作用域中定义的同名标识符是不可见的。即内层屏蔽了外层。内层屏蔽了外层的程序例子:#includestdio.hintid=3;main(){id=5;{intid=7;printf(”id=%d\n”,id);/*输出7*/}printf(”id=%d\n”,id);/*输出5*/}运行结果:id=7id=52.多文件结构多个源程序文件构成的较复杂程序宜采用分别编译方法,以提高效率。第八章小结在引入变量的存储类型概念以后,C语言中使用的变量,不仅要定义其数据类型,而且还要定义存储类型。变量的存储类型确定了变量的存储方式,生命期和作用域。变量定义的完整形式是:存储类型定义符数据类型定义符变量名;各种存储类型的变量的生命期和作用域概括如表8-2中。从自动变量到外部变量,是变量生命期和作用域的一种逻辑进程。正确地选择使用变量的存储类型,可以提高程序设计的质量和合理地使用系统的存储资源。所示。对自动变量和寄存器变量,每次控制流进入函数或程序块时都重新被初始化;对静态变量和外部变量,只在编译时初始化一次按照变量有存储类型的概念,C语言中的函数也有存储类型。因此,定义一个函数的完整说明应指出函数的数据类型和存储类型。函数都是外部函数,外部函数的存储类型定义符通常都被省略,只有当定义一个函数为外部静态函数时,才必须说明函数存储类型。C编译程序系统能动态地为需要申请存储的信息分配地址空间,当不再需要时,可释放占用的地址空间,以便再用。有关动态内存分配的内容,请参看188页。动态内存分配存储空间可用于建立链表。有关链表的内容在下一章中介绍。
本文标题:C语言第八章.
链接地址:https://www.777doc.com/doc-2909086 .html