C语言函数详解PPT课件.ppt_第1页
C语言函数详解PPT课件.ppt_第2页
C语言函数详解PPT课件.ppt_第3页
C语言函数详解PPT课件.ppt_第4页
C语言函数详解PPT课件.ppt_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

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

文档简介

第七章函数 在解决一个比较复杂的实际问题时 不可能把所有要完成的任务全都写在main函数中 这时 程序往往由一个main函数和若干个其它函数组成 每个函数各自完成相对独立的部分功能 C语言通过函数实现模块化的程序设计方法 函数间相互调用的示意 main f1 f11 f1 f11 f12 f2 f12 f2 f21 f21 函数的分类 从函数形式无参函数有参函数 从用户角度标准函数 库函数 由系统提供用户自定义函数 库函数由系统提供 用户只要按照要求的格式正确调用即可 不同的C编译系统提供的库函数有些不同 7 1库函数 使用库函数应注意的问题 1 调用库函数时要用 include命令将相关的头文件包含进来 如 调用数学函数 用 include math h 调用输入输出函数 用 include stdio h 2 库函数调用的一般形式 函数名 参数表 要注意函数的功能 参数的个数与类型 函数值的类型 如 求平方根的函数sqrt的形式是 doublesqrt doublex 3 库函数调用以两种方式出现 其一 出现在表达式中 即作为表达式的一部分参与运算 如 计算y x2 5 1 3 则通过以下语句调用来实现 y pow x 2 5 1 3 其二 独立的语句 即调用函数后加一分号 如 printf n 4 调用库函数时 要注意参数的一些特殊要求 如三角函数要求自变量参数用弧度表示 开平方函数要求自变量参数的值大于或等于0 使用库函数应注意的问题 续 函数返回值的类型缺省int型无返回值 void 函数体 函数类型函数名 形参类型说明表 声明部分语句部分 例有参函数 现代风格 intmax intx inty intz z x y x y return z 例无参函数voidprintstar printf n 或voidprintstar void printf n 7 2函数的定义和返回值 1 函数定义的一般格式 现代风格 多个形参说明之间要用逗号隔开 没有形参时 这一对括号不能省略 合法标识符 例有参函数 传统风格 intmax x y intx y intz z x y x y return z 传统风格 intmax2 intx inty 现代风格 intmax if x y max x elsemax y printf max max2 d n max return max voidmain inta b max scanf d d 例函数的定义 形参和函数体中定义的变量只在函数被调用时才临时分配存储单元 当退出函数时 这些存储单元全部被释放 称为局部性 因而与其它函数中的变量同名不会引起混淆 函数与函数之间是平等的 voidmain intmax2 intx inty intz if x y z x elsez y return z inta b max scanf d d 函数的定义是平行的 不能在一个函数的内部再定义其它函数 即每个函数都是一个相对独立的模块 不能在写某一个函数时又包含了另一个函数的定义 main函数的执行时有一点点小的特权 返回语句形式return 表达式 或return表达式 或return 功能 使程序控制从被调用函数返回到调用函数中 同时把返回值带给调用函数说明 函数中可以有多个return语句 但只有其中的一个return语句能够得到执行若函数中没有return语句 或者是一个不带表达式的return语句 则该函数结束时自动返回调用函数一个不确定的值若函数类型与return语句中表达式值的类型不一致 按前者为准 自动转换 函数调用转换void型函数 明确说明函数没有返回值 2 函数的返回值 intmax floatx floaty floatz z x y x y return z main floata b scanf f f 例函数返回值类型转换 main inta b max scanf d d 例函数可以有多个return语句 注意 在C语言中 函数名不能被赋值 只能通过return语句返回一个值 intmax2 intx inty max2 x y x y printstar printf n main inta a printstar printf a d n a 输出 a 10 voidprintstar printf n main inta a printstar printf a d a 编译错误 例函数带回不确定值 说明 调用函数时 其名字必须与定义的名字相同 函数调用时的实参只写名字不需要在名字前再带实参类型 如上面main函数中对max2函数的调用不能写成 max max2 inta intb 7 3函数的调用1 函数调用的一般形式 函数名 实参表 实参可以是常量 变量或表达式 多于一个时 以逗号隔开 若函数定义时无形参 则调用时无实参 但一对括号不能少 3 实参与形参 个数应一致 若实参少 则必有形参未得到值 不确定值 影响结果 若实参多 则多余的无效 TC 如 c max2 3 则c的值为 761 随机值 若 c max2 3 5 8 则c的值为 5 4 实参与形参的类型应一一对应相匹配 若不匹配 程序仍能运行 但得不出正确结果 TC 如 c max 3 0 5 0 则c的值为 0若 c max 3L 5L 则c的值为 3 函数的调用 续 5 函数必须先定义 后调用 将要被调用的函数定义在前 调用在后 返回值类型为int或char的函数可例外 6 函数可直接或间接地自己调用自己 递归调用 在7 6节介绍 7 实参表求值顺序 因系统而定 TurboC自右向左 include stdio h voidmain intp 2 printf d d d n p p p TC 3 3 2VC 3 3 2 include stdio h voidmain intp 2 printf d d d n p p p TC 3 2 2VC 2 2 2 函数的调用 续 2 函数调用的方式 1 函数表达式 例m max a b 2 2 函数语句 例printstar printf Hello World n 3 函数参数 例printf d max a b m max a max b c C语言对被调用函数要求 必须是已存在的函数库函数 include用户自定义函数 函数声明 7 4函数的声明 在C语言中 除了主函数外 对于用户定义的函数要遵循 先定义 后使用 的规则 凡是未在调用之前定义的函数 C编译程序默认函数的返回值为int类型 对于返回值为其它类型的函数 若把函数的定义放在调用之后 应该在调用之前对函数进行声明 或称为函数原型声明 有的也称函数说明 1 函数声明一般形式 函数声明的作用 告诉编译系统max2函数是float类型的 有2个float类型的参数 可选 在VC中不允许 说明 1 函数声明可以是一个独立的语句 如上面例子中就是采用独立语句的形式 2 函数声明中的形参名是一种虚设 它们可以是任意的用户标识符 既不必与函数首部中的形参名一致 又可以与程序中的任意用户标识符同名 因此 参数名也可以省略 如上面的例子中函数声明可写成 floatmax2 float float 3 注意函数定义与函数声明是不同的 定义是写出函数的完整形式 而声明是告诉系统此函数的返回值类型 参数的个数与类型 便于编译时进行有效的类型检查 说明 续 4 若函数的返回值类型为int或char 则可以不进行函数声明 系统默认 但是使用这种方法时 系统无法对参数的类型做检查 若调用函数时参数使用不当 在编译时也不会报错 因此 为了程序清晰和安全 建议都进行声明 5 若被调函数的定义出现在主调函数之前 也可以不进行函数声明 6 有些系统 如BorlandC VC 等 要求一定要用函数声明指出函数类型和形参类型 并且对void和int型函数也要进行函数声明 例函数声明举例 2 函数声明的位置 1 放在调用函数的声明部分 只有此调用函数能识别被调用函数 可以是独立语句 也可与其它变量的定义放在同一个语句中 如上面的用法也可以如下形式的语句 floata b c max2 float float 2 放在所有函数的外部 被调用之前 此时函数声明的后面所有位置上都可对该函数进行调用 floatmax2 float float main floata b c scanf f f floatmax2 floatx floaty 函数声明放在所有函数的外部 例函数声明举例 3 调用库函数时 要在程序的开头使用命令 include来包含相关的头文件 就是因为头文件中包含了这些库函数的原型声明 形参与实参的概念形式参数 定义函数时函数名后面括号中的变量名实际参数 调用函数时函数名后面括号中的表达式 7 5调用函数和被调用函数之间的数据传递 形参 x y形参必须指定类型 实参 a b实参 a 5 100 1 实参可以是常量或变量或表达式 但必须有确定的值 2 要求形参与实参类型一致 个数相同 多 略 少 随机值 3 形参在函数被调用前不占内存 函数调用时为形参分配内存 调用结束 内存释放 4 C语言的参数传递方式值传递方式 函数调用时 系统临时为被调函数的形参分配存贮单元 并将实参的值复制到形参中 当被调函数结束时 形参单元被释放 实参单元仍保留并维持原值 特点 单向的值传递 数值或地址值 有关参数传递的几点说明 x 1 2 1 2 1 728 1 变量作为参数 单向的数值传递 main voidswap int int intx 10 y 20 printf 1 x dy d n x y swap x y printf 4 x dy d n x y voidswap inta intb intt printf 2 a db d n a b t a a b b t printf 3 a db d n a b 例7 1函数参数之间的单向传递 程序运行结果为 1 x 10y 20 2 a 10b 20 3 a 20b 10 4 x 10y 20 main voidex intz inty intx intx 10 y 20 z 30 printf 1 x dy dz d n x y z ex y z x voidex intx inty intz printf 2 x dy dz d n x y z 例7 2实参向形参按位置传递数据 程序运行结果为 1 x 10y 20z 30 2 x 20y 30z 10 函数声明语句形参名是一种虚设 函数调用语句确定实参顺序 函数定义确定形参顺序 实参向形参按位置传递数据 补充例题 程序功能 求n1 n2 当数组名作为函数参数时 要求实参和形参都用数组名 或指针变量 第十章作介绍 由于数组名的值就是数组在内存中分配的存储空间的首地址 这种方法称之为 传址调用 方式 当把实参数组名的值 首地址 传给形参数组名后 由于形参数组名也代表首地址 这样实参数组和形参数组的首地址相同 即实参数组和形参数组占用相同的存储空间 在被调函数中 形参数组中各元素的值如果发生变化 就会使实参数组元素的值同时也发生变化 在函数调用结束后 虽然形参数组已不复存在 但实参数组元素的值已发生变化 可以在主调函数中进行使用 2 数组名作为参数 单向的地址值传递 例7 3选择法排序 对N个数排序的算法步骤如下 1 在N个数中寻找最小值 然后把这个最小值与最前面的那个数交换位置 2 排除最前面的那个数 i i 1 在余下的N 1个数中寻找最小值 然后把这个最小值与最前面的那个数交换位置 如此循环 直到最后只剩一个数 i N 1 时结束 对10个数排序的算法步骤演示如下 下标 0123456789 对10个数排序的算法步骤演示如下 下标 0123456789 总结 10个数排序 需要进行九次的上述操作 若有N个数需要排序 则需要进行N 1次的上述操作 10个数排序的完整程序如下 voidsort inta 10 inti j k t for i 0 i 9 i k i for j i 1 j 10 j if a j a k k j t a k a k a i a i t main inti x 10 5 7 4 2 8 6 1 9 0 3 printf theoriginalarray n for i 0 i 10 i printf d a i printf n sort x printf thesortedarray n for i 0 i 10 i printf d a i printf n 程序运行结果为 theoriginalarray 5742861903thesortedarray 0123456789 例7 4将一个数组中的n个数据按颠倒的顺序重新存放 解题思路为 借助于一个临时变量 将a 0 与a n 1 对换 再将a 1 与a n 2 对换 直到将a n 1 2 1 与a n int n 1 2 1 对换 程序采用循环来实现 设二个 位置指针变量 i和j i的初值为0 j的初值为n 1 将a i 与a j 交换 然后使i的值加1 j的值减1 再将a i 与a j 交换 直到i m为止 m n 1 2为 中间位置 见图7 2所示 i 0 j n 1 i 1 j n 2 m n 1 2 数组逆序程序 voidinv intx intn intt i j m n 1 2 for i 0 i m i j n 1 i t x i x i x j x j t main inti a 10 10 20 90 100 printf Theoriginalarray n for i 0 i 10 i printf d a i printf n inv a 10 printf Thearrayhasbeeninverted n for i 0 i 10 i printf d a i printf n 程序运行结果为 Theoriginalarray 102030405060708090100Thearrayhasbeeninverted 100908070605040302010 voidinv intx intn intt i j n 1 for i 0 i j i j t x i x i x j x j t 例7 5求二维数组每行元素的平均值 voidlineave intx 4 floaty intn inti j s for i 0 i n i s 0 注意初值的位置 for j 0 j 4 j s s x i j y i s 4 0 main inta 3 4 1 2 3 4 5 6 7 8 9 10 11 12 inti j floatb 3 lineave a b 3 for i 0 i 3 i for j 0 j 4 j printf 4d a i j printf ave 6 2d n b i 程序运行结果为 1234ave 2 505678ave 6 509101112ave 10 50 1 嵌套调用C规定 函数定义不可嵌套 但可以嵌套调用函数 7 6函数的嵌套调用与递归调用 includeintdif intx inty intz intmax intx inty intz intmin intx inty intz voidmain inta b c d 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 例求三个数中最大数和最小数的差值 2 递归调用定义 函数直接或间接的调用自身叫函数的递归调用 说明C编译系统对递归函数的自调用次数没有限制每调用函数一次 在内存堆栈区分配空间 用于存放函数变量 返回值等信息 所以递归次数过多 可能引起堆栈溢出 intf intx inty z z f y return 2 z 2 递归调用 includeintfac intn intf if n 0 n 1 f 1 elsef fac n 1 n return f main intn y printf Inputaintegernumber scanf d intfac intn 更完善的阶乘函数 intf if n 0 printf n 0 dataerror return 1 if n 0 n 1 f 1 elsef fac n 1 n return f 递归方法的要点 1 递推公式fn fn 1 n2 结束条件 n 0 n 1 例7 6用递归的方法求n的阶乘 includeintfib intn intf if n 1 n 2 f 1 elsef fib n 2 fib n 1 return f main intn s printf Inputaintegernumber scanf d 递归方法的要点 1 递推公式fn fn 2 fn 12 结束条件 n 1 n 2 例7 7用递归实现斐波那契数列 例用递归实现猴子吃桃问题 includeinttao intn intf if n 8 n 1 printf dataerror f 0 if n 8 f 1 elsef 2 tao n 1 2 return f main intn s printf Input1 8 scanf d 递归方法的要点 1 递推公式fn 2 fn 1 22 结束条件 已知第8天只剩下一个桃子 n 8 voidmove chargetone charputone printf c c n getone putone voidhanoi intn charone chartwo charthree if n 1 move one three else hanoi n 1 one three two move one three hanoi n 1 two one three main intm printf Inputthenumberofdisks scanf d 例Hanoi问题 include math h intisprime int main intx scanf d 例7 8编写函数isprime intn 用来判断自变量n是否为素数 若是 函数返回1 否则返回0 isprime intn inti flag 1 for i 2 i sqrt n i if n i 0 flag 0 break return flag isprime intn inti flag 1 for i 2 i sqrt n 7 7函数程序举例 include math h intisprime int voideven int main inta printf Enteraevennumber scanf d isprime intn 例7 9编写函数 验证任意偶数为两个素数之和并输出这两个素数 程序运行结果为 Enteraevennumber 1010 3 7 例7 10利用梯形法求定积分 利用梯形法求定积分 doubleinteg doublea doubleb doubles x h f double intn 100 i h fabs b a n s f a f b 2 0 for i 1 i n 1 i x a i h s s f x ruturns h doublef doublex returnsin x include math h doubleinteg doublea doubleb main doubles s integ 0 0 10 0 printf s f n s 程序运行结果为 s 1 837539 例7 11编写函数统计输入的一行字符中出现的每个小写字母的个数 include stdio h include string h voidcountch charc intb voidmain charc ch 81 intb 26 0 gets ch countch ch b for c a c z c printf c d c b c 97 if c 97 1 10 0 printf n voidcountch charc intb intk l l strlen c for k 0 k a 程序运行结果为 thisisastatisticsprogram a 3b 0c 1d 0e 0f 0g 1h 1i 4j 0k 0l 0m 1n 0o 0p 1q 0r 2s 5t 4u 0v 0w 0 x 0y 0z 0 intmax value intarray 3 4 inti j max max array 0 0 for i 0 imax max array i j return max main inta 3 4 1 3 5 7 2 4 6 8 15 17 34 12 printf maxvalueis d n max value a 例求二维数组中最大元素值 例求二维数组中各行元素之和 get sum row intx 3 intresult introw intcol inti j for i 0 i row i result i 0 for j 0 j col

温馨提示

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

评论

0/150

提交评论