幻灯片西南民族大学_第1页
幻灯片西南民族大学_第2页
幻灯片西南民族大学_第3页
幻灯片西南民族大学_第4页
幻灯片西南民族大学_第5页
已阅读5页,还剩169页未读 继续免费阅读

下载本文档

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

文档简介

1、第八章 函数1、熟练掌握函数的定义;2、对函数的参数和函数的值要深刻理解; 3、学会函数的调用;4、灵活掌握函数变量的类型及存储类别;本章要求: 函函 数数 函函 数数 概概 念念 函函 数数 调调 用用 应应 用用 举举 例例 递递 归归 调调 用用全局变量与局部变量全局变量与局部变量 动态与静态存储变量动态与静态存储变量内部与外部函数内部与外部函数 第八章 函数8 8. 1 8. 1 概述概述 8. 8.函数定义的一般形式函数定义的一般形式 8. 8.函数参数和函数的值函数参数和函数的值 8. 8.函数的调用函数的调用 8. 8.函数的嵌套调用函数的嵌套调用 8. 8.函数的递归调用函数的

2、递归调用 8. 8.数组作为函数参数数组作为函数参数 8. 8 8. 8 局部变量和全局变量局部变量和全局变量 8. 8.变量的存储类别变量的存储类别 8.10 8.10 内部函数和外部函数内部函数和外部函数本章要求:本章要求:1、熟练掌握函数的定义;、熟练掌握函数的定义;2、对函数的参数和函数的值要深刻理、对函数的参数和函数的值要深刻理 解;解; 3、学会函数的调用;、学会函数的调用;4、灵活掌握函数变量的类型及存储类、灵活掌握函数变量的类型及存储类 别;别; 一个程序可由一个主函数和若干个其他函一个程序可由一个主函数和若干个其他函数构成。数构成。在高级语。在高级语言中用子程序实现模块的功能

3、言中用子程序实现模块的功能, , 子程序由函数来子程序由函数来完成。完成。 C C是模块化程序设计语言是模块化程序设计语言源 程 序 文 件 1预 编 译 命 令说 明 部 分执 行 部 分函 数 1函 数 n源 程 序 文 件 i源 程 序 文 件 nC程 序C C程序结构程序结构&C C是是函数式函数式语言语言&必须有且只能有一个名为必须有且只能有一个名为mainmain的主函数的主函数&C C程序的执行总是程序的执行总是从从mainmain函数开始,在函数开始,在mainmain中结束中结束&函数函数不能嵌套定义不能嵌套定义, ,可以嵌套调用可以嵌套调用模

4、块化程序设计模块化程序设计v基本思想:将一个大的程序按功能分割成一些小模块基本思想:将一个大的程序按功能分割成一些小模块v特点:特点:l各模块相对独立、功能单一、结构清晰、接口简单各模块相对独立、功能单一、结构清晰、接口简单l控制了程序设计的复杂性控制了程序设计的复杂性l提高元件的可靠性提高元件的可靠性l缩短开发周期缩短开发周期l避免程序开发的重复劳动避免程序开发的重复劳动l易于维护和功能扩充易于维护和功能扩充v开发方法开发方法: : 函数分类函数分类 从用户角度从用户角度标准函数(库函数):由系统提标准函数(库函数):由系统提供供用户自定义函数用户自定义函数 从函数形式从函数形式无参函数无参

5、函数有参函数有参函数:1)1) 由系统提供,用户无须定义,也不必在由系统提供,用户无须定义,也不必在程序中作类型说明,只需在程序前包含有该函数原型的头文程序中作类型说明,只需在程序前包含有该函数原型的头文件即可在程序中直接调用。在前面各章的例题中反复用到件即可在程序中直接调用。在前面各章的例题中反复用到printf、scanf、getchar、putchar、gets、puts、strcat等等函数均属此类。函数均属此类。应注意:应注意:1 1、函数功能、函数功能2 2、函数参数的数目和顺序,及各参数的意义和类型、函数参数的数目和顺序,及各参数的意义和类型3 3、函数返回值的意义和类型、函数返

