




已阅读5页,还剩58页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章用函数实现模块化程序设计 2 问题 分别给下面2组数按从小到大的顺序排序34 56 23 12 4524 46 13 15 65 57 35代码重复 修改麻烦 可读性差 解决方法 使用函数 includeintmain inta 5 34 56 23 12 45 intb 7 24 46 13 15 65 57 35 voidsort inta intn sort a 5 sort b 7 排序函数 将有n个元素的整数数组由小到大排序voidsort inta intn intt inti j for j 0 ja i 1 t a i a i a i 1 a i 1 t includeintmain inta 5 34 56 23 12 45 intb 7 24 46 13 15 65 57 35 inti j t for j 0 ja i 1 t a i a i a i 1 a i 1 t for j 0 jb i 1 t b i b i b i 1 b i 1 t 3 模块化程序设计 日常生活中 计算机的组装手机中的各种应用物品的生产 4 模块化程序设计 基本思想 将一个大的程序按功能分割成一些小模块 每个模块用来实现特定的功能 把编程比做制造一台机器 函数就好比其零部件可以将这些 零部件 单独设计 调试 测试好 使用时拿出来装配 在总体调试这些 零部件 可以是自己设计制造 别人设计制造 现成的标准产品开发方法 自上向下 逐步分解 分而治之 任务分解 5 模块化程序设计 特点 各模块相对独立 功能单一 结构清晰 接口简单控制了程序设计的复杂性提高元件的可靠性缩短开发周期避免程序开发的重复劳动易于维护和功能扩充 6 模块化程序设计 一个函数中适合放多少行代码 1986年IBM在OS 360的研究结果 多数有错误的函数大于500行1991年对148000行代码的研究表明 小于143行的函数比更长的函数更容易维护 7 模块化程序设计 C是函数式语言 一个C程序由一个或多个程序模块组成若干相关的函数也可以合并成一个模块一个源程序文件由一个或多个函数以及其它有关内容组成必须有且只能有一个名为main的主函数C程序的执行总是从main函数开始 在main中结束函数不能嵌套定义 可以嵌套调用 不能调用main函数 函数 模块 8 函数 9 函数 就是功能 function 每一个函数用来实现一个特定的功能 函数的名字应反映其实现的功能 函数的要素 函数名返回值类型参数的名字和类型函数体 完成的操作 实现的功能 intaverage intx inty intresult result x y 2 returnresult 返回值类型 与实际返回的变量类型一致 函数名 标识符 形参表 函数的入口 接受调用者传入的参数 函数体 函数功能的主体实现部分 函数的出口 只能返回一个值给调用者 10 函数分类 从用户角度标准函数 库函数 由标准C编译系统提供第三方库函数 其它厂商开发的函数用户自定义函数从函数形式无参函数有参函数 使用库函数应注意 1 函数功能2 函数参数的数目和顺序 及各参数意义和类型3 函数返回值意义和类型4 需要使用的包含文件 11 一般格式函数类型标识符函数名 形参类型列表 声明部分语句部分 函数定义 例有参函数intmax intx inty intz z x y x y return z 例无参函数voidprintstar printf n 或voidprintstar void printf n C语言中 函数必须 先定义 后使用 12 一般形式函数名 实参表列 形参与实参形式参数 定义函数时函数名后面括号中的变量名实际参数 调用函数时函数名后面括号中的表达式 函数调用 例7 2比较两个数并输出大者main intmax intx inty inta b c scanf d d 13 关于形参与实参的说明 形参在函数被调用前不占内存 函数调用时为形参分配内存 调用结束 内存释放实参必须有确定的值 可以是常量 变量或表达式形参必须指定类型形参与实参类型一致 个数相同若形参与实参类型不一致 自动按形参类型转换 函数调用转换 函数参数和函数的值 14 函数的参数传递方式值传递函数调用时 为形参分配单元 并将实参的值复制到形参中 调用结束 形参单元被释放 实参单元仍保留并维持原值 特点形参与实参占用不同的内存单元单向传递 函数参数和函数的值 15 例交换两个数 值传递 函数参数和函数的值 includevoidmain voidsa intb intx 7 y 11 printf x d ty d n x y printf s n s printf x d ty d n x y voidswap inta intb inttemp temp a a b b temp 16 函数的参数传递方式地址传递含义 函数调用时 将数据的存储地址作为参数传递给形参 特点形参与实参占用同样的存储单元 双向 传递实参和形参必须是地址常量或变量 函数参数和函数的值 17 例交换两个数 地址传递 函数参数和函数的值 includevoids p1 int p2 intp p p1 p1 p2 p2 p voidmain inta b scanf d d 18 函数的返回值主调函数调用函数后得到的值例 c max 2 3 函数的返回值是通过返回语句return获得的return 表达式 或return表达式 或return 功能 使程序控制从被调用函数返回到调用函数中 同时把返值带给调用函数说明函数中可有多个return语句若无return语句 遇 时 自动返回调用函数若函数类型与return语句中表达式值的类型不一致 按函数类型为准 自动转换 函数调用转换void类型函数 不带返回值的函数 函数参数和函数的值 includeintmain intmax floatx floaty floata b intc scanf f f 1 5 2 6 变为2 19 调用的条件被调函数已定义使用库函数 用 include指令例 include自定义函数 位置在调用函数的后面 要先声明 再使用 函数的调用 20 函数声明和函数原型作用 告诉编译系统函数类型 参数个数及类型 以便检验函数定义与函数声明不同函数声明位置 程序的数据说明部分 函数内或外 若被调用函数定义出现在主调函数之前 可不作函数说明 函数的调用 例7 4 includeintmain floatadd floatx floaty floata b c printf Pleaseenteraandb scanf f f 例7 4 includefloatadd floatx floaty floatz z x y return z voidmain floata b c printf Pleaseenteraandb scanf f f 21 函数的调用方式函数语句 把函数调用作为一个语句函数表达式 函数出现在一个表达式中函数参数 函数调用作为一个函数的实参 函数的调用 printstar printf Hello World n m max a b 2 printf d max a b m max a max b c 22 C语言规定 函数定义不可嵌套 但可以嵌套调用函数 在调用一个函数的过程中又调用另一个函数 函数的嵌套调用 23 函数的嵌套调用 例求三个数中最大数和最小数的差值 d dif a b c printf Max Min d n d intdif intx inty intz returnmax x y z min x y z intmax intx inty intz intr r x y x y return r z r z intmin intx inty intz intr r x y x y return r z r z includeintdif intx inty intz intmax intx inty intz intmin intx inty intz voidmain inta b c d scanf d d d 24 定义函数直接或间接的调用自身 称为函数的递归调用 函数的递归调用 说明 C编译系统对递归函数的自调用次数没有限制每调用函数一次 在内存堆栈区分配空间 用于存放函数变量 返回值等信息 所以递归次数过多 可能引起堆栈溢出 25 字典是递归定义的典型实例字典中的任何一个词汇都是由 其它词汇 解释或定义的但 其它词汇 在被定义或解释时又间接或直接的用到那些由他们定义的词使用者读懂字典中全部词汇的释义的前提是必须掌握一些少量的 非常基础的词汇的含义否则 将陷入一个无解的问题陷阱中 函数的递归调用 26 函数的递归调用 例7 6解题思路 age 5 age 4 2age 4 age 3 2age 3 age 2 2age 2 age 1 2age 1 10 27 age 5 age 4 2 age 4 age 3 2 age 3 age 2 2 age 2 age 1 2 age 1 10 age 2 12 age 3 14 age 4 16 age 5 18 回溯阶段 递推阶段 结束递归的条件 递归过程 28 age 5 输出age 5 main c age 4 2 age函数n 5 c age 3 2 age函数n 4 c age 1 2 age函数n 2 c age 2 2 age函数n 3 c 10 age函数n 1 age 1 10 age 2 12 age 3 14 age 4 16 age 5 18 18 函数调用过程 29 例7 7求n的阶乘 函数的递归调用 includeintfac intn intf if n 0 printf n 0 dataerror elseif n 0 n 1 f 1 elsef fac n 1 n return f voidmain intn y printf Inputaintegernumber scanf d 注意内存溢出 30 任何一个递归调用程序必须包括两部分if 递归终止条件 return递归公式的初值 elsereturn递归函数调用返回的结果值 任何递归调用都必须向着 基本条件 的方向进行递归调用能在有限次数内终止 函数的递归调用 基本条件控制递归调用结束 仅当满足一定条件时 递归终止 称为条件递归 一般条件控制递归调用像基本条件转化 31 递归方法编写程序的优点符合人的思维习惯 逼近数学公式的表示从编程角度来看 简洁 直观 精炼 易编 易懂 逻辑清楚 结构清晰 可读性好递归方法编写程序的缺点增加了函数调用的开销耗费更多的时间和内存空间 效率低重复计算多 函数的递归调用 32 以下3种情况需要使用递归数学定义是递归的 如计算阶乘 排列组合数据结构是递归的 如链表问题的解法是递归的非数值计算领域存在很多必须用递归才能解决的经典问题Hanoi塔 骑士游历 八皇后问题等 函数的递归调用 33 数组元素作函数实参 值传递例两个数组比较大小算法描述 a和b为有10个元素的整型数组 比较两数组对应元素变量n m k分别记录a i b i a i b i a i k 认为数组a b若n k 认为数组a b若n k 认为数组a b 数组元素作为函数参数 34 数组元素作为函数参数 n 0m 0k 0 a b 35 数组元素作为函数参数 36 数组名作函数参数 地址传递在主调函数与被调函数分别定义数组 且类型应一致形参数组大小 多维数组第一维 可不指定形参数组名是地址变量说明用数组元素作实参时 向形参变量传递的是数组元素的值用数组名作实参时 向形参传递的是数组首元素的地址 数组名作为函数参数 37 例7 10求10个学生的平均成绩 数组名作为函数参数 includeintmain floataverage floatarray 10 floatscore 10 aver inti printf input10scores n for i 0 i 10 i scanf f floataverage floatarray 10 inti floataver sum array 0 for i 1 i 10 i sum sum array i aver sum 10 return aver 实参用数组名 形参用数组定义 38 在被调函数中对形参数组定义时可以指定每一维的大小 也可以省略第一维的大小说明 intarray 3 10 intarray 10 intarray intarray 3 多维数组名作函数参数 39 变量要先定义后使用 变量的有效范围 在一个函数中定义的变量 其它函数能否使用 每个变量都有作用域 在什么范围内有效 局部变量 局部变量 内部变量在函数内定义 只在本函数内有效 函数外无效说明 main中定义的变量只在main中有效不同函数中的同名变量 占不同内存单元 互不干扰形参属于局部变量可以在复合语句中定义变量 这些变量只在复合语句中有效 40 例不同函数中同名变量 局部变量 includevoidmain inta b a 3 b 4 printf main a d b d n a b sub printf main a d b d n a b voidsub inta b a 6 b 7 printf sub a d b d n a b 运行结果 main a 3 b 4sub a 6 b 7main a 3 b 4 41 全局变量 外部变量在函数外定义 可为本文件所有函数共用有效范围 从定义变量的位置开始到本源文件结束 及有extern说明的其它源文件说明全局变量增加了函数间数据联系的渠道若全局变量与局部变量同名 则全局变量被屏蔽建议不要在不必要时使用全局变量全局变量在程序全部执行过程中占用存储单元降低了函数的通用性 可靠性 可移植性全局变量使用过多 会降低程序清晰性 容易出错 全局变量 42 例7 15若外部变量与局部变量同名 分析结果 全局变量 includeinta 3 b 5 voidmain intmax inta intb inta 8 printf d n max a b intmax inta intb intc c a b a b return c 运行结果 8 43 存储方式静态存储 程序运行期间分配固定存储空间动态存储 程序运行期间根据需要动态分配存储空间内存用户区 变量的存储方式 程序开始执行时分配存储区 程序执行完毕释放 占据固定的存储单元 函数调用时分配存储区 调用结束时释放 存储空间不固定 44 自动 auto 静态 static 寄存器 register 外部 extern C中的存储类别 45 自动变量 auto变量 定义格式auto数据类型变量表 存储特点属于动态存储方式 定义但没有初始化 则其值是不确定的 由于自动变量的作用域和生存期 都局限于定义它的个体内 函数或复合语句 因此不同的个体中允许使用同名的变量而不会混淆 即使在函数内定义的自动变量 也可与该函数内部的复合语句中定义的自动变量同名 程序中的变量如果没有专门声明 都默认为自动变量 局部变量的存储类别 46 静态局部变量 static局部变量 定义格式static数据类型变量表 存储特点静态局部变量属于静态存储 在程序执行过程中 即使所在函数调用结束也不释放 换句话说 在程序执行期间 静态内部变量始终存在 但其它函数是不能引用它们的 只赋初值一次 且每次调用它们所在的函数时 不再重新赋初值 只是保留上次调用结束时的值 如果定义但没有初始化 则自动赋以 整型和实型 或 0 字符型 何时使用静态内部变量需要保留函数上一次调用结束时的值 变量只被引用而不改变其值 局部变量的存储类别 47 例7 16考察静态局部变量的值 includeintmain intf int inta 2 i for i 0 i 3 i printf d f a return0 intf inta autointb 0 staticintc 3 b b 1 c c 1 return a b c 运行结果 789 0 0 0 3 4 5 1 1 1 6 5 4 7 8 9 48 寄存器 register 变量一般情况下 变量的值都是存储在内存中的 为提高执行效率 语言允许将局部变量的值存放到寄存器中 这种变量就称为寄存器变量 定义格式 register数据类型变量表 局部变量的存储类别 49 用extern声明外部变量外部变量是在函数的外部定义的全局变量 编译时将外部变量分配在静态存储区 一般用extern来声明 声明格式 extern数据类型外部变量表 用法在一个文件内扩展外部变量的作用域外部变量有效的作用范围只限于定义处到本文件结束 在外部变量定义之前的函数需要引用该变量 使用extern对该变量作 外部变量声明 可以从 声明 处起 使用该外部变量 全局变量的存储类别 50 例7 18 includeintmain intmax externintA B C scanf d d d 51 用法将外部变量的作用域扩展到其他文件一个C程序可以由多个源程序文件组成 如何在一个文件中引用另一个文件中定义的外部变量 用extern声明外部变量 52 例7 19 includeintA intmain intpower int intb 3 c d m scanf d d 文件 文件 externA intpower intn inti y 1 for i 1 i n i y A return y 53 用法将外部变量的作用域限制在本文件中如何限制外部变量不被其他文件引用 定义静态外部变量 用extern声明外部变量 staticintA intmain externA voidfun intn A A n 54 用static声明一个变量的作用对局部变量用static声明 把它分配在静态存储区 该变量在整个程序执行期间不释放 其所分配的空间始终存在 对全局变量用static声明 则该变量的作用域只限于本文件 即被声明的文件 中 55 变量存储类别小结 静态 动态 存储方式 程序整个运行期间 函数调用开始至结束 生存期 编译时赋初值 只赋一次 每次函数调用时 赋初值 自动赋初值0或空字符 不确定 未赋初值 静态存储区 动态区 存储区 寄存器 局部变量 外部变量 作用域 定义变量的函数或复合语句内 本文件 其它文件 局部变量默认为auto型局部static变量具有全局寿命和局部可见性extern不是变量定义 可扩展外部变量作用域 register 局部static auto 外部static 外部 存储类别 56 作用域和生存期作用域如果一个变量在某个文件或函数范围内是有效的 就称该范围为该
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 深度反馈绩效协议
- IT系统安全审计检查清单模板
- 家具产品购销与安装合同
- 2026届湖南省长沙市岳麓区湖南师范大学附中化学高二第一学期期中质量跟踪监视模拟试题含解析
- 雨露计划申请书
- 父母恩情重如山读理解父母有感650字(11篇)
- 岗位职责说明书
- 技术项目开发阶段性评审报告表
- 企业行政办公物资申请与采购模板
- 初中诗歌朗诵技巧指导:以静夜思为例教学教案
- 医疗废物与污水处理培训
- 康复科疾病护理
- 4S店员工职业卫生培训
- 地下通道水泵房管理制度
- 溺水患者急救培训
- 2026版步步高大一轮高考数学复习讲义第十章 §10.1 计数原理与排列组合含答案
- 人力公司营销策划方案
- 医院医疗用房管理制度
- 股权代持协议终止协议书
- 捡土豆装车合同协议书
- 国际压力性损伤溃疡预防和治疗临床指南(2025年版)解读
评论
0/150
提交评论