第6,7章函数(作用域)_第1页
第6,7章函数(作用域)_第2页
第6,7章函数(作用域)_第3页
第6,7章函数(作用域)_第4页
第6,7章函数(作用域)_第5页
已阅读5页,还剩86页未读 继续免费阅读

下载本文档

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

文档简介

第6,7章

函数

变量存储类型

第6章函数

函数的定义函数参数的值的传递函数的调用数组作为函数的参数函数与指针变量的作用域及存贮类型(指向函数的指针不要求!)本章要点如前所述,C程序是由函数组成的。通过函数,我们可以一个较大的问题分成若干个小问题来解决,如用积木建房子。§1

函数概述一、函数的分类:标准库函数:由系统提供,用户可以不必自己去编写程序段而直接调用这些函数。但必须打开相应的头文件。如printf、scanf等函数。用户自定义函数:为了实现用户的特殊需要而自编的函数。如max(intx,inty){……}用户角度有参函数:在调用函数时,需要进行参数传递的函数,如max(a,b);无参函数:如getchar();有无参数1.无参函数的定义:

类型标识符函数名(){声明部分;/*定义变量*/语句;/*执行部分*/}2.有参函数的定义:

类型标识符函数名(形式参数说明表列){声明部分;/*定义变量*/语句;/*执行部分*/}§2

函数定义和调用函数的“类型标识符”用来说明函数的返回值的类型,通常我们称之为函数的类型。如果定义这个函数只是为了实现某个操作而不需要返回值,则应将该函数定义为无返回值类型,即void类型。如果你定义的函数不是void类型,则意味着该函数只有一个值。此时,在该函数的结束处,应使用return语句给主调函数带回一个值。当函数执行到return语句时,立即中止本函数的执行,而返回到主调函数处,同时将相应return语句中的值带回到主调函数。一个函数中可以有多个return语句,先执行到哪个,哪个就起作用,即执行到return语句时,程序将不再向下执行,而返回到调用它的地方。§3函数的返回值“形参”与“实参”:在定义函数时函数名后面括号中的变量称为“形式参数”,简称“形参”;调用函数时函数名后括号中对应参数称为“实际参数”,简称“实参”。如:intmax(intx,inty){return(x>y?x:y);}

形参voidmain(){inta=1,b=4;

……c=max(a,b)

……}

实参§4

函数的参数传递1、形参与实参必须一一对应。(个数、类型)2、定义函数时,必须指定形式参数的类型。函数定义举例intfactor(intn){ints=1,k;for(k=1;k<=n;k++){s=s*k;}

returns;}“函数类型”指函数返回值的类型,也就是说,当该函数执行完成以后,得到一个什么类型的结果。若省略此项,则认为返回类型是int若函数无返回值,则应定义类型为void函数定义举例intfactor(intn){ints=1,k;for(k=1;k<=n;k++){s=s*k;}

returns;}函数名:通常是一个标识符,在一个程序中除了主函数外其余函数的名字可以任意取,但应尽量做到见名知意。函数名后面的

“()”必须有,表示是函数。函数定义举例intfactor(intn){ints=1,k;for(k=1;k<=n;k++){s=s*k;}

returns;}形参表:函数定义时的参数称为形式参数,形式参数彼此间用逗号分隔。每个参数应分别指明其类型。没有形式参数的函数称为无参函数。注意无参函数名字后的圆括号不能省。函数定义举例intfactor(intn){ints=1,k;for(k=1;k<=n;k++){s=s*k;}

returns;}函数中所需变量的定义注:形参及函数中的变量均是在函数被调用时才为它们分配存储单元,函数调用结束后,其存储单元会被系统收回!函数定义举例intfactor(intn){ints=1,k;

for(k=1;k<=n;k++){s=s*k;}

returns;}Return语句:将函数计算之后的值通过return语句返回(带回)到调用的地方函数一旦执行到return语句,则该函数的执行就此结束,不再执行下面其它的语句。实参是如何将值传给形参的?先看下面的例子:实参是如何将值传给形参的?voidadd(intx,inty){x=x+10;y=y+10;}voidmain(){inta=3,b=5;add(a,b);printf(“%d,%d”,a,b);}例:验证C中函数调用时参数的值的传递。