6、回值的意义和类型4 4、需要使用的包含文件、需要使用的包含文件 标准函数一般均是系统提供,因此程序质量应是最高的,即速标准函数一般均是系统提供,因此程序质量应是最高的,即速度快、精度高且占内存少,调用方便。度快、精度高且占内存少,调用方便。C 中库函数按功能分类:中库函数按功能分类: 编程中常遇到完成某个功能的程序段出现多次,为使程编程中常遇到完成某个功能的程序段出现多次,为使程序更简化;常遇到大家均要用到的功能,为了减少不必要的序更简化;常遇到大家均要用到的功能,为了减少不必要的重复编程使程序质量提高。在计算机高级语言中,引入函数重复编程使程序质量提高。在计算机高级语言中,引入函数(或子程序

7、、过程),称为(或子程序、过程),称为标准函数标准函数,C中称中称库函数库函数。 函数函数 头文件头文件 输入、输出函数输入、输出函数 stdio.h 数学函数数学函数 math.h 字符和字符串函数字符和字符串函数 string.h 动态分配函数动态分配函数 malloc.h 图形函数图形函数 graphics.h语言不仅提供了语言不仅提供了极为丰富的库函数极为丰富的库函数( (如如Turbo CTurbo C,MS CMS C都提供了三百多个都提供了三百多个库函数库函数) ),还允许,还允许用户建立自己定义用户建立自己定义的函数。用户可把的函数。用户可把自己的算法编成一自己的算法编成一个个

8、相对独立的函个个相对独立的函数模块,然后用调数模块,然后用调用的方法来使用函用的方法来使用函数。可以说程序数。可以说程序的全部工作都是由的全部工作都是由各式各样的函数完各式各样的函数完成的,所以也把成的,所以也把语言称为函数式语语言称为函数式语言。言。2)2) 由用户按需要写的函数。由用户按需要写的函数。Void main( )Void main( ) int max( int a, int b ); int max( int a, int b ); int x, y, z; int x, y, z; printf(input two numbers:n); printf(input two

9、numbers:n); scanf(%d%d, &x, &y); scanf(%d%d, &x, &y); z=max(x, y);z=max(x, y); printf(maxmum=%d, z); printf(maxmum=%d, z); 函数说明与函数定义中的函数函数说明与函数定义中的函数头部分相同,但是末尾要加分号头部分相同,但是末尾要加分号 int max( int a, int b )int max( int a, int b ) if (ab) return a; else return b;【 1)1) 函数定义、函数说明及函数调用中均函数定义

10、、函数说明及函数调用中均不带参数。主调函数和被调函数之间不进行参数传送。此不带参数。主调函数和被调函数之间不进行参数传送。此类类,可以返回或不返回,可以返回或不返回函数值。函数值。2)2) 也称为带参函数。在函数定义及函数也称为带参函数。在函数定义及函数说明时都有参数,称为形式参数说明时都有参数,称为形式参数( (简称为形参简称为形参) )。在函数调。在函数调用时也必须给出参数,称为实际参数用时也必须给出参数,称为实际参数( (简称为实参简称为实参) )。进行。进行。通过参数向被调用函数传递数据。void Hello( ) void main( ) :无参函数:无参函数:函数定义、函数说明及函

11、数调用中均函数定义、函数说明及函数调用中均不带参数不带参数。主调函数和被调函数之间主调函数和被调函数之间不进行参数传送不进行参数传送。无参函数无参函数一个函数调用的简单例子一个函数调用的简单例子(无参)# include void main() printstar(); *调用printstar函数* print_message(); /*调用print_message函数*/ printstar(); *调用printstar函数*/ *定义printstar函数* printf(* * * * * * * * * * * * * * * *n); *定义print_message函数* p

12、rintf(How do you do!n); 运行情况如下:运行情况如下:* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *How do you do!How do you do!* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *【补补例例2】调用函数,输出若干个】调用函数,输出若干个 “ * ” 每行输出每行输出10个个“* *”,共输出三行。,共输出三行。 void myprint ( ) int i ; for (i=1; i=10;

13、i+) printf (* ) ; printf (n ) ; void main ( ) myprint ( ) ; myprint ( ) ; myprint ( ) ; 无参函数无参函数 *#include 输出一行输出一行10个个“*” 有参函数:有参函数:在函数定义及函数说明时都在函数定义及函数说明时都有参数有参数,称为形式参,称为形式参数数(简称为形参简称为形参)。在函数调用时也必须给出参数,称为实际。在函数调用时也必须给出参数,称为实际参数参数(简称为实参简称为实参)。进行函数调用时,主调函数。进行函数调用时,主调函数将把实参的将把实参的值传送给形参值传送给形参,供被调函数使用。

14、,供被调函数使用。void main( ) int a, b, c; scanf(%d,%d, &a, &b); c=c=max (a , b ) ;max (a , b ) ; printf(Max is %d, c ) ;max ( int x , int y)max ( int x , int y) int z; z=xy? x: y ; return( z ); void main( ) int x, y, z; scanf(%d,%d, &x, &y); z=xy? x: y ; printf(Max is %d, z ) ;:【补补例例2】调用函数,

