




已阅读5页,还剩74页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章函数 本章内容包括函数的基本概念和函数的定义方法 函数的调用 函数参数和函数的值 函数的嵌套调用 函数的递归调用 数组做函数参数 变量的类型 全局变量和局部变量 静态存储变量和动态存储变量 函数的分类 外部函数和内部函数 1 如果有两个同学参加学生会主席的竞选 现已统计出两个人的总得分 怎么确定谁当选 用函数来实现 提出问题 相关知识点 7 1函数的定义 函数参数和函数的值7 2函数的调用 7 1 1C语言对函数的规定 1 一个源程序文件由一个或多个函数组成2 一个c程序由一个或多个源程序文件组成3 c程序的执行从main函数开始到main 函数结束4 所有函数都是平行的 函数不能嵌套定义5 函数按使用角度分 标准函数 自定义函数 按形式分 无参函数 有参函数 7 1 2函数定义的一般形式 1 无参函数的定义形式类型说明符函数名 声明部分语句 3 可以有 空函数 类型说明符函数名 2 有参函数的定义形式类型说明符函数名 形参列表 声明部分语句 现在我们试着写出问题1的函数 1 两个数求最大值 定义两个形参x y 从x y中找到最大者 最大者的类型即函数类型 可得函数的首部 intmax intx inty 2 写出函数体 实现两个数求最大值intmax intx inty intz z x y x y z为x y中得最大者 return z 注意 return z 的作用是将z的值作为函数值带回主调函数中 即将最大值带回 说明 1 形参列表样式 intx inty 注意 每个形参都有类型 2 函数类型原则上要求与return后表达式类型一致 如不一致 表达式类型强制转换成函数的类型 如果函数的确不需要返回值 设为void型 3 return语句作用 一是 带返回值到函数调用处 二是 将流程返回函数调用处 如果该函数没有返回值 可以省略return 最后的 也具有将流程返回调用处的功能 4 如何确定一个函数是否需要返回值 想一想 我们真的将问题1完全解决了吗 7 2函数的调用 1 函数调用的一般形式 函数名 实参列表 回顾函数定义的一般形式 函数类型函数名 形参列表 2 C程序的一般结构 main 语句函数名 实参列表 函数调用 语句 函数类型函数名 形参列表 函数定义 函数体return语句 1 如果有两个同学参加学生会主席的竞选 现已统计出两个人的总得分 怎么确定谁当选 用函数来实现 解决问题 例7 1求两个数的最大值 main inta b c a 12 b 34 c max a b 函数调用 printf max d n c intmax intx inty 函数定义 intz z x y x y return z 分析例7 1的执行过程 a b 12 34 x y 12 34 主函数开始执行 定义变量a b c a b赋初值 主函数执行下述语句时 c max a b 传值给被调用函数intmax intx inty 被调用函数开始执行 定义变量z z存放最大值 c z 主函数执行下述语句z x y x y 34 被调用函数执行下述语句时 return z 带返回值z给主函数c max a b 34 注意被调函数执行完 主函数继续执行 输出最大值 printf max d n c 2 设某班50人 写一程序统计某一单科成绩各分数段的分布人数 每人的成绩随机输入 并要求按下面格式输出统计结果 表示实际分布人数 0 59 60 84 85 100 问题的深化 算法思想 1 定义一个输出n个 的函数 2 在main函数中统计各分数段的人数 分别用n1 n2 n3来存放 3 在函数调用时 n1作实参 传给形参n 输出0 59的分布人数 n2作实参 传给形参n 输出60 84的分布人数 n3作实参 传给形参n 输出85 100的分布人数 例7 2成绩分布情况 为简化问题 我们输入10个成绩 includevoidstar intn inti for i 0 i n i printf printf n main inti j n1 n2 n3 score i 1 n1 n2 n3 0 while i 0 1 猜年龄 5个小朋友排着队作游戏 第1个小朋友10岁 其余的年龄一个比一个大2岁 第5个小朋友的年龄 提出问题 相关知识点 7 3函数的嵌套调用7 4函数的递归调用 7 3函数的嵌套调用 嵌套调用的定义 C语言的函数调用可以嵌套 即在调用一个函数的过程中 可以再调用另一个函数 例如 intf1 intn main inty inta if n 5 y f2 n scanf d 7 4函数的递归调用 1 什么是递归调用递归就是某一事物直接或间接地由自己组成 故在调用一个函数的过程中 又出现直接或间接地调用该函数本身 称为函数的递归调用 2 递归的方式 直接递归 间接递归 1 猜年龄 5个小朋友排着队作游戏 第1个小朋友10岁 其余的年龄一个比一个大2岁 第5个小朋友的年龄 解决问题 算法思想 设age n 是求第n个人的年龄 那么 根据问题1的题义 我们可知 age 5 age 4 2age 4 age 3 2age 3 age 2 2age 2 age 1 2age 1 10 可以用数学公式表述如下 10 n 1 age n age n 1 2 n 1 下面用图表示求第5个人年龄的过程 例7 3问题1的源代码 age intn 求年龄的递归函数 intc c用作存放函数的返回值的变量 if n 1 c 10 elsec age n 1 2 returnc main printf age 5 d age 5 采用递归方法求1 2 3 n的和 该问题的递归公式 1 n 1 sum n sum n 1 n n 1 当n为1时 函数值为1是递归出口 采用递归方法求n 该问题的递归公式 1 n 1或n 0 Fia n Fia n 1 n n 1 当n为1或0时 函数值为1是递归出口 2 计算机协会在举办 数学趣味游戏 老师对婷婷说 我给你一个整数 若它是偶数 将它除以2 若它是奇数 将它乘以3加1 得到的结果再继续判断 是偶数 除以2 是奇数 乘以3加1 最后 看看这个数变成几 你会发现 不管我给你的是什么数 最终 它会变成1 现在 你编程验证以下 问题的深化 算法思想 这是 角谷猜想 的问题 1 输入一个整数 2 如果 是 转 4 结束 否则转 3 3 如果 是偶数 否则 转 2 4 输出 从中可以看出 是递归出口 用递归函数实现第 3 步 例7 4角谷猜想main intn printf inputanumber scanf d 3 相传古代印度布拉玛神庙中有一个僧人 他每天不分白天黑夜 不停地移动那些圆盘 据说 当所有64个圆盘全部从一根杆上移到另一根杆上的那一天就是世界的末日 这就是著名的汉诺塔 Hanoi 问题 如图 一次只能移动一个盘 且不允许大盘放在小盘的上面 自主学习 算法思想 怎样编写这种程序 思路上还是先从最简单的情况分析起 搬一搬看 慢慢理出思路 1 在A柱上只有一只盘子 假定盘号为1 这时只需将该盘从A搬至C 一次完成 记为move1fromAtoC 2 在A柱上有二只盘子 1为小盘 2为大盘 第 1 步将1号盘从A移至B 这是为了让2号盘能移动 第 2 步将2号盘从A移至C 第 3 步再将1号盘从B移至C 这三步记为 move1fromAtoB move2fromAtoC move3formBtoC 3 在A柱上有3只盘子 从小到大分别为1号 2号 3号第 1 步将1号盘和2号盘视为一个整体 先将二者作为整体从A移至B 给3号盘创造能够一次移至C的机会 这一步记为move 2 A C B 意思是将上面的2只盘子作为整体从A借助C移至B 第 2 步将3号盘从A移至C 一次到位 记为move3fromAtoC 第 3 步处于B上的作为一个整体的2只盘子 再移至C 这一步记为move 2 B A C 意思是将2只盘子作为整体从B借助A移至C 4 从题目的约束条件看 大盘上可以随便摞小盘 相反则不允许 在将1号和2号盘当整体从A移至B的过程中move 2 A C B 实际上是分解为以下三步第 1 1步 move1formAtoC 第 1 2步 move2formAtoB 第 1 3步 move1formCtoB 经过以上步骤 将1号和2号盘作为整体从A移至B 为3号盘从A移至C创造了条件 同样 3号盘一旦到了C 就要考虑如何实现将1号和2号盘当整体从B移至C的过程了 实际上move 2 B A C 也要分解为三步 第 3 1步 move1formBtoA 第 3 2步 move2formBtoC 第 3 3步 move1formAtoC 5 看move 2 A C B 是说要将2只盼自从A搬至B 但没有C是不行的 因为第 1 1步就要将1盘从A移到C 给2盘创造条件从A移至B 然后再把1盘从C移至B 看到这里就能明白借助C的含义了 因此 在构思搬移过程的参量时 要把3个柱子都用上 6 定义搬移函数move n A B C 物理意义是将n只盘子从A经B搬到Cmove n A B C 分解为3步 1 move n 1 A C B 理解为将上面的n 1只盘子作为一个整体从A经C移至B 2 输出n AtoC 理解将n号盘从A移至C 是直接可解结点 3 move n 1 B A C 理解为将上面的n 1只盘子作为一个整体从B经A移至C 这里显然是一种递归定义 当解move n 1 A C B 时又可想到 将其分解为3步 第1步 将上面的n 2只盘子作为一个整体从A经B到C move n 2 A B C 第2步 第n 1号盘子从A直接移至B 即n 1 AtoB 第3步 再将上面的n 2只盘子作为一个整体从C经A移至B move n 2 C A B 源代码 intstep 1 整型全局变量 预置1 步数 voidmove int char char char 声明要用到的被调用函数 voidmain intn 整型变量 n为盘数 printf 请输入盘数n scanf d 调用函数move n a b c 以下函数是被主程序调用的函数 voidmove intm charp charq charr 自定义函数 if m 1 如果m为1 则为直接可解结点 printf d move1 from cto c n step p r 直接可解结点 输出移盘信息 step step 1 步数加1 else 如果不为1 则要调用move m 1 move m 1 p r q 递归调用move m 1 printf d move d from cto c n step m p r 直接可解结点 输出移盘信息 step step 1 步数加1 move m 1 q p r 递归调用move m 1 本讲小结 1 什么是嵌套调用 2 什么是递归调用 递归出口 递归过程 1 在体育课上 20个学生正在测试100米 老师把学生成绩一一记录下来 现在将学生由快到慢排序 你能帮忙排一排 用函数实现 提出问题 相关知识点 7 5数组作为函数参数 7 5数组作为函数参数 一 数组元素作函数实参数组元素实际上就是该类型的一简单变量 如 有一整型数组a定义 inta 10 则其中的数组元素a 1 就是一个整型变量 所以 数组元素作为函数的实参 与用变量做实参一样 是单向传递 即 传值调用 例如 voidswap intx inty intt t x x y y t printf d d n x y main inta 3 5 2 数组a定义初始化 printf d d n a 1 a 2 swap a 1 a 2 调用swap函数 printf d d a 1 a 2 二 一维数组名作函数实参 数组名代表数组的首地址 所以 在函数调用时 把数组名作为函数实参传递 实质上就是把该数组的首地址传给了形参 称为 传址调用 什么是 传值 什么是 传址 所传数据类型不同 1 在体育课上 20个学生正在测试100米 老师把学生成绩一一记录下来 现在将学生由快到慢排序 你能帮忙排一排 用函数实现 解决问题 算法思想 主调函数main 程序的入口 包含主要的操作 将20个学生的成绩用数组a存放 有20个元素 输出排序前的成绩 即 输出数组a的20个元素值 调用函数来实现学生成绩的排序 即 对数组排序 输出排序后的成绩 即 调用返回后 输出数组a的20个元素值 被调用函数sort 用起泡法对数组元素排序 源代码 includevoidsort floatb intn inti j floatt for j 1 ja i 1 a i a i 1 为真 t a i a i a i 1 a i 1 t 将a i 与a i 1 对换 main floata 11 将10个数给a 1 到a 10 故定义数组长度为11 inti printf input10numbers n 输入10个数 for i 1 i 11 i scanf f 说明 1 数组名代表数组的首地址 2 数组名作函数实参 传递的是数组的首地址 称为传址调用 3 传值 传址 只是传递的数据类型不同 传值 一般的数值 传址 地址 4 不管 传值 还是 传址 C语言都是单向传递数据的 一定是实参传递给形参 反过来不行 也就是说C语言中函数参数传递的两种方式本质相同 单向传递 5 传址调用机制 分析 实参a数组的地址传给形参b数组 sort函数对形参b数组用起泡法排序 其实实质就是对实参数组a排序 达到目的 结论 传址调用 实参地址传递给形参 形参中的改变就是实参中的改变 可以理解成双向的 实参的地址值形参的地址值即实参的数值形参的数值 三 二维数组名作函数参数 作用 与一维数组名作函数参数相同 说明 1 在被调用函数中 形参数组定义时可以指定每一维的大小 也可以省略第一维的大小说明 但是不能把第二维的大小说明省略 更不能只指定第一维而省略第二维 2 实参数组可以大于形参数组 这时形参数组只取实参数组的一部分 其余部分不起作用 2 给定某年某月某日 将其转换成这一年的第几天并输出 问题的深化 算法思想 若给定的月是I 则将1 2 3 I 1月的各月天数累加 再加上指定的日 但对于闰年 二月的天数29天 因此还要判定给定的年是否为闰年 为实现这一算法 需设置一张每月天数列表 给出每个月的天数 考虑闰年 平年的情况 此表可设置成一个2行3列的二维数组 其中第一行对应的每列 设1 12列有效 元素是平年个月的天数 第二行对应的是闰年每月的天数 源代码 includeintday of year intday1 13 intyear intmonth intday inti j i year 4 0 7 6局部变量和全局变量 变量的分类 变量从数据类型的角度 可以分为整型 实型 字符型等 变量从作用域 变量的有效范围 可见性 的角度可以分为局部变量和全局变量 变量定义的位置决定了变量的作用域 7 7 1局部变量 1 定义 是指定义在函数内部或程序块内的变量 局部有效 也成为内部变量 2 作用域 为块 复合语句 作用域 即从定义点开始到所在块结束 3 C语言中 在以下各位置定义的变量均属于局部变量 1 函数体内定义的变量 在本函数范围内有效 作用域局限于函数体内 2 在复合语句内定义的变量 在本复合语句范围内有效 作用域局限于复合语句内 3 有参函数的形式参数也是局部变量 只在其所在的函数范围内有效 doublefun1 intx inty x y m n局部变量 在fun1函数内有效 作用域fun1函数 intm n intfun2 charch ch a b局部变量 在fun2函数内有效 作用域fun2函数 inta b main inta b a b局部变量 在main函数内有效 作用域main函数 intx y x y局部变量 在复合语句中有效 作用域复合语句 4 说明 1 main中定义的变量也只在main中有效 而且 main也不能使用其它函数中定义的变量 2 同名 不同作用域的变量是不同的变量 3 在各个函数中的局部变量起作用的时刻是不同的 例子1不同函数中同名不同义的变量f1 intn intm if n 100 m n 10 elsem n 1 printf d n m main intm scanf d 假设输入80 试分析程序的执行情况 例子2不同复合语句 程序段 中同名不同义的变量main intx y x 10 y 20 printf d d n x y inty 10 x y 5 printf d d n x y printf d d n x y 7 6 2全局变量 1 定义 是指定义在所有函数之外的变量 所有函数前 各个函数之间 所有函数后 也成为外部变量 intmax intf1 intn voidf2 main intf1 intn intmax voidf2 main max的使用范围 2 作用域 从定义全局变量的位置起到本源程序结束为止 3 说明 1 置全局变量的作用是为了增加函数间数据联系的渠道 例如 当有多个返回值需要带回时 可以使用全局变量 2 使用全局变量时 一定要小心 因为 全局变量在程序的全部执行过程中都有效 一个函数的使用会影响到其他函数的使用 3 在同一范围内 如果全局变量与局部变量同名 则局部变量优先于全局变量 例如 inta 3 b 5 a b为全局变量 intmax inta intb a b为局部变量 returna b a b 形参a b作用范围 main inta 8 a为局部变量 局部变量a作用范围printf d max a b 分析 运行结果 说明 局部变量a有效 全局变量a失效 7 7动态存储变量与静态存储变量 7 7 1变量的存储类别1 变量的生存期 1 定义 指变量值存在的时间长短 2 根据变量生存期的不同 可以将变量分为 动态存储变量和静态存储变量 变量的存储方式决定了变量的生存期 2 变量的存储方式 1 动态存储方式 是指在程序运行期间根据需要动态分配存储空间的存储方式 即需要时给存储空间 不需要时就释放 如形参 2 静态存储方式 是指在程序运行期间分配固定的存储空间的存储方式 如全局变量 3 变量的存储类别 1 定义 是指在内存中存储的方法 2 根据变量的作用域和生存期不同 可以将变量分为以下四类存储类别 7 7 2局部变量的存储方式 1 auto 1 默认存储类别 函数内 复合语句中定义的局部变量和形参均是auto型 属于局部变量的范畴 autointa b 2 与inta b 2 二者等价 2 自动变量是动态的 其所在的函数或复合语句执行时 系统动态为相应的自动变量分配存储单元 当自动变量所在的函数或复合语句执行结束后 自动变量失效 它所在的存储单元被系统释放 所以原来的自动变量的值不能保留下来 2 register 与auto类似 是C语言使用较少的一种局部变量的存储方式 该方式将局部变量存储在CPU的寄存器中 寄存器比内存操作要快很多 所以可以将一些需要反复操作的局部变量存放在寄存器中 也是动态的 注 CPU的寄存器数量有限 如果定义了过多的register变量 系统会自动将其中的部分改为auto型变量 3 static 1 被定义为static类型的局部变量 具有固定的存储空间 即使调用结束 其存储空间也不被释放 是静态的 2 被定义为static类型的局部变量 是在编译时赋初值的 即只赋初值一次 以后每次调用函数时 不再重新赋初值而只是保留上次函数调用结束时的值 3
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年人力资源管理师考试重点难点解析与模拟题集
- 2025年中央空调系统中级操作员考试要点解析
- 2025年互联网营销专家应聘笔试大纲及样题
- 2025年市场营销策略经理面试指南及预测题
- 2025年乡镇农技站招聘面试模拟题耕地质量管理员职位
- 2025年中石油区域加油站-电商-物流运营总监竞聘模拟题及答案
- 2025年客服专员招聘考试题库及参考答案详解
- 2025年人力资源管理师高级面试实战模拟题
- 2025年实战演练项目经理岗位面试题及应对策略解析
- 2025年乡镇儿童督导员招聘笔试备考攻略与答案详解
- 2025-2026学年粤教粤科版(2024)小学科学二年级上册(全册)教学设计(附目录)
- 2025年山东高考历史试卷真题讲评及备考策略指导(课件)
- 供养中心考试题及答案
- 2025年云南省中考英语试卷真题(含标准答案及解析)
- 开学第一课(教学课件)-八年级语文上册同步备课系列(部编版)
- 【公开课】第一节+内能及其改变(教学课件)物理沪科版2024九年级全一册
- 海事英语阅读 课件Unit 9 Text A Types of Maritime Vessels
- 发型师的职业素养
- 2025科技公司研发部门劳动合同范本
- 少儿沪语趣味启蒙课件
- 机电安装工程验收用表
评论
0/150
提交评论