已阅读5页,还剩36页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
教学目的 掌握函数定义的格式 掌握函数原形的概念及其与头文件的关系 掌握函数调用过程中参数传递的原理 掌握全局变量和局部变量的使用 掌握函数的调用机制 掌握静态局部变量的使用 掌握保留字inline的含义与使用 了解函数递归 掌握函数重载的方法 掌握和应用文件包含 宏定义 条件编译 第5章函数与编译处理 第5章函数与编译处理 5 1函数的定义与声明5 2函数值和函数类型5 3函数的参数5 4全局变量与局部变量5 5函数调用机制5 6静态局部变量5 7递归函数5 8内联函数5 9函数的重载5 10默认参数的函数5 11编译预处理5 12习题 5 1函数的定义与声明 函数的定义 一个C 程序是由若干个源程序文件构成的 而一个源程序文件是由若干个函数构成 includedoublefun1 doublea doubleb 用户定义函数 doublec c a b returnc voidmain 主函数 doublex y z cin x y z fun1 x y 函数调用cout x y z endl 5 1函数的定义与声明 函数的声明 C 中函数声明又被称为函数原型 标准库函数的函数原型都在头文件中提供 程序可以用 include指令包含这些原型文件 对于用户自定义函数 程序员应该在源代码中说明函数原型 函数原型是一条语句 它由函数头和分号组成 形式为 函数名 说明 函数原型和函数定义在函数类型 返回类型 函数名和参数表上必须完全一致 函数原型不必包含参数的名字 而只要包含参数的类型 一个源文件是一个编译单位 不是以函数为单位进行编译C 程序由一个或多个源文件组成主程序只能有一个 程序执行自主程序开始 由主程序结束而结束函数的定义必须遵照C 规定的格式 任何函数都由函数头和函数体组成 具体格式如下 函数名 函数体 函数分类 从用户角度 库函数 自定义函数从形式 无参函数 有参函数 返回 5 2函数值和函数类型 通常 函数被调用总希望得到一个确定的值 这就是函数的返回值 函数类型就是函数返回值的类型 函数的返回值是通过return语句获得的 return语句的格式为 return 表达式 或return表达式 return语句的功能有两个 A 强制程序执行的流程从被调函数返回到主调函数 B 给主调函数带回一个确定的函数值当函数类型和return语句中的表达式类型不一致时 则以函数类型为准 如果被调用函数中没有return语句 为了明确表示函数 不返回值 要用viod定义无类型 这样系统就保证不使函数带回任何值 函数也可以不明确声明和定义函数的类型 默认函数类型为int型 includefun 没有声明函数类型voidmain cout fun endl fun 没有定义函数类型 cout thisprogramhavenodeclaring type endl 返回 5 2函数值和函数类型 5 3函数的参数 形式参数和实际参数 形参和实参 在调用函数时 大多数情况下 主调函数和被调函数之间有数据传递关系 而函数之间的数据传递就是靠函数的参数进行的 在定义函数时 函数名后面括号内的变量名为 形式参数 在调用函数时 函数名后面括号内的表达式为 实际参数 5 3函数的参数 例 include iostream h intmax int int voidmain inta b c cin a b c max a b couty x y return z a b x y 123 456 123 456 5 3函数的参数 关于形参和实参说明几点 实参可以是变量 常量 或表达式 但必须有确定的值 而形参必须是变量 形参变量 只有发生函数调用时 形参才被分配存储单元 在调用结束时 形参所占的内存单元被释放 实参与形参的类型必须一致 否则会发生 类型不匹配 的错误 上例中实参对形参的数据传递是 值传递 由实参把数据传给形参 并且存储单元与形参是不同的单元 并将实参对应的值依次传递给形参变量 调用结束后 形参单元被释放 而实参单元保留并维持原值 返回 5 4全局变量与局部变量 程序的内存区域从程序中各个变量起作用的范围来看 变量可以分为全局变量和局部变量在所有函数体外部定义的变量为全局变量 全局变量可以被本文件中的所有函数所使用 在一个函数的内部定义的变量就是局部变量 局部变量只能在定义它的函数体内使用 程序在内存中的区域 一个程序将操作系统分配给其运行的内存块分为4个区域 5 4全局变量与局部变量 全局变量作用域 从被定义的位置起 至文件结束处止 说明 全局变量在程序的全部执行过程中都占用固定的内存单元 而不是仅在需要时才开辟单元 所以其生存期是整个程序运行期间 全局变量通常在程序顶部定义 具有初始值 全局变量由编译器建立 并且初始化为0 在定义全局变量时 进行专门初始化除外 在同一文件中全局变量与局部变量同名时 则在局部变量的作用域内 同名的全局变量不起作用 5 4全局变量与局部变量 局部变量作用域 只局限于本函数内说明 局部变量的生存期 只有当程序执行到本函数时 才给这些局部变量分配存储单元 当本函数执行完毕后 这些局部变量所占存储单元就被释放 不同函数体中可以定义相同名字的变量 但它们代表不同的对象 互不干扰 它们在内存中占用不同的内存单元 形参是局部变量 如果局部变量不被显式初始化 那么 其内容是不可预料的 返回 5 5函数调用机制 C 的函数调用过程 就是栈空间操作的过程 栈是一种先进后出或后进先出的数据结构 建立被调用函数的栈空间保护调用函数的运行状态和返回地址传递参数将控制转交被调函数 例 voidfuncA int int voidfuncB int voidmain inta 6 b 12 funcA a b voidfuncA intaa intbb intn 5 funcB n voidfuncB ints intx 返回 5 6静态局部变量 静态局部变量 局部变量定义时 前面冠以static 静态局部变量存放在内存的全局数据区 它始终驻留在全局数据区 直到程序运行结束 静态局部变量的初始化与全局变量类似 注意 静态局部变量只在函数第一次被调用时进行初始化 可见性 本函数内 includevoidfunc intn 1 全局变量voidmain staticinta 静态局部变量intb 10 局部变量cout a a b b n n endl b 4 func cout a a b b n n endl n 10 func voidfunc staticinta 2 静态局部变量intb 5 局部变量a 2 n 12 b 5 cout a a b b n n endl 返回 5 7递归函数 递归调用 直接或间接地调用自己直接递归调用 在函数f中调用函数f例如 voidf f 间接递归调用 函数f调用函数ff 而函数ff调用函数f注意 要有终止递归调用的条件 5 7递归函数 例 求n includelongfact intn if n 1 return1 returnfact n 1 n 递归调用 voidmain cout fact 4 endl fact 4 fact 3 4 fact 2 3 fact 1 2 1 24 返回 5 8内联函数 引入内联函数的目的 为了提高程序中函数调用的效率 例 将字符数组str中所有小写字母转换成大写字母 include includeintis letter char voidmain charstr 80 inti cout str for i 0 i strlen str i if is letter str i str i 32 cout theresultis str endl intis letter charch if ch a 上例中 频繁的调用函数is letter 来判断字符是否是小写字母 这将使程序的效率降低 这种调用过程需要保护现场和恢复现场 因此函数的调用需要一定的时间和空间开销 特别是对于像is letter 这样函数体代码不大 但调用频繁的函数来说 对程序的效率影响很大 如何来解决呢 当然 为了不增加函数调用给程序带来的负担 可以把这些小函数的功能直接写入到主调函数 但这样做的结果使程序的可读性降低了 为了解决这个问题 C 中使用了内联函数这个方法 定义内联函数的方法很简单 只要在函数定义的头前加上关键字inline就可以了 具体格式如下 inline函数名 函数体 内联函数能避免频繁的函数调用而降低程序的效率是因为 在程序编译时 编译器将程序中被调用的内联函数都用内联函数定义的函数体进行替换 include includeinlineintis letter charch voidmain charstr 80 inti cout str for i 0 i strlen str i if is letter str i str i 32 cout theresultis str endl 返回 inlineintis letter charch if ch a 5 9函数的重载 函数重载的定义 重载是指同一个函数名对应多个函数的现象 也就是说 多个函数具有同一个函数名 函数的重载就类似于多义字 同一个字在不同的条件下 可能有不同的意思 例如 火 这个字 他火了 愤怒房子着火了 燃烧日子过得红火 兴旺火这个字在上面的句子中有不同的意思 用C 的概念说 就是重载 问题的提出 例如 求两数之和 2个整数相加 2个浮点数相加 在C 中必须逐个定义不同名的多个函数重载 写多个同名函数 由系统根据参数的类型自动判断究竟调用哪个函数 所以重载函数至少在参数个数 参数类型 或参数顺序上有所不同 仅返回类型不同不行 5 9函数的重载 includeintadd int int doubleadd double double voidmain cout add 1 2 endl cout add 1 2 3 4 endl intadd inta intb returna b doubleadd doublea doubleb returna b 例 利用重载函数分别定义求两个整数和的函数与求两个实数之和的函数 5 9函数的重载 includeintadd int int intadd int int int voidmain cout add 1 2 endl cout add 1 2 3 endl intadd inta intb returna b intadd inta intb intc returna b c 例 利用重载函数分别定义求两个整数之和与求三个整数之和的函数 返回 5 10默认参数的函数 C 规定 实参与形参的个数必须相同 且类型相对应 但是 允许调用时不传递或部分不传递实参值 而采用缺省值 例 include iostream h voidset inta 0 intb 0 charc cout a b c endl voidmain set set 999 set 123 456 set 111 222 5 10默认参数的函数 说明 当又有函数声明又有函数定义时 默认参数应在函数声明中提供 定义中不允许默认参数 一旦某个参数定义了缺省值 其右边的所有参数必须定义缺省值 调用时 实参从左至右 逐一传递给形参 返回 5 11编译预处理 编译预处理 在对程序进行通常的编译前 对预处理命令进行 处理 预处理功能主要有三种 文件包含 宏定义和条件编译 预处理命令不是C 的语句 为了和C 语句区别 预处理命令前加 说明 并且预处理命令不加分号结束 1 include命令作用 把指定的源文件 或 头文件 的全部内容嵌入到当前文件中该点处 一般形式 include include 文件名 形式1 直接按系统标准方式检索文件目录形式2 在当前源文件的目录中寻找 找不到再按系统标准方式检索其它文件目录 例 将自己定义的头文件myhead h加到file1 cpp中 myhead h文件floatfun floatr file1 cpp文件 include include myhead h voidmain cout theresultis fun 3 0 endl floatfun floatr return3 14159 r r 编译前将文件myhead h中的所有内容复制到文件file1 cpp中 然后进行编译 结果如同下面程序 file1 cpp文件 includefloatfun floatr voidmain cout theresultis fun 3 0 endl floatfun floatr return3 14159 r r 2 define命令 define最常用的方法是建立常量 但已经被C 的const定义语句所代替 例 defineName 西华大学 voidmain charn 20 Name 编译之前预处理为 voidmain charn 20 西华大学 5 11编译预处理 define还可以定义带参数的宏 但也已经被C 的inline内联函数所代替 例 defineS a b a b a b x S 5 7 编译前预处理为 x 5 7 5 7 5 11编译预处理 3 条件编译命令作用 对满足条件的部分程序内容进行编译 否则不参与编译判断符号常量 进行条件编译 形式1 ifdef标识符程序段 endif作用 如果标识符被定义过 一般用 define命令定义 则编译程序段 否则不编译 形式2 ifdef标识符程序段1 else程序段2 endif作用 如果标识符被定义过 则编译程序段1 否则编译程序段2 5 11编译预处理 形式3 ifndef标识符程序段 endif作用 如果标识符没有被定义过 则编译程序段 否则不编译形式4 ifndef标识符程序段1 else程序段2 endif作用 如果标识符没有被定义过 则编译程序段1 否则编译程序段2 判断表达式 进行条件编译形式1 if 表达式 程序段 endif作用 如果表达式成立 表达式为 真 则编译程序段 否则不编译形式2 if 表达式 程序段1 else程序段2 endif作用 如果表达式成立则编译程序段1 否则编译程序段2 例 include iostream h defineStudent0voidmain ifdefStudentcout 处理学生信息 endl if Student cout 处理小学生信息 n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026届陕西省西安市蓝田县生物高一第一学期期末综合测试试题含解析
- 2024年南昌辅警协警招聘考试备考题库及答案详解(历年真题)
- 2024年孝感辅警协警招聘考试真题附答案详解(能力提升)
- 吉林外国语大学《金属切削机床概论》2024-2025学年第一学期期末试卷
- 聊城大学东昌学院《针织物设计与试织》2024-2025学年第一学期期末试卷
- 上海济光职业技术学院《金文与摩崖隶书(秦汉书法史论)》2024-2025学年第一学期期末试卷
- 2025-2026学年四川邻水实验学校数学高二第一学期期末复习检测试题含解析
- 宁波工程学院《企业级应用开发实训》2024-2025学年第一学期期末试卷
- 四川省绵阳市绵阳中学资阳育才学校2025-2026学年高二物理第一学期期末检测试题含解析
- 四川省成都市双流区棠湖中学2026届数学高二上期末教学质量检测模拟试题含解析
- 全国大学生职业规划大赛《网络直播与运营》专业生涯发展展示【高职(专科)】
- 人工智能与知识产权保护国际合作案例分析
- 2025执业药师考试真题及答案
- 医院消防改造项目施工组织方案
- 2024年医院财务预算编制方案
- 全国大学生职业规划大赛《生物制药技术》专业生涯发展展示【高职(专科)】
- 学堂在线 大数据机器学习 章节测试答案
- 放射人员职业安全培训课件
- 2025-2030二手车交易平台用户行为分析及市场拓展战略研究报告
- 仪表工业技术规范
- 职工职业健康体检表
评论
0/150
提交评论