15、输出若干个】调用函数,输出若干个“*” 每行输出每行输出 n 个个“* *”,共输出三行。,共输出三行。 void myprint_n (int n) int i ; for (i=1; i=n; i+) printf (* ) ; printf (n ) ; void main ( ) myprint_n(5); myprint_n(10); myprint_n(15); 有参函数有参函数 *#include 输出一行输出一行n个个“*” 【补例【补例3】计算】计算xy的值的值 请注意:请注意:C语言中语言中 解法解法1:调用库函数:调用库函数pow ,计算,计算xy 计算计算xy 调用库函

16、数调用库函数必须加此行必须加此行 pow要求要求x和和y为为double Input data: 2.0 3.0 2.000000的的3.000000次方是次方是 8.000000解法解法2:调用自编函数:调用自编函数mypow,计算,计算xy若库中未提供求若库中未提供求xy的函数,的函数,则用户先编写后再使用则用户先编写后再使用 #include #include double mypow ( double x, double y ) int i; double z ;z = 1.0;for ( i = 1; i b) return a; else return b; 形形参参: 形参出现在

17、函数定义中,形参出现在函数定义中,形参变量只有在被调用形参变量只有在被调用时才分配内存单元,在调用结束时,时才分配内存单元,在调用结束时,立立刻释放所分配刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量调用结束返回主调函数后则不能再使用该形参变量。 实实参参:max(,)实参和形参在数量上,类型上,顺序上应严格一致实参和形参在数量上,类型上,顺序上应严格一致否则会发生否则会发生”类型不匹配类型不匹配”的错误。的错误。 主调函数和被调用函数之间有主调函数和被调用函数之间有的关系。的关系。在不同的函

18、数之间传递数据,可以使用的方法有:在不同的函数之间传递数据,可以使用的方法有:通过形式参数和实际参数通过形式参数和实际参数用用returnreturn语句返回计算结果语句返回计算结果外部变量外部变量#include void main( ) int max(int int max(int ,int int ) ); /* 对对max函数的声明函数的声明 */ int aint a,b b,c c; scanf (scanf (,a a,b)b); printfprintf( ,c c );); int max(int ,int ) *定义有参函数定义有参函数max * int int ; ?

