




已阅读5页,还剩61页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章用函数实现模块化程序设计7 1为什么要用函数问题的提出 如果程序的功能多 规模大 所有代码都写在main函数中 会使主函数变得庞杂 阅读维护变得困难 若程序中多次实现某一功能 就需多次重复编写此功能的程序代码 这使程序冗余 解决的方法 用模块化程序设计的思路采用 组装 的办法简化程序设计的过程事先编好一批实现各种不同功能的函数把它们保存在函数库中 需要时直接调用 程序运行轨迹 main a d a e a main 主调函数和被调用函数之间的关系是相对的 C程序 由一个主函数和若干其它函数组成函数 完成特定功能程序段 由用户或系统定义函数间的调用关系 主函数可以调用其它函数 函数间可相互调用 函数多次被调用时体现优点 程序中各函数 可在一个或多个文件中某程序整体结构 主函数和两个被调用函数组成的程序一 通常方法 各函数包含在一个文件中 include stdio h voidmain voidp1 voidp2 p1 p2 p1 voidp1 printf n voidp2 printf Howdoyoudo n 二 文件包含的方法用 include 文件名 将所指文件中的内容包含进来进行预处理 然后一起进行编译 连接 运行用文件包含的方法 文件在同一目录 include stdio h include t2 h include t3 h voidmain p1 p2 p1 T2 h include stdio h voidp1 printf n T3 h include stdio h voidp2 printf Howdoyoudo n 三 工程的方法在vc环境下建立工程1 在文件菜单项中选新建命令 在新建选项卡中选工程2 在工程选项卡中选 Win32consoleApplication3 在位置写上工程路径 如E 4 在工程框写工程名 如 p15 选Anemptyproject 选完成 选确定6 在工程菜单项中选添加工程 再选文件 新建 7 若还有其它工程文件 重复步骤6 t1 cppvoidmain voidp1 voidp2 p1 p2 p1 t2 cpp include stdio h voidp1 printf n t3 cpp include stdio h voidp2 printf Howdoyoudo n 工程下应是 cpp C程序 1 编译的单位是文件而不是函数 2 多文件组成时 可用工程或文件包含的方法 3 程序执行从main开始 到main函数结束 4 函数定义是独立 平等的 不能嵌套定义但可嵌套调用 5 函数种类 标准库函数 由系统提供 用户定义的函数 6 函数的形式 无参 主调函数无数据传给被调函数 有参 主调函数有数据传递给被调函数返回值可有可无 7 2怎样定义函数7 2 1为什么要定义函函数不定义就无法使用 必须 先定义 后使用 定义时 指定函数的名字 以便以后按名调用 指定函数类型 即函数返回值的类型 指定函数参数的名字和类型 以便在调用函数时向它们传递数据函数的功能 是在函数体中确定的对于库函数 只用 include指令把有关的头文件包含到本文件模块中 7 2 2定义函数的方法1 无参函数的定义形式类型标识符函数名 声明部分语句部分 2 有参函数的定义形式类型标识符函数名 形式参数表列 声明部分语句部分 3 空函数定义形式类型名函数名 用空函数占一个位置 以便以后逐步扩充好处 程序结构清楚 可读性好 以后扩充新功能方便 对程序结构影响不大 7 3调用函数7 3 1函数调用的形式一般形式 函数名 实参表列 调用无参函数时 括号不能省略有多个实参时 各参数间用逗号隔开函数调用通常有3种方式 函数调用语句把函数调用单独作为一个语句如printf star 这时不要求函数带回值 只要求函数完成一定的操作 函数表达式 函数调用出现在另一个表达式中 要求函数带回一个确定的值以参加表达式的运算如c max a b 函数参数 函数调用作为另一函数调用时的实参如m max a max b c 其中max b c 是一次函数调用 它的值作为max另一次调用的实参 7 3 2函数调用时的数据传递1 形式参数和实际参数 形式参数 出现在被调函数中 通常由变量组成 实际参数 出现在主调函数中 通常由常量 变量 表达式组成2 实参和形参间的数据传递 在调用函数过程中 系统会把实参的值传递给被调用函数的形参 或者说 形参从实参得到一个值 该值在函数调用期有效 可参加被调函数中的运算 例7 2输入两个整数 求其中较大者 用函数找 解题思路 1 函数名应是见名知意 今定名为max 2 由于给定的两个数是整数 返回主调函数的较大数应该是整型 3 max函数应当有两个参数 以便从主函数接收两个整数 因此参数的类型应当是整型先编写max函数 intmax intx inty intz z x y x y return z 实参 主调函数提供 如常量 变量 表达式形参 被调函数提供 接收主调函数的数据调用函数时的数据传递 include stdio h voidmain inta b c intmax int int scanf d d 形参 调用时分配单元 结束时释放 调用时 形实参个数 类型 顺序一致 被调在主调函数后 要作原形声明 形实参单向值传递 被调函数形参变化时 不改变主调函数实参的值 形实参单向传递数据 占不同的存储单元 include stdio h voidmain inta 2 b 3 intadd intx inty printf a d b d n a b printf 单向值传递 虽然返回一片单元的址 里面的内容却不是原来的值 include stdio h inty 10 int g intb inty 10 i for i 0 i 10 i printf d n y i b i returny voidmain int x i a 10 1 2 3 4 5 6 7 8 9 10 x g a for i 0 i 10 i printf d n x i 7 3 4函数的返回值1 函数用return语句返回值2 若有多个return语句时 只有一个被执行例 if a b return a elsereturn b 3 return后括号可省 如 returna 4 return后可是表达式 如 return x y x y 5 函数值的类型是在定义函数时指定intmax intx inty floatmin floata floatb doubleabc doubled1 doubled2 6 语句return a b c 是合法的 返回表达式c的值 输入 1 52 5 输出 1 未加类型说明的函数自动按整型处理 2 函数值类型与return后表达式类型不一致时 以函数值为准 include stdio h voidmain intmax float float floata b intc scanf f f 函数无return语句时 返回一个不确定的值 include stdio h voidmain inta b c intp1 intp2 a p1 b p2 c p1 printf a d b d c d n a b c p1 printf n p2 printf Iamhappy n 运行结果 Iamhappy a 6 b 12 c 6 为表示不带返回值 用void定义函数 include stdio h voidmain voidp1 voidp2 p1 p2 p1 voidp1 printf n voidp2 printf Iamhappy n 7 4对被调用函数的声明和函数原型被调函数应具备的条件1 必须存在 标准或用户定义 不在同一文件时 用工程或文件包含的方法将各函数组织起来2 使用库函数 用 include将头文件包含进来 include stdio h include math h 3 若主调和被调函数在同一文件中 一般应在主调函数中对被调函数的类型作声明形式类型标识符被调函数名 类型1形参1 类型2参数2 主调函数中 对被调函数类型进行说明 include stdio h voidmain floatadd floatx floaty 函数声明 类型 名 形参类型 个数 通知编译 floata b c scanf f f 输入 3 66 5输出 sumis10 10000实型函数定义在后 又没有作原型声明 Vc中即使编译没有错 结果也有问题Tc中编译通不过 函数定义 声明 返回值的概念1 函数定义 对函数功能的确定 指定函数名 函数值类型 形参及类型 函数体等 是完整 独立函数单位2 函数声明 称函数原型 把函数名 类型 形参类型 个数 顺序 通知系统 以便调用函数时进行对照检查函数声明 原型 的形式 1 函数类型函数名 形参类型1 形参类型2 2 函数类型函数名 形参类型1形参名1 形参类型2形参名2 3 函数返回值为整型 不必声明 vc对字符型要声明 4 被调在主调函数之前定义 主调函数中可不必声明 因为编译已经知道函数的类型 并进行自动处理 include stdio h floatadd floatx floaty floatz z x y return z voidmain floata b c scanf f f 输入 3 66 5输出 sumis10 100000 7 5函数的嵌套调用函数间关系 是平行 独立的 不允许嵌套定义嵌套调用 在调用某函数过程中又调用另一函数 用弦截法求方程x3 5x2 16x 80 0的根 x2 x1 y x x f x2 f x1 f x2 f x1 f x 方法与步骤1 取x1 x2两点得f x1 f x2 异号 则x1 x2之间必有一根同号 改变x1 x2 直到f x1 f x2 异号为止2 连接f x1 f x2 两点成一直线 弦 此线交x轴于x点X点的坐标求法 连接f x1 f x2 两点的直线f x 称商差 弦 斜率 求x点的坐标 从x值得f x 3 若f x 与f x1 同号 则根在 x x2 区间 此时将x作新的x1若f x 与f x2 同号 则根在 x1 x 区间 此时将x作新的x2 4 重复步骤2 3直到 f x 为止 设 10 6 则f x 0 弦截法中用三个函数实现各部分的功能 f x 用来求方程x3 5x2 16x 80的值 xpoint x1 x2 求f x1 与f x2 的连线与x轴交点x坐标 root x1 x2 不断弦截 求 x1 x2 区间的实根 include stdio h include math h doublef doublex doubley y x 5 0 x 16 0 x 80 0 return y doublexpoint doublex1 doublex2 doublex x x1 f x2 x2 f x1 f x2 f x1 return x doubleroot doublex1 doublex2 doublex y y1 y1 f x1 do x xpoint x1 x2 y f x if y y1 0 y1 y x1 x elsex2 x while fabs y 0 0001 return x voidmain doublex1 x2 f1 f2 x do printf inputx1 x2 n scanf lf lf 运行 inputx1 x2 26Arootofequationis5 0000 f1 调用f1 2 间接递归 当调另一函数时 另一函数反调自身 f2 函数 f1 函数 调用f2 调用f1 7 6函数的递归调用递归 函数直接或间接的调用自身1 直接递归 在函数体内又调用自身 结束递归常用if语句控制不满足条件 继续递归满足条件 结束递归 5个人问年龄 第5个人比第4个人大2岁 第4个人比第3个人大2岁 第2个人比第1个人大2岁 第1个人为10岁age 5 age 4 age 3 age 2 age 1 2 age 4 2 age 3 2 age 2 2 age 1 10 18 16 14 12 include stdio h a intn intc if n 1 c 10 elsec 2 a n 1 return c voidmain printf d n a 5 用式子表示 age n 10n 1age n 1 2n 1 有些问题 可用递归 也可以用递推的方法解决 递推 从一个已知的事实出发 按一定规律推出下一个事实 再从已知的新的事实 推出下一个新的事实用递推法求n 即从1开始 乘2 乘3 一直到n includevoidmain inti s 1 for i 1 i1 用递归法求n includeintf intn ints if n 0 n 1 s 1 elses n f n 1 return s voidmain intn y scanf d main输入n 4 y f 4 输出 4 24 n 4f 4 s 4 f 3 24return 24 n 3f 3 s 3 f 2 6return 6 n 2f 2 s 2 f 1 2return 2 n 1f 1 f 1return 1 hanoi 汉诺 塔问题十九世纪未 欧洲玩具商店出现一种汉诺塔游戏 并有推销材料 说是古印度布拉玛神庙里的僧侣们在玩一种游戏 如果游戏结束 世界未日将来临 一 规则及分析n个盘子从一个座移到另一个座 每次只能移动一个盘子 不允许大盘在小盘上面 共有三个座 n个盘子由A座移到C座 需移动的次数是2n 1 若64个盘子移动的次数为 264 1 18 446 744 073 709 551 615一年的秒数是 365 24 60 60 3153600018446744073709551615 31536000 584942417355年即 5849亿年 从能源角度推算 太阳系寿命只有150亿年 二 方法与步骤1 将A上n 1个盘子借助C座移到B座2 把A上剩下一个盘子送到C座3 将n 1个盘子从B座借助A座移到C座三 实例 将A上3个盘子移到C步骤 1 A座上两个盘子借助C座移到B座2 A座上最后一个盘子移到C座3 B座上两个盘子借助A座移到C座第一步进一步分解 1 1A座上一个盘子从A C1 2A座上一个盘子从A B1 3C座上一个盘子从C B第二步进一步分解 A座上最后一个盘子从A C第三步进一步分解 3 1B座上一个盘子从B A3 2B座上一个盘子从B C3 3A座上一个盘子从A C 结论1 3步都是把n 1个盘子从一个座移到另一个座上 方法一样 只是座的名称不同而已 为使之一般化 将1 3步表示为 将one座上的n 1个盘子 借助three座 移到two座 只是对应关系不同 1 将n 1个盘子从一个座移到另一个座上 2 将1个盘子从一个座移到另一个座上 例用递归的方法解决汉诺塔程序如下 includevoidmove charx chary printf c c n x y voidhanoi intn charone chartwo charthree if n 1 move one three else hanoi n 1 one three two n 1个盘由1通过3移到2move one three 将1上的最后一个移到3hanoi n 1 two one three n 1个盘由2通过1移到3 voidmain intm printf inputthenumberofdiskes scanf d 7 7数组作为函数参数7 7 1数组元素作函数实参例7 9输入10个数 要求输出其中值最大的元素和该数是第几个数 解题思路 定义数组a 用来存放10个数设计函数max 用来求两个数中的大者在主函数中定义变量m 初值为a 0 每次调用max函数后的返回值存放在m中用 打擂台 算法 依次将数组元素a 1 到a 9 与m比较 最后得到的m值就是10个数中的最大者 includeintmain intmax intx inty inta 10 m n i printf 10integernumbers n for i 0 im m max m a i n i printf largestnumberis d n m printf dthnumber n n 1 10integernumbers 470 343467 4231 76 intmax intx inty return x y x y 7 7 2数组名作函数参数除了可以用数组元素作为函数参数外 还可以用数组名作函数参数 包括实参和形参 用数组元素作实参时 向形参变量传递的是数组元素的值用数组名作函数实参时 向形参传递的是数组首元素的地址例7 10有一个一维数组score 内放10个学生成绩 求平均成绩 解题思路 用函数average求平均成绩 用数组名作为函数实参 形参也用数组名在average函数中引用各数组元素 求平均成绩并返回main函数 includeintmain floataverage floatarray 10 floatscore 10 aver inti printf input10scores n for i 0 i 10 i scanf f 例7 11有两个班级 分别有10名和5名学生 调用一个average函数 分别求这两个班的学生的平均成绩 用同一函数求两组学生的平均成绩 includefloatf floata intn inti floatav sum 0 for i 0 i n i sum sum a i av sum n return av voidmain floats1 5 98 5 97 91 5 60 55 floats2 10 67 5 89 5 99 69 5 77 89 5 76 5 54 60 99 5 printf averofclassAis f n f s1 5 printf averofclassBis f n f s2 10 averageofclassAis 80 400000theaverageofBis78 200000 例7 12选择法排序思想 先在a 0 a 4 中找出最小数与a 0 对换 再在a 1 a 4 中 找最小数与a 1 对换 includevoidsort intb intn inti j k t for i 0 i n 1 i k i for j i 1 j n j if b j b k k j t b k b k b i b i t voidmain inta 5 i printf inputnumbersa n for i 0 i 5 i scanf d 7 7 3多维数组名作函数参数例7 13有一个 的矩阵 求所有元素中的最大值 解题思路 先使变量max的初值等于矩阵中第一个元素的值 然后将矩阵中各个元素的值与max相比 每次比较后都把 大者 存放在max中 全部元素比较完后 max的值就是所有元素的最大值 includeintmain intmv intarray 4 inta 3 4 1 3 5 7 2 4 6 8 15 17 34 12 printf Maxvalueis d n mv a return0 intmv intarray 4 inti j max max array 0 0 for i 0 imax max array i j return max 7 8局部变量和全局变量7 8 1局部变量定义变量可能有三种情况 在函数的开头定义在函数内的复合语句内定义在函数的外部定义在一个函数内部定义的变量只在本函数范围内有效在复合语句内定义的变量只在本复合语句范围内有效在函数内部或复合语句内部定义的变量称为 局部变量 floatf1 inta intb c charf2 intx inty inti j intmain intm n return0 a b c仅在此函数内有效 x y i j仅在此函数内有效 m n仅在此函数内有效 例如局部变量的应用 includef1 inta 10 b 25 c 30 printf d d d n a b c f2 inta intb intc a a 2 c a b 3 printf d d d n a b c voidmain inta 1 b 2 c 5 printf d d d n a b c f1 printf d d d n a b c f2 a b printf d d d n a b c 复合语句中定义局部变量 include stdio h voidmain inta 1 b 2 c 3 intc c a b printf a d b d c d n a b c printf a d b d c d n a b c 7 8 2全局变量全局变量 函数以外定义的变量作用域 从定义的位置开始到源程序结束说明 程序开始处定义 对源程序中所有函数有效 在程序中间定义 对其后面的函数有效 函数或复合语句中定义的变量若与全局变量同名 当函数或复合语句执行时 局部变量优先 全局变量不起作用 同文件所有函数都能引用全局变量 当某函数改变了全局变量的值时 会影响其它函数 全局变量的作用域及其使用情况 include stdio h inta 1 f1 intb b a 3 printf d d n a b f2 inta b a 5 b a 3 printf d d n a b f3 intb a 6 b a 3 printf d d n a b voidmain intb 3 printf d d n a b f1 printf d d n a b f2 printf d d n a b f3 printf d d n a b 7 14通过函数求最高分 最低分和平均值 include stdio h floatmax 0 min 0 floatav floata intn inti floataver sum sum max min a 0 for i 1 imax max a i elseif a i min min a i sum sum a i aver sum n return aver main floatave s 10 inti for i 0 i 10 i scanf f 编译 连接后生成的指令代码 外部 局部静态 static 程序运行开始到结束一直占用 局部动态 形参 函数调用时的现场保护和返回值等 函数调用时分配存储单元 调用结束时释放 程序区 静态存储区 动态存储区 代码段 数据段 7 9变量的存储方式和生存期7 9 1动态存储方式与静态存储方式数据类型 如整 实 字符型等存储类别 1 静态存储方式 分配的存储单元是固定的 2 动态存储方式 函数被调用时为变量分配存储单元 7 9 2局部变量的存储类别1 动态存储类别auto 在函数内声明 分配在动态区 声明符auto可省 未赋初值时其值未定义 每次调用重新赋值例如 intf inta autointb c 3 等价于 intb c 3 2 静态局部变量 static局部变量 静态存储类别 函数调用结束后 其值仍存在 下次调用时可继续使用局部静态和局部动态变量的使用 includef inta autointb 0 staticintc 3 b b 1 c c 1 return a b c voidmain inta 2 i for i 0 i 3 i printf 6d f a 局部静态变量 1 分配在静态区 程序结束时释放存储单元 2 开始赋初值一次 以后每次调用函数 使用前次操作的结果 3 未赋初值 其值为0 分配存储单元固定 4 在函数调用结束后值虽存在 但其它函数不能引用它 5 局部动态变量若未赋初值 其值不确定 所分配的存储单元不固定 局部静态变量特点需保留上一次调用的值时 用静态存储类别 例如打印1 5的阶乘值 includeintf intn staticintf 1 f f n return f voidmain inti for i 1 i 5 i printf d n f i 3 寄存器变量 register变量 寄存器类型 将变量与寄存器相关联特点 减少数据与内存之间交换频率 提高程序效率和速度 includeintf intn registerinti f 1 for i 1 i n i f f i return f voidmain inti for i 1 i 5 i printf d n f i 7 9 3全局变量的存储类别存放在静态存储区中的 因此它们的生存期是固定的 存在于程序的整个运行过程一般来说 外部变量是在函数的外部定义的全局变量 它的作用域是从变量的定义处开始 到本程序文件的末尾 在此作用域内 全局变量可以为程序中各个函数所引用 1 在一个文件内扩展外部变量的作用域外部变量有效的作用范围只限于定义处到本文件结束 如果用关键字extern对某变量作 外部变量声明 则可以从 声明 处起 合法地使用该外部变量 外部变量 也称全局变量 在函数外部定义作用域 从变量的定义处开始 到本程序文件的未尾1 程序后面声明外部变量 用extern声明 includeintmax intx inty intz externB printf d n B z x y x y return z voidmain externA B printf d n max A B intA 13 B
温馨提示
- 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年数字货币对货币政策传导的金融市场结构影响报告
- 应急信息报送规章制度
- 商务专员培训
- 某港池航道疏浚和吹填造陆工程施工组织设计
- 质量为纲-华为公司质量理念与实践
- 统编版语文一年级上册第八单元单元任务群整体公开课一等奖创新教学设计
- 新媒体视频节目制作全套教学课件
- 矿山企业采掘作业规程
- 人教版小学语文1-6年级背诵内容完整版
- CloudFabric云数据中心网解决方案-Underlay网络
- 分部、分项工程质量验收记录
- 场地平整工程合同范本
评论
0/150
提交评论