第6章 函数与模块化程序设计基础精选文档.ppt

上传人:石*** 文档编号:48027832 上传时间:2022-10-04 格式:PPT 页数:45 大小:2.47MB
返回 下载 相关 举报
第6章 函数与模块化程序设计基础精选文档.ppt_第1页
第1页 / 共45页
第6章 函数与模块化程序设计基础精选文档.ppt_第2页
第2页 / 共45页
点击查看更多>>
资源描述

《第6章 函数与模块化程序设计基础精选文档.ppt》由会员分享,可在线阅读,更多相关《第6章 函数与模块化程序设计基础精选文档.ppt(45页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、第第6章章 函数与模块化函数与模块化程序设计基础程序设计基础1本讲稿第一页,共四十五页6.1 概述概述6.1.1 模块与函数模块与函数1.功能模块功能模块求解较小问题的算法和程序称作求解较小问题的算法和程序称作“功能模块功能模块”,各功能模块可以先单独设计,然后将求解各功能模块可以先单独设计,然后将求解所有子问题的模块组合成求解原问题的程序。所有子问题的模块组合成求解原问题的程序。“自顶向下自顶向下”的模块化程序设计方法:的模块化程序设计方法:将一个大问题分解成多个解决小问题的模块将一个大问题分解成多个解决小问题的模块的设计思想。的设计思想。2本讲稿第二页,共四十五页2.由功能模块组成程序的结

2、构图由功能模块组成程序的结构图:主控模块主控模块模块模块1_1模块模块1_n模块模块2_1模块模块2_n模块模块n_1模块模块n_n模块模块1模块模块2模块模块n3.函数函数:完成相对独立功能的程序完成相对独立功能的程序3本讲稿第三页,共四十五页【例【例6-1】输入年月日,计算出该日为该年的第几天。输入年月日,计算出该日为该年的第几天。主控模块主控模块判断闰年判断闰年求某月的天数求某月的天数输输 出出输输 入入求总天数求总天数图图6-2 6-2 程序结构图程序结构图4本讲稿第四页,共四十五页程序实现程序实现:(1)判断闰年。)判断闰年。int leap(int year)int lp;lp=(

3、year%4=0&year%100!=0|year%400=0)?1:0;return lp;5本讲稿第五页,共四十五页(2 2)求某月的天数。)求某月的天数。int month_days(int year,int month)int month_days(int year,int month)int ds,d;int ds,d;switch(month)switch(month)case 1:case 1:case 3:case 3:case 5:case 5:case 7:case 7:case 8:case 8:case 10:case 10:case 12:d=31;break;cas

4、e 12:d=31;break;case 2:d=leap(year)?29:28;break;case 2:d=leap(year)?29:28;break;default:d=30;default:d=30;return d;return d;6本讲稿第六页,共四十五页(3 3)求天数和。)求天数和。int days(int year,int month,int day)int i,ds=0;for(i=1;imonth;i+)ds=ds+month_days(year,i);ds=ds+day;return ds;7本讲稿第七页,共四十五页4)在主函数中分别调用三个函数。在主函数中分别调

5、用三个函数。void main()int year,month,day,t_day;printf(Input year-month-day:n);scanf(%d-%d-%d,&year,&month,&day);t_day=days(year,month,day);printf(%d-%d-%d is%dth day of the year!n,year,month,day,t_day);注意注意:在完整的程序中在完整的程序中,前三个函数应放在前三个函数应放在main()函数之前。函数之前。8本讲稿第八页,共四十五页6.1.2 模块设计三个原则模块设计三个原则模块独立。模块独立。功能独立的子

6、功能功能独立的子功能模块之间的关系简单模块之间的关系简单使用独立变量使用独立变量模块规模适当模块规模适当分解模块要注意层次分解模块要注意层次对问题抽象化对问题抽象化设计时细化设计时细化9本讲稿第九页,共四十五页6.2 函数定义与使用函数定义与使用一、标准库函数一、标准库函数定义在不同的头文件中定义在不同的头文件中用户使用时,必须用用户使用时,必须用#include“头文件头文件”把相应的头文把相应的头文件包含到程序中来。件包含到程序中来。#include /*包含包含math.h头文件头文件 */#include /*包含包含 stdio.h 头文件头文件*/main()double a,b;

7、scanf(“%f“,&a);/*调用输入函数,输入变量调用输入函数,输入变量a的值的值*/b=sin(a);/*调用调用sin函数,求函数,求sin(a)的值的值*/printf(“%6.4f”,b);/*调用输出函数,输出变量调用输出函数,输出变量b的值的值*/10本讲稿第十页,共四十五页二、用户自定义函数二、用户自定义函数1.函数类型函数类型无参函数无参函数函数的定义无参数说明函数的定义无参数说明 有参函数有参函数 定义的参数有一个或一个以上的参数定义的参数有一个或一个以上的参数 空函数空函数当定义的函数既无参数也无执行语句。当定义的函数既无参数也无执行语句。空函数被调用时,什么也不做立