add(a,b);过程分析:voidadd(intx,inty){

3535voidmain(){inta=3,b=5;x=x+10;135y=y+10;1315}

add(a,b);实参是如何将值传给形参的35voidmain(){inta=3,b=5;printf(“%d,%d”,a,b);}输出结果:3,5函数调用结束后,形参所占的内存单元也释放。实参变量对形参变量进行数据传递时,遵循的原则是“单向值传递”。实参与形参所占内存单元不同。当形参中的值改变时,不会影响到实参中的值。即只能由实参把值传给形参,而不能反过来。这就是所谓的“单向值传递”。通过以上的分析,我们可以有如下结论:分析:以下程序能否实现两数交换swap(intm,intn){intz;

z=m;m=n;n=z;

printf("形参:m=%d,n=%d",m,n);}voidmain(){intm=3,n=5;swap(m,n);printf("实参:m=%d,n=%d",m,n);}在被调用函数中改变形参的值,不会影响到主调函数中的实参,因为其参数传值时的原则是“单向值传递”函数调用的一般形式:有参函数:函数名(实参表列);无参函数:函数名();对于有参函数,多个参数之间用逗号将实参分隔开;而对于无参函数,调用时也不能省略括号。注意:在调用函数时,对于实参时,不能再将类型说明符写在括号中。

intmax(int

x,int

y)//-------

函数定义

c=max(inta,intb);×

//------错误的函数调用

c=max(

a,b);√//------正确的函数调用§5

函数的调用

对于调用有参函数,若参数是表达式或变量,调用时先计算出表达式或变量的值,然后将计算出的表达式(变量)的值传给形参。对于多数C系统而言,对实参表列的求值顺序是按从右向左的顺序。intfunc(inta,intb){intc;if(a>b)c=1;if(a==b)c=0;if(a<b)c=-1;return(c);}

voidmain(){inti=3,a;a=func(i,++i);printf(“%d”,a);}例:验证实参表列的求值顺序

输出结果:0printf也是函数,因此在使用中,也同样存在参数求值顺序的问题。例如:设有x=3;

printf(“%d,%d”,x,x++);输出结果:4,3函数调用作为一个语句(函数语句):如:prinft(“Hello,world!!!”);(1)、函数调用的方式

函数调用出现在一个表达式中(函数表达式)。如:c=max(a,b);对于此类调用,参加的函数必定有一个返回值。函数调用作为一个函数调用的实参。(函数参数)。如:d=max(a,max(b,c));

则将函数调用max(b,c)的返回值作为另一次函数调用的实参。被调用的函数必须是已经存在的函数。如果该函数是库函数,那么必须在程序的开始处用#include语句将相应的头文件包含进来。如果是用户自定义的函数,则应在调用到这个函数之前让系统知道这个函数。有两种方法:(1)将被调用的函数的定义放在调用这个函数之前。如:(2)、对被调用函数的声明

intmax(intx,inty){returnx>y?x:y;}voidmain(){……..c=max(a,b);……}

3、在调用这个函数之前对所调用个函数作一个说明,让系统知道这个函数需要的参数、类型,以及返回值的类型,这即是对该函数的声明。但是注意,对函数说明时,括号后有分号;而函数定义时则没有。如:

intmax(intx,inty);

//--------①

函数的声明voidmain(){intmax(intx,inty);

//--------

②函数的声明c=max(a,b);主程序中对函数的调用语句……} intmax(intx,inty){returnx>y?x:y;}函数的定义

(2)、对被调用函数的声明函数声明可以在主调函数内,也可以在函数外。其区别在于:在函数体外部进行的声明,在本文件中的所有地方都有效,无需在主调函数内再次声明;在函数内部进行的声明,则所声明的函数只能在本函数内部使用;所谓的函数的嵌套调用,就是在调用一个函数的过程中,又调用了其它函数。如在主函数中调用了a函数,而在a函数中又调用了b函数,在b函数中又调用了c函数,这就是函数的嵌套调用。其调用过程如下图所示:

§6

函数的嵌套调用

main(){……a();

a(){……b();c(){……

……

……}

……}

……}b(){……c();

……}main(){inta=1,b;b=func1(a);printf(“%d”,b);}func1(intx){inty;y=func2(x)+1;returny;}

例:函数的嵌套调用func2(intx){inty;y=func3(x)+1;returny;}func3(intx){inty;y=x+5;returny;}输出结果:8数组元素做函数的实参,其用法与变量相同。(每个的数组元素相当于一个独立变量)。例如:§7函数与数组数组作为函数的参数,可以有两种情况:例:比较两个数组中的元素,统计出a中大于对应b中元素的位置。intcompare(intx,inty){intz;if(x>y)z=1;elseif(x==y)z=0;elsez=-1;returnz;}voidmain(){inta[10]=…,b[10]=…,i,t;

for(i=0;i<10;i++);{t=compare(a[i],b[i]);if(t>0)printf(“a[%d]>b[%d]”,i,i);}}

输出:a[2]>b[2]……0123auvw…bwvu…数组名作为函数参数: 前面我们已经知道:在C中,数组名代表的是数组的起始地址。因此,当数组名作为函数的参数时,所传递的也是数组的起始地址。§8数组作为函数的参数例:自编字符串复制函数strcopy

strcopy(charstr11[30],charstr22[30]){inti;for(i=0;str22[i]!=0;i++)str11[i]=str22[i];str11[i]=0;}voidmain(){charstr1[30];charstr2[30]=”abcde”;

printf(“%s”,str1);

strcopy(str1,str2);printf(“%s”,str1);}思考:main中打印出的结果是?Strcopy退出循环是时I值?main(){inti,a[5]={1,2,3,4,5};例1:数组名作为函数参数func(a);0x2000a[0]1a[1]2a[2]3a[3]4a[4]5voidfunc(intx[5]){voidfunc(intx[5]){x[3]=0;}for(i=0;i<5;i++)printf(“%d”,a[i]);}0x2000X[3]=0;}X[3](0x2000+3)所对应的元素0x2000a[0]1X[0]a[1]2X[1]a[2]3X[2]a[3]0X[3]a[4]5X[4]X[0]X[1]X[2]X[3]X[4]例2:试比较以下程序与上面程序的区别输出结果:12345voidfunc(intx){x=0;}main(){inti,a[5]={1,2,3,4,5};func(a[3]);for(i=0;i<5;i++)printf(“%d”,a[i]);}a[0]10x2000a[1]2a[2]3a[3]4a[4]5X4X01、当用数组名作为函数参数时,并不是象变量作形参一样,再开空间给形参数组,而是接收数组名传递来的数组的首地址。所以,在子函数中对数组的修改,实质上就是对主函数中数组的修改。2、实参数组与形参数组类型必须一致。3、主调函数和被调函数中分别定义数组名,可以一样,也可不一样,系统回自动区分,互不干扰。

由上面两例所得结论:再看几例:例1:自编字符串复制函数strcopy

strcopy(charstr1[30],charstr2[30]){inti;for(i=0;str2[i]!=0;i++)str1[i]=str2[i];str1[i]=‘\0’;}voidmain(){charstr1[30];charstr2[30]=”abcde”;

printf(“%s”,str1);

strcopy(str1,str2);printf(“%s”,str1);}再看几例:例2:自编求字符串长函数strlenth

strlenth(charstr[30]){inti;for(i=0;str2[i]!=0;i++);

returni;}voidmain(){charstr1[30]=”abcde”;

intlen;

len=strlenth(str1);printf(“%d”,len);}再看几例:例3:自编字符串比较函数strcomp

intstrcomp(charstr1[],charstr2[]){inti;for(i=0;str1[i]==str2[i]&&str1[i]!=0;i++);return(str1[i]-str2[i]);}voidmain(){charstr1[30],str2[30];

intd;

gets(str1);gets(str2);

d=strcomp(str1,str2);printf(“%d”,d);}

§9指针作为函数参数

1、传址调用:指针变量作为函数参数当指针变量作为函数参数时,传递的是变量的地址。读以下程序:voidtestpoint(int*p){intt;t=*p;t++;}voidmain(){inta=3,*p;p=&a;printf(“a=%d\n”,a);testpoint(p);printf(“a=%d\n”,a);}a30x2000:P主&at30x6000:P函&a如果将程序的第4)行改为(*p)++,请再观察程序的结果:voidtestpoint(int*p){intt;t=*p;t++;}voidmain(){inta=3,*p;p=&a;printf(“a=%d\n”,a);testpoint(p);printf(“a=%d\n”,a);}(*p)++;a30x2000:p&at30x6000:p&a例1:两数交换函数swapt:voidswap(int*p1,int*p2)

