C语言 第7章_函数.ppt_第1页
C语言 第7章_函数.ppt_第2页
C语言 第7章_函数.ppt_第3页
C语言 第7章_函数.ppt_第4页
C语言 第7章_函数.ppt_第5页
已阅读5页,还剩148页未读 继续免费阅读

下载本文档

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

文档简介

includevoidmain chara 10 bbcdef charb 10 cbcdef inti 0 n 0 flag 0 while 1 if a i 0 include includevoidmain chara 30 cbcdefaaa charb 30 cbcdefaazaaa inti 0 n 0 flag 0 while a i 0 我们可以把这个定义成我们自己的字符串比较函数 第七章 函数 本章要点 函数的概念函数的定义与调用函数的递归调用变量的作用域函数的作用域 主要内容 7 1函数是什么7 函数的定义和调用7 函数的嵌套调用和递归调用7 数组作为函数参数7 变量的作用域和生存期7 内部函数和外部函数7 提高部分 7 1函数是什么 一个 程序可由一个主函数和若干个其他函数构成 一个较大的程序可分为若干个程序模块 每一个模块用来实现一个特定的功能 在高级语言中用子程序 函数 实现模块的功能 函数间的调用关系 由主函数调用其他函数 其他函数也可以互相调用 同一个函数可以被一个或多个函数调用任意多次 也可以不被调用 includeintmax intx inty intz if x y z x elsez y returnz voidmain inta 1 b 5 intc c max a b printf d n c 例题7 1 想输出以下的结果 用函数调用实现 Howdoyoudo 解题思路 在输出的文字上下分别有一行 号 用一个函数print star来实现输出一行 号 再写一个print message函数来输出中间的信息 includevoidmain voidprintstar 对printstar函数原形声明 voidprint message 对print message函数原形声明 printstar 调用printstar函数 print message 调用print message函数 printstar 调用printstar函数 voidprintstar 定义printstar函数 printf n voidprint message 定义print message函数 printf Howdoyoudo n includevoidprintstar 定义printstar函数 printf n voidprint message 定义print message函数 printf Howdoyoudo n voidmain printstar 调用printstar函数 print message 调用print message函数 printstar 调用printstar函数 includevoidmain printstar 调用printstar函数 print message 调用print message函数 printstar 调用printstar函数 voidprintstar 定义printstar函数 printf n voidprint message 定义print message函数 printf Howdoyoudo n 说明 1 对于大规模的 程序 可包含多个源程序文件 2 一个源程序文件由一个或多个函数组成 程序编译是以文件为单位的 而不是以函数为单位 说明 3 程序的执行是从main函数开始的 在main函数中可以调用其他函数 在调用后流程返回到main函数 在main函数中结束整个程序的运行 说明 4 所有函数的定义都是平行的 即在定义函数时是分别进行的 是互相独立的 一个函数并不从属于另一函数 即函数不能嵌套定义 函数间可以互相调用 但不能调用main函数 main函数是系统调用的 说明 5 从用户使用的角度看 函数有两种 标准函数 即库函数 这是由系统提供的 用户不必自己定义这些函数 可以直接使用它们 不同的C系统提供的库函数的数量和功能会有一些不同 但许多基本的函数是共同的 用户自己定义的函数 用以解决用户的专门需要 说明 6 从函数的形式看 函数分两类 无参函数 无参函数一般用来执行指定的一组操作 在调用无参函数时 主调函数不向被调用函数传递数据 有参函数 主调函数在调用被调用函数时 通过参数向被调用函数传递数据 7 函数的定义和调用 7 2 1为什么要定义函数 C语言规定 在程序中用到的所有函数 必须 先定义 后使用 必须事先按规范对它进行定义 指定它的功能和名字 定义函数应包括以下几个内容 指定函数的名字 以便以后按名调用 指定函数的类型 即函数值的类型 返回值类型 指定函数的参数的名字和类型 以便在调用函数时向它们传递数据 对无参函数不需要这项 指定函数应当完成什么操作 也就是函数是做什么的 即函数的功能 这是最重要的 这是在函数体中解决的 对于C编译系统提供的库函数 是由编译系统事先定义好的 它们的定义已放在相关的头文件中 程序设计者只需用 include命令把有关的头文件包含到本文件模块中即可 7 2 2定义函数 1 定义无参函数的一般形式为 类型标识符函数名 声明部分语句部分 includevoidprintstar 定义printstar函数 printf n 语句部分 voidprint message 定义print message函数 printf Howdoyoudo n 语句部分 voidmain printstar 调用printstar函数 print message 调用print message函数 printstar 调用printstar函数 2 定义有参函数的一般形式为 类型标识符函数名 形式参数列表 声明部分语句部分 记住 includeintmax intx inty intz 声明部分z x y x y 语句部分returnz voidmain inta 12 b 5 intc c max a b printf d n c 3 定义空函数的一般形式为 类型标识符函数名 主调函数调用空函数时 只表明这里要调用一个函数 但函数本身什么工作也不做 等以后扩充函数功能时补充上 includevoidf voidmain inta 1 b 5 intc a b f printf d n c 7 2 3函数的调用 函数调用的一般形式为 函数名 实参表列 说明 1 如果是调用无参函数 则 实参表列 可以没有 但括弧不能省略 如print star 记住 includeintmax intx inty intz 声明部分z x y x y 语句部分returnz voidmain inta 12 b 5 intc c max a b printf d n c includevoidf voidmain inta 1 b 5 intc a b f printf d n c 3 如果实参表列包括多个实参 对实参求值的顺序并不是确定的 有的系统按自左至右顺序求实参的值 有的系统则按自右至左顺序 如 f i i 可能有歧义 应避免 2 如果实参表列包含多个实参 则各参数间用逗号隔开 如 max a b 实参与形参的个数应相等 类型应匹配 实参与形参按顺序对应 一一传递数据 主调函数和被调用函数之间有数据传递的关系 方法 参数 通过形式参数和实际参数 0个或多个 返回值 用return语句返回计算结果 0个或1个 说明 函数调用的过程 通过函数调用 可使两个函数中的数据发生联系 形参是变量 实参是数值 形参相当于变量定义实参相当于形参变量的初值返回值相当于函数的结果值函数调用时 从调用点进入函数函数返回值 返回到调用点继续执行 课堂练习 编写函数intp inta intb 返回ab在主函数中输入两个数 以这两个数为实际参数调用函数p 输出函数返回值 ab 要求不能调用pow函数 如果改为voidp inta intb 函数p用于输出abp函数和主函数分别该如何变化 关于形参与实参的说明 1 在定义函数中指定的形参 在未出现函数调用时 它们并不占内存中的存储单元 只有在发生函数调用时 函数max中的形参才被分配内存单元 在调用结束后 形参所占的内存单元也被释放 2 实参可以是常量 变量或表达式 例如 max 但要求它们有确定的值 在调用时将实参的值赋给形参 includevoidmain intmax intx inty inta b c printf pleaseinputtwonumber scanf d d 3 在被定义的函数中 必须指定形参的类型 4 实参与形参的类型应相同或赋值兼容 5 实参向形参的数据传递是单向 值传递 只能由实参传给形参 而不能由形参传回来给实参 在调用函数时 给形参分配存储单元 并将实参对应的值传递给形参 调用结束后 形参单元被释放 实参单元仍保留并维持原值 includevoidmain voidinc intx inty inta 3 b 7 inc a b printf a d b d n a b voidinc intx inty x y x printf x d y d n x y 函数的返回值是通过函数调用使主调函数得到的确定值 例如 c max 的值是 c max 的值是5 赋值语句将这个函数值赋给变量 return后面的值可以是一个表达式 例如 int int return 说明 1 函数的返回值是通过函数中的return语句获得的 一个函数中可以有一个以上的return语句 执行到哪一个return语句 哪一个语句起作用 return语句后面的括弧也可以不要例如 return 等价于 return includevoidmain intmax intx inty inta b c printf pleaseinputtwonumber scanf d d includevoidmain intmax intx inty inta b c printf pleaseinputtwonumber scanf d d 2 函数的返回值应当属于某一个确定的类型 在定义函数时指定函数返回值的类型 例如 下面是3个函数的首行 intmax float float 函数值为整型 charletter charc1 charc2 函数值为字符型 doublemin int int 函数值为双精度型 注意 凡不加类型说明的函数 自动按整型处理 3 在定义函数时指定的函数类型一般应该和return语句中的表达式类型一致 如果函数值的类型和return语句中表达式的值不一致 则以函数类型为准 对数值型数据 可以自动进行类型转换 即函数类型决定返回值的类型 4 对于不带返回值的函数 应当用 void 定义函数为 无类型 或称 空类型 说明 函数语句把函数调用作为一个语句 这时不要求函数返回值 只要求函数完成一定的操作 按函数在程序中出现的位置来分 可以有以下三种函数调用方式 includevoidprintstar printf n intprint message printf Howdoyoudo n return0 voidmain printstar print message printstar intprint message 具有返回值但是调用时函数语句没有使用该值 函数表达式函数出现在一个表达式中 这种表达式称为函数表达式 这时要求函数带回一个确定的值以参加表达式的运算 例如 includevoidmain intmax intx inty inta b c printf pleaseinputtwonumber scanf d d 函数参数函数调用作为一个函数的实参 例如 m max a max b c 其中max b c 是一次函数调用 它的值作为max另一次调用的实参 m的值是a b c三者中的最大者 includevoidmain intmax intx inty inta b c d printf pleaseinputthreenumber scanf d d d 7 2 4对被调用函数的声明和函数原型 在一个函数中调用另一函数 即被调用函数 需要具备哪些条件呢 1 首先被调用的函数必须是已经存在的函数 是库函数或用户自己定义的函数 但光有这一条件还不够 3 如果使用用户自己定义的函数 而被调函数的位置在主调函数的后面 应该在主调函数中对被调用的函数作声明 2 如果使用库函数 还应该在本文件开头用 include命令将调用有关库函数时所需用到的信息 包含 到本文件中来 函数原型的一般形式为 1 函数类型函数名 参数类型1 参数类型2 2 函数类型函数名 参数类型1参数名1 参数类型2参数名2 声明的作用是把函数名 返回值类型 函数参数的个数和类型等信息通知编译系统 以便在遇到函数调用时 编译系统能正确识别函数并检查调用是否合法 没说参数的名称 因为不需要 注意 函数的 定义 和 声明 不是一回事 函数的定义是指对函数功能的确立 包括指定函数名 函数值类型 形参名称及其类型 函数体等 它是一个完整的 独立的函数单位 函数的声明的作用则是把函数的名字 函数类型以及形参的类型 个数和顺序通知编译系统 以便在调用该函数时按此进行语法检查 课堂练习 编写判断素数的函数intsushu inta 在主函数中 使用sushu 函数对用户输入的数据进行判断 如果是素数就输出 YES 否则输出 NO 提示 函数返回值使用1或0 分别代表是或不是素数 includeintsushu inta inti for i 2 i a i if a i 0 break if i a return1 elsereturn0 voidmain intx printf pleaseinputanumber scanf d 上机考试中的问题 第一题定义大小为20的整型一维数组 运用循环将数组的前十个元素赋值为11到20 用变量n记录数组的实际元素个数 用for i 0 i n 1 i printf d array i 输出数组全部十个元素接收用户输入的整数a 将数组中与a相等的元素删除 将数组中的后续元素前移 并将n减一用for i 0 i n 1 i printf d array i 输出数组全部九个元素第二题定义大小为20的整型一维数组 运用循环将数组的前十个元素赋值为11到20 用变量n记录数组的实际元素个数 用for i 0 i n 1 i printf d array i 输出数组全部十个元素接收用户输入的整数a 把a插入到数组的首位置 注意 需要将数组中元素后移之后才能够插入a 并将n加一用for i 0 i n 1 i printf d array i 输出数组中十一个元素 includevoidmain inta 20 inti n 0 j intb for i 0 i 0 i a i 1 a i a 0 b n for i 0 i n 1 i printf d a i printf n 删除元素时 如果数组中有重复元素 则全部删掉 includevoidmain inta 20 11 11 12 11 13 14 15 16 17 18 inti n 10 j intb for i 0 i n 1 i printf d a i printf n scanf d includevoidmain inta 20 11 11 12 11 13 14 15 16 17 18 inti n 10 j intb for i 0 i n 1 i printf d a i printf n scanf d includevoidmain inta 20 11 11 12 11 13 14 15 16 17 18 inti n 10 j intb for i 0 i n 1 i printf d a i printf n scanf d includevoidmain inta 20 11 11 12 11 13 14 15 16 17 18 inti n 10 j intb for i 0 i n 1 i printf d a i printf n scanf d includevoidmain inta 20 11 11 12 11 13 14 15 16 17 18 inti n 10 j intb for i 0 i n 1 i printf d a i printf n scanf d 将删除元素 插入元素 打印全部元素都定义成函数 includeintf inta 20 intn inti j b scanf d 循环调用插入和删除 includeintshow inta 20 intn inti for i 0 i n i printf d a i printf n intf inta 20 intn intb inti j for i 0 i n 1 if a i b for j i j n 2 j a j a j 1 n continue i returnn voidmain inta 20 11 11 12 11 13 14 15 16 17 18 inti n 10 b show a n do scanf d 数组元素作参数与数组名作参数的不同点 includeintshow inta 20 intn inti for i 0 i n i printf d a i printf n voidf inta 20 a 2 99 voidg inta a 100 voidmain inta 20 11 11 12 11 13 14 15 16 17 18 inti n 10 show a n g a 5 f a show a n 重点 7 3函数的嵌套调用和递归调用 函数的嵌套调用就是在调用一个函数时 被调函数体内又调用了另一个函数 7 3 1函数的嵌套调用 例题7 3 解题思路 输入4个整数 找出其中最大的数 用一个函数来实现 定义max 4函数来计算4个数的最大者在max 4中 m max a b m max m c m max m d 编写程序 includevoidmain intmax 4 inta intb intc intd max 4函数的声明 inta b c d max printf Pleaseenter4intergernumbers scanf d d d d intmax 4 inta intb intc intd 定义max 4函数 intmax int int max函数的声明 intm m max a b 调用max函数 找出a和b中的大者 m max m c 调用max函数 找出a b c中的大者 m max m d 调用max函数找出a b c d中的大者 return m 函数返回值是4个数中的最大者 intmax intx inty 定义max函数 if x y returnx elsereturny 函数返回值是x和y中的大者 递推的过程 7 3 2函数的递归调用 在调用一个函数的过程中又出现直接或间接地调用该函数本身 称为函数的递归调用 语言的特点之一就在于允许函数的递归调用 例如 intf intx if x 1 return1 elsereturnx f x 1 有 个人坐在一起 问第 个人多少岁 他说比第 个人大 岁 问第 个人岁数 他说比第 个人大 岁 问第 个人 又说比第 个人大 岁 问第 个人 说比第 个人大 岁 最后问第 个人 他说是 岁 请问第 个人多大 age 5 age 4 2age 4 age 3 2age 3 age 2 2age 2 age 1 2age 1 10可以用数学公式表述如下 age n 10 age n 1 2 例题7 4 解题思路 includeintage intn intc if n 1 c 10 elsec age n 1 2 return c voidmain printf d n age 5 分别用递推方法和递归方法求 1 用递推方法求 从 开始 乘 再乘 一直乘到 递推法的特点是从一个已知的事实出发 按一定规律推下一个事实 再从这个新的已知的事实出发 再向下推出一个新的事实 这和递归不同 解题思路 例题7 5 includevoidmain longfac intn intn longfact 0 printf pleaseinputaintegernumber scanf d 说明 有的C编译系统 如TurboC2 0 整型数据的范围是 32768 32767 而当n的值等于8时 就超过了此范围 因此把函数fac和存放n 的变量fac和fact定义为long型 2 用递归方法递归的思路和递准是相反的 并不是先求1再求2 直到n 而是直接从目标出发提出问题 即 等于 而 可用下面的递归公式表示 解题思路 includevoidmain intfac intn intn y printf inputanintegernumber scanf d 未知 未知 递归边界条件已知 已知 已知 的过程 includevoidmain intfac intn intn y printf inputanintegernumber scanf d 输入负数会怎样 includevoidmain intfac intn intn y printf inputanintegernumber scanf d 输入负数会怎样 遇到异常时提前return是很常用的方法 includevoidf intn floatf f 100 0 n printf Hello n printf Hello f n f printf fHello f n f f voidmain intn scanf d includevoidf intn floatf f 100 0 n printf Hello n printf Hello f n f printf fHello f n f f voidmain intn scanf d includevoidf intn floatf f 100 0 n printf Hello n printf Hello f n f printf fHello f n f f voidmain intn scanf d if n 0 printf error 分母为零 n return return可以不带返回值只表示函数结束执行 includevoidf intn floatf if n 0 printf error 分母为零 n else f 100 0 n printf Hello n printf Hello f n f printf fHello f n f f voidmain intn scanf d 当代码比较多时或者 层次已经很多时右边的方法会使程序更加繁琐 说明 通过以上例子 可以看到 一个问题能否用递归方法处理 取决于以下3个条件 1 所求解的问题能转化为用同一方法解决的子问题 例如求n 可以转化为 n 1 n n 1 就是子问题 它的求解方法与n 是相同的 2 子问题的规模比原问题的规模小 如参数递减 第一次调用fac 5 第二次调用fac 4 越来越接近结束条件 3 必须要有递归结束条件 例如fac 1 1 fac 0 1 停止递归 否则形成无穷递归 系统无法完成执行过程 d max c max a b 属于递归调用吗 为什么 本质区别 递归调用中 第一层max没结束 就调用第二层了 等到第二层结束之后第一层才能结束而上述调用中 一个max调用完之后才调用另一个max 所以不存在递归调用 递归调用一定是在函数体的定义中直接或间接地调用了自己 课堂练习 用递归实现2n 关于递归的深入探讨 用递归思想解决问题的关键是 1 递归算法的设计 相当于循环中的循环体语句块 2 结束条件的设定 相当于循环结束条件 3 递归参数的使用 相当于循环变量的修正 如 i 例如 xy includeintf intx inty if y 0 return1 elsereturnf x y 1 x voidmain printf d n f 3 4 intFactorial intn if n 0 return1 elsereturnn Factorial n 1 intFactorial intn if n 0 return1 elsereturnn Factorial n 1 递归算法 intFactorial intn if n 0 return1 elsereturnn Factorial n 1 递归终止条件基本情况 intFactorial intn if n 0 return1 elsereturnn Factorial n 1 修改递归条件 intFactorial intn if n 0 return1 elsereturnn Factorial n 1 main F 3 n 3 F 3 3 F 2 n 2 F 2 2 F 1 n 1 F 0 1 计算Factorial 3 3 F 1 n 0 1 F 0 intFactorial intn if n 0 return1 elsereturnn Factorial n 1 F 3 n 3 F 3 3 F 2 n 2 F 2 2 F 1 n 1 F 0 1 计算Factorial 3 3 F 1 n 0 1 F 0 1 main intFactorial intn if n 0 return1 elsereturnn Factorial n 1 F 3 n 3 F 3 3 F 2 n 2 F 2 2 F 1 n 1 计算Factorial 3 3 F 1 main intFactorial intn if n 0 return1 elsereturnn Factorial n 1 F 3 n 3 F 3 3 F 2 n 2 F 2 2 F 1 n 1 计算Factorial 3 3 F 1 F 1 1 1 main intFactorial intn if n 0 return1 elsereturnn Factorial n 1 F 3 n 3 F 3 3 F 2 n 2 F 2 计算Factorial 3 3 F 2 2 2 main intFactorial intn if n 0 return1 elsereturnn Factorial n 1 F 3 n 3 F 3 计算Factorial 3 3 main intFactorial intn if n 0 return1 elsereturnn Factorial n 1 F 3 n 3 F 3 计算Factorial 3 3 F 3 6 main intFactorial intn if n 0 return1 elsereturnn Factorial n 1 F 3 计算Factorial 3 3 main intFactorial intn if n 0 return1 elsereturnn Factorial n 1 F 3 计算Factorial 3 3 3 6 main intFactorial intn if n 0 return1 elsereturnn Factorial n 1 计算Factorial 3 3 F 3 F 3 n 3 F 3 3 F 2 n 2 F 2 2 F 1 n 1 F 0 1 F 1 n 0 1 F 0 F 1 1 F 2 2 F 3 6 main 3 6 includeintFactorial int voidmain intk printf ComputeFactorial k Pleaseinputk scanf d 非递归调用 includeintFactorial int voidmain intk printf ComputeFactorial k Pleaseinputk scanf d 递归调用 例如 xy includeintf intx inty if y 0 return1 elsereturnf x y 1 x voidmain printf d n f 3 4 发生了几次函数f的调用 调用顺序依次是 返回顺序依次是 一般递归函数的形式 F x1 x2 xn if P1 E1elseif P2 E2 elseif Pm EmelseEm 1 Pi i 1 2 m 是测试表达式Ei i 1 2 m 1 是表达式F 可以出现在Pi和Ei中 F 可以出现多次 当F 出现在循环体中的时候 递归的功能将十分强大多次的递归调用将使程序执行规模大幅提升 递归定义斐波那契数列 intFibonacci intn if n 2 return1 elsereturnFibonacci n 1 Fibonacci n 2 假设n 5发生了几次调用 调用顺序依次是 返回顺序依次是 intFibonacci intn if n 2 return1 elsereturnFibonacci n 1 Fibonacci n 2 注意执行顺序 该节点是在整个左枝执行完之后才执行的 7 4数组作为函数参数 7 4 1数组元素作函数实参 由于实参可以是表达式 而数组元素可以是表达式的组成部分 因此数组元素可以作为函数的实参 与变量作实参一样 是单向传递 即 值传送 方式 7 4 2数组名作函数参数 可以用数组名作函数参数 此时并不是将该数组中全部元素传递给所对应的形参 由于数组名代表数组的首地址 所以只是将数组的首元素的地址传递给所对应的形参 因此对应的形参应当也是数组类型的 includevoidf inta 10 intn inti for i 0 i n i a i a i 1 n n 2 voidmain inta 10 1 2 3 4 5 6 7 8 9 10 n 10 inti f a n for i 0 i n i printf d a i includevoidfunction inta intb intt t a a b b t intf inta 10 intn inti j for i 0 i n 1 i for j 0 j n 1 j if a j a j 1 function a j a j 1 for i 0 i n i a i a i 1 n n 2 returnn voidmain inta 10 1 2 3 4 5 6 7 8 9 10 n 10 inti n f a n for i 0 i n i printf d a i 要想用函数改变实参的值就必须传地址传值做不到 用数组作为函数参数 在调用函数时并不另外开辟一个存放形参数组的空间 这点是和用变量作函数参数不同的 数组名代表数组的首元素的地址 因此 用数组名作函数实参时 只是将实参数组的首元素的地址传给形参数组 用一个函数实现用选择法对10个整数按升序排列 例题7 9 解题思路 所谓选择法就是先将10个数中最小的数与a 0 对换 再将a 1 到a 9 中最小的数与a 1 对换 每比较一轮 找出一个未经排序的数中最小的一个 共比较9轮 未排序时的情况 a 0 a 1 a 2 a 3 a 4 36194将5个数中最小的数1与a 0 对换 16394将余下的4个数中最小的数3与a 1 对换13694将余下的3个数中最小的数4与a 2 对换13496将余下的2个数中最小的数6与a 3 对换13469 voidsort intarray 10 intn inti j k t for i 0 i n 1 i 让k得到array i 和array n 1 的最小值的下标交换array k 和array i k i for j i 1 j n j if array j array k k j t array k array k array i array i t includevoidmain voidsort intarray intn inta 10 i printf enterthearray n for i 0 i 10 i scanf d 有4个学生 每个学生5门课的成绩 设计一个函数 用来求出其中的最高成绩 例题7 10 解题思路 用多维数组名作为函数的实参和形参 先使变量max的初值为二维数组中第一个元素的值 然后将二维数组中各个元素的值与max相比 每次比较后都把 大者 存放在max中 取代max的原值 全部元素比较完后 max的值就是所有元素的最大值 includevoidmain intmax value intarray 4 inta 3 4 1 3 5 7 2 4 6 8 15 17 34 12 printf maxvalueis d n max value a intmax value intarray 4 inti j max max array 0 0 for i 0 imax max array i j returnmax 说明 在被调用函数中对形参数组定义时可以指定每一维的大小 也可以省略第一维的大小说明 例如 定义highest score函数的首行可写为 inthighest score floatarray 5 但不能把第二维大小说明省略 如下面的定义是不合法的 inthighest score floatarray 7 5变量的作用域和生存期 7 5 1变量的作用域 局部变量和全局变量 1 局部变量在一个函数内部定义的变量是局部变量 它只在本函数范围内有效 在本函数以外是不能使用这些变量的 floatf1 inta 函数f1 intb c a b c有效 charf2 intx inty 函数f2 inti j x y i j有效 voidmain 主函数 intm n m n有效 主函数中定义的变量也只在主函数中有效 在其他函数中均无效 主函数也不能使用其他函数中定义的变量 2 不同函数中可以使用相同名字的变量 它们代表不同的对象 互不干扰 3 形式参数也是局部变量 实参是局部变量吗 includevoidf inta intb b a c printf d d n a b voidmain inta 1 intb 2 c 3 f 100 printf d d d n a b c 4 在一个函数内部 可以在复合语句 块语句 中定义变量 这些变量只在本复合语句中有效 voidmain inta b intc c a b c在此范围内有效a b在此范围内也有效 includevoidmain inta 1 intb 2 intc c a b printf d d d n a b c printf d d d n a b c includevoidmain inta 1 intb 2 intc c a b printf d d d n a b c printf d d d n a b c c a b includevoidmain inta 1 intb 2 c 100 intc c a b printf d d d n a b c printf d d d n a b c includevoidmain inta 1 intb 2 c 100 intc c a b printf d d d n a b c printf d d d n a b c 重名时不冲突本块里c有效本块外c有效 2 全局变量 在函数内定义的变量是局部变量 而在函数之外定义的变量称为外部变量 外部变量是全局变量 也称全程变量 全局变量可以被本文件中不同函数所共用 它的有效范围从定义变量的位置开始到本源文件结束 intp 1 q 5 外部变量 floatf1 inta 定义函数f1 intb c charc1 c2 外部变量 charf2 intx inty 定义函数f2 inti j voidmain 主函数 intm n p q有效 c1 c2有效 includeinta voidf a 100 voidmain a 20 f printf d n a includeinta voidf a 100 b 100 intb voidg a 200 b 200 voidmain a 20 b 20 g f printf d n d n a b includeinta voidf a 100 voidmain inta 20 f printf d n a includeinta voidf a 100 voidmain inta 20 f printf d n a 重名时不冲突本函数里a有效本函数外a有效 有4个学生 5门课的成绩 要求输出其中的最高成绩以及它属于第几个学生 第几门课程 例题7 11 解题思路 调用一个函数只能得到一个函数值 可以使用全局变量 通过全局变量从函数中得到所需要的值 includeintRow Column voidmain floathighest score floatarray 4 5 floatscore 4 5 61 73 85 5 87 90 72 84 66 88 78 75 87 93 5 81 96 65 85 64 76 71 printf Thehighestscoreis 6 2f n highest score score printf StudentNo is d nCourseNo is d n Row Column floathighest score floatarray 4 5 inti j floatmax max array 0 0 for i 0 imax max array i j Row i Column j return max 说明 由于全局变量在整个文件范围内都有效 因此在highest score函数中将行序号i和列序号j赋给全局变量Row和Column 在函数调用结束后 函数中的局部变量被释放了 但全局变量保存下来 可以在main函数中输出它们的值 建议不在必要时不要使用全局变量 原因如下 全局变量在程序的全部执行过程中都占用存储单元 而不是仅在需要时才开辟单元 使用全局变量过多 会降低程序的清晰性 在各个函数执行时都可能改变外部变量的值 程序容易出错 因此 要限制使用全局变量 它降低函数的通用性 因为函数在执行时要依赖于其所在的外部变量 如果将一个函数移到另一个文件中 还要将有关的外部变量及其值一起移过去 若该外部变量与其他变量同名时 就会出现问题 降低了程序的可靠性和通用性 一般要求把 程序中的函数做成一个封闭体 除了可以通过 参数 返回值 的渠道与外界发生联系外 没有其他渠道 7 5 2变量的存储方式和生存期 存储方式指的是数据在内存中存储的方法存储方式具体包含四种 自动的 auto 静态的 static 寄存器 register 外部的 extern 1 auto变量 函数中定义的局部变量 包括形参 默认都是自动的 关键字为auto 可以省略在调用该函数时系统会自动给它们分配存储空间 在函数调用结束时就自动释放这些存储空间例如 autointb c 3 2 static 声明静态变量 在程序开始执行之前 编译时 静态变量已经产生 直到程序结束执行之时 静态变量才会消失 关键字static当函数中的局部变量定义成静态的 该变量的值在函数调用结束后将不会消失 而保留原值 includevoidmain intfac intn inti for i 1 i 5 i printf d d n i fac i intfac intn staticintf 1 f f n returnf includevoidmain intfac intn inti for i 1 i 5 i printf d d n i fac i intfac intn intf 1 f f n returnf 对静态局部变量的说明 1 静态局部变量属于静态存储类别 在静态存储区内分配存储单元 在程序整个运行期间都不释放 而自动变量 即动态局部变量 属于动态存储类别 函数调用结束后即释放 2 对静态局部变量是在编译时赋初值的 即只赋初值一次 在程序运行时它已有初值 以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值 3 如在定义局部变量时不赋初值的话 则对静态局部变量来说 编译时自动赋初值 对数值型变量 或空字符 对字符变量 而对自动变量来说 如果不赋初值则它的值是一个不确定的值 4 虽然静态局部变量在函数调用结束后仍然存在 但其他函数不能引用它 因为它也是局部变量 includevoidmain intfac intn inti for i 1 i 5 i printf d d n i fac i intfac intn intf f f n returnf includevoidmain intfac intn inti for i 1 i 5 i printf d d n i

温馨提示

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

评论

0/150

提交评论