《函数及其应用.ppt》由会员分享,可在线阅读,更多相关《函数及其应用.ppt(72页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、关于函数及其应用关于函数及其应用1现在学习的是第1页,共72页 10.1 10.1 函函数的基本概念数的基本概念 一个较大的程序一般由若干个一个较大的程序一般由若干个程序模块程序模块(子程序子程序 )组成组成, 每一个模块每一个模块(子程序子程序)来完成一定的功能。在来完成一定的功能。在C语言中语言中, 子程序的子程序的作用是由函数来实现的。作用是由函数来实现的。 一个一个C程序可由一个程序可由一个主函数和若干个函数主函数和若干个函数构成,由主函构成,由主函数调用其它函数,其它函数也可互相调用。同一个函数可以被数调用其它函数,其它函数也可互相调用。同一个函数可以被一个或多个函数调用任意多次。一
2、个或多个函数调用任意多次。 下图是一个程序中函数调用的示意图:下图是一个程序中函数调用的示意图:现在学习的是第2页,共72页main( )A( )B( )C( )D( )E( )F( )G( )E( )H( )H( )H( )G( )函数调用函数调用示意图:示意图:调用现在学习的是第3页,共72页 (1). 一个源程序文件一个源程序文件由一个或多个函数组成由一个或多个函数组成.一个源程序一个源程序 文件是一个编译单位文件是一个编译单位,而不是以函数为单位进行编译而不是以函数为单位进行编译.说明说明: (2). 一个一个C程序可由程序可由一个或多个源程序文件一个或多个源程序文件组成组成. 这样可
3、以分别进行编写这样可以分别进行编写,编译编译,调试调试. 一个源文件可以为一个源文件可以为 多个多个C程序公用程序公用. (3). 所有函数是平行的所有函数是平行的, 一个函数并不从属于另一个函一个函数并不从属于另一个函 数数 , 函数可以相互调用,但不能调用函数可以相互调用,但不能调用main( )函数函数.现在学习的是第4页,共72页(4). 从从使用角度使用角度来分来分, 函数可分为:函数可分为: 数学函数数学函数 (#include math.h) 字符函数字符函数 (#include ctype.h) 库函数库函数 字符串函数字符串函数 (#include string.h) 输入输
4、出函数输入输出函数 (#include stdio.h) 动态存储分配函数动态存储分配函数 (#include stdlib.h) . 自定义函数自定义函数:现在学习的是第5页,共72页 从函数的从函数的形式形式来分;来分; 无参函数无参函数:主调函数没有数据传给被调函数主调函数没有数据传给被调函数 有参函数有参函数:主调函数可以将数据传给被调函数主调函数可以将数据传给被调函数 空函数空函数: 什么也不干,先占位置,以后扩展功能什么也不干,先占位置,以后扩展功能现在学习的是第6页,共72页一一. 函数定义的一般形式函数定义的一般形式:(自定义函数)(自定义函数) (1). 无参函数的定义形式:
5、无参函数的定义形式: 类型标识符类型标识符 函数名函数名( ) 函数体函数体 函数定义一律函数定义一律不能加分号不能加分号 (;) !说明:说明: 类型标识符是指类型标识符是指函数返回值的类型函数返回值的类型. 如果函数不要返回值,可写上如果函数不要返回值,可写上void.现在学习的是第7页,共72页(2). 有参函数定义:有参函数定义: 类型标识符类型标识符 函数名函数名(形式参数表列形式参数表列) 声明部分声明部分 语句语句 形式参数形式参数例: int add ( int x, int y ) int z; z=x+y; return z; 注注: 返回值返回值z 的类型的类型(int)
6、应与类型标识符统一。应与类型标识符统一。现在学习的是第8页,共72页1、函数参数与函数值;、函数参数与函数值;(1)形参与实参:形参与实参:例:例:main( ) int a,b,c; scanf(“%d, %d”, &a, &b); c=max(a, b); printf(“max is %d”, c); int max(int x, int y) /*定义有参函数定义有参函数max*/ int z; z=xy ? x : y; return(z); x,y为形参a,b为实参10.2 函数的参数现在学习的是第9页,共72页b. 实参实参可以是常量、变量、或表达式可以是常量、变量、或表达式,但
7、要求有确定值但要求有确定值. 如如: max(3, a+b) ; c. 实参与形参实参与形参的类型应一致,一的类型应一致,一 一对应。一对应。说明说明:a. 形参变量形参变量(上例中的上例中的x,y), 在在未调用未调用时,并不占时,并不占 用存储单元,当进行函数用存储单元,当进行函数调用时调用时,形参才分配内存,形参才分配内存 单元,调用结束后,形参就释放掉。单元,调用结束后,形参就释放掉。现在学习的是第10页,共72页d. 实参对形参的数据传递是实参对形参的数据传递是单向传值单向传值,只能是由实参传,只能是由实参传 给形参,而不能相反进行。给形参,而不能相反进行。 实参、形参在内存中实参、
8、形参在内存中,占据不同单元。占据不同单元。 2 a b 3 2 x 3 y 即使形参单元中的值发即使形参单元中的值发生变化,生变化,也不会影响也不会影响实参单实参单元的值元的值. 函数调用后,形参单元释放掉函数调用后,形参单元释放掉,实参单元仍保留。,实参单元仍保留。现在学习的是第11页,共72页例10.9 阅读一下程序,写出程序运行结果#include int swap(int x, int y)int temp;temp=x;x=y;y=temp;return 0;int main()int a, b;scanf(%d%d, &a, &b);swap(a,b);printf(%d,%dn,
9、a, b);return 0;Ch10_10_9.c 即使形参单元中的值发生即使形参单元中的值发生变化,变化,也不会影响也不会影响实参单实参单元的值元的值. 两变量进行交换两变量进行交换.现在学习的是第12页,共72页2. 函数的返回值与函数的返回值与return语句:语句: 执行执行C语言程序就是调用一个个函数,函数被调用语言程序就是调用一个个函数,函数被调用 时,可以返回某一个值作为该函数的值时,可以返回某一个值作为该函数的值(供主函数使用供主函数使用)。需要返回值时,在函数中返回的地方使用需要返回值时,在函数中返回的地方使用return语句语句: return(表达式)表达式); 这里表
10、达式的值就是函数的返回值。这里表达式的值就是函数的返回值。现在学习的是第13页,共72页说明:说明: a. return 语句后面的括号可省去:语句后面的括号可省去: 如:如: return(z); return z ; return 后面可以是一个表达式后面可以是一个表达式. 现在学习的是第14页,共72页 b. 当函数不需要带回返回值,当函数不需要带回返回值,C语言有二种方法处理语言有二种方法处理 : . .使用不带表达式的使用不带表达式的return语句,如语句,如: return; . .连连return也不用,这是因为函数末尾也不用,这是因为函数末尾,隐含隐含一个一个return 语
11、句语句 ,当遇到后面的大括号当遇到后面的大括号“” , 就把控制权交给主调就把控制权交给主调 函数。函数。现在学习的是第15页,共72页 为了明确表示不带回值,可用为了明确表示不带回值,可用“void“定义。定义。 如:如: void printstar( ); 这样可以保证函数不带回任何值这样可以保证函数不带回任何值.c. 若函数不指定带值返回,并不是不返回什么值,可能若函数不指定带值返回,并不是不返回什么值,可能 返回一个返回一个不定值不定值。 因为不考虑使用,即使返回是不定值因为不考虑使用,即使返回是不定值,也无多大关系。也无多大关系。 现在学习的是第16页,共72页#includein
12、t add(int x, int y)int z;z=x+y;return z;int main()int a, b, c;scanf(%d %d, &a, &b);c=add(a,b);printf(c=%dn, c);return 0; 例例:10.1 函数值传递的例子函数值传递的例子.(P149) 函数在被调用前函数在被调用前必须先必须先定义定义或或说明说明!Ch10_10_1.c现在学习的是第17页,共72页例例:10.2 函数地址传递的例子函数地址传递的例子.(P150) 输入一个由数字组成的字符串输入一个由数字组成的字符串,转换成一个整数转换成一个整数.#includeint ct
13、oi(char *p) int sum=0; while(*p) sum=sum*10; sum=sum+(*p-0); p+; return sum;int main( ) char str5; int x; printf(“string is :n); scanf(%s,str); x=ctoi(str); printf(“integer is %dn,x); return 0;数组名作为数组名作为函数的参数函数的参数 Ch10_10_2.c*p-0 把一个字符把一个字符数字转成数字数字转成数字.现在学习的是第18页,共72页3、函数的调用、函数的调用:(1). 函数调用的方式:函数调用的
14、方式: 有以下三种函数调用方式:有以下三种函数调用方式: a. 函数语句函数语句: 函数作为一条语句函数作为一条语句, 不要求函数带回值不要求函数带回值,完成一定的,完成一定的 功能、操作。如:功能、操作。如: printstar( ); b. 函数表达式函数表达式: 函数调用出现在一个表达式中。函数调用出现在一个表达式中。 如如: c=z*max(a,b); 这时要求函数这时要求函数带回一个确定的值带回一个确定的值, 以参加运算。以参加运算。现在学习的是第19页,共72页 c. 函数参数函数参数: 如:如:printf(“%d” , max(a,b) ); max(a,b) 作为作为 pri
15、ntf函数的一个参数。函数的一个参数。 现在学习的是第20页,共72页10.3 10.3 系统函数的应用系统函数的应用 C语言提供了十分丰富的库函数语言提供了十分丰富的库函数.这些这些函数函数可分为:可分为: 1. 数学函数数学函数,如如: sin(), sqrt() 函数等函数等.它们的包含文件是它们的包含文件是: “math.h”. 2. 字符串函数字符串函数,如如: gets(),strcmp()函数等函数等.它们的包含文件是它们的包含文件是: “string.h”. 3. 输入输出函数输入输出函数,它们的包含文件是它们的包含文件是: “stdio.h”. 现在学习的是第21页,共72页
16、10.3.1 数学函数数学函数 常用的数学函数有常用的数学函数有: (1). sqrt(): double sqrt(double x); 计算计算 ; x应应=0 (2). fabs(): double fabs(double x); 计算计算 x 的的绝对值绝对值 x (3). pow(): double pow(double x,double y); 计算计算xy 的值的值 (4). exp(): double exp(double x); 计算计算 ex 的值的值现在学习的是第22页,共72页例例10.3 求求z=xy+c 的值,在的值,在C语言中语言中xy可调用系统函数可调用系统函数
17、 pow()函数来求得。函数来求得。#include #include /必须加入数学库头文件必须加入数学库头文件int main()double x, y, z, c;printf(Please input x y cn);scanf(%lf%lf%lf, &x, &y, &c);z=pow(x,y)+c;printf(z=%lfn, z);return 0;C+另一注解方法另一注解方法现在学习的是第23页,共72页例例10.410.4 利用循环的方法产生利用循环的方法产生11001100间的间的1010个随机数,并个随机数,并在屏幕上显示在屏幕上显示. .关于关于 rand() 随机函数随
18、机函数: rand()会返回一随机数值会返回一随机数值,范围在范围在0至至RAND_MAX 间间. 现在学习的是第24页,共72页#include #includevoid main( ) printf( RAND_MAX =%ld n,RAND_MAX);说明说明: RAND_MAX是一宏定义值是一宏定义值. 是系统最大的被是系统最大的被rand()返回的返回的值值. 其值可用下列程序输出其值可用下列程序输出:视系统不同而不同视系统不同而不同(32767).现在学习的是第25页,共72页2. srand(seed)函数函数: srand()用来设置用来设置rand()产生随机数时的产生随机数
19、时的随机数种子随机数种子。参。参数数seed必须是个整数必须是个整数,通常可以利用通常可以利用time(0)的返回值来当的返回值来当做做seed. 如果每次如果每次seed都设相同值,都设相同值,rand()所产生的随机数值每次所产生的随机数值每次就会一样。就会一样。 3. time() 函数返回从函数返回从1970年开始经历时间的秒数。年开始经历时间的秒数。现在学习的是第26页,共72页例例10.4 利用系统函数利用系统函数rand(),此函数产生,此函数产生1100间的间的10个随机数,此函数在头件个随机数,此函数在头件 stdlib.h进行了声明进行了声明.#include#includ
20、e #include int main()int i,j;srand(time(0);for(i=0; i S2 函数返回值为函数返回值为0 S1 S2 函数返回值函数返回值0现在学习的是第31页,共72页例10.5 从键盘输入两个字符串,把两个字符串连接后输出到屏幕#include #include int main()char s180, s280;gets(s1);gets(s2);strcat(s1,s2);puts(s1);return 0;gets()以回车结束输入以回车结束输入.ch10_5.c现在学习的是第32页,共72页例例10.610.6从键盘输入一个字符串,求这一字符串长
21、度从键盘输入一个字符串,求这一字符串长度#include #include int main()int x;char str80;gets(str);x=strlen(str);printf(该字符串长度:该字符串长度:%dn, x);return 0;ch10_6.c现在学习的是第33页,共72页10.3.3 字符操作函数与转换函数1. isalnum(): 函数原型函数原型: int isalnum(int ch); 检查检查ch是否为是否为字母或数字字母或数字. 是字母或数字返回是字母或数字返回1, 否则返回否则返回0.2. isalpha(): 函数原型函数原型: int isalph
22、a(int ch); 检查检查ch是否为是否为字母字母. 是字母返回是字母返回1, 否则返回否则返回0.现在学习的是第34页,共72页3. islower(): 函数原型: int islower(int ch); 检查检查ch是否为是否为小写字母小写字母(az) . 是返回是返回1, 否则返回否则返回0.4. isxdigit(): 函数原型: int isxdigit(int ch); 检查检查ch是否为一个是否为一个十六进制字符十六进制字符(09或或af或或AF). 是返回是返回1, 否则返回否则返回0.现在学习的是第35页,共72页 5. atoi() 函数原型函数原型: int at
23、oi(char *str) 函数功能函数功能: 将将(一含有数字内容的一含有数字内容的)字符串转换成一个整数数值字符串转换成一个整数数值. 头文件头文件: #include #include int main() int n; char str =12345.78; n=atoi(str); printf(string=%s integer=%dn,str,n); return 0; 现在学习的是第36页,共72页例例10.710.7 从键盘输入一些字符,输出其中的大写字符与十六进从键盘输入一些字符,输出其中的大写字符与十六进制字符,当输入字符制字符,当输入字符 结束字符结束字符#includ
24、e #include int main()char ch;while( ( ch=getchar() ) != )if(isupper(ch) | isxdigit(ch) ) printf(%3c, ch);printf(n);return 0;ch10_7.c现在学习的是第37页,共72页10.4 10.4 自定义函数自定义函数 C语言允许用户自定义函数语言允许用户自定义函数. 例如例如: 下面是一个自定义函数下面是一个自定义函数,功能是求两个整数之和功能是求两个整数之和. int add(int x,int y) int z; z=x+y; return z; 现在学习的是第38页,共7
25、2页 关于对被调用函数的声明和函数原型关于对被调用函数的声明和函数原型: 在一个函数中调用另一个函数在一个函数中调用另一个函数(即被调函数即被调函数)需要具备哪些条件需要具备哪些条件? a. 函数要存在函数要存在(库函数或自定义函数库函数或自定义函数). 此外还要此外还要: b. 如果是如果是库函数库函数,一般应在文件开头用一般应在文件开头用#include命令把命令把 相关函数的一些信息包括进去相关函数的一些信息包括进去. 现在学习的是第39页,共72页 如果用户如果用户自己定义自己定义了一个函数,同时主调函数与被了一个函数,同时主调函数与被 调函数调函数在在同一源文件中同一源文件中: 一般
26、情况下,主调函数中要对被调用函数的作一一般情况下,主调函数中要对被调用函数的作一声明声明. 函数声明函数声明 即向编译系统声明将要调用此函数即向编译系统声明将要调用此函数, 并将有关信息通知编并将有关信息通知编译系统译系统.现在学习的是第40页,共72页例例: main( ) float a, b, c; scanf(“”%f,%f”,&a,&b); c=add(a,b); printf(“sum is %f”,c); float add(float x,float y) float z; z=x+y; return(z); 对被调函数的声明对被调函数的声明float add(float x,
27、float y ); 函数声明是一语句函数声明是一语句,要加分号要加分号 ;自定义自定义add函数函数. C语言在进行编译时是语言在进行编译时是从上到下从上到下逐行进行的逐行进行的,如果没有对函如果没有对函数进行声明数进行声明,如上例如上例,当编译到当编译到 “c=add(a,b);” 时时, 并不知道并不知道add是不是是不是函数名函数名,也无法判断实参也无法判断实参(a和和b)的的类型与个数类型与个数正确与否正确与否?现在学习的是第41页,共72页 (1). “定义定义”与与“声明声明”不是一回事不是一回事. “定义定义”: 是指对函数功能的确定是指对函数功能的确定,包括指定函数名包括指定
28、函数名,函数值类型函数值类型, 形参及其类型形参及其类型,函数体等函数体等. 它是一个它是一个完整的完整的, 独立的独立的函数函数 单位单位. 说明说明: 而而“声明声明”的作用的作用: : 则是把函数的名字则是把函数的名字, ,函数的类型函数的类型, ,以及形参的类型以及形参的类型, ,个个 数和顺序通知编译系统数和顺序通知编译系统, ,以便在调用该函数时系统按此以便在调用该函数时系统按此 检查检查. .现在学习的是第42页,共72页(2). 其实其实,在在函数声明中函数声明中也可以不写形参名也可以不写形参名,而只写形参的而只写形参的 类型类型. 如如: float add (float,
29、float); (3). 在在C语言中语言中,以上的函数声明称为以上的函数声明称为函数原型函数原型. 使用函数原型的主要作用是使用函数原型的主要作用是: 利用它在程序的编译阶利用它在程序的编译阶 段段, 对被调函数的合法性进行全面检查对被调函数的合法性进行全面检查. 现在学习的是第43页,共72页 函数原型的一般形式函数原型的一般形式:(a). 函数类型函数类型 函数名函数名( 参数类型参数类型1, 参数类型参数类型2, .)(b). 函数类型函数类型 函数名函数名( 参数类型参数类型1 参数名参数名1, 参数类型参数类型2 参数名参数名2, .)函数原型函数原型 第一种是基本的形式第一种是基
30、本的形式,为了便于阅读为了便于阅读,也允许加上参数名也允许加上参数名.但编译但编译系统并不检查参数名系统并不检查参数名,因此参数名是什么都无所谓因此参数名是什么都无所谓.现在学习的是第44页,共72页(4). (4). 对被调函数声明,在下列对被调函数声明,在下列三种情况三种情况下可省略:下可省略:说明说明:( (a).a).如果函数的返回值是如果函数的返回值是整型整型, ,或字符型或字符型可以省去(可以省去(以以 前我们遇到的大多是这种情况前我们遇到的大多是这种情况)。)。 系统自动按整型处理,建议加以说明为好。系统自动按整型处理,建议加以说明为好。( (b). b). 被调用函数的定义位置
31、出现被调用函数的定义位置出现在主调函数之前在主调函数之前, ,可省可省 去声明去声明, ,这时编译系统已知道了已定义的函数类型这时编译系统已知道了已定义的函数类型, , 会自动处理会自动处理. . 如下例如下例: :现在学习的是第45页,共72页 float add(float x,float y) /*定义定义add函数函数*/ float z; z=x+y; return(z); main( ) float add(float x,float y ); float a, b, c; scanf(“”%f,%f”,&a,&b); c=add(a,b); printf(“sum is %f”,
32、c) 此处不必对此处不必对add()作声明作声明( (c). c). 此外此外, ,在文件开头(在文件开头(所有函数定义之前所有函数定义之前), ,对函数进对函数进 行了函数的统一声明,可省去在主调函数中的声明。行了函数的统一声明,可省去在主调函数中的声明。现在学习的是第46页,共72页如如: : char letter(char,char ); /* 这三行处于所有函数之前这三行处于所有函数之前, float f1(float,float ); 且在函数外部且在函数外部.*/ int i2( float,float); main( ) /* main内内不必说明所调用函数类型不必说明所调用函
33、数类型 */ char letter(char c1,char c2) /*定义定义letter()函数函数*/ . float f1(float x, float y ) /*定义定义f1( )函数函数*/ . int i2(float j, float k) /*定义定义i2( )函数函数*/ . 现在学习的是第47页,共72页#include int fun(int n) int s=1, i;if(n=0) s=1;else for(i=1;i=n; i+) s = s*i;return s;int main()int a, b;scanf(%d, &a);b=fun(a);print
34、f(%d的阶乘为的阶乘为%dn, a,b);return 0;例例10.8 10.8 从键盘输入一个整数(从键盘输入一个整数(0-160-16),求此数的阶乘。),求此数的阶乘。Ch10_10_8.c现在学习的是第48页,共72页例10.10 输入二个整数,进行函数调用,问能否实现实参a,b的交换。#includeint swap(int *p3,int *p4) int m; m=*p3; *p3=*p4; *p4=m; return 0; int main( ) int a,b; int *p1,*p2; printf(Please input a,b :); scanf(%d,%d,&a
35、,&b); p1=&a; p2=&b; swap(p1,p2); printf(a=%d,b=%dn,a,b); return 0; 8P1 a运行运行: : 8,38,3( (回车回车) )输出输出: : 3,83,8 3P2 8P33P4Ch10_10_10.c指针为参数指针为参数现在学习的是第49页,共72页10.5 10.5 函数的应用函数的应用例例10.11 在在main函数中定义了一个整型数组并初始化,通过调用自函数中定义了一个整型数组并初始化,通过调用自定义函数定义函数sum把数组中把数组中-1前的所有元素值相加前的所有元素值相加.#include int sum(int b )
36、 int s=0, i=0; while( bi!=-1 ) s += bi+; return s;int main() static int a=1,2,3,4,5,6,7,8,9,-1,6; printf(Total=%dn, sum(a) ); return 0;Ch10_10_11.c数组名作为函数的参数数组名作为函数的参数进行调用进行调用.现在学习的是第50页,共72页例例10.14 10.14 输入一行英文字符,统计其中有多少单词,单输入一行英文字符,统计其中有多少单词,单词之间以空格为分隔词之间以空格为分隔#include int main()char string81;int
37、num;gets(string);num=numword(string);printf(There are %d wordsn, num);return 0;现在学习的是第51页,共72页int numword(char *str)int i, num=0, word=0;char ch;for(i=0; (ch=stri )!= 0; i+)if(ch= ) word=0;else if(word=0) word=1; num+; return num; num 统计单词个数统计单词个数, word用用来判断是否单词的标志来判断是否单词的标志.(1). 当前字符为空格当前字符为空格: 未出现
38、新单词未出现新单词 ,word=0, num 不不累加。累加。(2). 当前字符为非空格当前字符为非空格(分两种情况分两种情况):a. 前一字符为空格前一字符为空格(word=0),新词出新词出 现现, word=1, num 加加1 .b. 前一字符为非空格前一字符为非空格(word=1),未出未出 现新单词现新单词, num 不不加加1 .You are students.现在学习的是第52页,共72页 (1). (1). 函数的嵌套调用:函数的嵌套调用: C C语言中的函数是平行的,语言中的函数是平行的,不允许嵌套定义不允许嵌套定义。 所有函数的作用域都处于同一嵌套深度,即不允许在函数体
39、中所有函数的作用域都处于同一嵌套深度,即不允许在函数体中又定义另一个函数又定义另一个函数. . 但但允许嵌套调用允许嵌套调用函数函数, ,即在调用一个函数的过程中即在调用一个函数的过程中, ,又调用另一个又调用另一个函数。函数。10.6 函数的嵌套与递归调用现在学习的是第53页,共72页 main( ) a( )main( ) a( )函数函数 b( )b( )函数函数 调用函数调用函数a( ) a( ) 调用函数调用函数b( ) .b( ) . 结束结束 return returnreturn return 如如:现在学习的是第54页,共72页例例 求三角形面积求三角形面积 areaarea
40、2 2=s(s-a)(s-b)(s-c)=s(s-a)(s-b)(s-c)s=(a+b+c)/2smainarea# include # include void main() float a, b, c; float area(float a, float b, float c); float s(float a, float b, float c); scanf(%f%f%f, &a, &b, &c); printf(%fn, area(a, b, c);float area(float a, float b, float c) float ss; ss=s(a,b,c); return
41、sqrt(ss*(ss-a)*(ss-b)*(ss-c); float s(float a, float b, float c) return (a+b+c)/2;对被调函数的声明对被调函数的声明现在学习的是第55页,共72页开始调用(2 2). .函数的递归调用(函数的递归调用(recursiverecursive) 调用一个函数的过程中调用一个函数的过程中, 出现了直接或间接地调用出现了直接或间接地调用 该函数本身该函数本身 , 称之为函数的递归调用。称之为函数的递归调用。 C语言的特点之一是允许函数的递归调用。语言的特点之一是允许函数的递归调用。 递归调用可以简明递归调用可以简明 , 高
42、效的解决问题高效的解决问题(问题的一方面问题的一方面)。a. 直接递归调用;直接递归调用; int f (int x) int y , z; . z=f(y); return(z*z); 现在学习的是第56页,共72页b. 间接递归调用:间接递归调用: int f1(int x) int y,z; z=f2(y); return(z*z); int f2(int a ) int c; c=f1(a); return(3+c); 两种调用都是无休至的自我调用。两种调用都是无休至的自我调用。可以用可以用if语句来控制这种情况语句来控制这种情况. 现在学习的是第57页,共72页 通常用求一个数的通常
43、用求一个数的阶乘阶乘为例来说明递归函数。为例来说明递归函数。 1 (n=0,1) n!= n*(n-1)! (n1)例:例:10.18现在学习的是第58页,共72页 float fac(int n) float f; if (n0) printf (“n0, data error!”); exit(0); else if(n=0|n=1) f=1; else f=fac(n-1)*n; return(f) ; int main( ) int n ;float y; printf(“input a integer number:”); scanf(“%d”,&n); y=fac(n); prin
44、tf(“%d!=%f”, n, y); n n-1 下面设下面设 n=3,进行调用进行调用:ch10_10_18.c现在学习的是第59页,共72页fac(int n) else if (n=1|n=0) f =1; else f=fac(n-1)*3; return(f); main() . ( n= =3 ) y=fac(n); . fac(int n) . ( n= =2)else if (n=1|n=0) f = 1; else f=fac(n-1)*2; return(f); fac(int n) . ( n= =1)else if (n=1|n=0) f = 1; else f=fa
45、c(n-1)*n; return(f); 11*2现在学习的是第60页,共72页 调用调用fac函数计算函数计算3的阶乘时的情况:的阶乘时的情况: f=fac(2)*3 1. 这时函数将调用自己,因此仍然要理解为调用一个单这时函数将调用自己,因此仍然要理解为调用一个单 独的函数。独的函数。 2. 每一次当每一次当C语言中的任意函数被调用语言中的任意函数被调用(不管是否递归不管是否递归), 函数都将获得函数都将获得自己的一套局部变量和形式参数自己的一套局部变量和形式参数。 3. 函数递归时函数递归时,必须有个必须有个if语句,迫使函数返回,进而结语句,迫使函数返回,进而结 束递归束递归.现在学习
46、的是第61页,共72页 1. 1.数组名作函数参数数组名作函数参数: : 如如: :main( ) int array10; f1(array,10); f1(int arr,int n) .array0,arr0array, arr函数的应用现在学习的是第62页,共72页 实际上实际上, ,实参数组与形参数组共同占用一段内存空间实参数组与形参数组共同占用一段内存空间. . 在函数调用过程中在函数调用过程中, ,如果形参数组如果形参数组arrarr的元素值发生变的元素值发生变化化, ,相应实参数组的元素也发生同样变化相应实参数组的元素也发生同样变化. . .array0,arr0array,
47、arr现在学习的是第63页,共72页2.2.用多维数组名作函数参数用多维数组名作函数参数: : 在被调用函数中对形参数组的定义时在被调用函数中对形参数组的定义时, 可以指定每一维的可以指定每一维的大小大小,也可以省略第一维的大小说明也可以省略第一维的大小说明: 如如 int array310; 或或: int array 10;现在学习的是第64页,共72页例例: 有一个有一个3*4 的数组的数组,求所有元素中的最大值求所有元素中的最大值.ch10_10_18_1.c#include int max_value(int array4) int i,j,max; max=array00; for
48、(i=0;i3;i+) for(j=0;jmax) max=arrayij; return (max); int main() int a34=1,3,5,7,2,4,6,8,15,17,34,12; printf(max_value is %dn,max_value(a); return 1; 现在学习的是第65页,共72页例例2 21:1: 建立一个数组建立一个数组a,a,有有1010个元素个元素, ,通过函数调用的方通过函数调用的方 法实现法实现数组数组元素的逆序存放元素的逆序存放. .#include void main ( ) int i,a10,n; void reverse( i
49、nt p, int n); printf( Input the size of array:); scanf(%d,&n); printf( Input %d numbers:,n); for(i=0;in;i+) scanf(%d,&ai); reverse(a,n); for(i=0;in;i+) printf(%d , ai); 函数声明函数声明函数调用函数调用ch10_10_21_1.c现在学习的是第66页,共72页 void reverse(int p, int n) /数组为形参参数数组为形参参数 int i,j,t;for(i=0,j=n-1; ij; i+,j-) t=pi;
50、pi=pj; pj=t; printf(“After reversion: n);首尾交换数组各元首尾交换数组各元素的位置素的位置.现在学习的是第67页,共72页 说明说明: 实现交换数组各元素的另一种方法实现交换数组各元素的另一种方法,用指针为形参用指针为形参.void reverse(int *p, int n) int *pj, t;for(pj=p+n-1; ppj; p+, pj-) t=*p; *p =*pj; *pj=t; printf(“After reversion: n);调用调用: :reverse(a,n);reverse(a,n);ch10_10_21_2.c现在学习