19、; returnreturn();(); 运行情况如下:运行情况如下:, 通过函数调用,可使两个函数中的数据发生联系。通过函数调用,可使两个函数中的数据发生联系。void main() int n; scanf(%d, &n); s(n); printf(n=%dn, n );int s(int n) int i; for(i=n-1; i=1; i-) n=n+i; printf(n=%dn, n); 运行结果:运行结果:n=5050 n=100形参的值形参的值实参的值实参的值100s=0;for(i=1; iy? x: y ; return( z ); void main( ) i

20、nt x, y, z; scanf(%d,%d, &x, &y); z=xy? x: y ; printf(Max is %d, z ) ;:1 1、值传递、值传递方式方式l方式:方式: 函数调用时函数调用时, ,为形参分配单元为形参分配单元, ,并将实参的值并将实参的值复制复制到形到形参中参中, ,既实参将值直接赋给形参(变量)既实参将值直接赋给形参(变量) ;调用结束,形参;调用结束,形参单元被释放,实参单元仍保留并维持原值。单元被释放,实参单元仍保留并维持原值。 l特点:特点:u形参与实参占用形参与实参占用不同不同的内存单元的内存单元u称做称做单方向值调用单方向值调用-单

21、向单向传递传递实参变量对形参变量的数据传递有两种方式:实参变量对形参变量的数据传递有两种方式: 实参和形参在数量上,类型上,顺序上应严格一致实参和形参在数量上,类型上,顺序上应严格一致补例补例 交换两个数交换两个数void swap(int a,int b) int temp; temp=a; a=b; b=temp; printf(“a=%dtb=%dn, a, b ); Void main( ) int x=7,y=11; printf(x=%d, y=%dn, x, y ); printf(swapped:n); swap(x,y); printf(x=%d,ty=%dn, x, y )

22、;调用交调用交1.C711x:y:调用前:调用前:调用调用:711a:b:711x:y:swap:711x:y:117a:b:temp调用结束:调用结束:711x:y:调用之前调用之前x7y11x = 7 , y = 11printf (x = %d , y = %dn , x , y ) ;x7y11调用开始调用开始实参实参形参形参abx = 7 , y = 11711开辟开辟x7y11实参实参形参形参abx = 7 , y = 11711711temp = a ; a= b ; b = temp ;a = 11 , b = 7x7y11调用完毕调用完毕实参实参形参形参abx = 7 , y

23、 = 11711释放释放x = 7 , y = 11“按值按值”单向传递单向传递 printf (x = %d , y = %dn , x , y ) ;2 2、地址传递(暂略)、地址传递(暂略)l方式:方式: 函数调用时,将数据的函数调用时,将数据的存储地址存储地址作为参数传递作为参数传递给形参给形参,表示被调函数和主调函数操作的是同一批表示被调函数和主调函数操作的是同一批内存单元内容内存单元内容l特点:特点:u形参与实参占用形参与实参占用同样同样的存储单元的存储单元u形参的值发生改变,带回主调函数形参的值发生改变,带回主调函数-“双向双向”传递传递u实参和形参必须是实参和形参必须是地址地址

24、常量或变量常量或变量swap (int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a,b; scanf(%d,%d,&a,&b); printf(“a=%d,b=%dn”,a,b); printf(“swapped:n”); swap(&a, &b); printf(”a=%d,b=%dn,a,b);例例 交换两个数交换两个数a59b调前:调前:a59b调调swap:p1&a&bp2a95b交换:交换:p1&a&bp2a95b返回:返回:略返回值返回值: 函数的值是

25、指函数被调用之后,函数的值是指函数被调用之后,执行函数执行函数体中的程序段所取得的并返回给主调函数的值。体中的程序段所取得的并返回给主调函数的值。如如; ; 调用正弦函数取得调用正弦函数取得, 例例8.中,中,max(,)的值是,(,)的值是,max(,)的值是(,)的值是5。赋值语句将这个函数值赋。赋值语句将这个函数值赋给变量。给变量。 调用调用等。等。 : return(表达式表达式); return 表达式;表达式; return;使程序控制从被调用函数返回到调用函数中,使程序控制从被调用函数返回到调用函数中,同时同时 把返值带给调用函数把返值带给调用函数例例 无返回值函数无返回值函数v

26、oid swap(int x, int y ) int temp; temp=x; x=y; y=temp; 返回语句返回语句说明说明: (1 1)函数的返回值是通过函数中的函数的返回值是通过函数中的returnreturn语句获得的。语句获得的。 一个函数中可以有一个以上的一个函数中可以有一个以上的语句,执行到哪一个语句,执行到哪一个 语句,哪一个语句起作用。语句,哪一个语句起作用。 语句后面的括弧也可以不要语句后面的括弧也可以不要例如例如: : “;” 等价于等价于 “;” 后面的值可以是一个表达式。后面的值可以是一个表达式。例如例如: : 若无若无 语句,遇语句,遇“ ”时,自动返回调用

27、函数时,自动返回调用函数(2 2)函数的返回值应当属于某一个确定的类型,在定函数的返回值应当属于某一个确定的类型,在定 义函数时指定函数返回值的类型。义函数时指定函数返回值的类型。例如例如: 下面是下面是3个函数的首行:个函数的首行: int max(float ,float ) /* 函数值为整型 */ char letter(char c1,char c2) /* 函数值为字符型 */ double min(int ,int ) /* 函数值为双精度型 */ 注意:注意: 若函数类型与若函数类型与语句中表达式值的类语句中表达式值的类型不一致,按函数类型为准,自动转换型不一致,按函数类型为准

28、,自动转换-函数调函数调用转换用转换(3 3)对于不带回值的函数,应当用对于不带回值的函数,应当用“void”定义函定义函 数为数为“无类型无类型”(或称(或称“空类型空类型”)。此时)。此时在函在函 数体中不得出现数体中不得出现return语句。语句。 return、break、exit、contiune的作用:的作用: return 语句语句 退出调用函数退出调用函数 break 语句语句 退出退出switch语句体或本层循环语句体或本层循环 exit 结束整个程序执行结束整个程序执行 contiune 语句语句 return( (表达式)表达式)仅仅返回一个值返回一个值;若不返回任何值可

29、不要若不返回任何值可不要 return ( ); 凡函数未说明返回值类型均以凡函数未说明返回值类型均以 int 处理;处理; 例例 8.3 返回值类型与函数类型不同返回值类型与函数类型不同# include void main() int max(float ,float ); float ,; int c; scanf(,); c(,); printf( ,c); max(float ,float ) ; /* z为实型变量 */ ? ; return(z); , Max is Max is 说明说明: :如果是调用无参函数,则如果是调用无参函数,则“实参表列实参表列”可以没可以没 有,但括

30、弧不能省略。有,但括弧不能省略。实参与形参实参与形参个数相等个数相等,类型一致类型一致,按顺序一一按顺序一一 对应对应实参表求值顺序,因系统而定实参表求值顺序,因系统而定(Turbo C 自右向左自右向左)例例 8.4 实参求值的顺序实参求值的顺序#include void main() int f( int a, int b ); /* 函数声明 */ int i=2,p; p=f( i, +i ); /* 函数调用 */ printf(%dn, p ); int f( int a, int b) /* 函数定义 */ int c; if(ab) c=1; else if(a=b) c=0;

31、 else c=-1; return(c); 如果按自左至右顺序求实如果按自左至右顺序求实参的值,则函数调用相当参的值,则函数调用相当于(,)于(,) 如果按自右至左顺序求实如果按自右至左顺序求实参的值,则函数调用相当参的值,则函数调用相当于(于(3,),) 对于函数调用对于函数调用 int i=2, p;p=f( i, +i ); 函数调用的一般形式加上分号即构成函函数调用的一般形式加上分号即构成函数语句。数语句。 如:如: printf(“ %sn”, “BBI”);作为表达式中的一项出现作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。在表达式中,以函数返回值参与表达式的运

32、算。 如:如: y= max(a, b) + 100;函数作为另一个函数函数作为另一个函数调用的实际参数出现。调用的实际参数出现。 如:如: printf(“ %d n”, max(s, b) ) ; 如:如: y= max( max(a, b), c );首先被调用的函数必须是已经存在的函数(是库函数首先被调用的函数必须是已经存在的函数(是库函数或用户自己定义的函数)。但光有这一条件还不够。或用户自己定义的函数)。但光有这一条件还不够。如果如果,还应该在本文件开头用,还应该在本文件开头用#include 命令将调用有关库函数时所需用到的信息命令将调用有关库函数时所需用到的信息“包含包含”到本

33、到本文件中来。文件中来。 如果使用用户自己定义的函数,而该函数的位置在调用如果使用用户自己定义的函数,而该函数的位置在调用它的函数(即主调函数)的后面,应该在主调函数中它的函数(即主调函数)的后面,应该在主调函数中函数原型的一般形式为函数原型的一般形式为: : 声明的作用是把函数名、函数参数的个数和参数声明的作用是把函数名、函数参数的个数和参数类型等信息通知编译系统,以便在遇到函数调用时,类型等信息通知编译系统,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。编译系统能正确识别函数并检查调用是否合法。1.2.返回值是返回值是非非整型和字符型整型和字符型且函数定义在主调且函数定义

34、在主调 函数之后时,均须在主调函数里加说明。函数之后时,均须在主调函数里加说明。 格格 式:式: 或为:或为: float max( float a, float b );float max( float a, float b );或写为或写为: : float max( float, float ); float max( float, float );这便于编译系统进行检错,以防止可能出现的错误这便于编译系统进行检错,以防止可能出现的错误 声明的作用是把函数名、函数参数的个数和参数声明的作用是把函数名、函数参数的个数和参数类型等信息通知编译系统,以便在遇到函数调用时,类型等信息通知编译系统

35、,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。编译系统能正确识别函数并检查调用是否合法。(与函数定义不同(与函数定义不同)注意:注意: 函数的函数的“定义定义”和和“声明声明”的区别:的区别:l 是指对是指对函数功能的确立函数功能的确立,包括指定函数名,包括指定函数名,函数值类型、形参及其类型、函数体等,它是一个完函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。整的、独立的函数单位。l 的的作用则是把函数的名字、函数类型以及作用则是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便在调用形参的类型、个数和顺序通知编译系统,以便在调用该函数

36、时系统按此进行对照检查。该函数时系统按此进行对照检查。 void main() float a,b; int c; scanf(%f,%f,&a,&b); c=max(a,b); printf(Max is %dn,c);max(float x, float y) float z; z=xy?x:y; return(z);int型函数可不作函数说明型函数可不作函数说明例例 函数说明举例函数说明举例float add(float x, float y) float z; z=x+y; return(z);main() float a,b,c; scanf(%f,%f, &

37、a, &b); c=add(a, b); printf(sum is %f, c );被调函数出现在主调函数被调函数出现在主调函数之前,不必函数说明之前,不必函数说明void main( ) float add(float, float); /*function declaration*/ 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(); 在函数

38、外预先说明了各个函在函数外预先说明了各个函数的类型,则在以后的各主调数的类型,则在以后的各主调函数中,可不再对被调函数作函数中,可不再对被调函数作说明。说明。 例例8. 58. 5 对被调用的函数作声明对被调用的函数作声明# include void main() float a,b,c; scanf(f,f,a,b); cadd(a,b); printf(sum is f n,c);float add(float ,float ) *函数首部* float ; /* 函数体 */ z; return(z); 定义在后 例例8 8 对被调用的函数作声对被调用的函数作声明明# include f

39、loat add(float ,float ) *函数首部函数首部* float ; /* 函数体函数体 */ z; return(z);); void main()() float a,b,c; scanf(f,f,a,b);); cadd(a,b); printf(sum is f n,c);); 定义在前形式参数:函数名后面括号中的变量名称为“形式参数”(简称“形参形参”)。实际参数:主调函数中调用一个函数时,函数名后面括号中的参数(可以是一个表达式)称为“实际参数”(简称“实参实参”)。函数返回值:return后面的括号中的值作为函数带回的值(称函数返回值函数返回值)。 形式参数和实际