8、即返回其调用函数。空函数被调用时,什么也不做立即返回其调用函数。11本讲稿第十一页,共四十五页2.函数定义函数定义方式方式1 函数返回值类型名函数返回值类型名 函数名函数名(参数列表参数列表)参数类型说明参数类型说明 局部变量说明局部变量说明;语句序列语句序列;方式方式2 函数返回值类型名函数返回值类型名 函数名函数名(参数类型说明及参数列表参数类型说明及参数列表)局部变量说明局部变量说明;语句序列语句序列;如如:int max(a,b)int a,b;如如:int max(int a,int b)12本讲稿第十二页,共四十五页【例【例6-3】定义符号函数】定义符号函数sign。int sig

9、n(x)/*函数返回值类型未说明,默认为函数返回值类型未说明,默认为int,建议给出函数类型说明,建议给出函数类型说明*/int x;/*形式参数说明形式参数说明*/int y;/*函数体局部变量函数体局部变量*/y=x0?1:(x=0?0:-1);return y;/*返回函数值返回函数值*/注意注意:C语言函数分为两大部分语言函数分为两大部分:函数的说明部分函数的说明部分函数体部分。函数体部分。13本讲稿第十三页,共四十五页函数各部分作用函数各部分作用1)函数的说明部分函数的说明部分 函数说明部分说明函数的类型函数说明部分说明函数的类型,函数名函数名,参数表及参数表及参数类型。参数类型。(

10、1)函数的类型说明函数的类型说明函数的类型即函数的返回值类型。若函数不提供返回值,函数的类型即函数的返回值类型。若函数不提供返回值,则可定义其类型为则可定义其类型为:void。例如例如:void putdata(int a)(2)函数名函数名 函数名又称函数标识符。命名遵循函数名又称函数标识符。命名遵循C语语言标识符的语语言标识符的规定;函数名要反映函数完成的功能。规定;函数名要反映函数完成的功能。14本讲稿第十四页,共四十五页(3)参数表参数表参数表写在函数名后的参数表写在函数名后的()内,由一个或多个变量标内,由一个或多个变量标识符及类型标识符组成。识符及类型标识符组成。参数表中的变量称为

11、形式参数参数表中的变量称为形式参数,简称形参。简称形参。若函数没有形参,则称为无参函数,其后若函数没有形参,则称为无参函数,其后“()”不能省略。不能省略。参数必须指定类型。形参的类型说明有两种:参数必须指定类型。形参的类型说明有两种:方法方法1:int max(a,b)int a,b;方法方法2:int max(int a,int b)省略函数类型名时,省略函数类型名时,C语言默认其为语言默认其为int型。型。15本讲稿第十五页,共四十五页2)函数体函数体函数体包括变量定义和执行语句序列。函数所完函数体包括变量定义和执行语句序列。函数所完成的工作由函数体中一段程序实现。成的工作由函数体中一段

12、程序实现。函数的返回值用返回语句函数的返回值用返回语句return返回,形式返回,形式:return(表达式表达式);或或 return 表达式;表达式;如果函数的类型与如果函数的类型与return语句的表达式的类语句的表达式的类型不一致时型不一致时,则以函数的类型为准。返回时则以函数的类型为准。返回时自动进行数据转换。自动进行数据转换。(见下页例题见下页例题)16本讲稿第十六页,共四十五页例例6.3 定义函数定义函数power(x,n),求求x的的n次方。次方。函数定义如下函数定义如下:float power(float x,int n)int i;float t=1;for(i=1;ib)

