第4章函数和预处理.ppt_第1页
第4章函数和预处理.ppt_第2页
第4章函数和预处理.ppt_第3页
第4章函数和预处理.ppt_第4页
第4章函数和预处理.ppt_第5页
已阅读5页,还剩77页未读 继续免费阅读

下载本文档

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

文档简介

第4章函数与预处理 4 1概述4 2定义函数的一般形式4 3函数参数和函数的值4 4函数的调用4 5内置函数4 6函数的重载4 7函数模板4 8有默认参数的函数 4 9函数的嵌套调用4 10函数的递归调用4 11局部变量和全局变量4 12变量的存储类别4 13变量属性小结4 14关于变量的声明和定义4 15内部函数和外部函数4 16预处理命令 4 1概述模块化程序设计基本思想 将一个大的程序按功能分割成一些小模块特点 各模块相对独立 功能单一 结构清晰 接口简单控制了程序设计的复杂性提高元件的可靠性缩短开发周期避免程序开发的重复劳动易于维护和功能扩充开发方法 自上向下 逐步分解 分而治之 一个程序中函数调用的示意图 例4 1在主函数中调用其他函数 includeusingnamespacestd voidprintstar void cout endl voidprint message void cout WelcometoC endl intmain void printstar 调用printstar函数print message 调用print message函数printstar 调用printstar函数return0 运行情况如下 WelcometoC C 是模块化程序设计语言 C 是函数式语言必须有且只能有一个名为main的主函数C 程序的执行总是从main函数开始 在main中结束函数不能嵌套定义 可以嵌套调用主函数以外的函数大多是被封装在类中的 函数分类从用户角度标准函数 库函数 由系统提供用户自定义函数从函数形式无参函数有参函数 使用库函数应注意 1 函数功能2 函数参数的数目和顺序 及各参数意义和类型3 函数返回值意义和类型4 需要使用的包含文件 4 2定义函数的一般形式一般格式 合法标识符 函数返回值类型缺省int型无返回值void 函数体 函数类型函数名 形参类型说明表 说明部分语句部分 例有参函数intmax intx inty intz z x y x y return z 例无参函数voidprintstar void cout endl voidprint message void cout WelcometoC endl 说明 实参必须有确定的值形参必须指定类型形参与实参类型一致 个数相同若形参与实参类型不一致 自动按形参类型转换 函数调用转换形参在函数被调用前不占内存 函数调用时为形参分配内存 调用结束 内存释放 4 3函数参数和函数的值形参与实参形式参数 定义函数时函数名后面括号中的变量名实际参数 调用函数时函数名后面括号中的表达式 例 计算x的立方 includeusingnamespacestdfloatcube floatx return x x x intmain floata product cout a product cube a cout Cubeof a is product endl return0 x 1 2 1 2 1 728 例4 2调用函数时的数据传递 includeusingnamespacestd intmax intx inty intz z x y x y return z intmain inta b c cout a b c max a b cout max c endl return0 例比较两个数并输出大者 includeusingnamespacestd intmain inta b c intmax intx inty cin a b c max a b couty x y return z 运行情况如下 pleaseentertwointegernumbers 23 max 3 参数传递方式值传递方式方式 函数调用时 为形参分配单元 并将实参的值复制到形参中 调用结束 形参单元被释放 实参单元仍保留并维持原值特点 形参与实参占用不同的内存单元单向传递 例交换两个数 includeusingnamespacestd intmain intx 7 y 11 voidswap inta intb cin x y cout swapped n endl swap x y cout x y endl voidswap inta intb inttemp temp a a b b temp 函数的返回值返回语句形式 return 表达式 或return表达式 或return 功能 使程序控制从被调用函数返回到调用函数中 同时把返回值带给调用函数说明 函数中可有多个return语句若无return语句 遇 时 自动返回主调用函数若函数类型与return语句中表达式值的类型不一致 按前者为准 自动转换 函数调用转换void型函数 例无返回值函数voidswap intx inty inttemp temp x x y y temp 例 函数返回值类型转换 includeusingnamespacestd intmax floatx floaty floatz z x y x y return z intmain floata b intc cin a b c max a b cout Maxis c endl return0 运行结果 2 6 8 9Maxis8 4 4函数的调用函数调用一般形式函数名 实参表列 说明 实参与形参个数相等 类型一致 按顺序一一对应实参表求值顺序 因系统而定 TurboC自右向左 函数调用方式函数语句 例printstar 函数表达式 例m max a b 2 函数参数 例m max a max b c 函数说明对被调用函数要求 必须是已存在的函数库函数 include用户自定义函数 函数类型说明函数说明一般形式 函数类型函数名 形参类型 形参名 或函数类型函数名 作用 告诉编译系统函数类型 参数个数及类型 以便检验函数定义与函数说明不同函数说明位置 程序的数据说明部分 函数内或外 下列情况下 可不作函数说明若函数返回值是char或int型 系统自动按int型处理被调用函数定义出现在主调函数之前 例函数说明举例 调用函数时需要一定的时间和空间的开销 下图表示函数调用的过程 4 5内置函数 内置函数 内联函数 在编译时将所调用函数的代码直接嵌入到主调函数中 而不是将流程转出去 指定内置函数 只需在函数首行的左端加一个关键字inline 例4 4函数指定为内置函数 includeusingnamespacestd inlineintmax int int int 函数声明 注意左端有inlineintmain inti 10 j 20 k 30 m m max i j k couta a b 求a b c中的最大者if c a a c returna 实参代替形参 被置换成if j i i j if k i i k m i 注意 inline可以写在声明函数或定义函数时优点 内置函数节省运行时间缺点 增加了目标程序的长度 对内置函数的要求 规模很小 一般为5个语句以下使用频繁的函数不包括复杂的控制语句 如循环语句和switch语句 函数的重载 一组概念相同 处理对象 参数 不同的过程 出于方便编程的目的 用同一个函数名字来命名的技术称为函数重载重载是不同的函数 以参数的类型 个数和顺序来分辨函数体可以相同也可以不同 4 6函数的重载 例 voidprint double voidprint int voidfunc print 1 voidprint int print 1 0 voidprint double print a voidprint int print 3 1415f voidpirnt double 例4 5求3个数中最大的数 分别考虑整数 双精度数 长整数的情况 includeusingnamespacestd intmain intmax inta intb intc 函数声明doublemax doublea doubleb doublec 函数声明longmax longa longb longc 函数声明inti1 i2 i3 i cin i1 i2 i3 输入3个整数i max i1 i2 i3 求3个整数中的最大者cout i max i endl doubled1 d2 d3 d cin d1 d2 d3 d max d1 d2 d3 cout g1 g2 g3 g max g1 g2 g3 couta a b if c a a c returna doublemax doublea doubleb doublec if b a a b if c a a c returna longmax longa longb longc if b a a b if c a a c returna 运行情况如下 185 76567 i max 56756 8790 23 3214 78 d max 90 2367854 912456673456 g max 673456 例4 6参数个数不同 includeusingnamespacestd intmain intmax inta intb intc 函数声明intmax inta intb 函数声明inta 8 b 12 c 27 cout max a b c max a b c endl cout max a b max a b endl return0 intmax inta intb intc if b a a b if c a a c returna intmax inta intb if a b returna elsereturnb 运行情况如下 max a b c 27max a b 8两次调用max函数的参数个数不同 系统就根据参数的个数找到与之匹配的函数并调用它 定义函数模板的形式 template或template通用函数定义通用函数定义在调用函数时系统会根据实参的类型来取代模板中的虚拟类型 从而实现了不同函数的功能 类型参数可以不只一个 可以根据需要确定个数 如 template注意 它只适用于函数的参数个数相同而类型不同 且函数体相同的情况 如果参数的个数不同 则不能用函数模板 4 7函数模板 例4 7将例4 6程序改为通过函数模板来实现 includeusingnamespacestd template 模板声明 其中T为类型参数Tmax Ta Tb Tc if b a a b if c a a c returna intmain inti1 185 i2 76 i3 567 i doubled1 56 87 d2 90 23 d3 3214 78 d longg1 67854 g2 912456 g3 673456 g i max i1 i2 i3 d max d1 d2 d3 g max g1 g2 g3 cout i max i endl cout f max f endl cout g max g endl return0 intmax inta intb intc if b a a b if c a a c returna 函数在声明时可以预先给出默认的形参值 调用时如给出实参 则采用实参值 否则采用预先给出的默认形参值 例如 4 8有默认参数的函数 intadd intx 5 inty 6 returnx y voidmain void add 10 20 10 20add 10 10 6add 5 6 默认形参值必须从右向左顺序声明 并且在默认形参值的右面不能有非默认形参值的参数 因为调用时实参取代形参是从左向右的顺序 例 intadd intx inty 5 intz 6 正确intadd intx 1 inty 5 intz 错误intadd intx 1 inty intz 6 错误 调用出现在函数体定义之前时 默认形参值必须在函数原型中给出 而当调用出现在函数体定义之后时 默认形参值需在函数定义时给出 例 intadd intx 5 inty 6 voidmain void add 调用在定义前 intadd intx inty returnx y intadd intx 5 inty 6 returnx y voidmain void add 调用在定义后 例4 8求2个或3个正整数中的最大数 用带有默认参数的函数实现 includeusingnamespacestd intmain intmax inta intb intc 0 inta b c cin a b c cout max a b c max a b c endl cout max a b max a b endl c取默认值return0 intmax inta intb intc if b a a b if c a a c returna 运行情况如下 14 56135 max a b c 135max a b 14 在相同的作用域内 默认形参值的说明应保持唯一 但如果在不同的作用域内 允许说明不同的默认形参 例 intadd intx 1 inty 2 voidmain void intadd intx 3 inty 4 add 使用局部默认形参值 实现3 4 voidfun void add 使用全局默认形参值 实现1 2 4 9函数的嵌套调用嵌套调用C 规定 函数定义不可嵌套 但可以嵌套调用函数 例如 求三个数中最大数和最小数的差值 includeusingnamespacestd intdif intx inty intz intmax intx inty intz intmin intx inty intz intmain inta b c d cin a b c d dif a b c cout Max Min d endl return0 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 例 求n的阶乘 includeusingnamespacestd intfac intn intf if n n y fac n cout n y endl return0 例有以下程序 includeusingnamespacestd intf intn if n 1 return1 elsereturnf n 1 1 intmain inti j 0 for i 1 i 3 i j f i cout j endl return0 程序运行后的输出结果是 a 4b 3c 2d 1 if i j1112f 2 1 11 2 例 includeusingnamespacestd longfun intn longs if n 1 n 2 s 2 elses n fun n 1 returns intmain cout fun 3 endl return0 运行结果 ns33 fun 3 1 3 2 1 例4 10有5个人坐在一起 问第5个人多少岁 他说比第4个人大两岁 问第4个人岁数 他说比第3个人大两岁 问第3个人 又说比第2个人大两岁 问第2个人 说比第1个人大两岁 最后问第1个人 他说是10岁 请问第5个人多大 可以用式子表述如下 age n 10 n 1 age n age n 1 2 n 1 运行结果如下 18函数调用过程如图所示 includeusingnamespacestd intage intn intc if n 1 c 10 elsec age n 1 2 return c intmain cout1 在一个函数内部定义的变量是内部变量 它只在本函数范围内有效 也就是说只有在本函数内才能使用它们 在此函数以外是不能使用这些变量的 同样 在复合语句中定义的变量只在本复合语句范围内有效 这称为局部变量 localvariable 如 4 11局部变量和全局变量4 11 1局部变量 floatf1 inta 函数f1 intb c b c有效a有效 charf2 intx inty 函数f2 inti j i j有效x y有效 intmain 主函数 intm n intp q p q在复合语句中有效m n有效 说明 1 主函数main中定义的变量也只在主函数中有效 2 不同函数中可以使用同名的变量 它们代表不同的对象 互不干扰 3 可以在复合语句中定义变量 这些变量仅在本复合语句中有效 4 形式参数也是局部变量 其他函数不能调用 5 在函数声明中出现的参数名 其作用范围只在本行的括号内 例如intmax inta intb 函数声明中出现a b intmax intx inty 函数定义 形参是x y cout x y endl 合法 x y在函数体中有效cout a b endl 非法 a b在函数体中无效 编译时认为max函数体中的a和b未经定义 在函数内定义的变量是局部变量 而在函数之外定义的变量是外部变量 称为全局变量 全程变量 全局变量的有效范围为从定义变量的位置开始到本源文件结束 如 4 11 2全局变量 intp 1 q 5 全局变量全局变量p q的作用范围floatf1 inta 定义函数f1 intb c charc1 c2 全局变量全局变量c1 c2的作用范围charf2 intx inty 定义函数f2 inti j main 主函数 intm n 几点说明 4 12变量的存储类别概述变量是对程序中数据的存储空间的抽象 编译或函数调用时为其分配内存单元 10 程序中使用变量名对内存操作 变量的属性数据类型 变量所持有的数据的性质 操作属性 存储属性存储类型 寄存器 静态存储区 动态存储区生存期 变量在某一时刻存在 静态变量与动态变量作用域 变量在某区域内有效 局部变量与全局变量变量的存储类型auto 自动型register 寄存器型static 静态型extern 外部型变量定义格式 存储类型 数据类型变量表 4 12变量的存储类别概述变量是对程序中数据的存储空间的抽象 如 intsum autointa b c registerinti staticfloatx y 局部变量与全局变量局部变量 内部变量定义 在函数内定义 只在本函数内有效说明 main中定义的变量只在main中有效不同函数中同名变量 占不同内存单元形参属于局部变量可定义在复合语句中有效的变量局部变量可用存储类型 autoregisterstatic 默认为auto 运行结果 main a 3 b 4sub a 6 b 7main a 3 b 4 全局变量 外部变量定义 在函数外定义 可为本文件所有函数共用有效范围 从定义变量的位置开始到本源文件结束 及有extern说明的其它源文件 应尽量少使用全局变量 因为 全局变量在程序全部执行过程中占用存储单元降低了函数的通用性 可靠性 可移植性降低程序清晰性 容易出错 定义说明次数 只能1次可说明多次位置 所有函数之外函数内或函数外分配内存 分配内存 可初始化不分配内存 不可初始化 外部变量说明 extern数据类型变量表 外部变量定义与外部变量说明不同 若外部变量与局部变量同名 则外部变量被屏蔽 外部变量可用存储类型 缺省或static floatmax min floataverage floatarray intn inti floatsum array 0 max min array 0 for i 1 imax max array i elseif array i min min array i sum array i return sum n main inti floatave score 10 Input ave average score 10 cout max max min min average ave endl externcharc1 c2 externcharc1 c2 运行结果 max 13 includeusingnamespacestd externinta b intmax intz z a b a b return z intmain cout max max endl return0 inta 13 b 8 运行结果 max 8 inti includeusingnamespacestd intmain voidprt for i 0 i 5 i prt voidprt for i 0 i 5 i cout cout endl 例外部变量副作用 运行结果 动态变量与静态变量存储方式静态存储 程序运行期间分配固定存储空间动态存储 程序运行期间根据需要动态分配存储空间内存用户区 生存期静态变量 从程序开始执行到程序结束动态变量 从包含该变量定义的函数开始执行至函数执行结束 变量存储类型 局部变量默认为auto型register型变量个数受限 且不能为long double float型局部static变量具有全局寿命和局部可见性局部static变量具有可继承性extern不是变量定义 可扩展外部变量作用域 例文件file1 cinta main f2 f1 f1 autointb f2 f2 staticintc 例auto变量的作用域 includeusingnamespacestd intmain intx 1 voidprt void intx 3 prt cout 2ndx x endl cout 1stx x endl return0 voidprt intx 5 cout 3thx x endl 运行结果 3thx 52ndx 31stx 1 includeusingnamespacestd intmain voidincrement void increment increment increment return0 voidincrement void intx 0 x cout x endl 例局部静态变量值具有可继承性 运行结果 111 includeusingnamespacestd intmain voidincrement void increment increment increment return0 voidincrement void staticintx 0 x cout x endl 运行结果 123 例变量的寿命与可见性 includeinti 1 main staticinta registerintb 10 intc 0 cout MAIN n endl cout i i a a b b c c c c 8 other cout MAIN n endl cout i i a a b b c c i i 10 other other staticinta 2 staticintb intc 10 a a 2 i i 32 c c 5 cout OTHER endl printf i da d b dc d n i a b c b a Main i 1a 0b 10c 0 Other i 33a 4b 0c 15 Main i 33a 0b 10c 8 Other i 75a 6b 4c 15 8 4 33 15 4 43 6 75 15 6 includeusingnamespacestd intmain voidgx gy externintx y cout 1 x x ty y endl y 246 gx gy voidgx externintx y x 135 cout 2 x x ty y endl intx y voidgy cout 3 x x ty y endl 例用extern扩展外部变量作用域 运行结果 1 x 0y 02 x 135y 2463 x 135y 246 例引用其它文件中的外部变量 例引用其它文件中的变量 输出a b和a的m次方 Ch7 cpp Ch8 cpp 运行结果 Enterthenumberaanditspower 2 32 3 62 3 8 一个变量除了数据类型以外 还有3种属性 存储类别C 允许使用auto static register和extern4种存储类别 作用域指程序中可以引用该变量的区域 存储期指变量在内存的存储期限 以上3种属性是有联系的 程序设计者只能声明变量的存储类别 通过存储类别可以确定变量的作用域和存储期 4 13变量属性小结 4 14关于变量的声明和定义 把建立存储空间的声明称为定义而把不需要建立存储空间的声明称为声明例如 intmain externinta 声明a是一个已定义的外部变量 inta 是定义 定义a为整型外部变量 用static来声明一个变量对局部变量用static声明 使该变量在本函数调用结束后不释放 整个程序执行期间始终存在 使其存储期为程序的全过程 全局变量用static声明 则该变量的作用域只限于本文件模块 即被声明的文件中 用auto register static声明变量时 是在定义变量的基础上加上这些关键字 而不能单独使用 例如 statica 是不合法的 应写成staticinta 内部函数函数只能被本文件中其他函数所调用内部函数定义 static类型标识符函数名 形参表 外部函数函数能被其他

温馨提示

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

评论

0/150

提交评论