40、参数形式参数和实际参数 语言中不允许作嵌套的函数定义。因此各函数之间是平语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下一级函数的问题。但语言允许行的,不存在上一级函数和下一级函数的问题。但语言允许在一个函数的定义中出现对另一个函数的调用。这样就出现了在一个函数的定义中出现对另一个函数的调用。这样就出现了函数的嵌套调用函数的嵌套调用, , 即在被调函数中又调用其它函数。即在被调函数中又调用其它函数。例例 8. 用弦截法求方程用弦截法求方程 f(x)=x3-5x2+16x-80=0 f(x)=x3-5x2+16x-80=0 的根的根 取两个不同点x1, x2, 如果 f

41、(x1) 和 f(x2) 符号相反, 则(x1, x2) 区间内必有一个根。如果f(x1)与f(x2)同符号, 则应改变 x1, x2, 直到 f(x1)、f(x2) 异号为止。注意 x1、x2 的值不应差太大, 以保证(x1, x2) 区间内只有一个根。 连接( x1, f(x1) )和 (x2, f(x2) )两点, 此线(即弦)交x轴于x。 若 f(x)与 f(x1)同符号, 则根必在( x, x2 )区间内, 此时将 x 作为新的 x1。如果 f(x) 与 f(x2) 同符号, 则表示根在( x1, x )区间内, 将 x 作为新的 x2。 重复步骤 (2) 和 (3) , 直到 f(

42、x) 为止, 为一个很小的数, 例如 10-6。此时认为 f(x)0 。 取两个不同点取两个不同点x1, x2, 如果如果 f(x1) 和和 f(x2) 符号相反符号相反, 则则(x1, x2) 区间内必有一个根。如果区间内必有一个根。如果f(x1)与与f(x2)同符号同符号, 则应则应改变改变 x1, x2, 直到直到 f(x1)、f(x2) 异号为止。注意异号为止。注意 x1、x2 的的值不应差太大值不应差太大, 以保证以保证(x1, x2) 区间内只有一个根。区间内只有一个根。 连接连接( x1, f(x1) )和和 (x2, f(x2) )两点两点, 此线此线(即弦即弦)交交x轴于轴于

