版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第七章用函数实现模块化程序设计第七章用函数实现模块化程序设计1交实验报告140页3题格式:按照《上机指导书》171页附录D格式书写采用统一的实验报告纸交实验报告140页3题2算法是解决具体问题的方案基本要求:根据给出的算法编写程序7.1为什么要用函数算法是解决具体问题的方案基本要求:根据给出的算法编写程序7.3实际的软件开发实际问题往往由多个基本问题构成。要求软件开发人员首先分析问题,将问题分解为基本问题。其次,逐个解决每个基本问题。实际的软件开发实际问题往往由多个基本问题构成。4程序与问题的关系整个问题基本问题1…基本问题n整个程序函数1…函数n程序与问题的关系整个问题基本问题1…基本问题n整个程序函数15对软件开发人员的要求分析并分解问题(高级要求)。设计解决基本问题的函数(基本要求)。对软件开发人员的要求分析并分解问题(高级要求)。6例iA和iB为两个整数,iA是基数,iB是指数.如何计算变量result保存最后结果,base为底数,exponent为指数。result=1;for(counter=1;counter<=exponent;counter++){ result*=base;}
计算35、55、85例iA和iB为两个整数,iA是基数,iB是指数.变7问题如果要分别计算100对整数的次幂,需要多少for?问题8解决方案我们制造一个零件(函数),它负责计算次幂当需要计算次幂时,告诉零件基数和指数,零件返回结果。函数就象提供服务的人。解决方案我们制造一个零件(函数),它负责计算次幂9第一个角度:程序就是机器。函数就是零件。程序由函数构成。第二个角度:函数可以为其他函数提供服务,就象服务人员。第一个角度:101.什么是函数?函数就是可以完成某项基本任务的一组语句。函数名是唯一的。函数可以被其他的函数使用,称为函数的调用。1.什么是函数?函数就是可以完成某项基本任务的一组语句。11参数主调用函数给被调用函数一些数据,即参数。被调用函数根据参数值完成相应的工作。参数主调用函数给被调用函数一些数据,即参数。12返回值被调用函数完成工作后,可能会返回某些数据作为计算结果。返回值被调用函数完成工作后,可能会返回某些数据作为计算结果。13函数的要素函数名参数返回值函数体(语句)函数的要素函数名14函数调用示例:main()/*主函数*/{print_star();/*调用print_star函数画****/
print_message();/*调用print_message函数写字*/
print_star();}/*调用print_star函数画****/
print_star()/*定义print_star函数*/{prinf(“**********\n”);}print_message()/*定义print_message函数*/
{prinf(“Hello!\n”);}运行结果:**********Hello!**********
⑴一个源文件由一个或多个函数组成,是一个独立编译单元。⑵一个C程序由一个或多个源文件组成;⑶C程序执行总是从main函数开始,调用其他函数后流程回到main。⑷函数不能嵌套定义,但可互相调用。注意不能调用main函数。函数调用示例:main()15函数的分类1.函数参数形式无参函数有参函数2.从用户使用的角度分标准函数(库函数)用户自己定义的函数库函数编译系统提供的已设计好的函数,用户只需调用而无需要去实现它(scanf,printf,getchar,putchar等)。用户自定义函数程序员自己定义和设计的函数。有参函数例(输出两数中大者)#include<stdio.h>main(){intmax(intx,inty);intn1,n2,a;scanf("%d,%d",&n1,&n2);a=max(n1,n2);printf("max=%d",a);}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}无参函数例main(){print_star();print_message();print_star();}
print_star(){prinf(“**********\n”);}print_message(){prinf(“Hello!\n”);}函数的分类1.函数参数形式无参函数有参函数2.从用户使用167.2怎样定义函数
例如:
print_message(){printf(“Hello!\n”);}二、有参函数的定义形式类型标识符函数名(形参表列){说明部分语句}有参数传递例如:求x和y二者中大者intmax(intx,inty)/*x,y为形参*/{intz;/*函数体中变量的说明*/z=x>y?x:y;return(z);}/*将z的值作为函数返回值*/类型标识符函数名(){说明部分语句}无参数传递一、无参函数的定义形式三、空函数的定义形式类型标识符函数名(){}功能:调用后什么也不做。用处:建立程序结构,在需要时补充功能。例如:dummy(){}若无参数,类型标识符写void或不写函数返回值的类型,若不说明类型,默认为整型。是被初始化的内部变量,寿命和可见性仅限于函数内部7.2怎样定义函数例如:二、有参函数的定义形式类17四、形式参数和实际参数形式参数定义函数时函数名后面括弧中的变量名,简称形参。实际参数调用函数时函数名后面括弧中的表达式,简称实参。c=max(a,b);-----------------------实参:在运行时
把函数的max(intx,inty)把值传给函数。结果赋给{………函数名returu(z);形参:通知系统}要预留内存位置。上例中形参与实参、函数名与返回值之间的关系main(){intmax(intx,inty);inta,b,c;scanf(“%d,%d,&a,&b);c=max(a,b);printf(“Maxis%d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}形参表实参表四、形式参数和实际参数形式参数定义函数时函数名后面括弧中的18函数的返回值语句return将被调函数的一个确定值带回主调函数。return(函数返回值);或return函数返回值;通过函数调用使主调函数得到一个确定的值五、函数的返回值main(){intmax(intx,inty);inta,b,c;scanf(“%d,%d,&a,&b);c=max(a,b);printf(“Maxis%d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}此时函数的返回值是5,因此c=5有确定值的常量、变量或表达式函数的返回值语句return将被调函数的一个确定值带回主调函19⑴函数不加类型说明按整型处理⑵函数和return类型不一致以函数类型为准。⑶函数不返回值定义为void六、函数值的类型voidprint_star(){……}main(){intmax(intx,inty);inta,b,c;scanf(“%d,%d,&a,&b);c=max(a,b);printf(“Maxis%d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}⑴函数不加类型说明按整型处理⑵函数和return类型不一致以20小结int
Power(intiBase,intiExponent)返回类型: int
函数名: Power形式参数: iBase,iExponent
形式参数的数值由实际参数决定。小结intPower(intiBase,21注意:int
Power(intiBase,intiExponent)谁是被定义的函数?谁是参数?第一个int的作用是什么?后两个int的作用是什么?函数的使用者应该明确指明什么,才能使用函数?注意:intPower(intiBase,22调用函数就是使用函数。调用函数之前,必须首先声明函数。声明函数就是声明:函数名、函数返回值的类型和参数的类型。例:
intPower(int,int);7.3调用函数
调用函数就是使用函数。7.3调用函数23一、函数调用的一般形式
函数名(实际参数表)
有参数函数无参数函数
函数名()一、函数调用的一般形式函数名(实际参数表)有参数函数无24voidprint_star(){printf(“*******”);}main(){inta,b,c;scanf(“%d,%d,&a,&b);c=2*max(a,b);print-star();printf(“c=%d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}二、函数调用的具体方式1.函数调用作为一个语句函数名(实际参数表);调用可忽略或没有返回值的函数(如:scanf函数和printf函数)
2.函数调用出现在表达式中变量名=函数表达式调用带返回值的函数,其返回值参加表达式运算。无返回值函数的调用,不能出现在表达式中3.函数参数函数调用作为一个函数的参数。如:m=max(a,max(b,c))voidprint_star()main()intma25在程序编译阶段,对调用函数的合法性进行全面检查。如没有函数声明,编译到包含函数调用的语句时(如xx(a,b)),编译系统不知道xx是函数名,也无法判断实参(a,b)的类型和个数是否正确,无法进行正确性的检查。只有在运行时才会发现实参与形参的类型或个数不一致,出现运行错误。
在程序编译阶段,对调用函数的合法性进行全面检查。如没有函数声267.4、对被调用函数的声明和函数原型⒈对被调用函数说明的前提条件必须是已存在的函数,如用户自定义函数或库函数。2.被调用函数是用户自定义函数的函数说明主调函数和被调用函数在同一文件中,在主调函数中说明被调函数类型。7.4、对被调用函数的声明和函数原型⒈对被调用函数说明的前27在C语言中,以上的函数说明称为函数原型。/*定义add函数*/floatadd(floatx,floaty){floatz;z=x+y;return(z);}main(){floatadd(floatx,floaty);floata,b,c;scanf(“%f,%f”,&a,&b);c=add(a,b);printf(“sumis%f”,c);}对被调用函数的说明作为表达式被调用在C语言中,以上的函数说明称为函数原型。/*定义add函数283.被调用函数是库函数的函数说明文件开头用#include命令将调用库函数时需用到的信息“包含”到文件中(对这些库函数的原型说明全部都写在对应的头文件里)。
常用的头文件:#include“stdio.h”#include“math.h”#include“string.h”4.省略被调用函数声明的三种情况
floatadd(floatx,floaty){floatz;z=x+y;return(z);}main(){floata,b,c;scanf(“%f,%f”,&a,&b);c=add(a,b);printf(“sumis%f”,c);}(1)被调函数定义在主函数前3.被调用函数是库函数的函数说明文件开头用#includ29(2)函数返回值为整型或字符型,系统按整型处理。main(){inta,b,c;scanf(“%d,%d”,&a,&b);c=max(a,b);printf(“Maxis%d”,c);}max(intx,inty){intz;z=x>y?x:y;return(z);}无函数说明整型函数(2)函数返回值为整型或字符型,系统按整型处理。main(30⑶所有函数定义前,在函数的外部已说明函数类型。charletter(char,char);floatf(float,float);inti(float,float);main(){…….}charletter(charc1,charc2){……}floatf(floatx,floaty){……}inti(float,float){……}在所有函数之前说明函数类型此处不必说明定义函数letter、f和i⑶所有函数定义前,在函数的外部已说明函数类型。charle31复习函数的要素:名字、返回值、参数和代码定义函数:编写代码声明函数:声明名字、参数类型和返回值类型调用函数:给出名字和实际参数,如果有返回值则保存。复习函数的要素:32main(){inti;longt;t=1;
for(i=1;i<=n;i++)t=t*i;
printf(“n!=%ld\n”,t);}longxx(intx){longt=1;inti;if(x<=0)printf(“error”);elsefor(i=1;i<=x,i++)t=t*i;return(t);}main(){intn;longs;scanf(“%d”,&n);s=xx(n);printf(“%ld”,s);}例1:编写函数,求n!。main()longxx(intx)例1:编写函33例题1:求1+2+3+...+100的和。main(){inti,s=0;for(i=1;i<=100;i++)s=s+i;printf(“s=%d”,s);}例2:编写函数,求1+2+3+...n。intmm(intx){intt=0;inti;for(i=1;i<=x,i++)t=t+i;return(t);}main(){intn;ints;scanf(“%d”,&n);s=mm(n);printf(“%d”,s);}例题1:求1+2+3+...+100的和。例2:编写函数,求34执行细节---步骤
程序将从主函数开始执行当发生函数调用时,主调用函数暂停实际函数的值将被复制给形式参数(不需要任何语句,程序自动做该项工作).被调用函数执行遇到返回语句时,被调用函数将结果返回给主调用函数主调用函数恢复执行执行细节---步骤程序将从主函数开始执行35执行细节---存储分配被调用函数执行前,系统为其变量分配内存空间(包括形式参数)。实际参数的值被复制给形式参数(值传递).当被调用函数结束执行后,内存空间将被释放,下次调用时重新分配。执行细节---存储分配被调用函数执行前,系统为其变量分配内存36例:你可以判断出下面程序的结果吗?程序的执行过程是怎样的?例:你可以判断出下面程序的结果吗?37voidSwap(intiA,intiB){ intiTemp; iTemp=iA; iA=iB; iB=iTemp;}main(){ intiFirst=13,iSecond=27; Swap(iFirst,iSecond); printf("\niAis%d",iFirst); printf("\niBis%d",iSecond);}voidSwap(intiA,intiB)38main(){ intiFirst=13; intiSecond=27; Swap(iFirst,iSecond); printf("\niFirstis%d",iFirst); printf("\niSecondis%d",iSecond);}
iFirst=13 iSecond=27
main() iFirst=13 39iFirst=13iSecond=27 iB=27 iA=13 iTemp
main(){ intiFirst=13; intiSecond=27; Swap(iFirst,iSecond); printf("\niFirstis%d",iFirst); printf("\niSecondis%d",iSecond);}iFirst=13main()40voidSwap(intiA,intiB){ intiTemp; iTemp=iA; iA=iB; iB=iTemp;}iFirst=13iSecond=27 iB=27 iA=13 iTemp
iFirst=13iSecond=27 iB=13iA=27 iTemp
voidSwap(intiA,intiB)iFirs41main(){ intiFirst=13; intiSecond=27; Swap(iFirst,iSecond); printf("\niFirstis%d",iFirst); printf("\niSecondis%d",iSecond);}iFirst=13 iSecond=27
main()iFirst=13 42总结参数传递的时候,实际参数的数值复制给形式参数形式参数是实际参数的“复印件”。修改形式参数,不影响实际参数的数值。这一机制称为:call-by-value总结参数传递的时候,实际参数的数值复制给形式参数437.5函数的嵌套调用C语言不能嵌套定义,但可以嵌套调用。嵌套定义:在定义一个函数时,该函数体内包含另一个函数的定义。一.嵌套调用调用一个函数的过程中,又调用另一个函数。7.5函数的嵌套调用C语言不能嵌套定义,但可以嵌套调用。嵌44main函数调用A函数结束A函数调用B函数B函数192873456main函数调用A函数结束A函数调用B函数B函数19245例题:编写函数,求1!+3!+5!+...k!其中k是小于9的奇数,要求该函数中调用求阶乘函数求出各阶乘的值。doublexx(intx){doublet=1;inti;for(i=1;i<=x,i++)t=t*i;return(t);}doubleyy(intm){doubles=0;inti;for(i=1;i<=m;i++)if(i%2!=0)s=s+xx(i);return(s);}main(){intn;doublesum;scanf(“%d”,&n);sum=yy(n);printf(“%f”,sum);}例题:编写函数,求1!+3!+5!+...k!其中k是小于46直接递归调用间接递归调用在调用一个函数的过程中直接或间接地调用该函数本身。7.6、函数的递归调用直接递归调用间接递归调用在调用一个函数的过程中直接或间接地调47递归调用对应的一般算法:f(x)=终了公式递归公式说明不应出现无终止的递归调用,给定一个限制递归次数的条件。执行过程递归调用:记住本次现场,递归调用。终了调用:返回上次调用现场。递归调用对应的一般算法:f(x)=终了公式递归公式说明不应出48例:用递归法求n!算法:f(n)=1(n=1)f(n-1)*n(n>1)main(){doublejx(intm)intn;doublet;printf(“Inputn:”);scanf(“%d”,&n);t=jx(n);printf("%f",t);}doublejx(intm){doublef;if(m==1)f=1;elsef=jx(m-1)*m;returnf;}例:用递归法求n!算法:f(n)=1(49数组作参数的时候,函数可以使用数组元素的“原件”。数组的存储原理决定了这一效果。例:
intiList[LENGTH];
7.7数组作为函数参数
数组作参数的时候,函数可以使用数组元素的“原件”。7.750数组的存储原理
1000 1002 1004 1006 1008
10 20 30 40 50
iList[0] iList[1] iList[2] iList[3] iList[4]
数组的存储原理 51数组元素的地址如果数组iList存储在1000开始的内存空间,那么1000是iList[0]的地址,1002是iList[1]的地址,1004是iList[2]的地址。请问,iList[i]的地址?1000+i*2数组元素的地址如果数组iList存储在1000开始的内存空间52计算机访问数组元素的原理计算机根据数组的首地址、元素的下标和数据元素在内存的长度,计算元素的地址,然后根据地址访问数组元素。元素的下标由程序员指定。元素的类型是预先声明的。数组的首地址保存在数组名中。数组名就是数组的首地址。计算机访问数组元素的原理计算机根据数组的首地址、元素的下标和53计算机访问数组元素的原理访问iList[i],就是访问地址为iList+i*sizeof(int)其中,iList是首地址,i是元素的下标,sizeof(int)是元素在内存的长度(字节为单位)。计算机访问数组元素的原理访问iList[i],就是访问地址为54问题如果iArray也是数组名,而且iArray中存储的地址与iList相同,那么iArray[i]与iList[i]有什么关系?答:它们是同一数据元素。问题如果iArray也是数组名,而且iArray中存储的地址55一、数组元素做函数实参例题:有两个数组A,B各有10个元素,将它们逐个对应相比,如果A数组中的元素大于B数组中相应的元素数目多于B数组中的元素大于A数组中相应的元素数目,则认为A数组大于B数组,并分别统计出两个数组相应元素大于,小于和等于的个数。程序设计:1、函数large(x,y):比较两个数组元素的大小。
返回值flag=1当x>y0当x=y-1当x<y2、主函数:输入两个数组,调用large函数比较,计数,输出统计结果。一、数组元素做函数实参例题:有两个数组A,B各有10个元素,56intlarger(intx,inty){intflag;if(x>y)flag=1;elseif(x<y)flag=-1;elseflag=0;return(flag);}运行输入:enterarraya:1357986420enterarrayb:5389-1-35604运行结果:
>:4
=:1
<:5
a<bmain(){inta[10],b[10],i,n=0,m=0,k=0;for(i=0;i<10;i++)scanf(“%d”,&a[i]);for(i=0;i<10;i++)scanf(“%d”,&b[i]);for(i=0;i<10;i++){if(larger(a[i],b[i])==1)n=n+1;elseif(larger(a[i],b[i])==0)m=m+1;elsek=k+1;}if(n>k)printf(“a>b\n”);elseif(n<k)printf(“a<b\n”);elseprintf(“a=b\n”);}intlarger(intx,inty)运行输57二、数组名做函数参数数组名代表数组在内存中存放区域首地址。数组名作函数参数实现大量数据传递。数组名做函数的参数方法:⑴在主调函数和被调函数中分别定义数组;⑵实参数组和形参数组类型应一致;⑶实参数组和形参数组大小不一定一致,形参数组可以不指定大小(这里指一维数组)。说明数组名做函数的实参和形参时是“地址传递”。形参数组各元素的值发生变化会使实参数组各元素值发生同样的变化。二、数组名做函数参数数组名代表数组在内存中存放区域首地址。数58例1:编写函数,求一维数组中存放学生成绩的平均值。floataver(floata[],intn){inti;floatpj,sum=0;for(i=0;i<n;i++)sum=sum+a[i];pj=sum/n;return(pj);}main(){floatxs[10],pjf;inti;for(i=0;i<10;i++)scanf(“%f”,&xs[i]);pjf=aver(xs,10);printf(“pjf=%f”,pjf);}一维数组作函数参数时形参数组可不指定大小一维数组的大小把一维数组xs的首地址传给形参数组a例1:编写函数,求一维数组中存放学生成绩的平均值。float59例2:对数组中10个整数按由小到大排序。voidsort(intarray[],intn){intv,j,t;for(i=0;i<n-1;i++)for(j=i+1;j<n;j++)if(array[j]<array[k]){t=array[k];array[k]=array[i];array[i]=t;}main(){inta[10],i;for(i=0;i<10;i++)scanf(“%d”,&a[i]);sort(a,10);for(i=0;i<10;i++)printf(“%d”,a[i]);}由于地址传递,实参数组a改变例2:对数组中10个整数按由小到大排序。voidsort60例3:写一函数,使给定的一个二维整形数组(3*3)转置,即行列互换。voidxx(inta[3][3]){inti,j;for(i=0;i<3;i++){for(j=0;j<3;j++)printf(“%d”,a[j][i];)}printf(“\n”);}main(){inta[3][3],i,j;for(i=0;i<3;i++){for(j=0;j<3;j++)scanf(“%d”,&a[i][j]);}xx(a);}二维数组名做函数参数,可以指定每一维的大小或省略第一维的大小如:intarray[3][10];或intarray[][10];但intarray[3][];╳
和intarray[][];╳例3:写一函数,使给定的一个二维整形数组(3*3)转置,即行61总结当数组的名字作为形式参数时,被复制的是数组的首地址函数根据首地址处理的是数组元素的“原件”,而不是“复印件”。总结当数组的名字作为形式参数时,被复制的是数组的首地址627.8局部变量和全局变量在函数内部或复合语句内部定义的变量作用域:函数内或复合语句内。
局部变量⑴主函数main定义的变量只在主函数中有效,主函数不能使用其它函数定义的变量。⑵不同函数中的同名变量互不影响。⑶形参也是局部变量。在本函数中a、b、c有效f1(inta){intb,c;…}在本函数中a、b、c、d有效但与f1函数中的a、b、c不同f1(inta,intb){intd,c;…}在本函数中m、n有效main(){intm,n;…}7.8局部变量和全局变量在函数内部或复合语句内部定义的变63例:
main(){inta=10,b=10;
{intcc=a+b;a、b在此
…c在此范围范围内有效内有效
}….}例:64在函数外部定义的变量(也称外部变量)。作用域:可以为本文件中所有的函数公用。全局变量⑴从定义变量的位置开始到本文件结束,这段程序中的函数可直接使用外部变量。⑵如果在定义点之前的函数想使用外部变量,则应该在该函数中用关键字extern作“外部变量”说明。⑶如果在同一源文件中,外部变量和局部变量同名,则在局部变量的作用范围内,外部变量不起作用。优点⑴增加了函数间数据联系同一文件中的一些函数引用全局变量,当某个函数中改变了全局变量的值,其它函数中的全局变量值也随之改变。⑵函数可以得到多个返回值缺点⑴全局变量在程序的全部执行过程中都占用存储单元。⑵使用全局变量不符合程序设计中要求模块间“强内聚性、弱偶合性”的原则。⑶使用全局变量过多,会降低程序的可读性和可维护性。在函数外部定义的变量(也称外部变量)。作用域:可以为本文65变量的存储类别1.静态存储方式和动态存储方式静态存储方式:程序运行期间分配固定存储空间的方式。动态存储方式:程序运行期间根据需要进行动态的分配存储空间的方式。程序区静态存储区动态存储区全局变量,局部静态变量形式参数局部变量(自动)函数调用的现场保护和返回地址7.9变量的存储方式和生存期变量的存储类别1.静态存储方式和动态存储方式静态存储方式:662.静态存储变量和动态存储变量静态存储变量:用静态存储方式存储的变量。动态存储变量:用动态存储方式存储的变量。特点:在静态存储区分配存储单元,整个程序运行期间都不释放。
特点:函数开始调用时为变量分配存储空间,函数结束时释放这些空间。一个程序两次调用同一函数,其中同一个局部变量的内存地址可能不同。2.静态存储变量和动态存储变量静态存储变量:用静态存储方式存67C语言变量的属性:数据类型
存储类型存储类型:数据在内存中的存储方式。即静态存储方式和动态存储方式。3.变量的属性及其定义数据类型:整型,实型,字符型……存储分类符:auto(自动的)、register(寄存器的)static(静态的)、extern(外部的)定义变量的一般形式:存储分类符类型标识符变量名;如:autointa;staticintb;registerintd;C语言变量的属性:数据类型存储类型:数据在内存中的存储方式。68①auto(自动的)例如:autointa;
4.变量的存储类型⑴auto说明局部变量,该局部变量是自动变量;⑵自动变量存放在动态存储区,属于动态存储变量;⑶变量作用域是其所在的函数内部。①auto(自动的)例如:autointa;4.变量的存69说明:⑴在一个函数内如果局部变量不作存储类型说明,均为自动变量;⑵形式参数缺省存储类型是auto,但不能将auto加在形参说明之前。
如:intb,c=3等价于autointb,c=3;如:intmax(autointx,autointy){……}╳②static(静态的)static可用于说明局部变量——局部静态变量全局变量——外部静态变量说明:⑴在一个函数内如果局部变量不作存储类⑵形式参数缺省存储70局部静态变量
⑴作用域仅限于定义它的函数内部。⑵存放在静态存储区,整个程序运行期间都不释放。⑶编译时赋初值,每次调用不再赋初值,只保留调用结束时变量的值。
自动变量调用一次,重新赋值一次。⑷局部静态变量不赋初值,编译时自动赋0。
自动变量不赋初值,其值不确定。例如:打印1!~5!intfac(intn){staticintf=1;f=f*n;return(f)}main(){inti;for(i=1;i<=5;i++)printf(“%d!=%d\n”,i,fac(i));}局部静态变量⑴作用域仅限于定义它的函数内部。⑵存放在静态71外部静态变量
⑴只能在本源程序文件中被使用。⑵不论是否加static说明,编译时分配在静态存储区。③register(寄存器的)寄存器:CPU中运算器的组成部分,暂时存放数据。寄存器变量:直接放置在运算器的寄存器中的变量。引入寄存器变量是为了提高“存取”速度。外部静态变量⑴只能在本源程序文件中被使用。⑵不论是否加s72⑵属于动态存储变量,但不放在动态存储区中,放在寄存器中。说明:⑶寄存器变量的作用域与自动变量相同。⑴regiser只适用于说明局部变量;例如:registerinti;定义了i是寄存器变量。⑵计算机的寄存器数目有限,不宜定义太多寄存器变量。不同的系统允许使用的寄存器个数是不同的。⑴只有局部变量(非静态的)和形参可以作为寄存器变量。例如:registerstaticinti;╳⑵属于动态存储变量,但不放在动态存储区中,放在寄存器中。说73④exturn(外部的)⑴exturn适用于说明全局变量;⑵在多个源程序文件组成的程序中/*文件A.c*/inta;main(){……}例如:/*文件B.c*/exturninta;power(){……}也可以写成exturna;如果B文件中引用在A文件中定义的全局变量(该
全局变量不是static变量),需要在B文件中,用关键字extern说明。④exturn(外部的)⑴exturn适用于说明全局变量;⑵74⑷在同一个源文件中,全局变量的作用域之外的函数中使用该全局变量时,也需用extern对其说明。若在A文件中的全局变量是静态外部变量(static)
,则即使在B文件中用extern对其说明,也无法在A文件中使用该全局变量。/*文件A.c*/staticinta;main(){……}例如:/*文件B.c*/exturninta;power(){……}无法使用变量a⑷在同一个源文件中,全局变量的作用域之外的函若在A文件中的全757.11内部函数和外部函数一、内部函数定义:如果一个函数只能被本文件中其它函数调用,称为内部函数(又称静态函数)。格式:static类型标识符函数名(形参表)例如:staticintfun(a,b){..….}作用:函数的作用域限于所在文件,不同文件中同名函数互不干扰,便于程序的局部化。7.11内部函数和外部函数一、内部函数定义:如果一个函76二、外部函数定义:如果一个函数允许被其它文件调用,称为外部函数。格式:exturn类型标识符函数名(形参表)例如:exturnintfun(a,b){..….}intfun(a,b){..….}或
类型标识符函数名(形参表)或通常不加static标识符的函数都是外部函数。
在需要调用此函数的文件中,一般要用exturn说明所用的函数是外部函数。二、外部函数定义:如果一个函数允许被其它文件调用,称格式:e77第七章用函数实现模块化程序设计第七章用函数实现模块化程序设计78交实验报告140页3题格式:按照《上机指导书》171页附录D格式书写采用统一的实验报告纸交实验报告140页3题79算法是解决具体问题的方案基本要求:根据给出的算法编写程序7.1为什么要用函数算法是解决具体问题的方案基本要求:根据给出的算法编写程序7.80实际的软件开发实际问题往往由多个基本问题构成。要求软件开发人员首先分析问题,将问题分解为基本问题。其次,逐个解决每个基本问题。实际的软件开发实际问题往往由多个基本问题构成。81程序与问题的关系整个问题基本问题1…基本问题n整个程序函数1…函数n程序与问题的关系整个问题基本问题1…基本问题n整个程序函数182对软件开发人员的要求分析并分解问题(高级要求)。设计解决基本问题的函数(基本要求)。对软件开发人员的要求分析并分解问题(高级要求)。83例iA和iB为两个整数,iA是基数,iB是指数.如何计算变量result保存最后结果,base为底数,exponent为指数。result=1;for(counter=1;counter<=exponent;counter++){ result*=base;}
计算35、55、85例iA和iB为两个整数,iA是基数,iB是指数.变84问题如果要分别计算100对整数的次幂,需要多少for?问题85解决方案我们制造一个零件(函数),它负责计算次幂当需要计算次幂时,告诉零件基数和指数,零件返回结果。函数就象提供服务的人。解决方案我们制造一个零件(函数),它负责计算次幂86第一个角度:程序就是机器。函数就是零件。程序由函数构成。第二个角度:函数可以为其他函数提供服务,就象服务人员。第一个角度:871.什么是函数?函数就是可以完成某项基本任务的一组语句。函数名是唯一的。函数可以被其他的函数使用,称为函数的调用。1.什么是函数?函数就是可以完成某项基本任务的一组语句。88参数主调用函数给被调用函数一些数据,即参数。被调用函数根据参数值完成相应的工作。参数主调用函数给被调用函数一些数据,即参数。89返回值被调用函数完成工作后,可能会返回某些数据作为计算结果。返回值被调用函数完成工作后,可能会返回某些数据作为计算结果。90函数的要素函数名参数返回值函数体(语句)函数的要素函数名91函数调用示例:main()/*主函数*/{print_star();/*调用print_star函数画****/
print_message();/*调用print_message函数写字*/
print_star();}/*调用print_star函数画****/
print_star()/*定义print_star函数*/{prinf(“**********\n”);}print_message()/*定义print_message函数*/
{prinf(“Hello!\n”);}运行结果:**********Hello!**********
⑴一个源文件由一个或多个函数组成,是一个独立编译单元。⑵一个C程序由一个或多个源文件组成;⑶C程序执行总是从main函数开始,调用其他函数后流程回到main。⑷函数不能嵌套定义,但可互相调用。注意不能调用main函数。函数调用示例:main()92函数的分类1.函数参数形式无参函数有参函数2.从用户使用的角度分标准函数(库函数)用户自己定义的函数库函数编译系统提供的已设计好的函数,用户只需调用而无需要去实现它(scanf,printf,getchar,putchar等)。用户自定义函数程序员自己定义和设计的函数。有参函数例(输出两数中大者)#include<stdio.h>main(){intmax(intx,inty);intn1,n2,a;scanf("%d,%d",&n1,&n2);a=max(n1,n2);printf("max=%d",a);}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}无参函数例main(){print_star();print_message();print_star();}
print_star(){prinf(“**********\n”);}print_message(){prinf(“Hello!\n”);}函数的分类1.函数参数形式无参函数有参函数2.从用户使用937.2怎样定义函数
例如:
print_message(){printf(“Hello!\n”);}二、有参函数的定义形式类型标识符函数名(形参表列){说明部分语句}有参数传递例如:求x和y二者中大者intmax(intx,inty)/*x,y为形参*/{intz;/*函数体中变量的说明*/z=x>y?x:y;return(z);}/*将z的值作为函数返回值*/类型标识符函数名(){说明部分语句}无参数传递一、无参函数的定义形式三、空函数的定义形式类型标识符函数名(){}功能:调用后什么也不做。用处:建立程序结构,在需要时补充功能。例如:dummy(){}若无参数,类型标识符写void或不写函数返回值的类型,若不说明类型,默认为整型。是被初始化的内部变量,寿命和可见性仅限于函数内部7.2怎样定义函数例如:二、有参函数的定义形式类94四、形式参数和实际参数形式参数定义函数时函数名后面括弧中的变量名,简称形参。实际参数调用函数时函数名后面括弧中的表达式,简称实参。c=max(a,b);-----------------------实参:在运行时
把函数的max(intx,inty)把值传给函数。结果赋给{………函数名returu(z);形参:通知系统}要预留内存位置。上例中形参与实参、函数名与返回值之间的关系main(){intmax(intx,inty);inta,b,c;scanf(“%d,%d,&a,&b);c=max(a,b);printf(“Maxis%d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}形参表实参表四、形式参数和实际参数形式参数定义函数时函数名后面括弧中的95函数的返回值语句return将被调函数的一个确定值带回主调函数。return(函数返回值);或return函数返回值;通过函数调用使主调函数得到一个确定的值五、函数的返回值main(){intmax(intx,inty);inta,b,c;scanf(“%d,%d,&a,&b);c=max(a,b);printf(“Maxis%d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}此时函数的返回值是5,因此c=5有确定值的常量、变量或表达式函数的返回值语句return将被调函数的一个确定值带回主调函96⑴函数不加类型说明按整型处理⑵函数和return类型不一致以函数类型为准。⑶函数不返回值定义为void六、函数值的类型voidprint_star(){……}main(){intmax(intx,inty);inta,b,c;scanf(“%d,%d,&a,&b);c=max(a,b);printf(“Maxis%d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}⑴函数不加类型说明按整型处理⑵函数和return类型不一致以97小结int
Power(intiBase,intiExponent)返回类型: int
函数名: Power形式参数: iBase,iExponent
形式参数的数值由实际参数决定。小结intPower(intiBase,98注意:int
Power(intiBase,intiExponent)谁是被定义的函数?谁是参数?第一个int的作用是什么?后两个int的作用是什么?函数的使用者应该明确指明什么,才能使用函数?注意:intPower(intiBase,99调用函数就是使用函数。调用函数之前,必须首先声明函数。声明函数就是声明:函数名、函数返回值的类型和参数的类型。例:
intPower(int,int);7.3调用函数
调用函数就是使用函数。7.3调用函数100一、函数调用的一般形式
函数名(实际参数表)
有参数函数无参数函数
函数名()一、函数调用的一般形式函数名(实际参数表)有参数函数无101voidprint_star(){printf(“*******”);}main(){inta,b,c;scanf(“%d,%d,&a,&b);c=2*max(a,b);print-star();printf(“c=%d”,c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}二、函数调用的具体方式1.函数调用作为一个语句函数名(实际参数表);调用可忽略或没有返回值的函数(如:scanf函数和printf函数)
2.函数调用出现在表达式中变量名=函数表达式调用带返回值的函数,其返回值参加表达式运算。无返回值函数的调用,不能出现在表达式中3.函数参数函数调用作为一个函数的参数。如:m=max(a,max(b,c))voidprint_star()main()intma102在程序编译阶段,对调用函数的合法性进行全面检查。如没有函数声明,编译到包含函数调用的语句时(如xx(a,b)),编译系统不知道xx是函数名,也无法判断实参(a,b)的类型和个数是否正确,无法进行正确性的检查。只有在运行时才会发现实参与形参的类型或个数不一致,出现运行错误。
在程序编译阶段,对调用函数的合法性进行全面检查。如没有函数声1037.4、对被调用函数的声明和函数原型⒈对被调用函数说明的前提条件必须是已存在的函数,如用户自定义函数或库函数。2.被调用函数是用户自定义函数的函数说明主调函数和被调用函数在同一文件中,在主调函数中说明被调函数类型。7.4、对被调用函数的声明和函数原型⒈对被调用函数说明的前104在C语言中,以上的函数说明称为函数原型。/*定义add函数*/floatadd(floatx,floaty){floatz;z=x+y;return(z);}main(){floatadd(floatx,floaty);floata,b,c;scanf(“%f,%f”,&a,&b);c=add(a,b);printf(“sumis%f”,c);}对被调用函数的说明作为表达式被调用在C语言中,以上的函数说明称为函数原型。/*定义add函数1053.被调用函数是库函数的函数说明文件开头用#include命令将调用库函数时需用到的信息“包含”到文件中(对这些库函数的原型说明全部都写在对应的头文件里)。
常用的头文件:#include“stdio.h”#include“math.h”#include“string.h”4.省略被调用函数声明的三种情况
floatadd(floatx,floaty){floatz;z=x+y;return(z);}main(){floata,b,c;scanf(“%f,%f”,&a,&b);c=add(a,b);printf(“sumis%f”,c);}(1)被调函数定义在主函数前3.被调用函数是库函数的函数说明文件开头用#includ106(2)函数返回值为整型或字符型,系统按整型处理。main(){inta,b,c;scanf(“%d,%d”,&a,&b);c=max(a,b);printf(“Maxis%d”,c);}max(intx,inty){intz;z=x>y?x:y;return(z);}无函数说明整型函数(2)函数返回值为整型或字符型,系统按整型处理。main(107⑶所有函数定义前,在函数的外部已说明函数类型。charletter(char,char);floatf(float,float);inti(float,float);main(){…….}charletter(charc1,charc2){……}floatf(floatx,floaty){……}inti(float,float){……}在所有函数之前说明函数类型此处不必说明定义函数letter、f和i⑶所有函数定义前,在函数的外部已说明函数类型。charle108复习函数的要素:名字、返回值、参数和代码定义函数:编写代码声明函数:声明名字、参数类型和返回值类型调用函数:给出名字和实际参数,如果有返回值则保存。复习函数的要素:109main(){inti;longt;t=1;
for(i=1;i<=n;i++)t=t*i;
printf(“n!=%ld\n”,t);}longxx(intx){longt=1;inti;if(x<=0)printf(“error”);elsefor(i=1;i<=x,i++)t=t*i;return(t);}main(){intn;longs;scanf(“%d”,&n);s=xx(n);printf(“%ld”,s);}例1:编写函数,求n!。main()longxx(intx)例1:编写函110例题1:求1+2+3+...+100的和。main(){inti,s=0;for(i=1;i<=100;i++)s=s+i;printf(“s=%d”,s);}例2:编写函数,求1+2+3+...n。intmm(intx){intt=0;inti;for(i=1;i<=x,i++)t=t+i;return(t);}main(){intn;ints;scanf(“%d”,&n);s=mm(n);printf(“%d”,s);}例题1:求1+2+3+...+100的和。例2:编写函数,求111执行细节---步骤
程序将从主函数开始执行当发生函数调用时,主调用函数暂停实际函数的值将被复制给形式参数(不需要任何语句,程序自动做该项工作).被调用函数执行遇到返回语句时,被调用函数将结果返回给主调用函数主调用函数恢复执行执行细节---步骤程序将从主函数开始执行112执行细节---存储分配被调用函数执行前,系统为其变量分配内存空间(包括形式参数)。实际参数的值被复制给形式参数(值传递).当被调用函数结束执行后,内存空间将被释放,下次调用时重新分配。执行细节---存储分配被调用函数执行前,系统为其变量分配内存113例:你可以判断出下面程序的结果吗?程序的执行过程是怎样的?例:你可以判断出下面程序的结果吗?114voidSwap(intiA,intiB){ intiTemp; iTemp=iA; iA=iB; iB=iTemp;}main(){ intiFirst=13,iSecond=27; Swap(iFirst,iSecond); printf("\niAis%d",iFirst); printf("\niBis%d",iSecond);}voidSwap(intiA,intiB)115main(){ intiFirst=13; intiSecond=27; Swap(iFirst,iSecond); printf("\niFirstis%d",iFirst); printf("\niSecondis%d",iSecond);}
iFirst=13 iSecond=27
main() iFirst=13 116iFirst=13iSecond=27 iB=27 iA=13 iTemp
main(){ intiFirst=13; intiSecond=27; Swap(iFirst,iSecond); printf("\niFirstis%d",iFirst); printf("\niSecondis%d",iSecond);}iFirst=13main()117voidSwap(intiA,intiB){ intiTemp; iTemp=iA; iA=iB; iB=iTemp;}iFirst=13iSecond=27 iB=27 iA=13 iTemp
iFirst=13iSecond=27
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 集成电路数字化工厂架构搭建方案
- 摇臂钻安全操作规程
- 电子商务沙盘运营与管理(AI实践版) 实训工单汇 第1-8章 电子商务沙盘结构与流程认知 -第一轮、第二轮经营实战
- 公司督办事项办结单
- 2026年员工修车合同(1篇)
- 2026年眼镜店验光服务协议
- A级膜材料为什么成为软膜天花面光系统的重要组成部分
- 结肠镜检查与慢性肠炎
- 社交媒体数据中的高频词汇提取
- 良法善治申论试题及答案
- 药品信用档案管理制度
- 2025-2030中医院行业市场深度分析及竞争格局与投资价值研究报告
- 企业管理 华为会议接待全流程手册SOP
- 水利工程监理实施细则范本(2025版水利部)
- 有关PLC的毕业论文
- 员工职位申请表(完整版2026年版)
- 矛盾纠纷排查化解课件
- 企业营销策划(数字教材版)课件 第七章 渠道策划
- 勘察阶段工作进度计划安排及措施
- 安全用电培训医院课件
- (标准)转让合同协议书挖机
评论
0/150
提交评论