{intt;

t=*p1;*p1=*p2;*p2=t;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}a50x2000b302002p1&ap2&bp1&ap2&b例1:两数交换函数swapt:voidswap(int*p1,int*p2)

{intt;

t=*p1;*p1=*p2;*p2=t;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}a30x2000b502002p1&ap2&bp1&ap2&bvoidswap(int*p1,int*p2)

{int*p;

p=p1;p1=p2;p2=p;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}a30x2000b502002p1&ap2&bp1&ap2&bp例2:两数交换函数swapvoidswap(int*p1,int*p2)

{int*p;

p=p1;p1=p2;p2=p;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}a30x2000b502002p1&ap2&bp1&bp2&ap例2:两数交换函数swap例3:两数交换函数swapvoidswap(int*p1,int*p2)

{int*p;*p=*p1;*p1=*p2;*p2=*p;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}形参p1和p2得到main函数中a和b的地址,这样p1和p2的目标变量就是main函数的变量a和b。在swap函数中交换*p1和*p2的内容,就是交换a和b的内容,所以当函数调用结束后,尽管p1和p2已经释放,但操作结果仍保留在main函数的变量a和b中,这就是通过指针形参指向域扩展到主调函数的方法,达到主调函数与被调函数间交换多个数据的目的。

主调函数与被调函数之间数据传递的方法:①实参与形参之间的数据传递;②被调函数通过return语句把函数值返回到主调函数;③通过全局变量交换数据;④利用指针型参数在主调函数和被调函数之间传递数据。

