库函数函数的定义与返回值.ppt_第1页
库函数函数的定义与返回值.ppt_第2页
库函数函数的定义与返回值.ppt_第3页
库函数函数的定义与返回值.ppt_第4页
库函数函数的定义与返回值.ppt_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

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

文档简介

1、第七章函数,库函数、 函数的定义与返回值 函数的调用、 函数的说明 调用函数和被调用函数间的数据传递 函数的递归调用、 程序举例,第七章 函数,在解决一个比较复杂的实际问题时,不可能把所有要完成的任务全都写在main函数中。这时,程序往往由一个main函数和若干个其它函数组成,每个函数各自完成相对独立的部分功能。,在前面的章节中,我们编写的程序都是由一个main函数来组成,在main函数中调用过scanf、printf等系统函数。,模块化的程序设计方法,函数间相互调用的示意,main() f1() f11() f1(); f11(); f12() f2(); f12(); f2() f21()

2、 f21(); ,函数的分类,从函数形式 无参函数 有参函数?我们学习过哪些无参函数和有参函数?,从用户角度 标准函数(库函数):由系统提供 用户自定义函数,库函数由系统提供,用户只要按照要求的格式正确调用即可。不同的C编译系统提供的库函数有些不同。,7.1 库函数,使用库函数应注意的问题: 1、调用库函数时要用include命令将相关的头文件包含进来。 如:调用数学函数,用include math.h | 调用输入输出函数,用include stdio.h | 调用字符函数,用include ctype.h | 2、库函数调用的一般形式: 函数名(参数表) 要注意函数的功能、参数的个数与类型

3、、函数值的类型。 如:求平方根的函数sqrt的形式是:double sqrt (double x),3、库函数调用以两种方式出现。 其一:出现在表达式中,即作为表达式的一部分参与运算。 如:计算y=x2.5+1.3,则通过以下语句调用来实现。 y=pow(x,2.5)+1.3; 其二:独立的语句,即调用函数后加一分号。 如:printf(*n); 4、调用库函数时,要注意参数的一些特殊要求。如三角函数要求自变量参数用弧度表示,开平方函数要求自变量参数的值大于或等于0。,使用库函数应注意的问题(续),函数返回值的类型 缺省int型 无返回值: void,函数体,函数类型 函数名(形参类型说明表)

