变量的作用域与生存期-_第1页
变量的作用域与生存期-_第2页
变量的作用域与生存期-_第3页
变量的作用域与生存期-_第4页
变量的作用域与生存期-_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

第七章变量的作用域与生存期§7.1作用域与生存期概述▲变量的作用域(空间特性)●

变量的作用域也称为可见性,指变量能够被访问的范围。●

根据不同的作用域,变量可分为局部变量和全局变量两类。局部变量的作用范围限定在程序中的部分区域(函数、复合语句);全局变量的作用范围可以是整个文件甚至是整个程序。▲变量的存储类别(时间特性)除作用域(可见性)外的另外两个特性:变量所在存储单元如何分配(存储位置)?变量何时存在(生存期)?———存储类别。●变量的存放位置:RAM或CPU寄存器●

内存区域划分:代码区、静态存储区、动态存储区●存储类别:静态存储、自动存储●静态存储方式:存放在静态存储区,编译时就分配确定的相对位置,程序调入内存时即分配了固定的内存单元(静态分配)生存期为整个程序的运行过程。●自动存储方式:存放在动态存储区(栈区),临时分配。生存期仅在函数或复合语句(调用)执行期间。▲定义变量的声明格式决定了存储类别,进而决定了变量的生存期;而该定义变量的声明位置(内部/外部)则决定了变量的作用域.▲内部变量※定义:在函数内或复合语句内定义,只在本函数内或复合语句内有效。※说明:●main中定义的变量只在main中有效;●不同函数中同名变量,占不同内存单元;●形参属于内部变量;●分为自动变量、寄存器变量和静态内部变量

。§7.2内部变量floatf1(inta){intb,c;…….}charf2(intx,inty){inti,j;……}main(){intm,n;…….}a,b,c有效x,y,i,j有效m,n有效voidsub(){

int

a,b;a=6;b=7;

printf("sub:a=%d,b=%d\n",a,b);}void

main(){inta,b;a=3;b=4;

printf("main:a=%d,b=%d\n",a,b);sub();

printf("main:a=%d,b=%d\n",a,b);}#defineN5voidmain(){inti;

int

a[N]={1,2,3,4,5};

for(i=0;i<N/2;i++)

{

inttemp; temp=a[i];

a[i]=a[N-i-1]; a[N-i-1]=temp;

}

for(i=0;i<N;i++)

printf("%d",a[i]);}【例】不同函数中同名变量【例】复合语句中变量运行结果:54321运行结果:main:a=3,b=4sub:a=6,b=7main:a=3,b=4▲自动变量(auto)※格式:[auto]类型变量名列表;

auto可省略,autointa;等价于inta;※自动变量的生存期:自动变量存在于RAM中的动态存储区—“栈”,并且仅当定义它的函数或复合语句被执行时,才创建该变量,执行结束后该变量自动被删除掉,释放占用的内存空间。※自动变量用的最多,不会永久占用内存空间。#include<stdio.h>main(){autoint

a,b,c;a=1,b=2;c=add(a,b);/*创建add形参和局部变量*/{floatx=c;

printf("x=%f",x);}

printf("c=%d",c);}int

add(int

x,inty){intz;z=x+y;return(z);}a,b,c有效x,y,z有效x有效▲寄存器变量(建议不使用)

※格式:register类型变量名列表;※关键字register的真正作用是提醒编译程序所定义的变量在程序中使用频率较高。

※注意:●只有字符型、整型变量能放在寄存器中,包括:int、char、short、long等。●寄存器变量必须是auto类型的局部变量、形参,不能是全局变量或静态变量。※

由于寄存器数量很少,不能保证定义的寄存器变量总是能分配到寄存器,这时作为普通变量。※对于寄存器变量,不能做取地址(&)运算。【例】使用寄存器变量int

fac(intn){

registerinti,f=1;

for(i=1;i<=n;i++)f=f*i;

return(f);}voidmain(){

inti;

for(i=1;i<=1000;i++)

printf(“%d!=%d\n”,i,fac(i));}▲静态内部变量

※静态存储方式存放,作用域仍然是仅限于所在的函数或复合语句。※格式:static类型变量名列表;

staticinta;※形参不能是定义成static。※使用注意:●静态变量只初始化一次。●静态变量的值具有“记忆”性。●尽管生存期变长,但作用域(可见性)仍然局限在定义它的局部范围内。voidmain(){

inti;

for(i=0;i<3;i++)

inc1();

for(i=0;i<3;i++)

inc2();}【例】静态内部变量的生存期#include<stdio.h>voidinc1(){

intx=0;x++;

printf("ininc1x=%d\n",x);}voidinc2(){staticintx=0;x++;

printf("ininc2x=%d\n",x);}运行结果:ininc1x=1ininc1x=1ininc1x=1ininc2x=1ininc2x=2ininc2x=3§7.3外部变量●