§9指针与函数⑴一维数组的指针作函数参数例如被调函数abc的定义形式有以下三种:voidabc(intb[10]){……}voidabc(intb[]){……}voidabc(int*b){……}在主调函数有如下定义:inta[10],*p=a;则调用abc函数时可用abc(a)或abc(p)2023/7/29422.数组的指针作函数参数

当函数之间需要传递数组时,可以通过传递数组的首地址(即通过指针参数指向域的扩展),完成存取主调函数中数组元素的操作。

§9指针与函数【例8.20】字符串复制函数。voidcopystr(char*t,char*s)

{while((*t++=*s++)!='\0');}main(){charc[80],*p="Iamastudent.";copystr(c,p);

printf("%s\n",c);}2023/7/29432.数组的指针作函数参数

§9指针与函数⑵

二维数组的指针作函数参数

2023/7/29442.数组的指针作函数参数

由于指向二维数组的指针分为行指针和元素指针,所以他们作为函数参数的形式也不同。

二维数组的行指针作函数参数例如被调函数abc的定义形式有以下三种:voidabc(intb[2][4]){……}voidabc(intb[][4]){……}voidabc(int(*b)[4]){……}在主调函数有如下定义:inta[2][4],(*p)[4]=a;则调用abc函数时可用abc(a)或

