第8章函数与模块化程序设计基础.ppt

上传人:sccc 文档编号:4785437 上传时间:2023-05-14 格式:PPT 页数:49 大小:228.52KB
返回 下载 相关 举报
第8章函数与模块化程序设计基础.ppt_第1页
第1页 / 共49页
第8章函数与模块化程序设计基础.ppt_第2页
第2页 / 共49页
第8章函数与模块化程序设计基础.ppt_第3页
第3页 / 共49页
第8章函数与模块化程序设计基础.ppt_第4页
第4页 / 共49页
第8章函数与模块化程序设计基础.ppt_第5页
第5页 / 共49页
点击查看更多>>
资源描述

《第8章函数与模块化程序设计基础.ppt》由会员分享,可在线阅读,更多相关《第8章函数与模块化程序设计基础.ppt(49页珍藏版)》请在三一办公上搜索。

1、1,第8章 模块化程序设计,1.概述:模块,函数,算法2.函数的定义与说明(重点)3.函数的调用(重点,难点递归调用)4.变量的作用域(重点)5.变量的存储属性(重点,难点),2,8.1 概述,6.1.1 模块与函数1.功能模块求解较小问题的算法和程序称作“功能模块”,各功能模块可以先单独设计,然后将求解所有子问题的模块组合成求解原问题的程序。“自顶向下”的模块化程序设计方法:将一个大问题分解成多个解决小问题的模块的设计思想。,3,2.由功能模块组成程序的结构图:,3.函数:完成相对独立功能的程序,4,【例1】,输入年月日,计算出该日为该年的第几天。,5,程序实现:,(1)判断闰年。int l

2、eap(int year)int lp;lp=(year%4=0,6,(2)求某月的天数。int month_days(int year,int month)int ds,d;switch(month)case 1:case 3:case 5:case 7:case 8:case 10:case 12:d=31;break;case 2:d=leap(year)?29:28;break;default:d=30;return d;,7,(3)求天数和。int days(int year,int month,int day)int i,ds=0;for(i=1;imonth;i+)ds=ds+m

3、onth_days(year,i);ds=ds+day;return ds;,8,4)在主函数中分别调用三个函数。void main()int year,month,day,t_day;printf(Input year-month-day:n);scanf(%d-%d-%d,注意:在完整的程序中,前三个函数应放在main()函数之前。,9,8.1.2 模块设计三个原则,模块独立。功能独立的子功能模块之间的关系简单使用独立变量模块规模适当分解模块要注意层次对问题抽象化设计时细化,10,8.2 函数定义与使用,一、标准库函数定义在不同的头文件中用户使用时,必须用#include“头文件”把相应的

4、头文件包含到程序中来。#include/*包含math.h头文件*/#include/*包含 stdio.h 头文件*/main()double a,b;scanf(“%f“,/*调用输出函数,输出变量b的值*/,11,二、用户自定义函数,函数类型无参函数函数的定义无参数说明 有参函数 定义的参数有一个或一个以上的参数 空函数当定义的函数既无参数也无执行语句。空函数被调用时,什么也不做立即返回其调用函数。,12,2.函数定义,方式1 函数返回值类型名 函数名(参数列表)参数类型说明 局部变量说明;语句序列;方式2 函数返回值类型名 函数名(参数类型说明及参数列表)局部变量说明;语句序列;,如:

5、int max(a,b)int a,b;,如:int max(int a,int b),13,【例2】定义符号函数sign。,int sign(x)/*函数返回值类型未说明,默认为int,建议给出函数类型说明*/int x;/*形式参数说明*/int y;/*函数体局部变量*/y=x0?1:(x=0?0:-1);return y;/*返回函数值*/注意:C语言函数分为两大部分:函数的说明部分函数体部分。,14,函数各部分作用,1)函数的说明部分 函数说明部分说明函数的类型,函数名,参数表及参数类型。(1)函数的类型说明函数的类型即函数的返回值类型。若函数不提供返回值,则可定义其类型为:void

6、。例如:void putdata(int a)(2)函数名 函数名又称函数标识符。命名遵循C语语言标识符的规定;函数名要反映函数完成的功能。,15,(3)参数表,参数表写在函数名后的()内,由一个或多个变量标识符及类型标识符组成。参数表中的变量称为形式参数,简称形参。若函数没有形参,则称为无参函数,其后“()”不能省略。参数必须指定类型。形参的类型说明有两种:方法1:int max(a,b)int a,b;方法2:int max(int a,int b)省略函数类型名时,C语言默认其为int型。,16,2)函数体,函数体包括变量定义和执行语句序列。函数所完成的工作由函数体中一段程序实现。函数的