定义:在函数外定义●

作用域:(1)默认:从定义变量的位置开始到本源文件结束。(2)扩展:到其它源文件(其它源文件须用关键字extern声明变量)。(3)限制在本源文件:定义时加关键字static。●生存期:整个程序运行期间

定义声明次数:只能1次可说明多次位置:所有函数之外函数内或函数外分配内存:分配内存,可初始化不分配内存,不可初始化●

若外部变量与内部变量同名,则在函数中外部变量被屏蔽。/*ch7_17.c*/inta=3,b=5;int

max(inta,intb){intc;c=a>b?a:b;return(c);}voidmain(){

inta=8;

printf("max=%d",max(a,b));}【例】外部变量与内部变量(同名的局部变量屏蔽外部变量)运行结果:max=8floatmax,min;floataverage(floatarray[],intn){inti;floatsum=array[0];

max=min=array[0];for(i=1;i<n;i++){if(array[i]>max)

max

=array[i];elseif(array[i]<min)min

=array[i];sum+=array[i];}return(sum/n);}voidmain(){inti;floatave,score[10];/*Inputdatatoscore省略*/

ave=average(score,10);

printf("max=%6.2f\nmin=%6.2f\naverage=%6.2f\n",max,min,ave);}作用域maxmin外部变量增加了函数间数据联系的渠道intp=1,q=5;floatf1(inta){intb,c;…….}intf3(){…..}charc1,c2;charf2(intx,inty){inti,j;……}main(){intm,n;…….}c1,c2原来的作用范围p,q的作用范围externcharc1,c2;externcharc1,c2;c1,c2的作用范围扩展后c1,c2的作用范围扩展后用extern声明外部变量可以扩展外部变量的作用域int

add(int

x,inty){

intz;z=x+y;returnz;}voidmain(){

externint

a,b;

printf(“a+b=%d\n",add(a,b));}inta=3,b=4;【例】用extern扩展外部变量作用域运行结果:a+b=7【例】用extern将变量的作用域扩展到其它文件中intx=10,y=10;externvoidsub();voidadd(void){inty=5;y=10+x;x*=2;

printf("add:y=%d:",y);}voidmain(){x+=5;add();sub();

printf("main:x=%d,main:y=%d\n",x,y);}externintx;voidsub(){

inty=5;x-=y;

printf("sub:y=%d;",y);}file1.cfile2.c运行结果:add:y=25;sub:y=5;main:x=25;main:y=10;staticintx=10;voidadd2(){externinty;x+=10;y+=2;

printf("inadd2x=%d\n",x);}【例】static

型外部变量的作用域受到限制,限制在本文件内使用。运行结果:inadd1x=4inadd2x=20inadd1x=6inadd2x=30x=6;y=13staticintx=2;inty=3;externvoidadd2();voidadd1();voidmain(){add1();add2();add1();add2();

printf("x=%d;y=%d\n",x,y);}voidadd1(){x+=2;y+=3;

printf("in

addax=%d\n",x);}inti;voidmain(){voidprt();

for(i=0;i<5;i++)

prt();}voidprt(){

for(i=0;i<5;i++)

printf(“%c”,’*’);

printf(“\n”);}【例】外部变量副作用运行结果:*****【例】文件file1.cinta;voidmain(){…….…….f2;…….f1;…….}f1(){autointb;………f2;……..}f2(){staticintc;………}C作用域b作用域a作用域mainf2f1mainf1f2maina生存期:b生存期:c生存期:▲数据在内存中的分配方式※静态内存分配的特点●由编译器在编译阶段自动完成,不需要程序设计者干预或管理;●分配效率高;●由于分配的存储区域其大小是固定不可变的,也存在明显的不足之处;※动态内存分配(1)栈分配:自动变量存放在动态存储区中的栈区,只有当其所在的函数或复合语句被调用执行时才在栈区中为其临时分配存储单元,函数或复合语句一次执行结束后,所占用的存储单元就被释放,且后分配的存储单元会被先释放。§7.4动态内存分配▲数据在内存中的分配方式※动态内存分配(2)堆分配堆(heap)是动态内存区域中一部分自由空闲区域(一般是不连续,使用链表方式来管理,可包括多个大小不等的空闲区域)。C程序设计者可以通过库函数在堆中申请存储空间,不需要时可以释放(即返回给堆),释放后的存储空间又可以被再次申请使用。优点:根据实际需要的大小来申请和分配存储空间,不需要时随时可以释放。注意,申请的存储空间不宜过大

。▲通过库函数申请和释放存储空间的方法(1)申请malloc函数

v

温馨提示

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

评论

0/150

提交评论