C函数的高级特性与应用.ppt

上传人:max****ui 文档编号:6328709 上传时间:2020-02-22 格式:PPT 页数:34 大小:687.81KB
返回 下载 相关 举报
C函数的高级特性与应用.ppt_第1页
第1页 / 共34页
C函数的高级特性与应用.ppt_第2页
第2页 / 共34页
C函数的高级特性与应用.ppt_第3页
第3页 / 共34页
点击查看更多>>
资源描述
函数的高级特性与应用 1 函数与数组的关系函数与指针的关系内联函数函数的缺省参数函数重载的概念函数的嵌套调用函数的递归调用 2 函数与数组 数组元素和数组名都可以作为函数的参数每一个数组元素都可以看作是一个独立的变量 所以使用数组元素作为函数参数时 和普通变量作为函数的实参的用法没有区别 数组名作为函数的实参 实际上是把数组的首地址传递给函数 而不会将数组的内容复制一份传递给函数 3 例13 1 数组元素作函数的参数 includeusingnamespacestd intSum inta intb voidmain inta 1 2 3 4 5 6 7 8 9 将数组元素作为函数的参数cout 数组的两个元素之和是 Sum a 0 a 3 endl intSum inta intb returna b 4 在函数调用时 也可以将数组元素按照指针传递或者引用传递的方式传递给函数 intSum int pa int pb voidmain inta 1 2 3 4 5 6 7 8 9 将数组元素作为函数的参数cout 数组的两个元素之和是 Sum 5 数组元素按照引用传递 intSum int 6 数组名作为函数的实参 在C 中 数组名代表的是数组在内存空间中的首地址 将数组名作为函数的参数后 函数的形参将指向数组所在的内存空间 因此 在函数里对数组元素所作的改变 将影响到作为实参的数组的元素 数组名只是代表了内存中的一个地址 并没带有数组长度这样的信息 所以在将数组名作为函数的实参进行调用时函数调用时 需要传递一个代表数组长度的参数来指明数组的长度 7 例13 2 数组名作为实参 对一个指定数组求和的功能intSum inta intnLen voidmain intarr 1 2 3 4 5 6 7 8 9 10 数组名arr作为sum函数的实参cout 数组元素之和是 Sum arr 10 endl intSum inta intnLen intnRet 0 for inti 0 i nLen i nRet a i returnnRet 8 参数nLen指明要处理的数组的长度 函数定义时 形参表示的是数组的地址 所以定义形参时 数组的长度与声明无关 所以Sum函数也可以像下面这样声明 intSum inta 10 intnLen 用数组名作函数的实参时 形参和实参都指向同一段内存空间 因此 在函数里对形参表示的数组元素进行改变时 等同于改变了实参数组的数组元素的值 9 例13 3 在函数里修改实参数组元素的值voidfunc inta intnLen voidmain inti intarr 1 2 3 4 5 6 7 8 9 10 cout 调用函数之前 数组元素的值 endl for i 0 i 10 i cout arr i cout endl func arr 10 cout 调用函数之后 数组元素的值 endl for i 0 i 10 i cout arr i cout endl voidfunc inta intnLen for inti 0 i nLen i a i 2 10 函数与指针 指针可以作为函数的参数 函数也可以返回指针 甚至函数名本身也是指针 在前面已提到 用指针作为函数的参数可以达到以下的目的 传递较大的数据时 可以减少对内存空间的占用和提高执行效率 在函数里改变实参变量的值 从函数里带回多个运算结果 11 例13 4 例用指针作函数参数求数组之和 includeusingnamespacestd intSum int pa intnLen voidmain intarr 1 2 3 4 5 6 7 8 9 10 数组名arr作为sum函数的实参 其实传递的是数组首地址cout 数组元素之和是 Sum arr 10 endl intSum int pa intnLen 形参pa是一个指针 intnRet 0 for inti 0 i nLen i nRet pa i 利用指针加下标的方式访问数组元素 returnnRet 12 指针函数 函数的返回值为指针 例13 5 指针函数示例 注意 函数返回指针时 不可以返回局部变量的地址 13 函数的缺省参数 C 允许在定义函数时给其中的某个或某些形式参数指定缺省值 这样 当发生函数调用时 如果省略了对应位置上的实参的值时 则在执行被调函数时 以该形参的默认值进行运算 如 14 例13 6 形参缺省值 includeusingnamespacestd voidsum intnum 10 形参缺省值 inti s 0 for i 1 i num i s s i cout sumis s n voidmain sum 100 提供了实参值 被调函数以100进行运算 输出结果为5050sum 省略实参值 使用形参缺省值10 输出结果为55 15 注意 缺省参数一般在函数声明中提供 如果程序中既有函数的声明又有函数的定义时 则定义函数时不允许再定义参数的默认值 如果程序中只有函数的定义 而没有说声明函数 则默认参数才可出现在函数定义中 如 voidpoint intx 10 y 20 voidmain voidpoint intx inty cout x endl cout y endl 16 缺省参数的顺序 如果一个函数中有多个默认参数时 则形参分布中 默认参数应从右至左逐渐定义 如 voidmyfunc inta 1 floatb longc 20 错误voidmyfunc inta floatb 2 1 longc 30 正确 17 内联函数 内联函数的引入是为了解决函数调用的效率问题 在程序编译时 编译器将程序中出现的内联函数调用语句用内联函数的函数值进行替换 这样会增加目标程序的代码量 内联函数方法实际上是用空间换时间 只有经常使用且程序量较小的程序段 才适合使用内联函数 18 内联函数的定义方法和格式 inline函数值类型函数名 形参列表 函数体 如 inlinedoublesquare doublex returnx x voidmain doublex cout x cout thesqureis square x 19 内联函数与普通函数的区别和联系 在定义内联函数时 函数值的类型左面有 inline 关键字 而普通函数在定义时没有此关键字 程序中调用内联函数与调用普通函数的方法相同 当在程序中调用一个内联函数时 是将该函数的代码直接插入到调用点 然后执行该段代码 所以在调用过程中不存在程序流程的跳转和返回问题 而普通函数的调用 程序是从主调函数的调用点转去执行被调函数 待被调函数执行完毕后 再返回到主调函数的调用点的下一语句继续执行 从调用机理看 内联函数可加快程序代码的执行速度和效率 但这是以增加程序代码为代价来求得速度的 20 内联函数的限制 不是任何一个函数都可定义成内联函数内联函数的函数体内不能含有复杂的结构控制语句 如 switch和while 如果内联函数的函数体内有这些语句 则编译将该函数视同普通函数那样产生函数调用代码 递归函数不能被用来作为内联函数 内联函数一般适合于只有1 5行语句的小函数 对一个含有很多语句的大函数 没有必要使用内联函数来实现 21 函数重载 函数重载是指一个函数可以和同一作用域中的其他函数具有相同的名字 但这些同名函数的参数类型 参数个数 返回值 函数功能可以完全不同 如下例 22 例13 7 includeusingnamespacestd voidwhatitis inti cout thisisinteger i endl voidwhatitis charc cout thisischaracter c endl voidmain inti 1 charc a whatitis i whatitis c 23 在本例中定义了两个名称都叫whatitis的函数 但它们的形参类型不同 因此 这两个函数就是重载函数 为什么要使用函数重载 在原有C语言中 每个函数必须有其唯一的名称 这样的缺点是所有具有相同功能 而只是函数参数不一样的函数 就必须用一个不同的名称 而C 中采用了函数重载后 对于具有同一功能的函数 如果只是由于函数参数类型不一样 则可以定义相同名称的函数 24 匹配重载函数的顺序 由于重载函数具有相同的函数名 在进行函数调用时 系统一般按照调用函数时的参数个数 类型和顺序来确定被调用的函数 具体来说 按以下三个步骤的先后次序找到并调用那个函数 25 寻找一个严格的匹配 即 调用与实参的数据类型 个数完全相同的那个函数 通过内部转换寻求一个匹配 即 由C 系统对实参的数据类型进行内部转换 转换完毕后 如果有匹配的函数 则执行该函数 通过用户定义的转换寻求一个匹配 若能查出有唯一的一组转换 就调用那个函数 即 在函数调用处由程序员对实参进行强制类型转换 以此作为查找相匹配的函数的依据 26 例13 8 includeusingnamespacestd voidprint doubled cout thisisadouble d n voidprint inti cout thisisaninteger i n 27 voidmain intx 1 z 10 floaty 1 0 charc a print x 按规则1自动匹配函数voidprint inti print y 按规则2通过内部转换匹配函数voidprint doublei 因为系统能自动将float转换成double型print c 按规则2通过内部转换匹配函数voidprint inti 因为系统能自动将char型转换成int型print double z 按规则3匹配voidprint doublei 因为程序中将实参z强制转换为double型 28 定义重载函数时的注意事项 1 重载函数间不能只是函数的返回值不同 应至少在形参的个数 参数类型或参数顺序上有所不同 如 voidmyfun inti intmyfun inti 这种重载就是错误的 2 应使所有的重载函数的功能相同 如果让重载函数完成不同的功能 会破坏程序的可读性 29 函数嵌套调用 C 语言中函数的定义是平行的 独立的 所以 函数的定义是不能嵌套进行的 但函数的调用可以 嵌套调用即在调用一个函数的过程中 又调用另一函数 30 函数的递归调用 函数的递归调用即在函数体内部直接或间接的自己调用自己 即函数嵌套调用的是函数本身如下面定义求n 的函数 longfact longn if n 1 return1 returnfact n 1 n 函数fact调用自身 31 函数递归调用的条件 递归调用的条件也是我们在定义一个递归函数时应该遵循的原则 必须有完成函数任务的语句 如 上例求n 中的return1 有一个确定是否能避免递归调用的测试条件 如果条件不满足时就递归调用 否则就不再递归调用 有一个递归调用语句 并且该递归调用语句的参数应该逐渐逼近不满足条件 以致最后断绝递归 先测试 后递归调用 在递归函数定义中 必须先测试 后递归调用 也就是说 递归是有条件的 满足了条件后 才可以递归 32 关于递归调用的一点说明 递归函数都能用非递归函数来代替 如 求n 的非递归版longfact intiNum longsum 1 for inti iNum i 1 i sum i returnsum 33 递归调用的目的是简化程序设计 使程序易读但递归会增加系统开销 主要表现在会占用CPU时间和栈空间 效率较低非递归函数虽然效率较高 但比较难编程 相对来说可读性差鼓励用递归函数实现程序思想 34
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!