7、返回值用返回语句return返回,形式:return(表达式);或 return 表达式;如果函数的类型与return语句的表达式的类型不一致时,则以函数的类型为准。返回时自动进行数据转换。(见下页例题),17,例3 定义函数power(x,n),求x的n次方。,函数定义如下:float power(float x,int n)int i;float t=1;for(i=1;i=n;i+)t=t*x;/*1*x*x*x 共乘n次*/return t;/*返回t的值*/,18,8.3.函数参数和函数的值,实参的个数必须与形参相等,且参数顺序、类型要对应一致。实参与形参是按位置一一对应地传递数据的

8、。例6.5 编程输入两个数,输出其中较大的。#include“stdio.h”main()int a,b,m;int max(int,int);scanf(“%d,%d”,19,若程序运行时输入为:10,5便有输出为:10调用max函数时,实参a把值传给形参x,实参b把值传给形参y,按顺序传递,与形参名称无关。实参a和形参x,实参b和形参y一一对应。,int max(int x,int y)int t;if(xy)t=x;else t=y;return t;,20,1)形参y之间值的传递如图4.7所示意。a x b y2)关于形式参数和实际参数说明如下:形式参数在函数被调用时才被分配内存。当函

9、数执行完毕返回时,形式参数占用的内存空间便被释放。实参可以是变量、常量和表达式。如:y=power(x,4);y=power(x,i*2);但实参必须有确定的值。3)形参和实参的类型必须相容。4)形参和实参之间的关系是:单向的值的传递,21,8.4 函数的调用,6.3.1 函数调用与声明1.函数的调用有参数函数的调用形式:函数名(参数)无参数函数的调用形式:函数名()注意:当实际参数的个数、次序、类型与对应形式参数的个数、次序、类型不一致时,系统并不提示错误,后果却难以预测。,22,函数调用形式,函数语句调用、函数表达式调用和函数参数调用 void max(int a,int b,int c)