4、 说明部分 执行部分 ,7.2 函数的定义和返回值,1. 函数定义的一般格式,现代风格:,多个形参说明之间要用逗号隔开,没有形参时,这一对括号不能省略,合法标识符,如果函数的类型不是void,函数体最后要用return语句去返回一个值,例1 有参函数(现代风格) int max(int x,int y) int z; z = xy?x:y; return(z); ,例3 无参函数 void printstar( ) printf(*n); 或 void printstar(void ) printf(*n); ,函数的定义示例,例4 空函数 void dummy(void) ,函数体为空 (留

5、待以后补充),int max2(int x , int y) /*现代风格*/ int max; if(xy) max = x; else max = y; printf(max(max2)=%dn,max); return(max); void main() int a,b,max; scanf(%d,%d, ,例 函数的定义,形参和函数体中定义的变量只在函数被调用时才临时分配存储单元,当退出函数时,这些存储单元全部被释放(称为局部性,因而与其它函数中的变量同名不会引起混淆)。,main()时,main函数是什么类型的?,可改写为max=xy?x:y;,形参,实参,函数与函数之间是平等的,v

6、oid main() int max2(int x , int y) int z; if(xy) z=x; else z=y; return(z); int a,b,max; scanf(%d,%d, ,函数的定义是平行的,不能在一个函数的内部再定义其它函数。即每个函数都是一个相对独立的模块,不能在写某一个函数时又包含了另一个函数的定义(main函数的执行时有一点点小的特权!)。,返回语句 形式return(表达式);或 return 表达式; 或 return; 功能:使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数 说明: 函数中可以有多个return语句,但只有其中的一个r

7、eturn语句能够得到执行 若函数中没有return语句,或者是一个不带表达式的return语句,则该函数结束时自动返回调用函数一个不确定的值 若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换-函数调用转换 void型函数:明确说明函数没有返回值,2. 函数的返回值,int max(float x, float y) float z; z=xy?x:y; return(z); main() float a,b; scanf(%f,%f, ,例 函数返回值类型转换,main() int a,b,max; scanf(%d,%d, ,例 函数可以有多个return语句,注意

8、:在C语言中,函数名不能被赋值,只能通过return语句返回一个值。,int max2(int x,int y) max2= xy?x:y ; ,printstar() printf(*n); main() int a; a = printstar(); printf(a=%dn,a); ,输出:a=10,例 函数带回不确定值,printstar()是什么类型?,void型函数:明确说明函数没有返回值,#include /*void*/ printstar() printf(*#*n); main() int a; a=printstar(); a=printstar(); printf(a=

9、%dn,a); ,void printstar() printf(*n); main() int a; a = printstar(); printf(a=%d,a); ,编译错误!,(VC+)error C2120: void illegal with all types,说明: (1) 调用函数时,其名字必须与定义的名字相同。 (2) 函数调用时的实参只写名字不需要在名字前再带实参类型。 如上面main函数中对max2函数的调用不能写成: max = max2(int a,int b);, 7.3 函数的调用1. 函数调用的一般形式: 函数名(实参表);,说明: (3) 实参与形参,个数应

10、一致。若实参少,则必有形参未得到值(不确定值),影响结果。若实参多,则多余的无效(TC)。 如:c=max2(3); 则c的值为:761(随机值) 若:c=max2(3,5,8); 则c的值为: 5 (4) 实参与形参的类型应一一对应相匹配。若不匹配,程序仍能运行,但得不出正确结果(TC)。 如:c=max(3.0,5.0); 则c的值为: 0 若:c=max(3L,5L); 则c的值为: 3,函数调用说明(续),(5) 函数必须先定义,后调用。 将要被调用的函数定义在前,调用在后。返回值类型为int或char的函数可例外。 (6) 函数可直接或间接地自己调用自己(递归调用,在7.6节介绍),

11、函数调用说明(续),(7) 实参表求值顺序,因系统而定(Turbo C 自右向左),#include stdio.h void main() int p=2; printf(%d,%d,%dn,p,+p,p); /*TC: 3,3,2 VC: 3,3,2*/,#include stdio.h void main() int p=2; printf(%d,%d,%dn,p,p+,p); /*TC: 3,2,2 VC: 2,2,2*/,2. 函数调用的方式,1. 函数表达式: 例 m=max(a,b)*2; 2. 函数语句: 例 printstar(); printf(Hello,World!n

12、); 3. 函数参数: 例 printf(%d ,max(a,b); m=max(a,max(b,c);, 7.4 函数的说明,在C语言中,除了主函数外,对于用户定义的函数要遵循“先定义,后使用”的规则。凡是未在调用之前定义的函数,C编译程序默认函数的返回值为int类型。对于返回值为其它类型的函数,若把函数的定义放在调用之后,应该在调用之前对函数进行说明(或称为函数原型说明)。,C语言对被调用函数要求: 必须是已存在的函数 库函数: #include 用户自定义函数: 函数类型说明,1. 函数说明一般形式,函数说明语句 作用:告诉编译系统max2函数是float类型的、有2个float类型的参

13、数。,可选,在VC中不允许,说明,(1)函数说明可以是一个独立的语句;如上面例子中就是采用独立语句的形式。 (2)函数说明中的形参名是一种虚设,它们可以是任意的用户标识符,既不必与函数首部中的形参名一致,又可以与程序中的任意用户标识符同名。因此,参数名也可以省略。 如上面的例子中函数说明可写成: float max2(float,float);,(3)注意函数定义与函数说明是不同的,定义是写出函数的完整形式,而说明是告诉系统此函数的返回值类型、参数的个数与类型,便于编译时进行有效的类型检查。,(4)若函数的返回值类型为int或char,则可以不进行函数说明(系统默认)。但是使用这种方法时,系统

14、无法对参数的类型做检查。若调用函数时参数使用不当,在编译时也不会报错。因此,为了程序清晰和安全,建议都进行说明为好。,(5)若被调函数的定义出现在主调函数之前,也可以不进行函数说明。 (6)有些系统(如Borland C+、VC+等)要求一定要用函数说明指出函数类型和形参类型,并且对void和int型函数也要进行函数说明。,例 函数说明举例,2.函数说明的位置,(1)放在调用函数的说明部分(只有此调用函数能识别被调用函数)。可以是独立语句,也可与其它变量的定义放在同一个语句中。 如上面的用法也可以如下形式的语句: float a,b,c,max2(float,float); (2) 放在所有函

15、数的外部,被调用之前。(此时函数说明的后面所有位置上都可对该函数进行调用)。,float max2(float,float); main() float a,b,c; scanf(“%f%f”, float max2(float x,float y) ,函数说明放在所有函数的外部,例 函数说明举例,(3)调用库函数时,要在程序的开头使用 命令:#include 来包含相关的头文件,就是因为头文件中包含了这些库函数的原型说明。,形参与实参的概念 形式参数:定义函数时函数名后面括号中的变量名 实际参数:调用函数时函数名后面括号中的表达式,7.5 调用函数和被调用函数之间的数据传递,形参:x,y 形

16、参必须指定类型;,实参:a,b 实参: a+5,100,(1) 实参表达式也可以是变量或常量,但必须有确定的值; (2) 要求形参与实参类型一致,个数相同(多:略/少:随机值); (4) 形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放; (5) C语言的参数传递方式 值传递方式:函数调用时,系统临时为被调函数的形参分配存贮单元,并将实参的值复制到形参中;当被调函数结束时,形参单元被释放,实参单元仍保留并维持原值。 特点:单向的值传递(数值或地址值)。,有关参数传递的几点说明,x,1.2,1.2,1.728,1.变量作为参数(单向的数值传递),Cube kju:b n.

17、立方体, 立方,main() void swap(int , int); int x=10,y=20; printf(“(1)x=%d y=%dn”,x,y); swap(x,y); printf(“(4)x=%d y=%dn”,x,y); void swap(int a, int b) int t; printf(“(2)a=%d b=%dn”,a,b); t=a; a=b; b=t; printf(“(3)a=%d b=%dn”,a,b); ,例7.1 函数参数之间的单向传递,程序运行结果为: (1)x=10 y=20 (2)a=10 b=20 (3)a=20 b=10 (4)x=10 y

18、=20,main( ) void ex(int z,int y,int x); int x=10,y=20,z=30; printf(“(1)x=%d y=%d z=%dn”,x,y,z); ex(y,z,x); void ex(int x,int y,int z) printf(“(2)x=%d y=%d z=%dn”,x,y,z); ,例7.2 实参向形参按位置传递数据,程序运行结果为: (1)x=10 y=20 z=30 (2)x=20 y=30 z=10,函数说明语句 形参名是一种虚设,函数调用语句确定实参顺序,函数定义 确定形参顺序,实参向形参按位置传递数据,补充例题,当数组名作为函

19、数参数时,要求实参和形参都用数组名(或指针变量,第十章作介绍)。 由于数组名的值就是数组在内存中分配的存储空间的首地址,这种方法称之为“传址调用”方式。 当把实参数组名的值(首地址)传给形参数组名后,由于形参数组名也代表首地址,这样实参数组和形参数组的首地址相同,即实参数组和形参数组占用相同的存储空间。在被调函数中,形参数组中各元素的值如果发生变化,就会使实参数组元素的值同时也发生变化。在函数调用结束后,虽然形参数组已不复存在,但实参数组元素的值已发生变化,可以在主调函数中进行使用。,2.数组名作为参数,(单向的地址值传递),例7.3 选择法排序,对N个数排序的算法步骤如下: (1)在N个数中

20、寻找最小值,然后把这个最小值与最前面的那个数交换位置。,(2)排除最前面的那个数(i=i+1),在余下的N-1个数中寻找最小值,然后把这个最小值与最前面的那个数交换位置。 如此循环,直到最后只剩一个数(i=N-1)时结束。,对10个数排序的算法步骤演示如下:,下标: 0 1 2 3 4 5 6 7 8 9,对10个数排序的算法步骤演示如下:,下标: 0 1 2 3 4 5 6 7 8 9,总结:10个数排序,需要进行九次的上述操作。 若有N个数需要排序,则需要进行N-1次的上述操作。,10个数排序的完整程序如下:,void sort(int a10) int i,j,k,t; for(i=0;

21、i9;i+) k=i; for(j=i+1;j10;j+) if(ajak) k=j; t=ak; ak=ai; ai=t; ,main() int i,x10=5,7,4,2,8,6,1,9,0,3; printf(the original array:n); for(i=0;i10;i+) printf(%d,ai); printf(n); sort(x); printf(the sorted array:n); for(i=0;i10;i+) printf(%d,ai); printf(n); ,程序运行结果为: the original array: 5 7 4 2 8 6 1 9 0

22、 3 the sorted array: 0 1 2 3 4 5 6 7 8 9,例7.4 将一个数组中的n个数据按颠倒的顺序重新存放,解题思路为:借助于一个临时变量,将a0与an-1对换,再将a1与an-2对换,直到将a(n-1)/2-1与an-int(n-1)/2)-1对换。 程序采用循环来实现,设二个“位置指针变量”i和j,i的初值为0,j的初值为n-1,将ai与aj交换,然后使i的值加1,j的值减1,再将ai与aj交换,直到i=m为止。m=(n-1)/2为“中间位置”。见图7.2所示。,i=0,j=n-1,i=1,j=n-2,m=(n-1)/2,数组逆序程序,void inv(int

23、x ,int n) int t,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; t=xi; xi=xj; xj=t; ,main() int i,a10=10,20,90,100; printf(The original array:n); for(i=0;i10;i+) printf(%d ,ai); printf(n); inv(a,10); printf(The array has been inverted:n); for(i=0;i10;i+) printf(%d ,ai); printf(n ); ,程序运行结果为: The original arr

24、ay: 10 20 30 40 50 60 70 80 90 100 The array has been inverted: 100 90 80 70 60 50 40 30 20 10,void inv(int x ,int n) int t,i,j=n-1; for(i=0;ij;i+,j-) t=xi; xi=xj; xj=t; ,例7.5 求二维数组每行元素的平均值,void lineave(int x 4,float y ,int n) int i,j,s; for(i=0;in;i+) s=0; for(j=0;j4;j+) s=s+xij; yi=s/4.0;/*书印错: bi

25、=s/4.0*/ ,main() int a34=1,2,3,4,5,6,7,8,9,10,11,12; int i,j; float b3; lineave(a,b,3); for(i=0;i3;i+) for(j=0;j4;j+) printf(“%4d”,aij); printf(“ ave:%6.2dn”,bi); ,程序运行结果为: 1 2 3 4 ave: 2.50 5 6 7 8 ave: 6.50 9 10 11 12 ave: 10.50,1. 嵌套调用 C规定:函数定义不可嵌套,但可以嵌套调用函数,7.6 函数的嵌套与递归调用,#include int dif(int x,

26、int y,int z); int max(int x,int y,int z); int min(int x,int y,int z); void main() int a,b,c,d; scanf(%d%d%d, ,int dif(int x,int y,int z) return max(x,y,z)-min(x,y,z); int max(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); int min(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); ,例 求三个数中最大数和最

27、小数的差值,例 用弦截法求方程根,运行情况: Input x1,x2: 2,6 A root of equation is 5.0000,函数的嵌套举例,2.递归调用 定义:函数直接或间接的调用自身叫函数的递归调用,说明 C编译系统对递归函数的自调用次数没有限制 每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出,int f(int x) int y,z; z=f(y); . return(2*z); ,#include int fac(int n) int f; if(n=0|n=1) f=1; else f= fac(n-1)*n; r

28、eturn(f ); main() int n, y; printf(Input a integer number:); scanf(%d, ,int fac(int n) /*更完善的阶乘函数*/ int f; if(n0) printf(n0,data error!); return(-1); if(n=0|n=1) f=1; else f= fac(n-1)*n; return(f ); ,递归方法的要点: 1.递推公式 f n = f n-1*n 2.结束条件。 n=0|n=1,例7.6用递归的方法求n的阶乘,#include int fib(int n) int f; if(n=1|

29、n=2) f=1; else f= fib(n-2)+fib(n-1); return(f ); main() int n, s; printf(Input a integer number:); scanf(%d, ,递归方法的要点: 1.递推公式 f n = f n-2+ f n-1 2.结束条件。 n=1|n=2,例7.7 用递归实现斐波那契数列,#include math.h int isprime(int); main() int x; scanf(%d, ,编写函数isprime(int n)用来判断自变量n是否为素数,若是,函数返回1,否则返回0。,isprime(int n)

30、int i, flag=1; for(i=2;i=sqrt(n);i+) if(n%i=0) flag=0;break; return (flag); ,isprime(int n) int i, flag=1; for(i=2;i=sqrt(n) ,7.7 函数程序举例例7.8,#include math.h int isprime(int); void even(int); main() int a; printf(Enter a even number:); scanf(%d, isprime(int n) ,例7.9 编写函数,验证任意偶数为两个素数之和并输出这两个素数。,程序运行结果

31、为: Enter a even number:10 10=3+7,例7.10 利用梯形法求定积分,利用梯形法求定积分,double integ(double a,double b) double s,x,h,f(double); int n=100,i; h=fabs(b-a)/n; s=(f(a)+f(b)/2.0; for(i=1;i=n-1;i+) x=a+i*h; s=s+f(x); ruturn s; double f(double x) return sin(x); ,#include math.h double integ(double a,double b); main() d

32、ouble s; s=integ(0.0,10.0); printf(s=%fn,s); ,程序运行结果为: s=1.837539,例7.11 编写函数统计输入的一行字符中出现的每个小写字母的个数。,#include stdio.h #include string.h void countch(char c,int b); void main() char c,ch81; int b26=0; gets(ch); countch(ch,b); for(c=a;c=z;c+) printf(%c:%d,c,bc-97); if(c-97+1)%10=0)printf(n); ,void countch(char c,int b) int k,l; l=strlen(c); for(k=0;k=a ,程序运行结果为: this is a statistics program! a:3 b:0 c:1 d:

温馨提示

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

评论

0/150

提交评论