13、?a:b;y=yc?y:c;printf(max=%dn,y);void main()int x,y,z,m;scanf(%d,%d,%d,&x,&y,&z);max(x,y,z);/*采用函数语句形式调用函数采用函数语句形式调用函数max*/19本讲稿第十九页,共四十五页函数调用形式函数调用形式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,&x,&y,&z);m=max(x,y);m=max(m,z);printf(“max=%dn”,m);/*表达式调用形式表达式调用形

14、式*/m=max(x,y);printf(max=%dn,max(m,z);/*函数参数调用形式函数参数调用形式*/20本讲稿第二十页,共四十五页2.函数声明函数声明函数定义在函数定义在main()之后,需要进行函数说明。之后,需要进行函数说明。类型名类型名 函数名函数名(类型类型1 变量变量1,类型类型2 变量变量2,类型类型n 变量变量n);说明:说明:函数声明应与该函数定义的函数类型与名称、形参的函数声明应与该函数定义的函数类型与名称、形参的个数、类型、次序相一致。个数、类型、次序相一致。函数声明中的形参名可省略,其形式为函数声明中的形参名可省略,其形式为:类型名类型名 函数名(类型函数

15、名(类型1,类型,类型2,类型,类型n););类型名类型名 函数名函数名();当函数定义在主调函数之前,即先定义当函数定义在主调函数之前,即先定义,后调用。则调后调用。则调用时函数声明可以省略。用时函数声明可以省略。21本讲稿第二十一页,共四十五页例例6.4 编写计算编写计算x的的n次乘方的程序。次乘方的程序。#include stdio.h”main()float x,y;int n;float power(float x,int n);scanf(%f,%d,&x,&n);y=power(x,n);printf(“%8.2f”,y);float power(float x,int n)in

16、t i;float t=1;for(i=1;iy)t=x;else t=y;return t;24本讲稿第二十四页,共四十五页1)形参形参y之间值的传递如图之间值的传递如图4.7所示意所示意。a x b y2)关于形式参数和实际参数说明如下关于形式参数和实际参数说明如下:形式参数在函数被调用时才被分配内存。当函数执行完毕返形式参数在函数被调用时才被分配内存。当函数执行完毕返回时回时,形式参数占用的内存空间便被释放。形式参数占用的内存空间便被释放。实参可以是变量、常量和表达式。实参可以是变量、常量和表达式。如如:y=power(x,4);y=power(x,i*2);但实参必须有确定的值。但实参

17、必须有确定的值。3)形参和实参的类型必须相容形参和实参的类型必须相容。4)形参和实参之间的关系是形参和实参之间的关系是:单向的值的传递单向的值的传递10105525本讲稿第二十五页,共四十五页6.3.3 函数的嵌套调用函数的嵌套调用 调调用用一一个个函函数数的的过过程程中中又又调调用用了了另另一一个个函函数数,这这种种调调用用称称为为函函数数的嵌套调用的嵌套调用。函数函数1 函数函数2 函数函数3 .调用函数调用函数2 调用函数调用函数3 .26本讲稿第二十六页,共四十五页【例【例6-9】求方程求方程ax2+bx+c=0(a 0)的根。的根。#include#include void main

18、()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,&a,&b,&c);if(dict(a,b,c)x1=root(a,b,c,1);/*调用函数调用函数root*/x2=root(a,b,c,0);printf(实根实根x1=%f,x2=%fn,x1,x2);else printf(无实根无实根!n);27本讲稿第二十七页,共四十五页dict()和和root()int dict(float a,float b,

19、float c)int f;if(b*b-4*a*c=0)f=1;else 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;28本讲稿第二十八页,共四十五页嵌套过程嵌套过程void main().x1=root(a,b,c,1)x2=root(a,b,c,0).root(a,b,c,flag).d=dict(a,b,c).return x

20、;dict(a,b,c).return f;图图6-3 嵌套调用过程嵌套调用过程 调用调用 返回返回 返回返回 调用调用29本讲稿第二十九页,共四十五页6.3.4 递归调用递归调用(重点重点)函数调用函数本身,称为函数的递归调用。递归调用函数调用函数本身,称为函数的递归调用。递归调用形式如下:形式如下:1)直接递归直接递归 void a().a();.2)间接递归间接递归 void a().b();.void b().a();.30本讲稿第三十页,共四十五页用递归算法计算用递归算法计算n!讨论:讨论:采用递归的方法计算。采用递归的方法计算。n!的递归定义形式的的递归定义形式的:编程编程:if(

21、初始条件初始条件)表达式表达式;else 递推表达式递推表达式;1 n=0;n=n*(n-1)!n031本讲稿第三十一页,共四十五页例程序:例程序:#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”,&n);y=fac(n);printf(“%d!=%ldn”,n,y);32本讲稿第三十二页,共四十五页分析分析:当程序输入当程序输入3时时y=fac(3)3*fac(2)2*fac(1)1*fac(0)133

22、本讲稿第三十三页,共四十五页例例6.11 汉诺塔游戏汉诺塔游戏汉诺塔汉诺塔(Tower of Hanoi)游戏。游戏。底座上有三根针,第底座上有三根针,第一根针上放着从大到小一根针上放着从大到小64个金片。游戏的目标是把所个金片。游戏的目标是把所有金片从第一根针通过第二根针移到第三根针上。移有金片从第一根针通过第二根针移到第三根针上。移动过程中大的金片不能压在小的金片上。动过程中大的金片不能压在小的金片上。把把n(n1)个金片从第一根针个金片从第一根针a上移到第三根针上移到第三根针c的问题的问题分解成如下步骤分解成如下步骤:(1)将将n-1个金片从个金片从a经过经过c 移动到移动到b。(2)将

