书签 分享 收藏 举报 版权申诉 / 96
上传文档赚钱

类型第5章 函数与模块化编程.ppt

  • 上传人(卖家):最好的沉淀
  • 文档编号:5819378
  • 上传时间:2023-05-11
  • 格式:PPT
  • 页数:96
  • 大小:6.65MB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《第5章 函数与模块化编程.ppt》由用户(最好的沉淀)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    第5章 函数与模块化编程 函数 模块化 编程
    资源描述:

    1、第第5章章程序设计方法学基础程序设计方法学基础结构化与模块化结构化与模块化哈尔滨工业大学哈尔滨工业大学5.1结构化程序设计结构化程序设计像搭积木一样写代码像搭积木一样写代码n5.1.1自底向上的程序设计方法自底向上的程序设计方法n5.1.2 自顶向下、逐步求精的结构化程序设计方法自顶向下、逐步求精的结构化程序设计方法5.1.1自底向上的程序设计方法自底向上的程序设计方法n自底向上(自底向上(Down-top)的程序设计方法)的程序设计方法先编写出基础程序段先编写出基础程序段然后再逐步扩大规模、补充和升级某些功能然后再逐步扩大规模、补充和升级某些功能实际上是一种自底向上构造程序的过程实际上是一种

    2、自底向上构造程序的过程CBCCAB功能增加、规模增大功能增加、规模增大功能简单、规模较小功能简单、规模较小5.1.1自底向上的程序设计方法自底向上的程序设计方法n【例【例5.15.1】任务任务1 1:只猜一次。:只猜一次。设计一个只能猜一次的猜数游戏:设计一个只能猜一次的猜数游戏:先由计算机先由计算机“想想”一个数,然后请用户猜,如果用户猜对了,则一个数,然后请用户猜,如果用户猜对了,则计算机给出提示计算机给出提示“正确!正确!”,否则提示,否则提示“错误!错误!”,并告诉用户,并告诉用户所猜的数是大还是小。所猜的数是大还是小。5.1.1自底向上的程序设计方法自底向上的程序设计方法n【例【例5

    3、.15.1】任务任务1 1:只猜一次。:只猜一次。#include#include /包含函数包含函数rand()所需的头文件所需的头文件#include /包含函数包含函数time()所需的头文件所需的头文件int main(void)int magic;/计算机计算机“想想”的数的数int guess;/用户猜的数用户猜的数 srand(time(NULL);/为函数为函数rand()设置随机数种子设置随机数种子magic=rand()%100+1;/计算机计算机“想想”一个随机数一个随机数printf(Guess a number:);scanf(%d,&guess);/输入用户猜的数输

    4、入用户猜的数if(guess magic)printf(Wrong!Too big!n);else if(guess magic)printf(Wrong!Too small!n);else printf(Right!n);return 0;5.1.1自底向上的程序设计方法自底向上的程序设计方法n【例【例5.25.2】任务任务2 2:直到猜对为止。在例:直到猜对为止。在例5.15.1的猜数游戏基础上,将的猜数游戏基础上,将游戏改为:直到猜对为止,同时记录用户猜的次数,以此来反映游戏改为:直到猜对为止,同时记录用户猜的次数,以此来反映用户用户“猜猜”数的水平数的水平。5.1.1自底向上的程序设计

    5、方法自底向上的程序设计方法n【例【例5.25.2】任务任务2 2:直到猜对为止。直到猜对为止。#include#include /包含函数包含函数rand()所需的头文件所需的头文件#include /包含函数包含函数time()所需的头文件所需的头文件int main(void)int magic;/计算机计算机“想想”的数的数 int guess;/用户猜的数用户猜的数 srand(time(NULL);/为函数为函数rand()设置随机数种子设置随机数种子 magic=rand()%100+1;int counter=0;/记录用户猜数次数的计数器记录用户猜数次数的计数器 do prin

    6、tf(Try%d:,counter+1);scanf(%d,&guess);/输入用户猜的数输入用户猜的数 counter+;/计数器变量加计数器变量加1 if(guess magic)printf(Wrong!Too big!n);else if(guess magic)printf(Wrong!Too big!n);else if(guess magic)printf(Wrong!Too small!n);else printf(Right!n);while(guess!=magic&counter magic)printf(Wrong!Too big!n);else if(guess m

    7、agic)printf(Wrong!Too small!n);else printf(Right!n);while(guess!=magic&counter magic,则输出提示信息“错误!太大!”step2.4.2:若guess magic,则输出提示信息,则输出提示信息“错误!太大!错误!太大!”step2.4.2:若:若guess magic,则输出提示信息,则输出提示信息“错误!太小!错误!太小!”step2.4.3:若:若guess=magic,则输出提示信息,则输出提示信息“正确!正确!”step2.5:判断用户是否猜对且猜的次数是否小于:判断用户是否猜对且猜的次数是否小于10次

    8、次step2.6:若用户未猜对且猜的次数小于:若用户未猜对且猜的次数小于10次,则返回次,则返回step2.2 否则输出用户猜的次数否则输出用户猜的次数counterstep3:判断用户是否继续猜下一个数:判断用户是否继续猜下一个数step4:若是,则返回:若是,则返回step1,否则算法结束,否则算法结束5.1.2自顶向下、逐步求精的程序设计方法自顶向下、逐步求精的程序设计方法n完整的流程图5.2模块化程序设计模块化程序设计分工与合作的艺术分工与合作的艺术n5.2.1 模块分解的基本原则模块分解的基本原则n5.2.2 如如“活字印刷活字印刷”般的函数般的函数n5.2.3 函数调用和参数传递函

    9、数调用和参数传递n5.2.4 最佳编码原则最佳编码原则防御式编程防御式编程n5.2.5 多文件编程多文件编程n5.2.6 最佳编码原则最佳编码原则正确运用变量的作用域和存储类型正确运用变量的作用域和存储类型5.2.1 模块分解的基本原则模块分解的基本原则n“诸葛亮诸葛亮”式的领导方式式的领导方式n事无巨细、事必躬亲事无巨细、事必躬亲n分工分工+协作协作n分而治之(分而治之(Divide and Conquer)n各司其职各司其职5.2.1 模块分解的基本原则模块分解的基本原则n模块分解应遵循的基本原则是保证每个模块的相对独立性模块分解应遵循的基本原则是保证每个模块的相对独立性(Module I

    10、ndependence),衡量模块独立性程度的标准主要是),衡量模块独立性程度的标准主要是看如下两个标准:看如下两个标准:n(1)内聚度()内聚度(Cohesion):内聚度,也称聚合度或聚合性,是指每个模):内聚度,也称聚合度或聚合性,是指每个模块内各个元素(例如语句、程序段等)之间联系的紧密程度,它是模块内块内各个元素(例如语句、程序段等)之间联系的紧密程度,它是模块内的元素之间的关联程度或聚合能力的度量。模块内各个元素之间的联系越的元素之间的关联程度或聚合能力的度量。模块内各个元素之间的联系越紧密,则其内聚度越大,模块独立性就越强,系统就越容易理解和维护。紧密,则其内聚度越大,模块独立性

    11、就越强,系统就越容易理解和维护。n(2)耦合度()耦合度(Coupling):耦合度,也称关联度或耦合性,是指不同模):耦合度,也称关联度或耦合性,是指不同模块之间相互联系的紧密程度,它是模块之间关联程度(即依赖关系,或者块之间相互联系的紧密程度,它是模块之间关联程度(即依赖关系,或者说接口复杂性)的一种度量。模块之间的依赖关系包括控制关系、调用关说接口复杂性)的一种度量。模块之间的依赖关系包括控制关系、调用关系、数据传递关系。耦合度是从模块外部考察模块的独立性程度。耦合度系、数据传递关系。耦合度是从模块外部考察模块的独立性程度。耦合度的强弱取决于模块间接口的复杂性、调用模块的方式以及通过接口

    12、传送数的强弱取决于模块间接口的复杂性、调用模块的方式以及通过接口传送数据的多少。据的多少。5.2.1 模块分解的基本原则模块分解的基本原则n【例例5.6】按照模块化程序设计方法重新设计猜数游戏,游戏的要按照模块化程序设计方法重新设计猜数游戏,游戏的要求为:求为:n显示一个菜单,让用户选择游戏的方式:显示一个菜单,让用户选择游戏的方式:n(1)选择)选择1,则猜一个数;,则猜一个数;n(2)选择)选择2,则猜多个数,直到用户选择,则猜多个数,直到用户选择0退出为止;退出为止;n(3)选择)选择0,退出游戏。其中,猜每一个数的方式有三种:只,退出游戏。其中,猜每一个数的方式有三种:只猜一次,直到猜

    13、对为止,最多猜猜一次,直到猜对为止,最多猜10次。次。5.2.1 模块分解的基本原则模块分解的基本原则n【例例5.6】按照模块化程序设计方法重新设计猜数游戏。按照模块化程序设计方法重新设计猜数游戏。5.2.1 模块分解的基本原则模块分解的基本原则n【例例5.6】按照模块化程序设计方法重新设计猜数游戏。按照模块化程序设计方法重新设计猜数游戏。5.2.1 模块分解的基本原则模块分解的基本原则n【例例5.6】按照模块化程序设计方法重新设计猜数游戏。按照模块化程序设计方法重新设计猜数游戏。int main(void)int magic;/计算机计算机“想想”的数的数 char choice=0;/将保

    14、存用户选择的变量初始化为将保存用户选择的变量初始化为ASCII码值为码值为0的空字符的空字符 while(choice!=0)/只要用户不选只要用户不选0,就继续猜下一个数,就继续猜下一个数 计算机生成一个随机数计算机生成一个随机数 显示一个固定式菜单并返回用户的选择显示一个固定式菜单并返回用户的选择 switch(choice)/判断用户选择的是何种操作判断用户选择的是何种操作 case 1:用户猜数,只猜一次用户猜数,只猜一次 break;case 2:用户猜数,直到猜对为止用户猜数,直到猜对为止 break;case 3:用户猜数,最多猜用户猜数,最多猜10次次 break;case 0

    15、:提示游戏结束提示游戏结束 break;default:提示输入数据错误提示输入数据错误 清空输入缓冲区清空输入缓冲区 return 0;5.2.1 模块分解的基本原则模块分解的基本原则n【例例5.6】按照模块化程序设计方法重新设计猜数游戏。按照模块化程序设计方法重新设计猜数游戏。int main(void)int magic;/计算机计算机“想想”的数的数 char choice;/用户的选择用户的选择 do 计算机生成一个随机数计算机生成一个随机数 显示一个固定式菜单并返回用户的选择显示一个固定式菜单并返回用户的选择 switch(choice)/判断用户选择的是何种操作判断用户选择的是何

    16、种操作 case 1:输入用户猜的数,只猜一次输入用户猜的数,只猜一次 break;case 2:输入用户猜的数,直到猜对为止输入用户猜的数,直到猜对为止 break;case 3:输入用户猜的数,最多猜输入用户猜的数,最多猜10次次 break;case 0:提示游戏结束提示游戏结束 break;default:提示输入数据错误提示输入数据错误 清空输入缓冲区清空输入缓冲区 while(choice!=0);/只要用户不选只要用户不选0,就继续猜下一个数,就继续猜下一个数 return 0;5.2.1 模块分解的基本原则模块分解的基本原则n【例例5.6】按照模块化程序设计方法重新设计猜数游戏

    17、。按照模块化程序设计方法重新设计猜数游戏。n根据上面的主函数框架,至少需要设计下面根据上面的主函数框架,至少需要设计下面4个子模块:个子模块:n(1)显示一个固定式菜单并返回用户的选择)显示一个固定式菜单并返回用户的选择n(2)用户猜数,只猜一次)用户猜数,只猜一次n(3)用户猜数,直到猜对为止)用户猜数,直到猜对为止n(4)用户猜数,最多猜)用户猜数,最多猜10次次n从上述对应三种游戏方式的三个模块中进一步提炼出从上述对应三种游戏方式的三个模块中进一步提炼出4个公共子任务,按执个公共子任务,按执行顺序划分再抽象出行顺序划分再抽象出4个子模块:个子模块:n(1)计算机生成一个随机数)计算机生成

    18、一个随机数n(2)输入用户猜的数)输入用户猜的数n(3)测试用户输入数据的合法性和有效性)测试用户输入数据的合法性和有效性n(4)对猜对与否做出决策)对猜对与否做出决策5.2.2如如“活字印刷活字印刷”般的函数般的函数n用户自定义函数的基本语法格式为:用户自定义函数的基本语法格式为:5.2.2如如“活字印刷活字印刷”般的函数般的函数n【例例5.7】将例将例5.6猜数游戏实例中设计的如下猜数游戏实例中设计的如下3个子模块定义为函个子模块定义为函数。数。n(1)显示一个固定式菜单并返回用户的选择)显示一个固定式菜单并返回用户的选择n(2)计算机生成一个随机数)计算机生成一个随机数n(3)对用户猜对

    19、与否做出决策)对用户猜对与否做出决策5.2.2如如“活字印刷活字印刷”般的函数般的函数5.2.2如如“活字印刷活字印刷”般的函数般的函数/函数功能:显示菜单并返回用户的选择函数功能:显示菜单并返回用户的选择char MenuSelection(void)char choice;/用户的选项用户的选项 printf(1.Guess Oncen);printf(2.Guess until rightn);printf(3.Guess up to ten timesn);printf(0.Exitn);printf(Input your choice:);scanf(%c,&choice);/注意这

    20、里注意这里%c前面有个空格,避免读入前面的回车前面有个空格,避免读入前面的回车 return choice;5.2.2如如“活字印刷活字印刷”般的函数般的函数#include /调用调用srandtime()所需包含的头文件所需包含的头文件#include /调用调用rand()所需包含的头文件所需包含的头文件#define MAX_NUMBER 100 /计算机生成的随机数的上限计算机生成的随机数的上限#define MIN_NUMBER 1 /计算机生成的随机数的下限计算机生成的随机数的下限/函数功能:计算机生成并返回一个随机数函数功能:计算机生成并返回一个随机数int MakeNumbe

    21、r(void)int magic;srand(time(NULL);/为函数为函数rand()设置随机数种子设置随机数种子 magic=(rand()%(MAX_NUMBER-MIN_NUMBER+1)+MIN_NUMBER;return magic;5.2.2如如“活字印刷活字印刷”般的函数般的函数int IsRight(int magic,int guess)if(guess magic)printf(Wrong!Too big!n);return 0;else return 1;5.2.2如如“活字印刷活字印刷”般的函数般的函数int IsRight(int magic,int gues

    22、s)int flag;if(guess magic)printf(Wrong!Too big!n);flag=0;else flag=1;return flag;n【例例5.85.8】将例将例5.65.6猜数游戏实例中设计的如下猜数游戏实例中设计的如下3 3个子模块定义为个子模块定义为函数。函数。n(1 1)用户猜数,只猜一次)用户猜数,只猜一次n(2 2)用户猜数,直到猜对为止)用户猜数,直到猜对为止n(3 3)用户猜数,最多猜)用户猜数,最多猜1010次次5.2.3 函数调用和参数传递函数调用和参数传递5.2.3 函数调用和参数传递函数调用和参数传递5.2.3 函数调用和参数传递函数调用和

    23、参数传递/函数功能:只猜一次函数功能:只猜一次void GuessOnce(int magic)int guess;/用户猜的数用户猜的数 printf(Guess a number:);scanf(%d,&guess);/读入用户猜的数读入用户猜的数 if(IsRight(magic,guess)printf(Right!n);printf(The magic number is%dn,magic);5.2.3 函数调用和参数传递函数调用和参数传递/函数功能:直到猜对为止函数功能:直到猜对为止void GuessUntilRight(int magic)int guess;/用户猜的数用户猜

    24、的数 int counter=0;/记录用户猜数次数的计数器变量初始化为记录用户猜数次数的计数器变量初始化为0 do printf(Try%d:,counter+1);scanf(%d,&guess);/读入用户猜的数读入用户猜的数 counter+;/记录用户猜的次数记录用户猜的次数 while(!IsRight(magic,guess);/调用调用IsRight()进行猜数决策进行猜数决策 printf(The magic number is%dn,magic);printf(counter=%dn,counter);/输出用户猜数的次数输出用户猜数的次数5.2.3 函数调用和参数传递函数

    25、调用和参数传递#define MAX_TIMES 10/函数功能:最多猜函数功能:最多猜10次次void GuessUpToTen(int magic)int guess;/用户猜的数用户猜的数 int counter=0;/用户猜的次数用户猜的次数 do printf(Try%d:,counter+1);scanf(%d,&guess);/读入用户猜的数读入用户猜的数 counter+;/记录用户猜的次数记录用户猜的次数 while(!IsRight(magic,guess)&counter=MIN_NUMBER&number=MAX_NUMBER)?1:0;5.2.4最佳编码原则最佳编码原

    26、则防御式编程防御式编程/函数功能:输入并返回用户猜的数,能够检查输入数据的合法性和有效性函数功能:输入并返回用户猜的数,能够检查输入数据的合法性和有效性int InputGuess(int counter)int guess;/用户猜的数用户猜的数 int ret;/保存保存scanf()的返回值,用于判断是否成功读入指定数目的数据的返回值,用于判断是否成功读入指定数目的数据 printf(Try%d:,counter+1);ret=scanf(%d,&guess);/读入用户猜的数读入用户猜的数 while(ret!=1|!IsValidNum(guess)/判断用户输入的数据是否合法有效判

    27、断用户输入的数据是否合法有效 printf(Input error!n);while(getchar()!=n);/清除输入缓冲区中的非数字字符清除输入缓冲区中的非数字字符 printf(Try%d:,counter+1);ret=scanf(%d,&guess);/读入用户猜的数读入用户猜的数 return guess;5.2.4最佳编码原则最佳编码原则防御式编程防御式编程/函数功能:只猜一次函数功能:只猜一次void GuessOnce(const int magic)int guess;/用户猜的数用户猜的数 int counter=0;/记录用户猜数次数的计数器变量初始化为记录用户猜数

    28、次数的计数器变量初始化为0 guess=InputGuess(counter);/调用函数调用函数InputGuess()返回用户猜的数返回用户猜的数 if(IsRight(magic,guess)printf(Right!n);printf(The magic number is%dn,magic);5.2.4最佳编码原则最佳编码原则防御式编程防御式编程/函数功能:直到猜对为止函数功能:直到猜对为止void GuessUntilRight(const int magic)int guess;/用户猜的数用户猜的数 int counter=0;/记录用户猜数次数的计数器变量初始化为记录用户猜数

    29、次数的计数器变量初始化为0 do guess=InputGuess(counter);/调用函数调用函数InputGuess()返回用户猜的数返回用户猜的数 counter+;/记录用户猜的次数记录用户猜的次数 while(!IsRight(magic,guess);printf(The magic number is%dn,magic);printf(counter=%dn,counter);/输出用户猜数的次数输出用户猜数的次数5.2.4最佳编码原则最佳编码原则防御式编程防御式编程#define MAX_TIMES 10/函数功能:最多猜函数功能:最多猜10次次void GuessUpTo

    30、Ten(const int magic)int guess;/用户猜的数用户猜的数 int counter=0;/用户猜的次数用户猜的次数 do guess=InputGuess(counter);/调用函数调用函数InputGuess()返回用户猜的数返回用户猜的数 counter+;/记录用户猜的次数记录用户猜的次数 while(!IsRight(magic,guess)&counter=MIN_NUMBER&magic=MAX_NUMBER);/断言验证假设的正确性断言验证假设的正确性 return magic;n通常,仅在下面两种种情况下考虑使用断言:通常,仅在下面两种种情况下考虑使用

    31、断言:n(1 1)检查程序中的各种假设的正确性,例如确认一个计算结果是否在合)检查程序中的各种假设的正确性,例如确认一个计算结果是否在合理的范围内。理的范围内。n(2 2)证实或测试某种不可能发生的状况确实不会发生,例如一些理论上)证实或测试某种不可能发生的状况确实不会发生,例如一些理论上不应该执行到的分支(如不应该执行到的分支(如switchswitch的的default:default:后)确实不会被执行。后)确实不会被执行。n使用断言的基本原则如下:使用断言的基本原则如下:n(1 1)使用断言捕捉不应该或者不可能发生的非法情况。不要混淆非法情)使用断言捕捉不应该或者不可能发生的非法情况。

    32、不要混淆非法情况与错误情况,后者是必然存在的,并且是需要对其进行相应处理的。况与错误情况,后者是必然存在的,并且是需要对其进行相应处理的。n(2 2)每个)每个assertassert只检验一个条件,因为同时检验多个条件时,若断言失只检验一个条件,因为同时检验多个条件时,若断言失败,则无法判断是哪个条件导致的。败,则无法判断是哪个条件导致的。5.2.4最佳编码原则最佳编码原则防御式编程防御式编程n函数设计和防御式编程时需要遵循的几项基本原则:函数设计和防御式编程时需要遵循的几项基本原则:n(1 1)函数的规模要小,尽量控制在)函数的规模要小,尽量控制在5050行代码以内,因为这样的函数比代行代

    33、码以内,因为这样的函数比代码行数更长的函数更容易维护,出错的几率更小。码行数更长的函数更容易维护,出错的几率更小。n(2 2)函数的功能要单一,不要让它身兼数职,不要设计具有多用途的函)函数的功能要单一,不要让它身兼数职,不要设计具有多用途的函数。数。n(3 3)仅通过函数参数和返回值在函数之间传递信息。)仅通过函数参数和返回值在函数之间传递信息。n(4 4)在函数接口中清楚地定义函数的行为,包括入口参数、出口参数、)在函数接口中清楚地定义函数的行为,包括入口参数、出口参数、返回状态、异常处理等,定义好函数接口以后,轻易不要改动。返回状态、异常处理等,定义好函数接口以后,轻易不要改动。n(5

    34、5)在函数的入口处,对参数的有效性和合法性进行检查,以增强程序)在函数的入口处,对参数的有效性和合法性进行检查,以增强程序的健壮性。的健壮性。n(6 6)在执行某些敏感性操作(如执行除法、开方、取对数、赋值、参数)在执行某些敏感性操作(如执行除法、开方、取对数、赋值、参数传递等)之前,应检查操作数的合法性以及数据类型的匹配性,以避免传递等)之前,应检查操作数的合法性以及数据类型的匹配性,以避免发生除零、数值溢出、精度损失等错误。发生除零、数值溢出、精度损失等错误。5.2.4最佳编码原则最佳编码原则防御式编程防御式编程n函数设计和防御式编程时需要遵循的几项基本原则:函数设计和防御式编程时需要遵循

    35、的几项基本原则:n(7 7)当函数需要返回值时,应确保函数中的所有控制分支都有返回值。)当函数需要返回值时,应确保函数中的所有控制分支都有返回值。n(8 8)由于并非所有的编译器都捕获实参与形参类型不匹配的错误,所以)由于并非所有的编译器都捕获实参与形参类型不匹配的错误,所以在函数调用时应确保函数的实参类型与形参类型一致。在程序开头进行在函数调用时应确保函数的实参类型与形参类型一致。在程序开头进行函数原型声明,并将函数参数的类型书写完整,有助于编译器进行类型函数原型声明,并将函数参数的类型书写完整,有助于编译器进行类型匹配检查。在函数没有参数和返回值时,最好用匹配检查。在函数没有参数和返回值时

    36、,最好用voidvoid显式声明。显式声明。n(9 9)使用好的编码风格,可以大大降低程序出错的可能性。)使用好的编码风格,可以大大降低程序出错的可能性。n(1010)避免闪电式编程,用怀疑的眼光审视所有的代码、数据输入和输)避免闪电式编程,用怀疑的眼光审视所有的代码、数据输入和输出,直到你确认它们正确时为止。出,直到你确认它们正确时为止。n(1111)不要对编译器发出的警告熟视无睹,编译器的警告通常捕捉到许)不要对编译器发出的警告熟视无睹,编译器的警告通常捕捉到许多愚蠢的编码错误。多愚蠢的编码错误。n(1212)简单为美,不要滥用技巧,让你的代码过于复杂。)简单为美,不要滥用技巧,让你的代码

    37、过于复杂。5.2.4最佳编码原则最佳编码原则防御式编程防御式编程n把程序分成多个源文件的主要优点如下:把程序分成多个源文件的主要优点如下:n(1 1)把逻辑相关的函数和变量放在同一个源文件中,可以使程序的结构)把逻辑相关的函数和变量放在同一个源文件中,可以使程序的结构清晰。清晰。n(2 2)可以分别对每一个源文件单独进行编译。当程序规模很大且需要频)可以分别对每一个源文件单独进行编译。当程序规模很大且需要频繁修改时,这种方法可以极大地节约时间。繁修改时,这种方法可以极大地节约时间。n(3 3)把函数分组放在不同的源文件中,并创建与源文件同名的头文件)把函数分组放在不同的源文件中,并创建与源文件

    38、同名的头文件(声明与定义分离),这样更利于函数的复用。(声明与定义分离),这样更利于函数的复用。5.2.5多文件编程多文件编程n把程序分割为多个源文件时,通常会遇到这样的一些问题:某把程序分割为多个源文件时,通常会遇到这样的一些问题:某个源文件中的函数如何调用在其他源文件中定义的函数呢?函个源文件中的函数如何调用在其他源文件中定义的函数呢?函数如何访问其他文件中的外部变量呢?两个源文件如何共享同数如何访问其他文件中的外部变量呢?两个源文件如何共享同一个宏定义或类型定义呢?一个宏定义或类型定义呢?n使用使用#include#include文件包含编译预处理命令。它的作用就是告诉预处理器打文件包含

    39、编译预处理命令。它的作用就是告诉预处理器打开指定的文件,并把该文件的内容插入到当前文件中。因此,当几个源开指定的文件,并把该文件的内容插入到当前文件中。因此,当几个源文件需要访问相同的信息时,就可以把这些信息放入一个文件中,然后文件需要访问相同的信息时,就可以把这些信息放入一个文件中,然后利用利用#include#include编译预处理命令把该文件的内容插入每个源文件中。编译预处理命令把该文件的内容插入每个源文件中。n#include编译预处理命令通常有两种书写格式,分别为:编译预处理命令通常有两种书写格式,分别为:n#include n#include filepath5.2.5多文件编程

    40、多文件编程n如何避免一个头文件不会被包含两次?如何避免一个头文件不会被包含两次?n用条件编译用条件编译#ifndef和和#endif来封闭头文件的内容来封闭头文件的内容n#ifndef GUESS_Hn#define GUESS_Hn#define MAX_NUMBER 100n#define MIN_NUMBER 1n#define MAX_TIMES 10n#endif5.2.5多文件编程多文件编程n拆分源文件。一些简单而又基本的原则如下:拆分源文件。一些简单而又基本的原则如下:n(1 1)将每个函数或者每组逻辑上密切相关的函数集)将每个函数或者每组逻辑上密切相关的函数集合放入一个单独的源

    41、文件中。合放入一个单独的源文件中。n(2 2)创建一个与此源文件同名的头文件,在这个头)创建一个与此源文件同名的头文件,在这个头文件中放置在相应源文件中定义的函数的函数原型。文件中放置在相应源文件中定义的函数的函数原型。n(3 3)每个需要调用)每个需要调用“定义在这个源文件中的函数定义在这个源文件中的函数”的源文件都应包含这个自定义的头文件。的源文件都应包含这个自定义的头文件。n(4 4)源文件也应包含与其同名的头文件,以方便编)源文件也应包含与其同名的头文件,以方便编译器检查头文件中的函数原型是否与同名源文件中的译器检查头文件中的函数原型是否与同名源文件中的的函数定义是否一致。的函数定义是

    42、否一致。n(5 5)主函数单独放在一个源文件中,这个文件可以)主函数单独放在一个源文件中,这个文件可以命名为命名为main.cmain.c,也可用程序的名字来命名,例如,也可用程序的名字来命名,例如guess.cguess.c。5.2.5多文件编程多文件编程n1.1.变量的作用域变量的作用域n指变量的可用性范围,即变量可在程序中被读写访问的区域或范围。变量的指变量的可用性范围,即变量可在程序中被读写访问的区域或范围。变量的作用域取决于它们在程序中被定义的位置。变量的作用域规则是:每个变量作用域取决于它们在程序中被定义的位置。变量的作用域规则是:每个变量仅在定义它的语句块(包含下级语句块)内有效

    43、。仅在定义它的语句块(包含下级语句块)内有效。n【例例5.125.12】下面程序主要用于演示局部变量同名时的作用域。下面程序主要用于演示局部变量同名时的作用域。5.2.6 最佳编码原则最佳编码原则正确运用变量的作用域和存储类型正确运用变量的作用域和存储类型#include int main(void)int x=1,y=1;/局部变量局部变量y的作用域在主函数内的作用域在主函数内 int y=2;/局部变量局部变量y的作用域在该复合语句内的作用域在该复合语句内 x=3;printf(x=%d,y=%dn,x,y);/访问的是复合语句内定义的访问的是复合语句内定义的y printf(x=%d,y

    44、=%dn,x,y);/访问的是主函数内定义的访问的是主函数内定义的y return 0;n1.1.变量的作用域变量的作用域n【例例5.135.13】下面程序主要用于演示局部变量和全局变量同名时的作用域。下面程序主要用于演示局部变量和全局变量同名时的作用域。5.2.6 最佳编码原则最佳编码原则正确运用变量的作用域和存储类型正确运用变量的作用域和存储类型#include void Function(void);int x=1;/全局变量全局变量int y=2;/全局变量全局变量int main(void)Function();printf(x=%d,y=%dn,x,y);/打印全局变量打印全局变量

    45、x和和y的值的值 return 0;void Function(void)int x,y;/局部变量隐藏全局变量局部变量隐藏全局变量 x=2;y=1;printf(x=%d,y=%dn,x,y);/打印局部变量打印局部变量x和和y的值的值n1.1.变量的作用域变量的作用域n【例例5.135.13】下面程序主要用于演示局部变量和全局变量同名时的作用域。下面程序主要用于演示局部变量和全局变量同名时的作用域。5.2.6 最佳编码原则最佳编码原则正确运用变量的作用域和存储类型正确运用变量的作用域和存储类型#include void Function(int x,int y);int x=1;/全局变量

    46、全局变量int y=2;/全局变量全局变量int main(void)Function(x,y);printf(x=%d,y=%dn,x,y);/打印全局变量打印全局变量x和和y的值的值 return 0;void Function(int x,int y)/形参也是局部变量,局部变量隐藏全局变量形参也是局部变量,局部变量隐藏全局变量 x=2;y=1;printf(x=%d,y=%dn,x,y);/打印局部变量打印局部变量x和和y的值的值n1.1.变量的作用域变量的作用域n【例例5.145.14】下面程序主要用于演示并列语句块内的局部变量同名时是否会产下面程序主要用于演示并列语句块内的局部变量

    47、同名时是否会产生干扰。生干扰。5.2.6 最佳编码原则最佳编码原则正确运用变量的作用域和存储类型正确运用变量的作用域和存储类型#include void Function(int x,int y);int main(void)int x=1;/局部变量局部变量 int y=2;/局部变量局部变量 Function(x,y);/实参和形参同名实参和形参同名 printf(x=%d,y=%dn,x,y);/访问的是主函数内定义的局部变量访问的是主函数内定义的局部变量x和和y return 0;void Function(int x,int y)/并列语句块内的局部变量同名并列语句块内的局部变量同名

    48、 x=2;y=1;printf(x=%d,y=%dn,x,y);/访问的是形参列表中定义的局部变量访问的是形参列表中定义的局部变量x和和yn1.1.变量的作用域变量的作用域n编译器是如何区分不同作用域的同名变量的呢?编译器是如何区分不同作用域的同名变量的呢?n一个变量名之所以能代表两个不同的值,仅当它能代表两个不同的内存一个变量名之所以能代表两个不同的值,仅当它能代表两个不同的内存地址。编译器是通过将同名变量映射到不同的内存地址来实现作用域的地址。编译器是通过将同名变量映射到不同的内存地址来实现作用域的划分的。局部变量和全局变量被分配的内存区域不同,使其内存地址不划分的。局部变量和全局变量被分

    49、配的内存区域不同,使其内存地址不同,所以二者同名也不会相互干扰。同,所以二者同名也不会相互干扰。n同样,由于同名的局部变量(例如形参和实参)被分配的内存地址不同,同样,由于同名的局部变量(例如形参和实参)被分配的内存地址不同,即在内存中占据不同的存储单元,所以局部变量同名不会相互干扰。正即在内存中占据不同的存储单元,所以局部变量同名不会相互干扰。正因为形参和实参在内存中占据不同的存储单元,所以形参值的改变不会因为形参和实参在内存中占据不同的存储单元,所以形参值的改变不会影响到实参。影响到实参。5.2.6 最佳编码原则最佳编码原则正确运用变量的作用域和存储类型正确运用变量的作用域和存储类型n1.

    50、1.变量的作用域变量的作用域n【例例5.155.15】利用单独计算累加通项的方法,编程计算利用单独计算累加通项的方法,编程计算1!+2!+3!+1!+2!+3!+n!n!。5.2.6 最佳编码原则最佳编码原则正确运用变量的作用域和存储类型正确运用变量的作用域和存储类型#include int main(void)int n,j;/内层循环变量内层循环变量j的定义需要放到这里的定义需要放到这里 long sum=0;/累加求和变量初始化为累加求和变量初始化为0 long p=1;/累乘求积变量初始化为累乘求积变量初始化为1 scanf(%d,&n);for(int i=1;i=n;i+)for(

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:第5章 函数与模块化编程.ppt
    链接地址:https://www.163wenku.com/p-5819378.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库