




已阅读5页,还剩65页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Chap8函数 主要内容 1 函数的定义2 函数的调用 包括嵌套调用和递归调用 3 局部变量和全局变量4 变量的存储类别5 综合题目重点 1 如何编写函数2 如何调用函数 包括库函数和自定义函数 第8章函数 8 1概述模块化程序设计基本思想 将一个大的程序按功能分割成一些小模块 即函数也可以说是完成某些特定功能的代码块 函数的优点 特点 各模块相对独立 功能单一 结构清晰 接口简单易于维护和功能扩充缩短开发周期 实现 编写一次 多次调用 避免在不同的程序中重复编写相同的函数 避免程序开发的重复劳动开发方法 自上向下 逐步分解 分而治之 8 2函数的定义一般格式 合法标识符 函数返回值类型缺省int型无返回值void 函数体 例有参函数 现代风格 intmax intx inty intz z x y x y return z 例无参函数voidprintstar printf n 或voidprintstar void printf n 形参类型说明表 类型名形式参数1 类型名形式参数2 空函数 函数类型函数名 调用此函数时 什么也不做 只是表明这里要调用一个函数 而现在这个函数的功能还没实现 空函数在程序设计中常常用到的 1 预留函数 便于以后扩充程序功能 2 便于程序的模块化设计和调试 程序设计中往往根据需要确定若干模块 分别由一些函数来实现 一个大系统 需要编写很多用户函数 而这些函数不可能也没有必要同步完成 通常从一些基本模块开始 编写一个调试一个 对于没有编写的函数就需要用空函数代替 从而也有利于集体创作 注意 良好的程序设计习惯 为了使程序具有良好的可读性并减少出错 凡不要求返回值的函数都应定义为空类型 即使函数类型为整型 也不使用系统的缺省处理 不能嵌套定义函数 return 8 3函数的返回值返回语句形式 return 表达式 或return表达式 或return 功能 使程序控制从被调用函数返回到调用函数中 同时把返值带给调用函数说明 函数中可有多个return语句 但是只能返回一个确定的值 若无return语句 遇 时 自动返回调用函数若函数类型与return语句中表达式值的类型不一致 按前者为准 自动转换 函数调用转换void型函数 例无返回值函数voidswap intx inty inttemp temp x x y y temp 用 8 4函数的调用重点1 如何调用一个函数2 对被调函数的声明3 主调函数和被调函数之间如何进行数据传递调用形式函数名 实参表 说明 实参与形参个数相等 类型一致 按顺序一一对应实参表求值顺序 因系统而定 TurboC自右向左 对被调函数的声明对被调用函数要求 必须是已存在的函数库函数 include用户自定义函数 函数类型说明函数说明一般形式 函数类型函数名 形参类型 形参名 或函数类型函数名 不常用 作用 告诉编译系统函数类型 参数个数及类型 以便检验函数说明位置 程序的数据说明部分 函数内或外 下列情况下 可不作函数说明若函数返值是char或int型 系统自动按int型处理被调用函数定义出现在主调函数之前 例函数说明举例 8 5函数参数及其传递方式形参与实参形式参数 定义函数时函数名后面括号中的变量名实际参数 调用函数时函数名后面括号中的表达式 例比较两个数并输出大者 voidmain inta b c scanf d d 说明 实参必须有确定的值形参必须指定类型形参与实参类型一致 个数相同形参在函数被调用前不占内存 函数调用时为形参分配内存 调用结束 内存释放 8 5函数参数及其传递方式形参与实参形式参数 定义函数时函数名后面括号中的变量 此时的参数无具体的值 仅仅表示参数的类型 个数 以及在函数体内对其如何处理 实际参数 调用函数时函数名后面括号中的表达式其作用是 该函数被调用时用来接收实参的值 例计算x的立方 floatcube floatx return x x x voidmain floata product printf Pleaseinputvalueofa scanf f x 1 2 1 2 1 828 参数传递方式值传递方式方式 函数调用时 为形参分配单元 并将实参的值复制到形参中 调用结束 形参单元被释放 实参单元仍保留并维持原值特点 形参与实参占用不同的内存单元单向传递 写出程序的运行结果 includevoidmain intx 8 y 11 voidswap inta intb printf x d ty d n x y printf swapped n swap x y printf x d ty d n x y voidswap inta intb inttemp temp a a b b temp 地址传递方式 函数调用时 将数据的存储地址作为参数传递给形参特点 形参与实参占用同样的存储单元 双向 传递实参和形参必须是地址常量或变量 如何定义一个函数 如何定义一个函数 第一步 参数分析函数需要的参数 包括参数的个数以及每个参数的类型第二步 函数返回值若无返回值为void 第三步 编写函数体 例如 编写一个函数求n 并调用要处理的数据是n 因此必须有一个参数n 类型为int 返回值为long型 即longfact intn 求n longintfact intn 定义函数 longintp 1 while n p n return p voidmain 调用函数 intn printf inputan n scanf d 作业 例 计算两个整数的最小公倍数voidmain intm n min intmin multiple intx inty 函数声明 printf ninputm n scanf d d 嵌套调用 8 6函数的嵌套与递归调用嵌套调用C规定 函数定义不可嵌套 但可以嵌套调用函数 例求三个数中最大数和最小数的差值 includeintdif intx inty intz intmax intx inty intz intmin intx inty intz voidmain inta b c d printf inputa b c n scanf d d 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 递归调用定义 程序调用自身的编程技巧或者函数直接或间接的调用自身叫函数的递归调用 一个比较经典的描述是老和尚讲故事 他说从前有座山 山上有座庙 庙里有个老和尚在讲故事 这样没完没了地反复讲故事 直到最后老和尚烦了停下来为止 反复讲故事可以看成是反复调用自身 但如果不能停下来那就没有意义了 所以最终还要能停下来 递归的关键在于找出递归方程式和递归终止条件 即老和尚反复讲故事这样的递归方程式要有 最后老和尚烦了停下来这样的递归的终止条件也要有 递归调用定义 程序调用自身的编程技巧或者函数直接或间接的调用自身叫函数的递归调用 说明C编译系统对递归函数的自调用次数没有限制每调用函数一次 在内存堆栈区分配空间 用于存放函数变量 返回值等信息 所以递归次数过多 可能引起堆栈溢出 intf intx inty z z f y return 2 z 递归算法一般用于解决三类问题 数据的定义形式是按递归定义的 比如阶乘的定义及裴波那契数列的定义 f n f n 1 f n 2 f 0 1 f 1 1 问题解法按递归算法实现 例如回溯等 数据的结构形式是按递归定义的 如树的遍历 图的搜索等 递归解决实际问题的例子很多 如经典的梵塔问题 分析递归问题的关键 1 每次调用自己时参数的变化规律 2 递归结束的条件 例如 求n 分析 f n f n 1 n n 1 规律f 1 1 n 0 1 递归结束条件 例求n的阶乘 includefloatfac 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 floaty printf Inputaintegernumber scanf d 汉诺塔 例编写函数 验证陈景润研究的哥德巴赫猜想 任意大偶数为两个素数之和并输出这两个素数 所谓大偶数是指6开始的偶数 分析 isprime inta 实现判断一个数a是否为素数 even intx 实现找到并输出两个素数 其和等于x voidmain 实现输入一个大偶数 并调用even 输出该大偶数对应的两个素数 设变量x为任意大偶数 可从x中依次减去i i从2变化到x 2 依次判断i x i是否为素数 步骤如下 i初值为2 判断i是否是素数 若是 执行步骤 若不是 执行步骤 判断x i是否是素数 若是 执行步骤 若不是 执行步骤 输出结果 返回调用函数 使i增1 重复执行步骤 数组 程序 include math h intisprime int 函数声明 voideven int voidmain inta printf Enteraevennumber 6 scanf d voideven intx 函数定义 inti for i 2 i x 2 i if isprime i if isprime x i printf d d d n x i x i return intisprime inta 函数定义 inti for i 2 i a i if a i 0 return0 return1 数组 8 7数组作为函数参数数组元素作函数实参 值传递 例两个数组大小比较 n 0m 0k 0 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 参数传递分类 值 地址地址传递方式 函数调用时 将数据的存储地址作为参数传递给形参特点 形参与实参占用同样的存储单元 双向 传递实参和形参必须是地址常量或变量数组名作函数参数地址传递在主调函数与被调函数分别定义数组 且类型应一致形参数组大小 多维数组第一维 可不指定形参数组名是地址变量 例求学生的平均成绩 includefloataverage intstu 10 intn voidvoidmain intscore 10 i floatav printf Input10scores n for i 0 i 10 i scanf d floataverage intstu 10 intn inti floatav total 0 for i 0 i n i total stu i av total n returnav 实参用数组名 形参用数组定义 intstu 比较 例数组元素与数组名作函数参数比较 includevoidswap2 intx inty intz z x x y y z voidmain inta 2 1 2 swap2 a 0 a 1 printf a 0 d na 1 d n a 0 a 1 值传递 includevoidswap2 intx intz z x 0 x 0 x 1 x 1 z voidmain inta 2 1 2 swap2 a printf a 0 d na 1 d n a 0 a 1 地址传递 例数组元素与数组名作函数参数比较 举例 例 编写函数实现 用冒泡法对n个整数升序排序 并编写主函数实现数据的输入输出 分析 主程序的算法 S1 输入一批数据 个数为N 存入一维数组a S2 调用函数sort 对一维数组中的数据按从小到大的顺序排序 S3 输出数组a中的各元素 函数sort 的编写 首先 确定函数的类型 void 参数 一维数组的首地址 数据的个数 共2个 然后编写函数体 实现排序 重点 分析参数的传递 比较传值与传地址的区别 各有何用处 图示 形参数组与实参数组的结合方式 word word 例数组排序 简单选择排序 9 49 i 0 例数组排序 简单选择排序 13 68 i 1 i 8 例数组元素升序排序 简单选择排序 数组a与数组array实际上是一个数组 array 的长度无意义 因此可以不说明 比较两种参数传递方式 传值调用 单向数据传递 对形参的改变不影响实参的值 且只能通过return语句返回最多一个值传地址调用 实参传给形参的是数据的地址 所达到的目的是 形参与实参共用同一片存储单元 对形参的改变实际上是对实参的改变 从而实现主 被调函数之间的多个数据传递 变量分类 例求二维数组中最大元素值 intmax value intarray 3 4 inti j k max max array 0 0 for i 0 imax max array i j return max voidmain inta 3 4 1 3 5 8 2 4 6 8 15 18 34 12 printf maxvalueis d n max value a 变量分类 8 8变量的分类概述变量是对程序中数据的存储空间的抽象 编译或函数调用时为其分配内存单元 10 程序中使用变量名对内存操作 变量的属性数据类型 变量所持有的数据的性质 操作属性 存储属性存储器类型 寄存器 静态存储区 动态存储区生存期 变量在某一时刻存在 静态变量与动态变量作用域 变量在某区域内有效 局部变量与全局变量变量的存储类型auto 自动型register 寄存器型static 静态型extern 外部型变量定义格式 存储类型 数据类型变量表 如 intsum autointa b c registerinti staticfloatx y 作用域 自动的 auto 变量 函数的形参和在函数中定义的变量 通常省略存储类别 即隐含指定为自动变量 前面1 7章中的变量均属自动变量 自动变量在需要时系统给他门分配存储空间 在函数调用结束时自动释放这些存储空间 例autointa 2 b 3 与inta 2 b 3 等价 静态的 static 1 静态局部变量 作用域为本函数内部存储类别为静态存储类 因此其生存期与该函数所在程序运行期间相同 即当函数调用结束时能保留原值 在下一次调用该函数时该变量的值是上一次函数调用结束时的值 直至程序运行结束 voidmain voidincrement void increment increment increment voidincrement void intx 0 x printf d n x 例局部静态变量值具有可继承性 运行结果 111 voidmain voidincrement void increment increment increment voidincrement void staticintx 0 x printf d n x 运行结果 123 Register变量 registerintk 则给变量k分配的空间为某个寄存器 优点 速度快 只有局部变量和形参可以定义为register变量 因为机器的寄存器数量有限 因此该类型不常用 外部的 extern 变量 用extern声明外部变量 是为了扩展外部变量的作用域 因外部变量不常用 因此extern也很少使用 必须使用外部变量时 一般建议使用静态全局变量 即在函数体外定义变量时存储类别为 static如staticinta 2 f 变量a的作用范围仅限于本源程序文件内 其它程序中即使用externinta 声明也不能引用a 综合题1 编程实现小学生算术练习系统 主菜单包括5项 加法 减法 乘法 除法 退出 前四项中每一项又包括子菜单 一级 二级 三级 返回4项 其中一级实现10以内的运算 二级实现50以内的整数运算 三级实现100以内的整数运算 进入某一级后 反复练习 由机器产生两个随机数random 用户输入运算结果 输出正确或错误 待结束时给出本级题目中计算正确的百分比 要求每个功能分别用函数实现 作业 综合题2 自动阅卷程序 设单选题20个 2分 题 多选题20个 每题4个供选答案 3分 题 且只要与答案不一致即错 编写函数实现 阅单选题 阅多选题 阅一个人的答题 编写主函数实现批阅N个人的答题卡 正确答案在主程序中输入 分析 voidmain 1 输入正确答案 分别存入一维数组dd 二维数组ss 2 批阅N个人的答题 用循环 将成绩存入数组sc 3 输出每个人的最后成绩 person 函数类型为int 参数两个 dd ss 函数体 1 输入某人的答案 分别存入dd1和ss1 2 分别调用函数single 和many 判别对错并计分 返回总成绩 single 函数类型int 参数dd dd1 函数体 统计数组dd与dd1中相同元素的个数 乘2即得单选题的成绩 返回该成绩 many 函数类型int 参数ss ss1 函数体 统计数组ss与数组ss1中对应行元素相同的行数 乘3即得多选题的成绩 并返回 然后分析各函数的具体实现算法 程序1 分析程序中的传地址调用 嵌套调用时程序的执行过程 程序2 定义存放正确答案的数组为全局的 则dd ss将不作为参数使用 一般情况使用参数传递 include stdio h 程序1 defineN400 numofperson defineNUM20 numofquestion voidmain chardd NUM 1 ss NUM 1 5 intsc N 1 i printf nenterrightanswerofsingleselect n printf n format pressenterafterfinishedinputingallofanswers n for i 1 i NUM i dd i getchar getchar printf nenteranswerofmultiselect n printf nformat pressenterafterinputingaquestion n for i 1 i NUM i gets ss i for i 1 i N i sc i person dd ss printf nno score for i 1 i N i printf n 6d 6d i sc i intperson chardd charss 5 chardd1 21 ss1 31 5 ints i intsignle many printf nenteranswerofsingleselect for i 1 i NUM i dd1 i getchar getchar printf nenteranswerofmultiselect for i 1 i NUM i gets ss1 i s single dd dd1 many ss ss1 return s intsingle chardd chardd1 intn 0 i for i 1 i NUM i if dd i dd1 i n return 2 n intmany charss 5 charss1 5 intn 0 i for i 1 i NUM i if strcmp ss i ss1 i n return n 3 多个文件组成一个程序的方法 1 使用project生成项目文件2 使用include将所有的文件包含到一个文件中 1 从作用域分 局部变量与全局变量局部变量 内部变量定义 在函数内定义 只在本函数内有效说明 voidmain中定义的变量只在voidmain中有效不同函数中同名变量 占不同内存单元形参属于局部变量可定义在复合语句中有效的变量局部变量可用存储类型 autoregisterstatic 默认为auto 全局变量 外部变量定义 在函数外定义 可为本文件所有函数共用有效范围 从定义变量的位置开始到本源文件结束 及有extern说明的其它源文件 外部变量说明 extern数据类型变量表 若外部变量与局部变量同名 则外部变量被屏蔽 特别注意 若局部与全局变量同名 则局中局优先全局变量在程序全部执行过程中占用存储单元 不提倡使用应用 从函数返回多个返回值 局部变量和全局变量小结 局部变量 保证了函数之间的独立性 常用 全局变量 增加了函数之间数据传递的通道 但降低了函数间的独立性 降低了程序的清晰性 因此副作用太大 除非特别需要时 一般不用 占用内存情况 局部变量仅当他所在的函数被调用时才存在 执行完该函数返回后 该变量不再存在全局变量在程序的全部执行过程中一直存在 直至程序执行完 才释放它所占的内存空间 2 从生存期分 动态变量与静态变量存储方式静态存储 程序运行期间分配固定存储空间动态存储 程序运行期间根据需要动态分配存储空间内存用户区 生存期静态变量 从程序开始执行到程序结束动态变量 从包含该变量定义的函数开始执行至函数执行结束 静态变量 分配固定空间 程序整个运行期间都存在 从程序开始执行到程序结 编
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年高考语文二轮复习专题2小说阅读突破练9复合文本阅读的考查方式
- 中国人的健康现状
- 绿茶冲泡技术课件
- 井下透水安全培训
- 重症监护室术后健康宣教指南
- 关于超额预定的培训方案
- 【课件】+声音的产生与传播(教学课件)2024-2025学年初中物理人教版(2024)八年级上册+
- 珠宝门店黄金培训
- 学校领导安全培训
- 2025年深远海风电场建设规划与海上风能资源评估报告
- 煤炭采购及运输的合规性流程
- 数字化赋能城乡融合发展
- 心脏骤停病人的抢救与护理
- 小红书种草营销师(初级)认证考试真题试题库(含答案)
- 汽车行业智能汽车维修与保养方案
- 安全防汛培训课件
- 医药运输配送员培训
- 战略合作框架协议
- 药品经营使用和质量监督管理办法2024年宣贯培训课件
- DB11T 1445-2017 民用建筑工程室内环境污染控制规程
- 35kV线路工程电杆组立施工方案
评论
0/150
提交评论