43、x。方法:方法: 若若 f(x)与与 f(x1)同符号同符号, 则根必在则根必在( x, x2 )区间内区间内, 此时此时将将 x 作为新的作为新的 x1。如果。如果 f(x) 与与 f(x2) 同符号同符号, 则表示根在则表示根在( x1, x )区间内区间内, 将将 x 作为新的作为新的 x2。 重复步骤重复步骤 (2) 和和 (3) , 直到直到 f(x) 为止为止, 为一个为一个很小的数很小的数, 例如例如 10-6。此时认为。此时认为 f(x)0 。N-S流程图流程图 实现各部分功能的几个函数实现各部分功能的几个函数: :用函数用函数 f(x) 代表代表 x 的函数的函数: x3-5

44、x2+16x-80。2. 用函数调用用函数调用 xpoint ( x1, x2) 来求来求 (x1, f(x1) )和和 ( x2, f(x2) )的连线与的连线与 x轴的交点轴的交点x 的坐标。的坐标。3. 用函数调用用函数调用 root ( x1, x2) 来求来求 (x1, x2) 区间的区间的 那个实根。显然那个实根。显然, 执行执行 root 函数过程中要用到函函数过程中要用到函 数数 xpoint, 而执行而执行 xpoint 函数过程中要用到函数过程中要用到 f 函数。函数。 include include float f(float x) float y;return(y);