abc(p)用函数输入输出整型二维数组,函数的形参为行指针。voidinarr(int(*p1)[4],intm){inti,j;/*可改写为void

inarr(intp1[][4],intm)*/for(i=0;i<m;i++)for(j=0;j<4;j++)scanf("%d",*(p1+i)+j);}2023/7/2945main(){inta[3][4],(*p)[4];p=a;inarr(a,3);outarr(p,3);}2.数组的指针作函数参数

voidoutarr(int(*p2)[4],intm){inti,j;for(i=0;i<m;i++){for(j=0;j<4;j++)printf("%6d",p2[i][j]);printf("\n");}}

可改写为voidoutarr(intp2[3][4],intm)/§9指针与函数⑵

二维数组的指针作函数参数

②指向二维数组元素的指针作函数参数2023/7/29462.数组的指针作函数参数

指向二维数组元素的指针作函数参数时,是利用二维数组元素按行连续存储的的特点,访问数组的每一个元素。被调函数的形参必须定义为指向二维数组元素的指针变量。例如被调函数abc的定义形式如下:voidabc(int*b){……}另外,在主调函数有如下定义:inta[2][4],*p=a[0];则调用abc函数时可用abc(a[0])、abc(&a[0][0])或

abc(p)【例】用函数输入输出整型二维数组,函数的形参为指向二维数组元素的指针。voidinarr(int*p1,intm,intn){inti,j;for(i=0;i<m;i++)for(j=0;j<n;j++)scanf("%d",p1+n*i+j);}2023/7/29472.数组的指针作函数参数

main(){inta[3][4],*p;p=&a[0][0];inarr(a[0],3,4);outarr(p,3,4);}voidoutarr(int*p1,intm,intn){inti,j;for(i=0;i<m;i++){for(j=0;j<n;j++)printf("%6d",*(p1+n*i+j));printf("\n");}}就是在调用一个函数的过程中又直接或间接地调用了该函数

§10

函数的递归调用(不要求)

直接调用例:设有func函数定义如下intfunc(){intb;b=func();returnb;}voidmain()

{:

func();}则以下程序执行过程如下:func(){intb;b=func();returnb;}func(){intb;b=func();returnb;}func(){intb;b=func();returnb;}间接调用例:设func1函数、func2函数定义如下intfunc1(){……;func2();……}voidmain()

{:

func1();}则当主函数中调用了func1函数时的执行过程如下:func1(){……;func2();……}func2(){……;func1();……}func1(){…func();……}intfunc2(){……;func1();……}显然,在函数的递归调用中,如果不加以控制,则其最终必将耗尽系统资源,或死循环。因此,在递归调用的函数中,必须有一个条件来判断何时递归调用停下来。

递归出口!用递归求n!递归过程

。1.应用递归的原因和领域

递归定义

┏1当n=0

阶乘n!=┃┗n*(n-1)!当n>0用递归求解更简单用递归求n!例1、求阶乘的函数。

1若n=0Fact(n)=

