1 / 57

8 函数

8 函数. 8.1 C 程序模块. 一、 C 程序模块. 一个 C 程序可由一个 main( ) 函数和多个其它函数构成。.  其它函数指的是:.  系统函数 由系统提供,放在头文件中.  自编函数 由程序设计人员编写. main. funa. funb. func. fund. funx. funy. 二、函数的调用. 如:. P137.  所有的函数都 具有两种特征:.  返回值.  参数. ( 返回值和参数都是可缺省的 ). 8.2 库函数. 一、库函数简介.

grace
Download Presentation

8 函数

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 8 函数

  2. 8.1 C程序模块 一、C程序模块 一个C程序可由一个main( )函数和多个其它函数构成。

  3.  其它函数指的是: 系统函数由系统提供,放在头文件中 自编函数由程序设计人员编写

  4. main funa funb func fund funx funy 二、函数的调用 如: P137

  5.  所有的函数都 具有两种特征: 返回值 参数 (返回值和参数都是可缺省的)

  6. 8.2 库函数 一、库函数简介 系统自带的标标准库函数根据不同的功能作用放在不同的头文件中。

  7. 如:stdio.h用于标准输入/输出 math.h用于数学计算 ctype.h用于字符处理 string.h用于字串处理 time.h用于时间/日期的处理 dir.h用于控制目录和路径 graphics.h用于图形操作 dos.h 用于接口处理 bios.h 

  8. 二、库函数的作用  使程序更具有“ 独立性”和“ 可移植”性。  使用时只需在程序的开头加上一条语句: #include <.h> 根据使用的函数来确定  使程序具有“ 模块化”。

  9. 例1:求两个浮点型数值x/y的余数。 (注意:不能写成3.6%1.7) #include <stdio.h> #include <math.h> main( ) { float x, y, z; scanf("%f%f", &x, &y); z=fmod(x, y); printf(" z=%f", z); }

  10. 8.3 自定义函数 一、自定义函数的作用  使程序具有“ 积木”功能。(模块化)  使程序具有“ 重构”功能。

  11. 二、 函数的定义及调用 定义 [存储类型符] [返回值类型符] 函数名([形参表列]) 形参说明 { 说明部分 语句 }

  12.  调用  变量名=函数名([实参表列]); (变量名的类型必须与函数的返回值类型相同)  函数名([实参表列]);

  13. 三、函数声明 一般情况下,函数被调用之前必须要有函数声明。 (函数声明的意义在于提供函数原型) 函数声明的格式: [返回值类型符] 函数名(形参类型);

  14. 四、举例 例1:求二个数中的最大值 int max (x, y) int x, y; {int z; z=x>y? x:y; return (z); } 或:int max (int x, int y) {int z; z=x>y? x:y; return (z); } 用return语句,返回函数的值。

  15. 通过函数调用求二个数中的最大值: #include <stdio.h> int max (int, int); /*函数原型*/ main( ) { int a, b, t; scanf("%d%d", &a, &b); t=max(a, b); /*函数调用*/ printf("value of maximize is: t=%d",t); } int max(int x, int y) /*函数定义*/ { int z; z=x>y? x:y; return(z); }

  16. 例2:求二实数之和 #include <stdio.h>float add( );/*函数说明*/main ( ) { float a, b, c;scanf("%f, %f",&a, &b);c=add(a, b);/*函数调用*/ printf ("sum= %f";c); } float add( float x, float y); /*函数定义*/ { float z; z=x+y; return z; } 若函数的定义放在main( )函数之前可省略函数说明。

  17. 例3:求二实数之和(将例2程序改写如下:) #include <stdio.h>float add( float x, float y); /*函数定义*/ { float z; z=x+y; return z; } main ( ) { float a, b, c;scanf(“ %f, %f”,&a, &b);c=add(a, b); /*函数调用*/ printf ("sum= %f";c); }

  18. 单向 形参。 调用时:实参值 传递 五、自定义函数中的几个重要特征 1. 形参与实参 实参:出现在调用函数中, 形参: 出现被调用函数中。 函数被调用时,临时分配单元给形参,调用完毕, 这些单元被释放。

  19. 注: 实参可为表达式,只传递表达式的值。 实参、形参类型一致。 可在形参表列中对形参说明。

  20. 2. 函数返回  return; 函数无返回值  return 表达式的值; 或 return 变量的值; 通过return语句将流程返回主调函数。

  21. 3. 函数名 要选择一个简洁的有意义的名字作为函数名。 从函数名可以反映出函数的功能。 P139 例5.7,例5.8

  22. 8.4 数组作为函数的参数 一、数组元素作为函数的参数 由于数组元素的性质与相同类型的简单变量的性质完全相同,因此,把数组元素作为函数的参数也和简单变量一样。 使用方法:把数组元素作为函数的实参。 作用:传值。

  23. 例2:将数组元素作为函数的实参数 #include <stdio.h> #include <conio.h> main( ) { float b[3]; float ave; b[0]=21.3; b[1]=b[0]/3; b[2]=8.2; printf(" b[0]=%4.1f\t b[1]=%4.1f\t b[2]=%4.1f\n",b[0],b[1],b[2]); float Expfun1(float a,float b,float c); /*函数说明*/ ave=Expfun1(b[0],b[1],b[2]); /*函数调用*/ printf(" ave=%4.1f\n",ave); printf(" b[0]=%4.1f\t b[1]=%4.1f\t b[2]=%4.1f\n",b[0],b[1],b[2]);

  24. getch(); } float Expfun1(float a,float b,float c) /*函数定义*/ { float sum,aver; sum=a+b+c; a=a+5.5; b=b+5.5; c=c+5.5; aver=sum/3.0; printf(" a=%4.1f\t b=%4.1f\t c=%4.1f\n",a,b,c); return (aver); }

  25. 程序运行结果: b[0]=21.3 b[1]= 7.1 b[2]= 8.2 /*调用前*/ a=26.8 b=12.6 c=13.7 ave=12.2 b[0]=21.3 b[1]= 7.1 b[2]= 8.2 /*调用后值未变*/

  26. 1. 数组名的作用 数组名代表的是数组的起始地址; 也就是第1个元素的地址。

  27. 2. 把数组名作为函数参数的规则 使用数组名作为函数的参数时,形参和实参必须是同一类型的数组名,系统采用地址传送方式进行数据传递,即实参的首地址传递给形参的首地址,实参与形参共享相同的数据单元。 使用方法:函数的实参和形参都必须是数组名。 作用:传址。 (可以在函数中修改数组元素的值。)

  28. 例1:将数组名作为函数的形参和实参 #include <stdio.h> #include <conio.h> main( ) { float Expfun2(float a[4]); /*函数说明*/ float s[4]={88.5,90.5,70,71}; float ave; printf(" s[0]=%4.1f\t s[1]=%4.1f\t s[2]=%4.1f\t s[3]=%4.1f\n",s[0],s[1],s[2],s[3]); ave=Expfun2(s); /*函数调用*/ printf(" ave=%4.1f\n",ave); printf(" s[0]=%4.1f\t s[1]=%4.1f\t s[2]=%4.1f\t s[3]=%4.1f\n",s[0],s[1],s[2],s[3]); getch(); }

  29. float Expfun2(float a[4]) /*函数定义*/ { float sum,aver; sum=a[0]+a[1]+a[2]+a[3]; aver=sum/3.0; a[0]=a[0]/10; a[1]=a[1]/10; a[2]=a[2]/10; a[3]=a[3]/10; printf(" a[0]=%4.1f\t a[1]=%4.1f\t a[2]=%4.1f\t a[3]=%4.1f\n",a[0],a[1],a[2],a[3]); return (aver); }

  30. 程序运行结果: s[0]=88.5 s[1]=90.5 s[2]=70.0 s[3]=71.0/*调用前*/ a[0]= 8.9 a[1]= 9.1 a[2]= 7.0 a[3]= 7.1/*调用中*/ ave=106.7 s[0]= 8.9 s[1]= 9.1 s[2]= 7.0 s[3]= 7.1/*调用后值改变*/

  31. s[0] a[0] 88.5 s[1] a[1] 90.5 s[2] a[2] 70.0 s[3] a[3] 71.0  运行结果分析: 显然,数组s元素的值在调用前后生了变化,数组s和a共用一段内存单元: P43 例5.10, 例5.11,例5.12

  32. 三、多维数组名作为函数参数 • P148 例5.14

  33. 8.5嵌套调用 • P151 例5.16,例5.17,例5.18

  34. 8.6 递归调用 一、递归的特点 一个问题能够成为递归必须具备的条件是:  后一部分与原始问题类似  后一部分是原始问题的简化

  35. 二、程序中的递归方式 1. 直接递归调用:函数直接调用本身 2. 间接递归调用:函数间接调用本身

  36. 直接调用: int f(x) int x; { int y, z;  z=f (z);  } 间接调用: int f1 (x) int x; { int y, z;  z=f2 (y);  } int f2 (t) int t; { int a, b;  a=f1 (b);  } 以下表示了递归的概念.

  37. 1 (n=0, 1) n(n–1)! (n>1) n!= 显然:上述例子会无限递归 (无限执行)。所以, 在递归调用时都必须有条件限制。 当条件成立, 调用递归, 否则结束。 例1:求n! 1. 从数学上定义

  38. 2. 程序: #include <stdio.h> long fac(int n) /*函数定义, 计算n!*/ { long f;if (n<0) printf("input error!\n");elseif (n= = 0 ¦¦n= =1) f =1;else f =nfac(n –1); return (f); }

  39. main ( ) { int n; long y; printf("input a integer! ") scanf ("%d", &n); y=fac(n); /*函数调用, 计算n!*/ printf("%d!=%15ld", n, y); }

  40. 3. 执行过程: 设:输入 5 (n=5) 第1次调用:y=fac(5) —— 返回:y=5fac(4) 第2次调用:y=5*4fac(3) 第3次调用:y=5*4*3fac(2) 第4次调用:y=5*4*3*2fac(1) 第5次调用:y=5*4*3*2*1*fac(0) P173

  41. 8.7 标识符的作用域  标识符可以具有四种作用域。  函数作用域  文件作用域  块作用域  函数原型作用域 (作用域: 有效范围) 可根据标识符的作用域区分局部变量和全局变量。

  42. 一、局部变量 凡在函数(含main 函数)内部定义的变量称为局部变量。 局部性: 局部变量仅在函数内部有效。

  43. 1. 不同的函数可有同名同类型的变量,它们占不同的内存单元, 互不影响。 2. 形参为局部变量。 3. 在复合语句中可定义仅在复合语句中有效的临时变量。 P159 例5.21,例5.22

  44. 二、全局变量 一个源文件中, 在所有函数之外定义的变量为全局变量。 有效性:自定义位置开始至文件结尾全部有效。

  45. 例: int p=1, q=5; float f1(a) int a; {int b, c; } char c1, c2; p,q的作用范围 char f2(x,y) int x, y; { int i, j;} main ( ) { } c1, c2的作用范围

  46. 注意 1. 全局变量所作用到的函数,相当于这些函数的公共变量。当一个函数对其值进行改变后,另一个函数使用该变量的值亦相应改变。好处:函数之间值传递。 2. 不要随意使用全局变量。一是始终占据内存单元;二是由于函数依赖于外部定义的变量,减少了通用性。

  47. 3.不在作用域内函数。若使用全局(外部)变量,需在函数体内加上extern保留字。3.不在作用域内函数。若使用全局(外部)变量,需在函数体内加上extern保留字。 4.全局和局部变量同名时,局部变量有效。

  48. 例: float f1 (x) int x; {extern int a, b;  } int a=0; b= –1 main ( ) {  } a, b作用域 P162 例5.24 例8.15

  49. 8.8 变量的存储类型 一、标识符的属性 一个标识符的属性除了前面已讲过的基本属性外,还具有一些其它的属性:  存储类别  存储期

  50. 二、存储类别 1. 存储类型和存储期  自动型 (auto) 自动存储期  寄存器型(register)  外部型(extern) 静态存储期  静态型(static)

More Related