C语言课件(函数).ppt_第1页
C语言课件(函数).ppt_第2页
C语言课件(函数).ppt_第3页
C语言课件(函数).ppt_第4页
C语言课件(函数).ppt_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

函数 程序的模块化函数定义原型调用参数传递函数的嵌套调用递归函数程序设计举例 C语言程序设计 简介 分而治之与程序的模块化把一个规模较大的问题分解成若干个较小的相对独立的部分 对每一个部分使用一个较小的程序段 即程序模块 module 来处理 从较小的程序段或组件来构建程序 这些小片段或组件比原始程序更容易实现和管理 这些小组件可以被重复使用 函数 C语言的函数 在C语言中 函数 function 是构成程序的基本模块 一个C程序由一个或多个函数组成 有且仅有一个主函数 即main 函数 每个函数完成一个相对独立的且功能明确的任务 由主函数调用其他函数 其他函数也可以互相调用 同一个函数可以被一个或多个函数调用任意多次 函数 C语言的函数 C语言的函数有两大类 标准库函数提供了丰富的函数 例如数学计算 sqrt abs 输入 输出 scanf printf 自定义函数程序员可以编写函数来完成特定的任务 应该熟悉C系统中的标准函数库 应该避免从零开始构建一切 函数 为什么使用函数 函数使程序模块化 程序采用模块化结构的好处 分而治之提高程序开发的效率 使程序易于管理 代码重用使用现有的函数作为构件来创建程序 函数可以被重复使用 抽象隐藏了实现的细节 例如使用库函数 printf 但并不知道它的具体实现 没有影响使用 函数 案例分析 一个简单的函数 编写和使用一个简单的函数 cw0801 c 定义一个函数square 用来计算任意整数的平方 然后 使用该函数计算从1到10所有整数的平方 函数 includeintsquare int voidmain intx for x 1 x 10 x printf d square x intsquare inty returny y 声明函数 使用函数 定义函数 149162536496481100 函数的定义 定义函数的格式 函数名 一个有效的标识符 函数类型 返回值的类型说明符 如果不指定 即缺省 就是int void 表示函数不返回任何值 参数表 声明参数 多个参数用逗号分隔 接收传递进来的数据 必须为每个参数指定数据类型 但int可以省略 函数 函数头 函数体 函数的定义 定义函数的格式 函数体 包括声明语句和可执行语句 在函数体内可以声明变量 不能定义函数 即函数的定义不允许嵌套 控制返回 结束执行 把程序的控制交还主调函数 也可以用return返回一个数值 return return 函数 无返回值 有返回值 案例分析 函数的定义 函数的定义 cw0802 c 定义函数找出三个数中的大数 函数 includeintmaximum int int int voidmain inta b c printf Inputthreeintegers scanf d d d 函数原型 接口 interface 函数原型 函数原型 用来对函数进行声明 编译器使用函数原型来检查函数调用的合法性 注意 函数原型要与函数的定义一致 例如intmaximum inta intb intc intmaximum int int int 函数 函数原型 函数原型在程序文件中的位置不同 作用范围不同 在所有函数的外面在函数内部 函数 main voidfuncA intfuncB int intfuncB int 函数原型 如果程序中没有包含函数原型 编译程序会使用该函数第一次出现的情形来形成自己的函数原型 函数的定义函数的调用默认情况下 编译程序假定函数返回int型的结果 但不会对参数进行任何假定 如果传递给函数的参数不正确 编译程序不会检查到这些错误 函数 函数原型 函数原型强迫参数采用正确的数据类型 举例printf 3f sqrt 4 函数原型使编译程序把整数值4转换为double型的值4 0没有与函数原型中的参数类型完全对应的参数值会在调用函数之前被转换成合适的数据类型 遵守C语言的提升规则 函数 doublesqrt double 函数原型与头文件 头文件每个标准库函数都有对应的头文件 包含了标准库中所有函数的函数原型 以及那些函数所需的数据类型和常量的定义 使用 include命令把头文件包含到程序文件中 include例如 include程序员可以创建自己的头文件使用 h扩展名 使用下面的命令格式包含头文件 include 文件名 例如 include abc h 函数 函数调用 函数调用使用函数 也称为调用函数 函数 main inta b c scanf d d 1 2 6 intmax inta intb intc c a b a b returnc 3 4 5 1 2 主调函数暂停 保存现场 3 把实参的值拷贝给形参 控制权交给函数max 4 5 被调函数执行结束 把函数值返回给主调函数 同时把控制权还给主调函数 6 恢复现场 主调函数继续执行 参数传递 函数间的数据传递方式 参数返回值 函数 intmax inta intb returnc main c max a b 参数传递 返回值传递 调用 实参和形参 实参和形参 函数 intmax inta intb intc a b a b returnc main inta b c scanf d d 形式参数简称 形参 在函数定义时表示可以接受传递过来的值 实际参数简称 实参 在函数调用时给出 形参 形参 函数 intmax inta intb intc a b a b returnc main inta b c scanf d d 只有在函数被调用 启动后 才临时为其分配存储单元 并接受主调函数传来的数据 在函数调用结束后 形参所占存储单元被释放 实参 实参 函数 intmax inta intb intc a b a b returnc main inta b c scanf d d 实参是函数调用时主调函数传送给被调函数的形式参数的实际值 实参可以是常量 变量和表达式 实参必须有确定的值 参数传递 参数传递的顺序 函数 intmax inta intb intc a b a b returnc main intx 6 y y max x x printf d y 当实参表列中有多个实参时 对实参的求值顺序并不确定 VC和BC是按从右往左的顺序求值 b x a x 7 在参数传递时 参数传递 参数传递的影响 函数 intmax inta intb intc a b a b a b returnc main inta 6 b 5 c c max a b printf d d d a b c 实参与形参不共用存储单元 参数传递时 把实参的值复制一份给形参 形参值的变化不影响实参的值 所以 形参和实参可以同名 6 5 6 值传递和引用传递 函数间参数的传递有两种类型 值传递主调函数把实参的值的副本传递给被调函数的形参 在被调函数内改变形参的值不会改变主调函数中实参的值 如果函数不需要修改参数的值 就采用这种调用方式 引用传递主调把实参 自身 传递给被调函数的形参 在被调函数内改变形参的值将改变主调函数中实参的值 用于可信的函数 在C语言中 所有参数传递都采用值传递 函数 参数传递 实参和形参的类型应该相同或赋值兼容 函数 intmax inta intb intc a b a b returnc main intx 6 y 5 z z max x y printf d z 如果x y是整型 则结果正确 如果x y是字符型 则自动进行类型转换 结果正确 如果x y是短整型 则自动进行类型转换 结果正确 如果x或y是实数 则自动进行类型转换 有数据丢失 结果可能不正确 b y a x 在参数传递时 函数的返回值 函数返回值的类型应该与函数的类型一致 如果不一致 采用函数的类型 对返回值进行类型转换 函数 intmax floata floatb floatc a b a b returnc main floatx 6 5 y 5 6 z z 2 max x y printf f z c的类型 返回值的类型 max x y 的类型 2 max x y 的类型 函数的嵌套调用 嵌套调用在调用一个函数的过程中又调用另一个函数 函数 案例分析 函数的嵌套调用 计算圆环的面积分析圆环的面积 外圆的面积 内圆的面积可以定义两个函数circleArea计算圆的面积ringArea计算圆环的面积 函数 doublecircleArea doubler doubleringArea doubler1 doubler2 案例分析 函数的嵌套调用 计算圆环的面积源代码 cw0804 c 函数 include definePI3 14doublecircleArea doubler doubleringArea doubler1 doubler2 voidmain doubler1 r2 s printf tInputr1 r2 scanf lf lf 案例分析 函数的嵌套调用 计算圆环的面积源代码 续 函数 doublecircleArea doubler returnPI r r doubleringArea doubler1 doubler2 if r1 r2 returncircleArea r2 circleArea r1 elsereturncircleArea r1 circleArea r2 Inputr1 r2 12Theareais 9 42 程序设计举例 掷骰子 掷骰子问题每个玩家掷两个骰子 每个骰子都有6个面 这些面中包含了1点 2点 3点 4点 5点和6点 当骰子静止下来之后 计算两个朝上的面中的点数和 本次投掷的结果 如果第一次投掷的结果是7或11 那么这个玩家就获胜 如果第一次投掷的结果是2 3或12 那么这个玩家就输了 即庄家获胜 如果第一次投掷的结果是4 5 6 8 9或10 那么这个结果就是该玩家的 点数 为了获胜 玩家必须继续掷骰子 直到 掷出了点数 在掷出点数之前 如果玩家掷出了7 那么玩家就输了 函数 程序设计举例 掷骰子 掷骰子初始设计定义一个函数rollDice 用来模拟掷一次骰子产生两个随机数 1 6 返回它们的和 点数 函数 掷第一次 胜 输 掷一次 胜 输 程序设计举例 掷骰子 掷骰子细化设计定义一个变量保存游戏进展的状态gamestatus0 继续1 胜利 游戏结束 2 失败 游戏结束 函数 程序设计举例 掷骰子 掷骰子实现 cw0807 c 函数 include include includeintrollDice void voidmain intgameStatus sum myPoint srand time NULL sum rollDice 掷第一次 程序设计举例 掷骰子 掷骰子实现 函数 switch sum case7 case11 gameStatus 1 break case2 case3 case12 gameStatus 2 break default gameStatus 0 myPoint sum printf Pointis d n myPoint break 掷第一次之后的结果 程序设计举例 掷骰子 掷骰子实现 函数 while gameStatus 0 sum rollDice if sum myPoint gameStatus 1 elseif sum 7 gameStatus 2 if gameStatus 1 printf Youwins elseprintf Youloses 继续游戏 胜负判断 程序设计举例 掷骰子 掷骰子实现 函数 introllDice intdice1 dice2 sum dice1 rand 6 1 第一个骰子的点数dice2 rand 6 1 第二个骰子的点数sum dice1 dice2 printf Yourolled d d d n dice1 dice2 sum returnsum 递归函数 递归函数直接或间接调用自己的函数 函数 案例分析 递归函数 用递归方法计算n 分析5 5 4 3 2 15 5 4 4 4 3 递归公式 函数 基本情形 简化问题 s 1 n 1 while n 20 s n s 迭代 n n n 1 案例分析 递归函数 举例 用递归方法计算n 源代码 cw0805 c 函数 includelongfac intn longf if n 0 n 1 f 1 elsef n fac n 1 printf t d ld n n f returnf voidmain printf n t5 ld n fac 5 1 12 23 64 245 1205 120 递归调用 案例分析 递归函数 举例 用递归方法计算n 分析 函数 5 5 4 4 3 3 2 2 1 1 120 5 24 4 6 3 2 2 1 1 递归调用 从递归调用返回值 用递归方案解决问题小结 用递归 函数 方案解决问题递归函数只知道如何去解最简单的情形 基本情形 简单的返回一个值把复杂的问题分成两部分 函数知道如何去做的部分函数不知道如何去做的部分这一部分与原问题相似 且更简单函数可以调用自己的新形式来解决这个更小的问题 递归调用 最终遇到基本情形函数识别出基本情形 将结果返回给前一个情形一系列的结果按顺序返回直到把最终结果返回给原始的调用者 可能是main 函数 函数 案例分析 递归方案 使用递归方法计算斐波拉契数列 0112358 分析从第三个数开始 每个数是前两个数的和 第一 二个数是确定的 递归公式fib n fib n 1 fib n 2 fib 1 0fib 2 1 函数 递归与迭代 递归与迭代的比较循环迭代 明确使用了循环结构递归 重复调用递归函数终止条件迭代 循环条件不满足递归 遇到基本情形都有可能出现无限循环如何选择迭代 性能好递归 可读性好 函数 程序设计举例 汉诺塔问题 汉诺塔问题问题假设有三个分别命名为X Y和Z的塔座 在塔座X上插有n个直径大小各不相同 依从小到大编号为1 2 n的圆盘 现要求将X轴上的n个圆盘移到塔座Z上 并按同样的顺序叠放 移动时必须遵循以下规则 每次只能移动一个圆盘 圆盘可以插在X Y和Z中的任一塔座上 任何时候都不能将一个较大的圆盘压在较小的圆盘之上 函数 程序设计举例 汉诺塔问题 汉诺塔问题分析n 1时将圆盘1从塔座X移到塔座Z 函数 基本情形 程序设计举例 汉诺塔问题 汉诺塔问题分析n 1时 函数 1 利用塔座Z为辅助塔座 将压在圆盘n之上的n 1个盘从塔座X移到塔座Y 与原问题类似 2 将圆盘n从塔座X移到塔座Z 3 利用塔座X为辅助塔座 将塔座Y上的n 1个圆盘移动到塔座Z 与原问题类

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论