【课程ppt】C语言程序设计 第6章 函数程序设计_第1页
【课程ppt】C语言程序设计 第6章 函数程序设计_第2页
【课程ppt】C语言程序设计 第6章 函数程序设计_第3页
【课程ppt】C语言程序设计 第6章 函数程序设计_第4页
【课程ppt】C语言程序设计 第6章 函数程序设计_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

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

文档简介

1、C语言程序设计第6章 函数程序设计 第6章 数组程序设计6.1 函数概述 6.2 自定义函数示例6.3 函数定义及调用 6.4 函数嵌套和递归函数6.5 数组作为函数的参数6.6 函数应用举例6.1 函数概述C语言程序的特点:函数化结构函数分类:系统函数、用户函数系统函数:printf()、scanf()、sqrt()等用户函数:在程序中编写的函数,又称自定义函数。用户函数的特例:main()函数如果在程序中经常需要某种处理,就可以编写一个函数,在需要这种处理时,就调用该函数。示例计算a!+b!+c! 6.2 自定义函数示例例6-1编程计算表达式a!+b!+c!的值。 程序结构只有main()

2、函数的阶乘程序#includevoid main()int a,b,c,i;long t,sum;printf(Input a,b,c:);scanf(%d,%d,%d,&a,&b,&c);for(t=1,i=1;i=a;i+)t=t*i;sum=t;for(t=1,i=1;i=b;i+)t=t*i;sum+=t;for(t=1,i=1;i=c;i+)t=t*i;sum+=t;printf(SUM=%ldn,sum);使用自定义函数的阶乘程序#include void main()long f(int n);int a,b,c,i;printf(Input a,b,c:);scanf(%d,%