n*Fact(n-1)若n>0longFact(longn){longs;

if(n==0)return1;//递归出口elses=n*Fact(n–1);//递归return(s);}Main(){longn;Scanf(“%ld”,&n);Printf(“%ld”,fact(n));}主程序n=4Fact(4)(1)n3Fact(3)(2)(1),4topn2Fact(2)(3)(1),4top(2),3n1Fact(1)(4)top(1),4(2),3(3),2n0Fact(0)top(1),4(2),3(3),2(4),1Return1top(1),4(2),3(3),2(4),1Return1top(1),4(2),3(3),2Return2(1),4top(2),3Return6(1),4topReturn24结束递归过程1.递归过程的特点:是程序设计的一个强有力的工具,它具有结构清晰,程序易编、易读、易调试,程序正确性易证明等优点;但运行效率低。2.基本原理:基本原理是重复地把问题转化为与原问题相似的新问题,直到问题可解决为止。3.关键点:

①用较简单的新问题来表示较复杂的原问题例如:n!=n(n-1)!,或n!=(n+1)!/(n+1)前者(n-1)!较原问题n!简单,可行;而后者(n+1)!较n!更复杂,不可行。②不能产生自己调用自己的无穷序列,即必须有一个递归调用序列的“出口”,来终止递归调用。递归函数:Fun(n){if(n>0)fun(n/2);Printf(“%d”,n);}Main(){inta=6;fun(a);}请问该程序输出结果是:0136§11返回指针的函数指针函数:一个函数的返回值是一个指针(即地址)。函数定义形式:

类型说明*函数名(形参表)

函数体

例:int*rp(int1,inty){………}例:输入1-7整数,输出对应星期名#include<stdio.h>#include<string.h>voidmain(){inti;char*day_name(intn);printf(“inputDayNo:\n”);scanf(“%d”,&i);printf(“DayNo:%2d%s\n”,i,day_name(i));}char*day_name(intn){staticchar*name[8]={“error”,”Monday”,”Tuesday”,………};return((n<1||n>7)?name[0],name[n]);}指针数组变量的作用域:使用变量都必须先定义。但并非定义之后,在程序的任何地方均可使用这一变量。变量是有一定的作用范围的。根据变量的作用范围,可将变量分为局部变量(内部变量)和全局变量(外部变量)。局部变量:作用范围局限与某个函数或结构体复合语句内。全局变量:在函数体外定义的变量是全局变量。其作用范围为定义之处开始,至整个程序结束。

§12变量的存储类型intmax(intx,inty){inta;

if(x>y)returnx;elsereturny;}voidmain(){inta=3,b=5,c;c=max(a,b);}局部变量例:

x,y的作用范围

a的作用范围不同函数中可以定义同名变量,互不干扰

a,b,c的作用范围主函数中定义的量也属局部变量如果变量的定义是放在某复合语句中的,那么,该变量的作用范围就只在这个复合语句中有效。intmax(intx,inty){

c=x-y;

returnc;}voidmain(){inta=3,b=5,c;c=max(a,b);}局部变量例:

x,y的作用范围

语法错误,不能识别的标识符C

a,b,c的作用范围主函数中定义的量也属局部变量

inta,b;voidfunc(intx,inty){a=x+5;b=y+3;}voidmain(){func(3,8);printf(“a=%d,b=%d\n”,a,b);func(4,6);printf(“a=%d,b=%d\n”,a,b);func(a,b);printf(“a=%d,b=%d\n”,a,b);}全局变量例:

a,b的作用范围

x,y的作用范围a=8,b=11a=9,b=9a=14,b=12

inta,b;voidfunc(intx,inty)

{intb;a=x+5;

b=y+3;}voidmain(){func(3,8);printf(“a=%d,b=%d\n”,a,b);func(4,6);printf(“a=%d,b=%d\n”,a,b);func(a,b);printf(“a=%d,b=%d\n”,a,b);}全局变量例:

a,b的作用范围

x,y的作用范围,全局变量b被屏蔽,局部变量b起作用a=8,b=0a=9,b=0a=14,b=0全局变量自动初始化为0;全局变量在所有函数之外定义的变量在程序中定义它的位置以后都有效自动初始化为0从程序运行起即占据内存,程序运行过程中可随时访问,程序退出时释放内存在定义点之前或在其他文件中引用,应该进行如下声明:extern类型名变量名;使函数之间的数据交换更容易,也更高效但是并不推荐使用因为谁都可以改写全局变量,所以很难确定是谁改写了它结论:尽可能不使用全局变量!全局变量与局部变量同名屏蔽原则:局部优先局部变量的全局变量比较:根据变量的存在的时间(生存期),变量可划分为:动态存储变量和静态存储变量。动态存储方式:是在程序运行期间根据需要进行动态分配存储空间的方式。与之对应的变量被称为动态存储变量。通常,如果定义的变量没有其它的说明的话,系统自动将之作为一个动态存储变量,简称动态变量。当然,也可用关健字“auto”进行定义。静态存储方式:是指程序在运行期间分配给固定存储空间的方式。与之对应的变量被称为静态存储变量,简称静态变量。必须用关健字“static”进行定义。

§13

动态存储变量与静态存储变量

§13

动态存储变量与静态存储变量

指数据在内存中存储的方式,即编译器为变量分配内存的方式,它决定变量的生存期动态存储根据需要临时分配存储空间,离开即释放静态存储在程序运行期间分配固定的存储空间不释放程序区静态存储区动态存储区形参、自动变量、函数调用的现场等全局变量、静态变量自动变量(auto)“自动”体现在进入语句块时自动申请内存,退出时自动释放内存动态局部变量标准定义格式auto类型名变量名;缺省的存储类型不初始化时,值是不确定的

add(a,b);printf(“%d,%d”,a,b);Add(a,b);printf(“%d,%d”,a,b);}voidadd(intx,inty){

3535voidmain(){inta=3,b=5;x=x+10;y=y+10;}

add(a,b);voidadd(intx,inty){

35voidmain(){inta=3,b=5;x=x+10;y=y+10;}1315

add(a,b);35voidmain(){inta=3,b=5;printf(“%d,%d”,a,b);}

add(a,b);printf(“%d,%d”,a,b);Add(a,b);printf(“%d,%d”,a,b);}voidadd(intx,inty){

3535voidmain(){inta=3,b=5;x=x+10;y=y+10;}voidadd(intx,inty){

35voidmain(){inta=3,b=5;x=x+10;y=y+10;}1315

add(a,b);printf(“%d,%d”,a,b);Add(a,b);printf(“%d,%d”,a,b);}35voidmain(){inta=3,b=5;

add(a,b);printf(“%d,%d”,a,b);Add(a,b);printf(“%d,%d”,a,b);}静态变量(static)一个函数的内部变量在函数退出后失效。再次进入函数,变量值重新初始化把此变量定义为static,则变量的值可以保存到下次进入函数staticinti;静态变量和全局变量都是静态存储类型自动初始化为0从静态存储区分配,生存期为整个程序运行期间但作用域不同对于用“static”关健字定义的静态变量则不同:该类型的变量由系统分配一个专门的存储空间来存放;当函数调用结束后,该变量所占空间并不释放,当下次再调用该函数时,该变量中已有值。如下例所示:§13

动态存储变量与静态存储变量

intf(inta){intb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);}

voidmain(){inta=2,b,i;b=f(a);printf(“%d\n”,b);b=f(a);printf(“%d\n”,b);}

b=f(a);2?2voidmain(){inta=2,b;intb=0;b=b+1;staticintc=3;0§13

动态存储变量与静态存储变量

3intf(inta){

b=f(a);2?voidmain(){inta=2,b;intb=0;b=b+1;staticintc=3;c=c+1;1§13

动态存储变量与静态存储变量

32intf(inta){

b=f(a);2?voidmain(){inta=2,b;intb=0;b=b+1;}staticintc=3;c=c+1;return(a+b+c);1§13

动态存储变量与静态存储变量

42intf(inta){

b=f(a);27voidmain(){inta=2,b;§13

动态存储变量与静态存储变量

4printf(“b=%d\n”,b);输出:b=7b=f(a);intf(inta){

2intb=0;0staticintc=3;b=b+1;

b=f(a);27voidmain(){inta=2,b;intb=0;b=b+1;staticintc=3;c=c+1;1§13

动态存储变量与静态存储变量

42intf(inta){

printf(“b=%d\n”,b);b=f(a);b=f(a);27voidmain(){inta=2,b;intb=0;b=b+1;}staticintc=0;c=c+1;return(a+b+c);1§13

动态存储变量与静态存储变量

52intf(inta){

printf(“b=%d\

温馨提示

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

评论

0/150

提交评论