资源预览内容
第1页 / 共31页
第2页 / 共31页
第3页 / 共31页
第4页 / 共31页
第5页 / 共31页
第6页 / 共31页
第7页 / 共31页
第8页 / 共31页
第9页 / 共31页
第10页 / 共31页
亲,该文档总共31页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第4章 模块化设计与应用主要内容:模块化程序设计模块化程序设计函数定义函数定义函数声明函数声明 函数调用函数调用函数的传递参数函数的传递参数函数的返回值函数的返回值预处理预处理模块化分模块化分4.1 模块化程序设计方法 4.1.1模块化程序设计思想将整个系统进行分解成若干功能独立的,分别设计、将整个系统进行分解成若干功能独立的,分别设计、编程和测试的模块。编程和测试的模块。特点:特点:v程序员能单独地负责一个或几个模块的开发。程序员能单独地负责一个或几个模块的开发。v开发一个模块不需要知道系统其它模块的内开发一个模块不需要知道系统其它模块的内 部结构和编程细节。部结构和编程细节。v模块之间的接口尽可能简明,模块应尽可能模块之间的接口尽可能简明,模块应尽可能 彼此隔离。彼此隔离。v具有可修改性具有可修改性v具有易读性具有易读性 v具有易验证性具有易验证性模块化分方法:自上向下,逐步分解,分而治之模块化分方法:自上向下,逐步分解,分而治之 4.1 模块化程序设计方法4.1.2模块规划实例块规划实例 例例4-1 4-1 简简单单计计算算器器问问题题描描述述:完完成成一一个个简简单单的的计计算算器器程程序序。要要求求能能够够完完成成如如下下的的常常用用运运算算:加加、减减、乘乘、除除、取取余余、倒倒数数、以以e e为为底底的的对对数数、以以1010为为底底的的对对数数、开开平平方方、指指数数运运算算、正正弦弦、余余弦弦、正正切切、二二、八八、十十、十十六六进进制制之之间间的的相相互互转转换换、位位运运算算符符运运算算、位位段段位位运运算算、求求pi()pi()和阶乘。和阶乘。 问题分析1.模块分类2.模块功能细化六则运算对数运算以10为底的运算以e为底的运算4.1.2模块规划实例解决方案解决方案4.1 模块化程序设计方法简单计算器简单计算器对对数数运运算算六六则则运运算算幂幂运运算算三三角角运运算算阶阶乘乘进进制制转转换换Pi位位运运算算以以e为为底底以以10为为底底开开方方指指数数运运算算余余弦弦正正切切正正弦弦二二转转八八十十十十六六八八转转二二十十十十六六十十转转二二八八十十六六十十六六转转二二八八十十位位运运算算符符运运算算位位段段位位运运算算 例例4-2 4-2 学生成绩档案管理学生成绩档案管理问问题题描描述述:完完成成一一个个综综合合的的学学生生成成绩绩档档案案管管理理系系统统。要要求求能能够够管管理理N N个个学学生生的的3 3门门功功课课( (英英语语、高高数数和和C C语语言言) )的的成成绩绩,需需要要实实现现以以下下功功能能:读读入入/ /存存储储学学生生信信息息、录录入入/ /修修改改/ /删删除除学学生生基基本本信信息息、录录入入/ /修修改改成成绩绩、按按学学号号/ /姓姓名名查查询询、排排序序、浏浏览览、统统计计每每门门课课的的优优、良良、中中等等、及及格格、不不及格人数。及格人数。 4.1 模块化程序设计方法 问题分析问题分析1.模块分类2.模块功能细化学生信息维护学生成绩维护学生信息录入、修改、查询等解决方案解决方案学生成绩档案管理学生成绩档案管理学学生生成成绩绩管管理理学学生生档档案案管管理理查查询询统统计计录录入入成成绩绩修修改改成成绩绩读读入入学学生生信信息息录录入入学学生生信信息息修修改改学学生生信信息息删删除除学学生生信信息息存存储储学学生生信信息息按按学学号号查查询询按按姓姓名名查查询询浏浏览览排排序序4.2 函数v从用户角度从用户角度l标准函数(标准函数(库函数库函数):由系统提供由系统提供l用户自定义函数用户自定义函数v从函数形式从函数形式l无参函数无参函数l有参函数有参函数函数分类函数分类4.2.1 函数的定义一般形式:一般形式: 函数类型函数类型 函数名函数名(数据类型数据类型 参数参数1, 数据类型数据类型 参数参数2, )函数体函数体函数的唯一标识函数的唯一标识, 符合符合标识符命名规则标识符命名规则 函数定义不允许嵌套 函数函数返回值返回值类型类型缺省缺省intint类型类型无返回值无返回值voidvoid类型类型float max(float x, float y) return x y ? x : y;4.2.2 函数的声明 函函数数类类型型 函函数数名名(数数据据类类型型 参参数数名名1, 数数据据类类型型 参参数数名名2, ); 不能略掉 ;函数声明一般形式:函数声明一般形式:函数声明举例函数声明举例 (1)void main() float max(float x, float y); /函数声明函数声明 float a, b, c; c = max(a, b);float max(float x, float y) return x y ? x : y;主调函数中对被主调函数中对被调用函数的说明调用函数的说明函数声明举例函数声明举例 (2)float max(float x, float y); / 函数声明void main()/ 不需要再次声明float max(float, float) float a, b, c; c = max(a, b);float max(float x, float y) return x y ? x : y;在所有函数定义之在所有函数定义之前前, 进行函数声明进行函数声明函数声明举例函数声明举例 (3)float max(float x, float y)/* 函数定义具有声明作用函数定义具有声明作用 */ return x y ? x : y;void main() /* 不需要再次声明float max(float,float) */ float a, b, c; c = max(a, b);当被调用的函当被调用的函数定义出现在数定义出现在主调函数之前主调函数之前函数声明举例函数声明举例 (4)当被调用函数的函当被调用函数的函数类型为数类型为int型时型时main() int a,b,c; scanf( %d, %d, &a, &b); c=max(a,b); /*函数调用 */ printf(max is %d,c);int max (int x, int y) int z; z=xy?x:y; return(z);4.2.3 函数的调用函数名函数名(实参表列实参表列);说明说明(1) (1) 在在主主调调函函数数中中调调用用一一个个函函数数时时,函函数数名名后后面面括括号号中中的的参参数数( (可可以以是是一一个个表表达达式式) )称称为为“实实际际参参数数”( (简称简称“实参实参”) )。(2) (2) 实实参参必必须须在在类类型型上上按按顺顺序序与与形形参参一一一一对对应应和和匹匹配配。如如果果类类型型不不匹匹配配,C C编编译译程程序序将将按按赋赋值值兼兼容容的的规则进行转换。规则进行转换。 (3) (3) 调调用用函函数数时时,函函数数名名称称必必须须与与具具有有该该功功能能的的自自定义函数名称完全一致。定义函数名称完全一致。main() int a,b,c; a=4;b=5; c=max(a,b); /*函数调用 */ printf(max is %d,c);4.2.3 函数的调用 函数调用方式:函数调用方式:(1)函数表达式函数表达式 例例: m=max(a,b)*2;(2) 函数语句函数语句 例例:printf(“Hello,World!n”);(3) 函数实参函数实参 例例:m=max(a,max(b,c);4.2.4 函数的传递参数函数的传递参数 在主调函数和被调用函数之间的数据传递是通过函数在主调函数和被调用函数之间的数据传递是通过函数的参数进行的。的参数进行的。c=max(a,b);(main 函数)(max 函数)max(int x, int y) int z; z=xy?x:y; return(z); max(int x, int y) int z; z=xy?x:y; return(z);main() int a,b,c; scanf(%d,%d,&a,&b); c=max(a,b); printf(Max is %d,c);形参形参实参实参参数传递参数传递单向值传递单向值传递只能把实参的“值传递”给形参不能把形参的值传递给实参,即对形参的值所作的改变不能带回给实参实参和形参是不同的变量实参和形参是不同的变量具有不同的存储空间形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放在在函函数数没没有有被被调调用用时时,函函数数中中的的形形参参只只是是一一个个符符号号,系系统统并并不不为为之之分分配配内内存存空空间间,只只有有该该函函数数被被调调用用时时,才才会会为为之之分分配配存存储储空空间间,并并且且在在调调用用结结束后,形参所占的内存也被释放。束后,形参所占的内存也被释放。 例例4-5 定义一个有两个参数函数定义一个有两个参数函数Swap,函数,函数Swap能够完成对这两个参数的值的交换。能够完成对这两个参数的值的交换。 由此可以看出,虽然在函数Swap()中,变量nNum1和nNum2的值已经交换,但并没有影响到主函数中的nNumber1和nNumber2的值,此时仍然输出为nNumber1=4,nNumber2=7。这里,请读者思考一下:有没有办法使最后的输出结果为nNumber1=7,nNumber2=4呢?请到后面的第6章中找答案。对于主调函数和被调用函数之间的数据传递是通过函数参数实现的,实参变量对形参变量的数据传递是单向传递,即只由实参传给形参,而不能由形参传回来给实参的内容已讲述完毕。但读者可能希望通过函数调用使主调函数能得到一个被调用函数的执行结果,这又该如何实现呢?参数传递举例参数传递举例void swap(int x, int y)int t;t=x; x=y; y=t;main()int a=1, b=4;swap(a, b);1a4b1x4y41返回语句返回语句v形式:形式: return(表达式表达式); 或或 return 表达式表达式; 或或 return;v功能:使程序控制从功能:使程序控制从被调用函数被调用函数返回到调用函数中,同返回到调用函数中,同时把返回值带给调用函数时把返回值带给调用函数v说明:说明:l函数中可有多个函数中可有多个returnreturn语句语句l若无若无returnreturn语句,遇语句,遇 时,时,自动自动返回调用函数返回调用函数l若若函数类型函数类型与与returnreturn语句中表达式值语句中表达式值的类型不一致,的类型不一致,按前者为准,自动转换按前者为准,自动转换-函数调用转换函数调用转换lvoidvoid型函数型函数不返回值,定义函数类型为空类型不返回值,定义函数类型为空类型例例: : 无返回值函数无返回值函数 void swap(int x,int y ) int temp; temp=x; x=y; y=temp; 4.2.5 函数的返回值函数的返回值4.3预处理预处理命令是由ANSI统一规定的,但不是C语言本身的组成部分,不能直接对它们进行编译。4.3.1文件包含所谓所谓“文件包含文件包含”是指一个源文件将另外一是指一个源文件将另外一个或多个源文件的全部内容包含到本文件之个或多个源文件的全部内容包含到本文件之中。它是中。它是C预处理程序的一个重要功能,其预处理程序的一个重要功能,其一般形式为:一般形式为: #include 文件名文件名 或或 #include 4.3预处理文件包含命令的功能是把指定的文件包含命令的功能是把指定的文件文件插入该命令行位置取代插入该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连成一个该命令行,从而把指定的文件和当前的源程序文件连成一个源文件。源文件。4.3.2宏定义在在C语言源程序中允许用一个标识符来表示一语言源程序中允许用一个标识符来表示一个字符串,个字符串, 称为称为“宏宏”。被定义为。被定义为“宏宏”的标识的标识符称为符称为“宏名宏名”。在编译预处理时,对程序中所。在编译预处理时,对程序中所有出现的有出现的“宏名宏名”,都用宏定义中的字符串去替,都用宏定义中的字符串去替换,换, 这称为这称为“宏替换宏替换”或或“宏展开宏展开”。在。在C语言语言中,中,“宏宏”分为有参数和无参数两种。分为有参数和无参数两种。 1. 不带参数的宏定义不带参数的宏定义#define 标识符标识符 字符串字符串不是语句,而是一种编译预处理命令 作用:在编译预处理时,把程作用:在编译预处理时,把程作用:在编译预处理时,把程作用:在编译预处理时,把程序中在该命令之后出现的所有序中在该命令之后出现的所有序中在该命令之后出现的所有序中在该命令之后出现的所有标识符进行替换为字符串标识符进行替换为字符串标识符进行替换为字符串标识符进行替换为字符串#include #define PI 3.14159#define R 5.3main()printf(area = %fn, PI * R * R);printf(circumference = %fn, 2 * PI * R);2005年4月(填空题)(7)以下程序运行后的输出结果是 【7】 。#define S(x) 4*x*x+1main() int i=6,j=8; printf(“%dn”,S(i+j);答案答案答案答案:81:814.4应用实例 例例4-6 简单计算器简单计算器 问题描述:采用函数调用方式完成简单计算器程序的问题描述:采用函数调用方式完成简单计算器程序的六则运算模块、幂运算、三角函数模块和求六则运算模块、幂运算、三角函数模块和求pi。 问题分析问题分析使用计算器前先要进行功能选择,将功能选择定义为一个函数。由于幂运算模块又被分解成了两个功能小模块(开方、指数运算),因此需要设计类似于主菜单的二级菜单,方便选择功能。由于三角函数模块又被分解成了三个功能小模块(正弦、余弦、正切),因此也需要设计类似于主菜单的二级菜单,方便选择功能。然后先定义三个函数分别实现这三个功能小模块,再在二级菜单中调用它们。本小节只定义两个函数分别实现正弦、余弦,余下的正切将在第6章实现。求pi模块不用再继续分解了,只要定义一个函数即可。 程序实现程序实现其他代码详见书4.4应用实例 例例4-7 学生成绩档案管理。学生成绩档案管理。 问题描述:问题描述: (1)在第在第4.1节里,把学生成绩档案管理规划成节里,把学生成绩档案管理规划成了四大功能模块,除了四大功能模块,除统计模块统计模块外其它三个模块还外其它三个模块还被进一步分解被进一步分解(如图如图4-2所示所示)。现在需要设计一个。现在需要设计一个“主菜单主菜单”和三个和三个“二级菜单二级菜单”供供“用户用户”选择选择功能。定义四个函数分别实现这四个功能。定义四个函数分别实现这四个“菜单菜单”。 (2)输入输入N个学生个学生1门课程的成绩,按课程统计门课程的成绩,按课程统计各级别各级别(优、良、中、及格和不及格优、良、中、及格和不及格)人数并输出。人数并输出。并要求按上面的并要求按上面的“主菜单主菜单”选择选择“统计模块统计模块”可可以得到统计数据。定义一个函数实现此功能。以得到统计数据。定义一个函数实现此功能。 例例4-7 学生成绩档案管理。学生成绩档案管理。 问题描述:问题描述: (1)在第在第4.1节里,把学生成绩档案管理规划成节里,把学生成绩档案管理规划成了四大功能模块,除了四大功能模块,除统计模块统计模块外其它三个模块还外其它三个模块还被进一步分解被进一步分解(如图如图4-2所示所示)。现在需要设计一个。现在需要设计一个“主菜单主菜单”和三个和三个“二级菜单二级菜单”供供“用户用户”选择选择功能。定义四个函数分别实现这四个功能。定义四个函数分别实现这四个“菜单菜单”。 (2)输入输入N个学生个学生1门课程的成绩,按课程统计门课程的成绩,按课程统计各级别各级别(优、良、中、及格和不及格优、良、中、及格和不及格)人数并输出。人数并输出。并要求按上面的并要求按上面的“主菜单主菜单”选择选择“统计模块统计模块”可可以得到统计数据。定义一个函数实现此功能。以得到统计数据。定义一个函数实现此功能。4.4应用实例(1) 在前面章节中已实现了“主菜单”功能,只不过都是在主函数main()一个函数中实现的。这里改为调用函数来实现。“二级菜单”的实现可以参照上面简单计算器的“二级菜单”实现。 具体程序代码如程序清单4-24所示。(2) 在前两章里采用多分支选择结构和循环结构已实现了部分统计功能,这里的任务是定义一个单独的函数实现这些功能。这里完成的功能相对简单,在后面的章节中会继续完善。代码见书(1) 函数的定义。(2) 函数的调用。(3) 函数的参数和函数的返回值。定义和使用函 数是一定要明确参数和返回值的类型。(4) 预处理。(1) 模块化程序设计方法。 (2) 计算机算法可分为两大类别:数值运算算法 和非数值运算算法。知识层面方法层面4.5 本章小结
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号