《C程序设计》(第三版)第八章 函数.ppt

上传人:dream****gning 文档编号:145121125 上传时间:2020-09-16 格式:PPT 页数:65 大小:648.50KB
返回 下载 相关 举报
《C程序设计》(第三版)第八章 函数.ppt_第1页
第1页 / 共65页
《C程序设计》(第三版)第八章 函数.ppt_第2页
第2页 / 共65页
《C程序设计》(第三版)第八章 函数.ppt_第3页
第3页 / 共65页
《C程序设计》(第三版)第八章 函数.ppt_第4页
第4页 / 共65页
《C程序设计》(第三版)第八章 函数.ppt_第5页
第5页 / 共65页
点击查看更多>>
资源描述

《《C程序设计》(第三版)第八章 函数.ppt》由会员分享,可在线阅读,更多相关《《C程序设计》(第三版)第八章 函数.ppt(65页珍藏版)》请在金锄头文库上搜索。

1、C语言程序设计,主讲人:杉杉 E-mail:,第八章 函数,8.1 概述 8.2 函数定义和调用 8.3 函数的嵌套调用和递归调用 8.4 数组作为函数参数 8.5 局部变量和全局变量 8.6 内部函数和外部函数 8.7 动态存储变量与静态存储变量 8.8 程序举例,8.1 概述,函数分为:库函数和用户自定义函数 C库函数非常丰富,在调用库函数时,必须清楚: (1)函数的功能和名称 (2)参数的个数和顺序,每个参数的意义和类型 (3)函数值的意义和类型 (4)使用标准函数时需要使用包含文件,8.2 函数定义和调用,8.2.1 函数的定义 8.2.2 函数的返回值与函数类型 8.2.3 对被调用