23、第将第n个金片移动到个金片移动到c。(3)再将再将n-1个盘子从个盘子从b经过经过a移动到移动到c。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移动到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*/主函数如下:#incl

24、ude main()int n;printf(Input n:);scanf(%d,&n);hanoi(n,1,2,3);/*n个金片从第一根针经过第二根针移动到第三根针上*/35本讲稿第三十五页,共四十五页6.4 变量的作用域及存储特性变量的作用域及存储特性例例void f1()int t=2;a*=t;b/=t;main()int a,b;printf(“Enter a,b:”);scanf(“%d,%d”,&a,&b);f1();/*调用函数调用函数f1()*/printf(“a=%d,b=%d”,a,b);编译程序会提示出错编译程序会提示出错:Undefined symbol a 和和

25、 Undefined symbol b。为什么。为什么?36本讲稿第三十六页,共四十五页全局变量(外部变量)局部变量(内部变量)定义位置函数体外函数体内作用域从定义处到文件结束从定义处到本函数结束举例所有在函数体外定义的变量(1)所有在函数体内定义的变量(2)形式参数注意与局部变量同名的处理不同函数中同名局部变量互不干扰6.4.1 变量的作用域变量的作用域1.变量按作用域:分为全局变量和局部变量2.区别:37本讲稿第三十七页,共四十五页例例程序程序#include int a,b;/*a,b为全局变量为全局变量*/void f1()int t1,t2;t1=a*2;t2=b*3;b=100;p

26、rintf(“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 38本讲稿第三十八页,共四十五页将程序改为:将程序改为:#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();printf(“a=%d,b=%d”,a,b);程序输出结果为程序输出结果为:t

27、1=4,t2=12 a=2,b=4 结论:全局变量与局部变结论:全局变量与局部变量同名时,局部变量的作量同名时,局部变量的作用域屏蔽全局变量用域屏蔽全局变量39本讲稿第三十九页,共四十五页6.4.2 变量的存储特性变量的存储特性1.变量按存在时间分变量按存在时间分:静态变量,动态变量静态存储变量:生存期为程序执行的整个过程,在该过静态存储变量:生存期为程序执行的整个过程,在该过程中占有固定的存储空间,也称永久存储。程中占有固定的存储空间,也称永久存储。动态存储变量:只生存在某一段时间内。动态存储变量:只生存在某一段时间内。例如:例如:函数的形参、函数体或分程序函数的形参、函数体或分程序中定义的

28、变量,只有中定义的变量,只有当程序进入该函数或分程序时才分配存储空间,函数当程序进入该函数或分程序时才分配存储空间,函数/分程序执行完后,变量的存储空间又被释放。分程序执行完后,变量的存储空间又被释放。2.变量属性:数据类型,存储特性变量属性:数据类型,存储特性完整的变量定义完整的变量定义:存储特性存储特性 数据类型数据类型 变量名变量名;40本讲稿第四十页,共四十五页3.变量的存储特性变量的存储特性1)auto型型有形式参数、函数内变量、分程序变量。有形式参数、函数内变量、分程序变量。进入程序自动分配内存,不长期占用内存。进入程序自动分配内存,不长期占用内存。2)static 型型 局部静态

29、变量局部静态变量 全局静态变量全局静态变量长期占用内存长期占用内存自动型自动型 auto静态型静态型 static寄存器型寄存器型 register外部型外部型 extern41本讲稿第四十一页,共四十五页例例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)42本讲稿第四十二页,共四十五页3)register型型将使用频率高的变量定义为将使用频率高的变量定义为register

30、型型,可以提高运行可以提高运行速度。速度。寄存器变量只限于寄存器变量只限于整型整型、字符型字符型、指针型指针型的局部变量。寄存的局部变量。寄存器变量是动态变量,仅允许说明两个寄存器变量。器变量是动态变量,仅允许说明两个寄存器变量。例如例如:register int d;register char c;数据内存 运算器 运算器 结果 控制器 数据寄存器寄存器43本讲稿第四十三页,共四十五页4)extern型型引用引用:extern 类型类型 变量名变量名;如果某个模块文件中要用到另一个模块文件中的全局变如果某个模块文件中要用到另一个模块文件中的全局变量,要用量,要用extern说明。说明。例如例

31、如:程序模块程序模块file1.c中定义了全局变量中定义了全局变量 int s;另一程序另一程序file2.c的函数的函数fun1()需要使用这个变量需要使用这个变量s。在。在file2.c的的fun1()对对s进行外部变量说明进行外部变量说明:fun1()extern int s;/*表明变量表明变量s是在其他文件定义的是在其他文件定义的*/.定义时分配内存定义时分配内存,其他文件引用时不再分配内存。其他文件引用时不再分配内存。44本讲稿第四十四页,共四十五页练习练习: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)45本讲稿第四十五页,共四十五页

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com