第八章函数课题:第八章函数§1~§4教学目的:1、掌握函数定义的一般形式2、掌握函数调用的一般形式教学重点:教学难点:函数定义、调用的一般形式形式参数和实际参数步骤一复习引导一个C语言源程序可由一个主函数和若干个辅助函数组成。由主函数调用其他函数,其他函数也可以互相调用。步骤二讲授新课§8.1概述例8.1main(){printstar();print_message();printstar();}printstar(){printf(“**********\n”);}print_message(){printf(“Howdoyoudo!\n”);}说明:1、一个源程序文件由一个或多个函数组成。一个源程序文件是一个编译单位。2、一个C程序由一个或多个源程序文件组成。这样可以分别编写、分别编译,提高调度效率。3、C程序的执行从main函数开始,在main函数中结束整个程序的运行。4、所有函数都是平行的,即函数不能嵌套定义,函数可以互相调用,但不能调用main函数。5、从用户使用的角度看,函数有两种:标准函数(库函数)和用户自己定义的函数6、从函数的形式看,函数分为两类:无参函数和有参函数§8.2函数定义的一般形式(一)无参函数的定义形式类型标识符函数名(){函数体(包括声明部分和执行部分)}例:printstar(){printf(“**********\n”);}(二)有参函数定义的一般形式类型标识符函数名(形式参数表){函数体(包括声明部分和执行部分)}例如:intmax(intx,inty){intz;z=xy?x:y;return(z);}(三)一个函数可以是空函数如dummy(){}§8.3函数参数和函数的值(一)形式参数和实际参数形式参数:定义函数时函数名后括号中的变量名,简称形参;实际参数:调用函数时函数名后括号中的表达式,简称实参。main(){inta,b,c;scanf(“%d,%d”,&a,&b);c=max(a,b);/*调用max函数*/printf(“max=%d”,c);}intmax(intx,inty)/*定义max函数*/{intz;z=xy?x:y;return(z);}关于形参和实参的说明:形参在未出现函数调用时,并不占内存中的存储单元。只有在发生函数调用时,函数中的形参才被分配内存单元。在调用结束后,形参所占的内存单元也被释放。2、实参可以是常量、变量或表达式,如:c=max(3,a+b);但要求它们有确定的值。在调用时将实参的值赋给形参(如果形参是数组名,则传递的是数组的首地址,而不是变量的值。)3、在被定义的函数中,必须指定形参的类型;4、实参与形参的类型应一致。5、C语言规定,实参对形参的数据传递是“值传递”,即单向传递。在内存中,实参单元与形参单元是不同的单元。(二)函数的返回值1、return语句return(表达式);或:return表达式;或:return;或:函数执行到最后遇到“}”return语句的用途有二:(1)用于结束函数的执行并返回到调用者;(2)用来向调用者传递一个返回值。注意:该语句对非void函数适用。2、函数值的类型如:intmax(x,y)charletter(c1,c2)doublemin(x,y)C语言默认函数返回值为int型。3、函数值的类型和return语句中表达式的值不一致,则以函数类型为准;main(){floata,b;intc;scanf(“%f,%f”,&a,&b);c=max(a,b);printf(“Maxis%d\n”,c);}max(floatx,floaty){floatz;z=xy?x:y;return(z);}若输入的数据情况为:1.5,2.5则输出的结果为:Maxis24、如果被调函数中没有return语句,则函数带回一个不确定值。5、为了明确表示“不带回值”,可以用“void”定义“无类型”(或称“空类型”)。如:voidprint_message(){printf(“Howdoyoudo!\n”);}§8.4函数的调用要正确实现函数间的相互调用需满足下列条件:第一,被调用函数必须存在且允许调用;第二,必须给出满足函数运行时要求的参数;第三,在调用一个函数之前一般应该对被调用函数进行声明。(一)函数声明的一般形式函数类型函数名(参数类型1,参数类型2,…,参数类型n);或:函数类型函数名(参数类型1参数名1,参数类型2…);如:intprint(charformat,…);charfun2(inti,charp1);floatadd(float,float);注意:函数声明与函数定义不同!(二)函数调用的一般方法函数调用形式:函数名(实参表列);1.函数语句如:前述例子中的print();2.函数表达式如:c=max(a,b);3.函数参数如:m=max(a,max(b,c));printf(“%d”,max(a,b));例:main(){inti=2,p;p=f(i,++i);printf(“%d”,p);}TC环境下,按自右而左的顺序求值。此例f(i,++i)~f(3,3)例:计算组合C(m,n)=m!/(n!(m-n)!)main(){intm,n;longcmn,temp;longfactor(int);scanf(“%d%d”,&m,&n);cmn=factor(m);temp=factor(n);cmn=cmn/temp;cmn=cmn/factor(m-n);printf(“%ld\n”,cmn);}步骤三课堂小结1、有参函数的定义形式2、形参和实参的区别3、函数的声明和调用步骤四布置作业书面作业:(第八章课后练习)8.1intf(inta,intb){intc;if(ab)c=1;elseif(a==b)c=0;elsec=-1return(c);}课题:第八章函数§5~§7教学目的:1、掌握函数的嵌套调用和递归调用2、掌握虚实结合教学重点:教学难点:嵌套和递归调用、数组作为函数参数递归调用、虚实结合步骤一复习引导floatroot(floatx1,floatx2){inti;floatx,y,y1;y1=f(x1);do{x=xpoint(x1,x2);y=f(x);if(y*y10){y1=y;x1=x;}else{y2=y;x2=x;}}while(fabs(y)=0.0001);return(x);}步骤二、讲授新课§8.6函数的递归调用直接或间接调用自身的函数为递归函数。一个问题采用递归方法来解决时必须符合以下条件:(1)可将一个问题转化为具有同样解法的规模较小的问题;(2)必须有明确的结束条件。[例8.7]:有5个人坐在一起,问第5个人多少岁,他说比第4个人大2岁,问第4个人的岁数,他说比第3个人大2岁,问第3个人的岁数,他说比第2个人大2岁,问第2个人,他说比第1个人大2岁,问第一个人,他说是10岁。请问第5个人的岁数?(P158)分析:显然这是一个递归问题。即:age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10程序:age(intn){intc;if(n==1)c=10;elsec=age(n-1)+2;return(c);}main(){printf(“%d”,age(5));}[例8.8]:利用递归求n!(P160)例:Fibonacci数列已在前面定义过,用递归函数求此数列的第n项。fib(intn){intf;if(n==0||n==1)f=1;elsef=fib(n-1)+fib(n-2);return(f);}[习题8.13]:用递归方法求n阶勒让德多项式的值,递归公式为:1(n=0)Pn(x)=x(n=1)((2n-1)xPn-1(x)-(n-1)Pn-2(x))/n(n1)main(){intx,n;floatp(int,int);printf(“\nInputn&x:”);scanf(“%d,%d”,&n,&x);printf(“n=%d,x=%d\n”,n,x);printf(“P%d(%d)=%6.2f”,n,x,p(n,x));}floatp(intn,intx){if(n==0)return(1);elseif(n==1)return(x);elsereturn(((2*n-1)*x-p((n-1),x)-(n-1)*p((n-2),x))/n);}例:双递归。这段程序的结果是_________voidf(intb,intt){intm;if(bt){m=(b+t)/2;printf(“%d\n”,m);f(b,m-1);f(m+1,t);}}main(){f(1,6);}§8.7数组作为函数参数虚实结合(哑实结合)一、数组元素作函数实参值传递:用赋值的方法,把实在参数的值赋给被调函数对应的形式参数。不希望破坏调用函数中作为实在参数对象的值时,使用“值传递”方式;注意:数组元素作为函数实参时如同简单变量。二、数组名作函数参数地址传递:指形参与实参结合的不是数据本身,而是把数据的地址传递给被调用函数。结合后的形参与实参都指向同一个存储区。在函数间传递一批数据时,一般采用“地址传递”方式。[例8.13]:用选择法对数组中10个整数按由小到大排序。main(){inta[10],i;printf(“enterthearray\n”);for(i=0;i10;i++)scanf(“%d”,&a[i]);sort(a,10);printf(“thesortedarray:\n”);for(i=0;i10;i++)printf(“%d”,a[i]);printf(“\n”);}三、多维数组名作函数参数main(){staticinta[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}};printf(“maxvalueis%\n”,max_value(a));}步骤三课堂小结函数的嵌套调用和递归调用,注意调用的过程数组作为函数参数有两种情况:传递数组元素的值、传递数组名步骤四布置作业书面作业:(第八章课后练习)8.2、8.17、15课题:第八章函数§8-§10教学目的:1、掌握局部变量和全局变量的作用范围2、掌握变量的存储类别,了解内部函数和外部函数教学重点:教学难点:局部变量和全局变量、变量的存储类别变量的作用域和生存期步骤一、复习引导在函数调用过程中,不仅要注意实参和形参的数据结合,而且要注意各个变量的作用域和生存期。步骤二、讲授新课§8.8局部变量和全局变量一、局部变量在一个函数内部定义的变量是内部变量,它只在本函数范围内有效。二、全局变量在函数之外定义的变量称为外部变量,即全局变量(全程变量)。全局变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。使用全局变量可以增加函数间的数据联系;[例8.15]:有一个一维数组,内放10个学生成绩,写一函数,求出平均分,最高分和最低分。floatmax=0,min=0;floataverage(floatarray[],intn){inti;floataver,sum=array[0];max=min=array[0];for(i=1;in;i++){if(array[i]max)max=array[i];elseif(array[i]min)min=array[i];sum=sum+array[i];}aver=sum/n;return(aver);}main(){floatave,score[10];inti;for(i=0;i10;i++)scanf(“%f”,&score[i]);ave=average(score,10);printf(“%6.2f,%6.2f,%6.2f”,max,min,ave);}在同一源文件中,如果外部变量与局部变量同名,则在局部变量的作用范围内外部变量不起作用;[例8.16