2、函数的说明和函数原型 8.2.4 函数的调用 8.2.5 函数的形参与实参,8.2.1 函数的定义,根据函数是否需要参数,可将函数分为无参函数和有参函数两种。 1. 无参函数的一般形式 2. 有参函数的一般形式 3说明,1. 无参函数的一般形式,函数类型 函数名( ) 说明语句部分; 可执行语句部分; ,2. 有参函数的一般形式,函数类型 函数名(数据类型 参数,数据类型 参数2 ) 说明语句部分; 可执行语句部分; ,【例8.1】 定义一个函数,用于求两个数的和。,/*功能:定义一个求两个数的和的函数并在主函数中调用*/int sum(int n1, int n2) return (n1+n

3、2);main() int sum(int n1, int n2);/*函数说明*/ int num1,num2; printf(“input two numbers:n”); scanf(“%d%d”, return 语句后面的()可以不要,如return z;和return (z);等价。 (2)return语句的功能 返回调用函数,并将“返回值表达式”的值带给调用函数。 注意:调用函数中无return语句,并不是不返回一个值,而是一个不确定的值。为了明确表示不返回值,可以用“void”定义成“无(空)类型”。,2函数类型,在定义函数时,对函数类型的说明,应与return语句中返回值表达式

4、的类型一致。 如果不一致,则以函数类型为准。 如果缺省函数类型,则系统一律按整型处理。 良好的程序设计习惯: 凡不要求返回值的函数都应定义为空类型void; 即使函数类型为整型,也不使用系统的缺省处理。,8.2.3 对被调用函数的说明和函数原型,对被调用函数进行声明,其一般格式如下: 函数类型 函数名(数据类型 参数名1, 数据类型 参数名2); 语言规定在以下2种情况下,可以省去对被调用函数的说明: 当被调用函数的函数定义出现在调用函数之前时。 如果在所有函数定义之前,在函数外部(例如文件开始处)预先对各个函数进行了说明,则在调用函数中可缺省对被调用函数的说明。,【例8.2】对被调用函数作声

5、明,#include void main() float add(float x, float y); /*对被调用函数add声明*/ float a,b,c; scanf(%f,%f,注意:函数的定义和声明的区别。,8.2.4 函数的调用,语言中,函数调用的一般形式为: 函数名(实际参数表) ; 如果调用无参函数,则实际参数表可以没有,但括号不能省。 切记:实参的个数、类型和顺序,应该与被调用函数所要求的参数个数、类型和顺序一致,才能正确地进行数据传递。,在语言中,可以用以下几种方式调用函数: (1)函数表达式。函数作为表达式的一项,出现在表达式中,以函数返回值参与表达式的运算。这种方式要求

6、函数有返回值。 如c=max(a,b)*20; (2)函数语句。C语言中的函数可以只进行某些操作而不返回函数值,这时的函数调用可作为一条独立的语句。 如:Print( ); (3)函数实参。函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须有返回值。 如:d=max(a,max(b,c);,说明: (1)调用函数时,函数名称必须与具有该功能的自定义函数名称完全一致。 (2)实参在类型上按顺序与形参,必须一一对应和匹配。如果类型不匹配,C编译程序将按赋值兼容的规则进行转换。如果实参和形参的类型不赋值兼容,通常并不给出出错信息,且程序仍然继续执行,

7、只是有可能得不到正确的结果。 (3)如果实参表中包括多个参数,对实参的求值顺序随系统而异。有的系统按自左向右顺序求实参的值,有的系统则相反。Turbo C和MS C是按自右向左的顺序进行的 。,8.2.5 函数的形参与实参,函数的参数分为形参和实参两种,作用是实现数据传送。 形参出现在函数定义中,只能在该函数体内使用。发生函数调用时,调用函数把实参的值传送给被调用函数的形参,从而实现调用函数向被调用函数的数据传送。,【例8.3】定义一个函数max,实现求用户从终端输入的2个整型数中的较大者.,#include stdio.h void main() int max(int x,int y);

8、int a,b,c; scanf(%d,%d,说明: 1:函数调用前形参不占用内存中的存储单元,只有在发生函数调用时形参才被分配内存单元,在调用结束后,形参所占内存单元被释放。因此,形参只有在该函数内有效。因此在执行一个被调用函数时,形参的值如果改变,并不会改变主调函数的实参的值。 2. 实参可以是常量、变量、表达式、函数等。无论是何种类型,在进行函数调用时,都必须具有确定的值,以便把这些值传送给形参。因此,应预先用赋值、输入等办法,使实参获得确定的值。 3. 实参对形参的数据传送是单向的“值传递”,即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。,【例8.4】函数参数的传递,m

9、ain( ) int a=88,b=66; int swap(int ,int ); printf(“调用交换前:a=%d,b=%dn”,a,b); swap(a,b); printf(“调用交换后:a=%d,b=%dn”,a,b); int swap(int x,int y) int temp; printf(“调用中交换前:x=%d,y=%dn”,x,y); temp=x;x=y;y=temp; printf(“调用中交换后:x=%d,y=%dn”,x,y); ,8.3 函数的嵌套调用和递归调用,8.3.1 嵌套调用 8.3.2 递归调用,8.3.1 嵌套调用,函数的嵌套调用:在调用一个函

10、数的过程中,又调用另一个函数。 C语言允许嵌套调用,不允许嵌套定义。,【例8.5】 计算s=1k+2k+3k+Nk (N=5,K=4),#define K 4 #define N 5 long f1(int n,int k)/*计算n的k次方*/ long power=n; int i; for(i=1;ik;i+) power *= n; return power; long f2(int n,int k)/*计算1到n的k次方之累加和*/ long sum=0; int i; for(i=1;i=n;i+) sum += f1(i, k); return sum; main() print

11、f(Sum of %d powers of integers from 1 to %d = ,K,N); printf(%dn,f2(N,K) ); ,8.3.2 递归调用,在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。 在递归调用中,调用函数又是被调用函数,执行递归函数将反复调用其自身。 为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回。,举一个例子,有甲乙丙丁4人,甲比乙大3岁,乙比丙大3岁,丙比丁大3岁,若知道丁为20岁,问甲为多大? 递归调用有两个过程 递归过程,即自身不断

12、调用自己,直至满足某种条件出现确定值,终止递归; 递推过程,由后及前,逐步返回,直到得到最初的返回值,即为所求。,【例8.6】有甲乙丙丁4人,甲比乙大3岁,乙比丙大3岁,丙比丁大3岁,若知道丁为20岁,问甲为多大?,int age(int n) int c; if(n=1) c=20; else c=age(n-1)+3; return(c); #include void main() printf(%d,age(4); ,【例8.7】用递归的方法求n! 1 (n=0,1) n!= n*(n-1)! (n1),float fac(int n) float f; if(n0) printf(n0

13、,dataerror!); else if(n=0 | n=1) f=1; else return(f); ,f=fac(n-1)*n;,【例8.8】用递归的方法求汉诺塔问题。,#include void main() void hanoi(int n,char one,char two,char three); int m; printf(input the number of diskes:); scanf(%d, ,void hanoi(int n,char one,char two,char three) void move(char x,char y); void move(char

14、 x,char y) printf(%c-%cn,x,y); ,if(n=1) move(one,three); else hanoi(n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three);,8.4 数组作为函数参数,8.4.1 数组元素作为函数参数 8.4.2 数组名作为函数参数,【例8.9】有两个数组a,b,逐个比较数组中对应元素的大小。分别统计a数组中元素大于、小于、等于b数组中元素的次数,#include void main() int large(int x,int y); int a10,b10,i,n=0,m=

15、0,k=0; for(i=0;ibi:%d timesnai=bi:%d timesnaibi:%d timesn,n,m,k);,large(int x,int y) int flag; if(xy)flag=1; else if(x=y)flag=0; else flag=-1; return(flag); ,【例8.10】 写一函数,统计字符串中字母的个数。,int isalp(char c) if (c=a ,for(i=0;stri!=0;i+) if (isalp(stri) num+;,说明: (1)用数组元素作实参时,只要数组类型和函数的形参类型一致即可,并不要求函数的形参也是

16、下标变量。换句话说,对数组元素的处理是按普通变量对待的。 (2)在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元。在函数调用时发生的值传送,是把实参变量的值赋予形参变量。,8.4.2 数组名作为函数参数,数组名作函数参数时,既可以作形参,也可以作实参。要求形参和相对应的实参必须是类型相同的数组(或指向数组的指针变量),都必须有明确的数组说明。,【例8.11】 已知某个学生5门课程的成绩,求平均成绩。,float aver( float a 5 ) /*求平均值函数*/ int i; float av,s=a0; for(i=1;i5;i+) s += ai; av=s/5; return av; void main() float score5,av; int i; printf(ninput 5 scores:n); for(i=0;i5;i+) scanf

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号