10、int y;y=(ab)?a:b;y=yc?y:c;printf(max=%dn,y);void main()int x,y,z,m;scanf(%d,%d,%d,/*采用函数语句形式调用函数max*/,23,函数调用形式,int max(int a,int b)int y;y=(ab)?a:b;return y;void main()int x,y,z,m;scanf(%d,%d,%d,/*函数参数调用形式*/,24,8.4.3.函数声明,函数定义在main()之后,需要进行函数说明。类型名 函数名(类型1 变量1,类型2 变量2,类型n 变量n);说明:函数声明应与该函数定义的函数类型与名

11、称、形参的个数、类型、次序相一致。函数声明中的形参名可省略,其形式为:类型名 函数名(类型1,类型2,类型n);类型名 函数名();当函数定义在主调函数之前,即先定义,后调用。则调用时函数声明可以省略。,25,例4 编写计算x的n次乘方的程序。,#include stdio.h”main()float x,y;int n;float power(float x,int n);scanf(%f,%d,float power(float x,int n)int i;float t=1;for(i=1;i=n;i+)t=t*x;return t;,26,8.5 函数的嵌套调用,调用一个函数的过程中又

12、调用了另一个函数,这种调用称为函数的嵌套调用。函数1 函数2 函数3.调用函数2 调用函数3.,27,【例5】求方程ax2+bx+c=0(a0)的根。,#include#include void main()float a,b,c,x1,x2;int dict(float,float,float);float root(float,float,float,int);printf(Input a,b,c:);scanf(%f,%f,%f,28,dict()和root(),int dict(float a,float b,float c)int f;if(b*b-4*a*c=0)f=1;else

13、f=0return f;float root(float a,float b,float c,int flag)float d,x;d=dict(a,b,c);/*调用函数 dict*/if(d)x=flag?(-b+sqrt(d)/(2*a):(-b-sqrt(d)/(2*a);return x;,29,嵌套过程,30,8.6 递归调用(重点),函数调用函数本身,称为函数的递归调用。递归调用形式如下:1)直接递归 void a().a();.,2)间接递归 void a().b();.void b().a();.,31,用递归算法计算n!,讨论:采用递归的方法计算。n!的递归定义形式的:,编

14、程:if(初始条件)表达式;else 递推表达式;,32,例程序:,#include long fac(unsigned n)long f;if(n=0)f=1;/*递归结束条件*/else f=n*fac(n-1);return f;,main()long y;int n;scanf(“%d”,33,分析:当程序输入3时y=fac(3)3*fac(2)2*fac(1)1*fac(0)1,34,void hanoi(int n,int a,int b,int c)if(n=0)return;/*0个金片不处理*/if(n=1)printf(%d-%dn,a,c);/*n=1时,直接将金片从a移

15、动到c*/else hanoi(n-1,a,c,b);/*先将n-1个金片从a经过c 移动到b*/printf(%d-%dn,a,c);/*将第n个金片从a移动到c*/hanoi(n-1,b,a,c);/*再将n-1个金片从b经过a移动到c*/主函数如下:#include main()int n;printf(Input n:);scanf(%d,/*n个金片从第一根针经过第二根针移动到第三根针上*/,35,例6 汉诺塔游戏,汉诺塔(Tower of Hanoi)游戏。底座上有三根针,第一根针上放着从大到小64个金片。游戏的目标是把所有金片从第一根针通过第二根针移到第三根针上。移动过程中大的金

16、片不能压在小的金片上。把n(n1)个金片从第一根针a上移到第三根针c的问题分解成如下步骤:(1)将n-1个金片从a经过c 移动到b。(2)将第n个金片移动到c。(3)再将n-1个盘子从b经过a移动到c。,36,8.7 数组与函数,使用时与普通变量一样,值传递方式,在函数调用时将值传递给,实参,形参,8.7.1 数组元素做函数参数,37,【例6】一个数组中有10个整型元素,求数组中所有素数之和。,#include stdio.h#include math.hvoid main()int a10,i,sum=0;int prime(int x);printf(enter 10 numbers:n)

17、;for(i=0;i10;i+)scanf(%d,&ai);if(prime(ai)sum+=ai;printf(sum=%dn,sum);,int prime(int x)int f=1,k;if(x=1)f=0;for(k=2;k=sqrt(x);k+)if(x%k=0)f=0;break;return(f);,38,地址传递方式,实参与形参共地址,相当于对同一对象的两个不同名字。,8.7.2 数组名做函数参数,在函数调用时将其地址值传递给,实参,形参,39,#include stdio.hint f(int b,int m,int n)int i,s=0;for(i=m;in;i=i+2

18、)s=s+bi;return s;void main()int x,a=1,2,3,4,5,6,7,8,9;x=f(a,3,7);printf(%dn,x);,【例7】分析下面程序的运行结果。,40,8.8 变量的作用域及存储特性,例void f1()int t=2;a*=t;b/=t;main()int a,b;printf(“Enter a,b:”);scanf(“%d,%d”,编译程序会提示出错:Undefined symbol a 和 Undefined symbol b。为什么?,41,8.4.1 变量的作用域,1.变量按作用域:分为全局变量和局部变量2.区别:,42,例程序,#in

19、clude int a,b;/*a,b为全局变量*/void f1()int t1,t2;t1=a*2;t2=b*3;b=100;printf(“t1=%d,t2=%dn”,t1,t2);main()a=2;b=4;f1();printf(“a=%d,b=%d”,a,b);,程序输出结果为:t1=4,t2=12 a=2,b=100,43,将程序改为:,#include int a=2,b=4;/*a,b为全局变量*/void f1()int t1,t2;t1=a*2;t2=b*3;b=100;printf(“t1=%d,t2=%dn”,t1,t2);main()int b=4;f1();pri

20、ntf(“a=%d,b=%d”,a,b);,程序输出结果为:t1=4,t2=12 a=2,b=4 结论:全局变量与局部变量同名时,局部变量的作用域屏蔽全局变量,44,8.9 变量的存储特性,1.变量按存在时间分:静态变量,动态变量静态存储变量:生存期为程序执行的整个过程,在该过程中占有固定的存储空间,也称永久存储。动态存储变量:只生存在某一段时间内。例如:函数的形参、函数体或分程序中定义的变量,只有当程序进入该函数或分程序时才分配存储空间,函数/分程序执行完后,变量的存储空间又被释放。2.变量属性:数据类型,存储特性完整的变量定义:存储特性 数据类型 变量名;,45,3.变量的存储特性,1)a

21、uto型有形式参数、函数内变量、分程序变量。进入程序自动分配内存,不长期占用内存。2)static 型 局部静态变量 全局静态变量长期占用内存,46,例,f(int a)int b=0;static int c=3;b+;c+;printf(“%5d%5d%5d”,a,b,c);return(a+b+c);main()int a=2,k;for(k=0;k3;k+)printf(“%5dn”,f(a);(看L4_11),47,3)register型,将使用频率高的变量定义为register型,可以提高运行速度。,寄存器变量只限于整型、字符型、指针型的局部变量。寄存器变量是动态变量,仅允许说明两

22、个寄存器变量。例如:register int d;register char c;,48,4)extern型,引用:extern 类型 变量名;如果某个模块文件中要用到另一个模块文件中的全局变量,要用extern说明。例如:程序模块file1.c中定义了全局变量 int s;另一程序file2.c的函数fun1()需要使用这个变量s。在file2.c的fun1()对s进行外部变量说明:fun1()extern int s;/*表明变量s是在其他文件定义的*/.定义时分配内存,其他文件引用时不再分配内存。,49,练习:main()int i=1;static int a=10;register int b=5;printf(“i=%d,a=%d,b=%dn”,i,a,b);other();printf(“i=%d,a=%d,b=%dn”,i,a,b);other()int i;static int a;i=6;a=100;printf(“i=%d,a=%dn”,i,a);(看L4_12),

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号