45、/ * 定 义 函 数 , 以 实 现 f(x) x3-5x2+16x-80 * y=(x-5.0)*x+16.0)* x-80.0;float xpoint (float x1,float x2) *定义xpoint函数,求出弦与x轴交点 */ float y; y=( x1* f(x2)-x2*f(x1) ) (f(x2)- f(x1); return (y); float root(float x1,float x2) /* 定义root函数,求近似根 */ float x,y,y1; y1 f(x1); do while(fabs(y)0.0001); return( x) void

46、main( ) *主函数主函数 */ float x1,x2,f1,f2,x; do printf( ,:); scanf(,x1,x2); f1 f(x1); f2 f(x2); while(f1* f2); xroot( x1, x2 ); printf(“ root of equation is .n”,x );运行情况如下:input ,:, root of equation is 5.0000补例补例1 求三个数中求三个数中最大数最大数和和最小数最小数的的差值差值#include int dif( int x, int y, int z ); int max( int x, int

47、y, int z ); int min( int x, int y, int z);void main() int a,b,c,d; scanf(%d%d%d, &a,&b,&c); d=dif( a, b, c ); printf(Max-Min=%dn, d ); main( )调用函数调用函数dif输出输出结束结束dif函数函数max函数函数调用函数调用函数max调用函数调用函数minmin函数函数【补例补例2】编写函数】编写函数mysum,用以求,用以求 其中其中 f ( i ) = i +5 niif0)( return i+5; scanf(%d,&

48、n);printf(%d,%dn,n, mysum ( n );void main( ) int n ;int mysum ( int n ) int i , s = 0 ;for ( i=0; i=n ; i+ )s = s + myf(i);return s ;int myf(int i)int mysum ( int n ) ; int myf ( int i ) ;niif0)()(if for(i=0;i 1) 用用递归递归方法求方法求n! n!= = (n-1)! * * n按公式可编程如下:按公式可编程如下:if (n0)printf(“n1)【例【例8. 8】用递归法计算用递归

49、法计算n!【例【例8.7】有个人坐在一起,问第个人多少岁?他说有个人坐在一起,问第个人多少岁?他说比第个人大岁。问第个人岁数,他说比第个人比第个人大岁。问第个人岁数,他说比第个人大岁。问第个人,又说比第个人大岁。问第大岁。问第个人,又说比第个人大岁。问第个人,说比第个人大岁。最后问第个人,他说是个人,说比第个人大岁。最后问第个人,他说是岁。请问第个人多大。岁。请问第个人多大。 age(5)= age (4)+2age(4)= age (3)+2age(3)= age (2)+2age(2)= age (1)+2age(1)= 10用数学公式表述如下:age(n)= 10 ()age(n-1)+

50、2 ()有有5人,每人的年龄均是前一个人年龄人,每人的年龄均是前一个人年龄+2,问第五个人的年龄,问第五个人的年龄?第第5人人 第第4人人 第第3人人 第第2人人 第第1人人 (第(第5人年人年 龄是第龄是第 4人年龄人年龄+2, 第第4人人 年龄是第年龄是第3人年龄人年龄 +2, 依次类推。)依次类推。)( 第第1人年龄是人年龄是10则第二人年则第二人年龄是龄是12.) age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10 回推回推 递推递推归递公式:归递公式:age(n)=10 (n=1) age(n)=

51、 age(n-1)+2 (n1) (当第一个人年龄确定,其它人年龄可知)(当第一个人年龄确定,其它人年龄可知) int age(int n) void main( ) int c; int num; if (n= =1) c=10; scanf(“%d”, &num); else c=age(n-1) +2; printf(“age is %dn” , ); return ( c); age(4)+2 age(1)+2c=10age(5)=18 age(4)=16 age(1)=10输出输出age(5)main( ) 用一个主函数调用age函数,求得第5人的年龄。*求年龄的递归函数*运

52、行结果如下:运行结果如下: 18 【例【例8-9】Hanoi塔问题塔问题 一块板上有三根针,一块板上有三根针,A A,B B,C C。A A针上套有针上套有6464个大小不等个大小不等的圆盘,大的在下,小的在上。要把这的圆盘,大的在下,小的在上。要把这6464个圆盘从个圆盘从A A针移动针移动C C针上,每次只能移动一个圆盘,移动可以借助针上,每次只能移动一个圆盘,移动可以借助B B针进行。但针进行。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。求移动的步骤。上。求移动的步骤。ABC略略如果如果n=1n=1,则将圆盘从则将圆盘从A

53、 A直接移动到直接移动到C C。如果如果n=2n=2,则:则: 1.1.将将A A上的上的n-1(n-1(等于等于1)1)个圆盘移到个圆盘移到B B上;上; 2.2.再将再将A A上的一个圆盘移到上的一个圆盘移到C C上;上; 3.3.最后将最后将B B上的上的n-1(n-1(等于等于1)1)个圆盘移到个圆盘移到C C上。上。如果如果n=3n=3,则:则: A. A. 将将A A上的上的n-1(n-1(等于等于2 2,令其为,令其为n)n)个圆盘移到个圆盘移到B(B(借助于借助于C)C),步骤如下:步骤如下: (1)(1)将将A A上的上的n-1(n-1(等于等于1)1)个圆盘移到个圆盘移到C

54、 C上。上。 (2)(2)将将A A上的一个圆盘移到上的一个圆盘移到B B。 (3)(3)将将C C上的上的n-1(n-1(等于等于1)1)个圆盘移到个圆盘移到B B。 B. B. 将将A A上的一个圆盘移到上的一个圆盘移到C C。 C. C. 将将B B上的上的n-1(n-1(等于等于2 2,令其为,令其为n)n)个圆盘移到个圆盘移到C(C(借助借助A)A),步,步骤如下:骤如下: (1)(1)将将B B上的上的n-1(n-1(等于等于1)1)个圆盘移到个圆盘移到A A。 (2)(2)将将B B上的一个盘子移到上的一个盘子移到C C。 (3)(3)将将A A上的上的n-1(n-1(等于等于1

55、)1)个圆盘移到个圆盘移到C C。 到此,完成了三个圆盘的移动过程。到此,完成了三个圆盘的移动过程。略略 从上面分析可以看出,当从上面分析可以看出,当n n大于等于大于等于2 2时,移动的时,移动的过程可分解为三个步骤:过程可分解为三个步骤:第一步第一步 把把A A上的上的n-1n-1个圆盘移到个圆盘移到B B上;上;第二步第二步 把把A A上的一个圆盘移到上的一个圆盘移到C C上;上;第三步第三步 把把B B上的上的n-1n-1个圆盘移到个圆盘移到C C上;其中第一步和上;其中第一步和第三步是类同的。第三步是类同的。 当当n=3n=3时,第一步和第三步又分解为类同的三步,时,第一步和第三步又

56、分解为类同的三步,即把即把n-1n-1个圆盘从一个针移到另一个针上,这里的个圆盘从一个针移到另一个针上,这里的n=n-1n=n-1。 显然这是一个递归过程,据此算法可编程显然这是一个递归过程,据此算法可编程如下:如下:略略由上面的分析可知:将个盘子从座移到座可以分解为以下3个步骤: 1.1.将上个盘借助座先移到座上。将上个盘借助座先移到座上。2.2.把座上剩下的一个盘移到座上。把座上剩下的一个盘移到座上。3.3.将个盘从座借助于座移到座上。将个盘从座借助于座移到座上。ABC略略程序如下程序如下:#include void main() void hanoi( int n, char one,

57、char two, char three ); /* 对hanoi函数的声明 */ int m; printf( input the number of diskes:“ ); scanf( “%d”, &m); printf( The step to moveing %d diskes:n, m ); hanoi( m , A, B ,C ); 略略void hanoi(int n, char one, char two, char three) /*定义hanoi函数,将个盘从one座借助two座,移到three座 */ void move( char x, char y ); /

58、* 对move函数的声明 */ if(n=1) move( one ,three); else hanoi( n-1, one, three, two); move( one, three ); hanoi( n-1, two, one, three ); void move(char x,char y) /* 定义move函数 */ printf(“%c-%cn, x, y) ; 略略运行情况如下:运行情况如下:input the number of diskes:3 The steps to noving 3 diskes: 略略 数组可以作为函数的参数使用,进行数据传送。数数组可以作为函

59、数的参数使用,进行数据传送。数组用作函数参数有两种形式,组用作函数参数有两种形式,是把数组元素是把数组元素( (下标变下标变量量) )作为实参使用;作为实参使用;是把数组名作为函数的形参和是把数组名作为函数的形参和实参使用。实参使用。数数 数组元素就是下标变量,它与普通变量并无区别。数组元素就是下标变量,它与普通变量并无区别。因此它作为函数实参使用与普通变量是完全相同的,在发因此它作为函数实参使用与普通变量是完全相同的,在发生函数调用时,把作为实参的数组元素的值传送给形参,生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。实现单向的值传送。 711x:y:调用前:调用前:调用

60、结束:调用结束:711x:y:例例 交换两个数交换两个数void main() int x=7,y=11; printf(x=%d, y=%dn,x,y); printf(swapped:n); swap(x,y); printf(x=%d,ty=%dn,x,y);swap(int a,int b) int temp; temp=a; a=b; b=temp; printf(“a=%dtb=%dn,a,b);调用:调用:711a:b:711x:y:swap:711x:y:117a:b:temp普通变量作参数普通变量作参数例例 交换两个数交换两个数Void main() int x2=7, 11; printf(swapped:n); swap (x0, x1 ); printf(“x0=%d x1=%d , x0, x1);Void swap(int a,int b)int temp; temp=a; a=b; b=temp; printf(“a=

温馨提示

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

评论

0/150

提交评论