3、d,%d,&a,&b,&c);printf(SUM=%ldn,f(a)+f(b)+f(c);long f(int n) /* 计算阶乘的函数 */long t;int i;for(t=1,i=1;i=n;i+)t*=i;return(t);求n!函数调用函数f()求c!6.3 函数的定义及调用6.3.1 函数的定义6.3.2 函数值和return命令6.3.3 函数调用6.3.1函数定义 函数定义的一般格式函数类型 函数名(形式参数表) 函数体 形式参数表的格式 数据类型变量1,数据类型变量2,数据类型 变量n函数的值的类型例6-2 定义连续输出50个*字符的函数。void p_star50(

4、void) int i; for(i=1;i=50;i+) putchar(*);6.3.1函数定义无形参有形参例6-3 定义连续输出n个*字符的函数。void p_star(int n) int i; for(i=1;iy?x:y;return(m);float max(float x,float y)if(xy)return x;elsereturn y; 6.3.2 函数值和return命令例6-5int sum(int n)int s,i;for(s=0,i=1;i=n;i+)s+=i;return(s);6.3.3 函数调用 1函数原型和函数声明 函数原型函数原型是是定义函数时函数体

5、以外的那些内容。一般形式:函数类型 函数名(数据类型1形参1,类型2形参2,类型n 形参n)简化形式:函数类型 函数名(数据类型1,数据类型2,数据类型n) 函数声明函数声明是在主调函数的函数体说明部分描述被调函数原型。函数调用函数调用是对已定义函数的具体应用。一般形式: 函数名(实参表)6.3.3 函数调用/* program e6-6.c */#includevoid main()void p_star50(void); int k;for(k=1;k=20;k+)p_star50(); putchar(n);例6-6 调用p_star50()函数,连续输出20行*字符串,每行50个*字符

6、。void p_star50(void) int i;for(i=1;i=50;i+)putchar(*);return;函数原型及函数声明函数调用6.3.3 函数调用/* program e6-7.c */#includevoid main()void p_star(int n); int k;for(k=1;k=5;k+)p_star(k); putchar(n);例6-7 调用p_star()函数,输出*字符图案。*void p_star(int n)int i;for(i=1;i=n;i+)putchar(*);return;函数原型及函数声明函数调用函数定义函数实参函数形参6.3.3

7、 函数调用例6-8 调用求和函数sum(),计算表达式/* program e6-8.c */#includevoid main()int sum(int); printf(%dn,sum(20)+sum(50); int sum(int n)int s,i;for(s=0,i=1;i=n;i+)s+=i;return(s);6.3.3 函数调用函数调用的三种形式 当被调用函数为void类型时,函数无返回值,函数调用是一个独立的语句。 当被调用函数有返回值时,函数调用出现在表达式中,是表达式的一部分。 函数调用也可以作为一个函数的实参。例6-9 利用求两个数的最大数函数max(),求得三个数的

8、最大数。#includevoid main()float max(float,float); float a,b,c;printf(a,b,c: );scanf(%f,%f,%f,&a,&b,&c);printf(Max=%fn,max(max(a,b),c); float max(float x,float y)float m;m=xy?x:y;return(m);函数调用作为函数的实参6.3.3 函数调用注意函数调用时,实参和形参按照在参数表中的位置对应传值。例6-10 编写输出n个连续的任意字符的函数p_string(),并调用该函数输出一个5行的“*”三角形图案 #include vo

9、id main()void p_string(int,char); int k;for(k=1;k=5;k+)p_string(k,*); putchar(n);void p_string(int n,char ch)int i;for(i=1;i=n;i+)putchar(ch);return; 按位置对应 传送6.4 函数嵌套和递归函数6. 4. 1 函数嵌套6. 4. 2 递归函数6. 4. 1 函数嵌套函数嵌套是指在一个用户函数的函数体中,又出现了另外用户函数的调用。如函数a调用函数b,函数b又调用函数c等。 #includevoid main()long fac(int); long

10、 cmn(int,int); int m,n;printf(m,n=);scanf(%d,%d,&m,&n);printf(C(%d,%d)=%ldn,m,n,cmn(m,n); long fac(int k) /* 定义求k!的函数 */int i;long t;for(i=1,t=1;i1时,其值为sum(n-1)+n。由此,定义递归函数:long sum(int n)if(n=1)return(1);else return(sum(n-1)+n); 6. 4. 2 递归函数计算sum(3)的处理过程 高到低进行递推描述。 调用sum(3),将其描述为sum(2)+3; 调用sum(2),

11、将其描述为sum(1)+2; 调用sum(1),问题已到最低层,有确定值:sum(1)=1; 由低到高逐级求得上层结果。 由sum(1)+2求得sum(2); 由sum(2)+3求得sum(3);完整程序代码#includevoid main()long sum(int);int n;printf(n=);scanf(%d,&n);printf(Sum=%dn,sum(n);long sum(int n)if(n=1)return(1);else return(sum(n-1)+n);6. 4. 2 递归函数2非公式递归问题有的问题不能直接用一个递归公式进行描述,但可以用递归方法进行描述,我们

12、将其归类为非公式递归问题。例6-14 汉诺塔问题。有三个柱和n个大小各不相同的盘子,开始时,所有盘子以塔状叠放在柱A上,要求按一定规则,将柱A上的所有盘子移动到柱B上,柱C为移动缓冲住。移动规则: 一次只能移动一个盘子。 任何时候不能把盘子放在比它小的盘子的上面。C语言程序设计(第3版)张磊编著 清华大学出版社6. 4. 2 递归函数汉诺塔问题递归实现过程若只有一个盘子,则直接从 A 移到 B,问题结束;若有n(n1)个盘子,则须经过如下三个步骤:第一步:按照移动规则,把A上面的 n-1 个盘子,移到C。第二步:将A上仅有的一只盘子(也就是最大的一只)直接移到柱B上。第三步:用第一步所述方法,

13、将C柱上的n-1个盘子移到B柱上。与第一步一样,这一步实际上是由一系列更小的一次仅移一个盘子的操作组成。BA汉诺塔问题的递归算法:hanoi(n个盘,AB,缓柱C) if (n=1) 直接从A移到B else hanoi(n-1个盘,AC,缓柱B) 移动n号盘子:AB hanoi(n-1个盘,CB,缓柱A) #include void main() int disks; void hanoi(int,char,char,char); printf(Number of disks: ); scanf(%d,&disks); printf(n); hanoi(disks,A,B,C);void h

14、anoi(int n,char A,char B,char C) if (n=1) printf(%c - %c ,A,B); return; elsehanoi(n-1,A,C,B);printf(%c - %c ,A,B);hanoi(n-1,C,B,A);BA6.5 数组作为函数的参数 6.5.1 数组元素作为函数参数6.5.2 一维数组名作为函数参数6.5.3 用一维数组求解二维数组问题数组作为函数参数的目的,是为了实现数组数据在函数间的传送。6.5.1 数组元素作为函数参数数组元素作为函数的参数时,只传送作为实参的数组元素,此时按使用其他简单变量的方法使用数组元素。例6-15 把一个

15、整型数组的所有素数找出来。求解问题的思路 设计判断素数的函数prime(),函数原型: int prime(int k) 当k为素数时,函数值为1;否则,函数值为0。 在主函数main()中建立一个自然数数组natural,然后用它的每一个数组元素调用prime()函数求素数。int prime(int k) int sk,i;int flag=1; sk=sqrt(k);for(i=2;i=sk;i+)if(k%i=0)flag=0; break;return(flag); #define N 10#include#includevoid main()int prime(int);int i

16、,naturalN;printf(Data: );for(i=0;iN;i+) scanf(%d,&naturali);for(i=0;iN;i+)if( prime(naturali ) printf(%d ,naturali);printf(n);数组元素作函数参数6.5.2 一维数组名作为函数参数数组名的实质就是数组的首地址。数组名作为函数参数时传送的是数组的开始地址,是一种传址调用。形参数组和实参数组要在各自的函数中进行等同的定义。例6-16 定义求一维数组最大元素值的函数v_max(),并在主函数中调用它求数组元素的最大值。6.5.2 一维数组名作为函数参数/* program e6

17、-16.c */#include#define N 10void main()int v_max(int aN); int dataN,i;printf(Data: );for(i=0;iN;i+)scanf(%d,&datai);printf(Max=%dn,v_max(data);int v_max(int aN)int i;int max=a0;for(i=1;iN;i+)if(maxai)max=ai;return(max);v_max()函数调用开始时的数组状态 6.5.2 一维数组名作为函数参数/* program e6-16-1.c */#include#define N 10v

18、oid main() void input(int,int ); int v_max(int,int ); int data50; printf(Data: ); input(N,data); printf(Max=%dn,v_max(N,data);int v_max(int n,int a) int i; int max=a0; for(i=1;in;i+) if(maxai) max=ai; return(max);void input(int n,int a) int i; for(i=0;in;i+) scanf(%d,&ai);程序改进,注意数组参数的变化6.5.3 用一维数组求解

19、二维数组问题二维数组在内存中按行逐列存储,各个数组元素依次占用连续的存储单元,存储后的状态与一维数组是没有区别的。因此,可以用一个对应的一维数组来处理二维数组。以22数组example为例说明二维数组与一维数组的关系 二维数组example可视为由example0和example1两个元素构成的一维数组, example0是example第0行的一维数组,example1是example第1行的一维数组。数组example的首地址可用example0表示。 若把一维数组p映射到mn的二维数组example的存储空间,则二维数组元素和一维数组元素有如下对应关系:exampleij对应于pi*n+

20、jexample0 example00p0example01p1example1 example10p2example11p36.5.3 用一维数组求解二维数组问题例6-17 求下列34矩阵的所有元素的和。/* program e6-17.c */#includevoid main() int sum_array(int,int,int );int arr34=16,27,8,-6,-17,21,5,19,66,9,58,86;printf(Sum=%dn,sum_array(3,4,arr0);int sum_array(int m,int n,int a)int i,s=0;for(i=0

21、;im*n;i+)s+=ai;return(s);6.6 函数应用举例6.6.1计算长方体的面积6.6.2利用递归函数计算Fibonacci数列6.6.3排序函数的设计与应用6.6.1计算长方体的面积例6-18 设计一个计算矩形面积的函数,并调用该函数计算长方体的面积。问题分析 设矩形面积函数为area(),原型:float area(foat,float) 设长方体的长、宽、高分别为a、b、c,面积为s: s= 2(area(a,b)+area(b,c)+area(a,c) 设计主函数main(),在其中输入a、b、c,然后调用area()计算长方体面积,并输出结果。#includevoid

22、 main()float area(float,float);float a,b,c,s;printf(a,b,c: );scanf(%f,%f,%f,&a,&b,&c);s=(area(a,b)+area(b,c)+area(a,c)*2;printf(S=%fn,s);float area(float x,float y)return(x*y);6.6.2 利用递归函数计算Fibonacci数列 例6-19 计算Fibonacci数列的第n个数。问题分析与算法设计 描述计算Fibonacci数的递归公式 根据fib(n)的递归公式,设计递归函数 long fib(int n) 在主函数ma

23、in()中输入数据n,然后调用fib()函数求得第n个Fibonacci数,并输出结果。/* program e6-19.c */#includevoid main()long fib(int); int n;printf(n=);scanf(%d,&n);printf(Fibonacci(%d): %ldn,n,fib(n); long fib(int n) i f(n=1|n=2) return(1); else return(fib(n-1)+fib(n-2);6.6.3排序函数的设计与应用例6-20 设计一个对一维数组排序的sort()函数,并调用它实现数组排序。问题分析与算法设计 设

24、计排序函数sort(),排序算法使用冒泡排序法。 sort()函数原型 void sort(int,int ) 设计input()实现数组输入、设计output()实现数组输出。函数原型: void input(int,int ) void output(int ,int ) 设计主函数mian(),在其中定义数组data。 调用input()函数建立data数组。 调用output()函数输出data数组。 调用sort()函数对data数组排序。 调用output()函数输出排序后的结果。实现程序对应参加排序的元素数对应排序的数组名/* program e6-20.c */#include

25、#define N 10void main()void sort(int,int ); void input(int,int ); void output(int,int );int i,dataN;input(N,data); output(N,data); sort(N,data); output(N,data); void input(int n,int a)int i;for(i=0;in;i+)scanf(%d,&ai);void output(int n,int a)int i;for(i=0;in;i+) printf(%d ,ai);printf(n);void sort(in

26、t n,int a)int i,j,temp;for(i=1;in;i+) for(j=0;jaj+1) temp=aj;aj=aj+1;aj+1=temp; 6.7 变量的作用域和存储类型 6.7.1变量的作用域 6.7.2变量的存储类型 6.7.1 变量的作用域1局部变量在函数体内定义的变量称为局部变量,也称为内部变量。局部变量只能在定义它的函数中使用。例 6-21 局部变量举例#includevoid main()void p_star50(void); int i;for(i=1;i=20;i+)p_star50(); putchar(n);void p_star50(void)int

27、 i;for(i=1;i=50;i+)putchar(*);return;6.7.1 变量的作用域2.全局变量全局变量是在函数之外定义的变量。在任何一个函数之外的位置,都可以定义全局变量。在一个程序中,凡是在全局变量之后定义的函数,都可以使用在其之前定义的全局变量。因此,一个全局变量,可以被多个函数使用, 但并不一定能被所在程序中的每一个函数使用,全局变量也有一定的作用范围。 6.7.1 变量的作用域例6-22 局部变量和全局变量示例。/* program e6-22.c */#include int a=3,b=5; void main()int max(int,int);int a=8; printf(MAX=%dn,max(a,b); int max(int m,int n)return(mn?m:n); 定义全局变量 定义局部变量 局部变量 全局变量6.4.2 变量的存储类型1auto型变量auto型变量通常称为自动变量,只有函数的局部变量才能定义为auto型。auto型变量在函数被调用时为其分配存储空间,存储于内存的动态存储区,函数执行结束时存储空间自动释放。auto型变量在赋值以前,具有不确定的值。auto型变量的定义形式auto 数据类型 变量名;在定义局部变量时,如果缺省存储类型项

温馨提示

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

评论

0/150

提交评论