




已阅读5页,还剩136页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
教学目的与要求 掌握函数的定义与调用方法 函数参数的传递方式变量存储类型及变量的生存期和有效范围掌握函数的嵌套调用与递归调用了解带参数的main函数 重点与难点 重点 函数定义函数调用函数声明等基本概念函数的嵌套调用与递归调用变量的存储类别与作用域 难点 函数参数的值传送函数的递归调用静态变量 引例 设计学生信息管理的程序 4 1概述 模块化程序设计思想 将一个大的程序按功能分解成一些小模块 使每一模块成为 功能单一结构清晰接口简单容易理解的子程序 C语言中的函数 f 例1 求2个数中较大者 4 1程序解析 includevoidmain inta b max scanf d d includevoidmain intmax intx inty 对被调用函数max的声明 inta b c scanf d d max函数的定义 intmax intx inty intz if x y z x elsez y return z 例2 输入圆柱体的高和半径 求圆柱体积 volume r2 h 要求定义和调用函数cylinder r h 计算圆柱体的体积 includeintmain void doubleheight radius volume doublecylinder doubler doubleh 函数声明 printf Enterradiusandheight scanf lf lf 定义求圆柱体积的函数 doublecylinder doubler doubleh doubleresult result 3 1415926 r r h 计算体积 returnresult 返回结果 Enterradiusandheight 3 010Volume 282 743 includevoidmain voidspc intn inta scanf d 例3 输出n个空格的函数 voidspc intn inti for i 0 i n i printf return 有一个空格 include stdio h main intn k c printf pleaseinput n k n scanf d d intfac intm inti s 1 for i 1 i m i s i return s 说明 1 2 一个源程序文件 c 由一个或多个函数构成 3 c程序的执行从函数开始 执行过程中调用其他函数 该函数执行结束后返回函数 在函数中结束整个程序的运行 一个程序中有且只有一个函数 4 所有函数的是平行的 不能嵌套 5 从用户使用的角度看 函数分为 函数和函数 6 从函数的形式看函数分两类 函数 函数 main main main main 定义 库 自定义 无参 有参 4 2函数的定义 函数是指完成一个特定工作的独立程序模块 库函数 由C语言系统提供定义如scanf printf 等函数自定义函数 需要用户自己定义如计算圆柱体体积函数cylinder main 也是一个函数 C程序由一个main 或多个函数构成 1 返回运算结果的函数定义 doublecylinder doubler doubleh doubleresult result 3 1415926 r r h returnresult 函数类型函数名 形参表 函数首部 函数体 函数实现过程return表达式 把函数运算的结果回送给主函数 只能返回一个值 函数返回值的类型 没有分号 形参 类型1参数1 类型2参数2 类型n参数n参数之间用逗号分隔 每个参数前面的类型都必须分别写明 不能写成doubler h doublecylinder doubler doubleh 函数首部 函数体 写在一对大括号内 doubleresult result 3 1415926 r r h 计算圆柱体积 returnresult 返回运算结果 分析函数的定义 函数类型 函数名 形参表 与函数类型一致 有参函数 例有参函数intmax intx inty intz z x y x y return z 2 不返回运算结果的函数定义 void函数名 参数表 函数首部 函数体 函数实现过程return 可以省略return 这类函数通常用于屏幕输出等 表示不返回结果 不能省略否则函数类型被默认定义为int或者char printstar printf main inta a printstar printf d a 例6无返回值的函数返回后带回不确定值 输出 10 voidprintstar printf main inta a printstar printf d a 编译错误 例7 输出5之内的数字金字塔 输出数字金字塔 includeintmain void voidpyramid intn 函数声明 pyramid 5 调用函数 输出数字金字塔 return0 voidpyramid intn inti j for i 1 i n i 行数 for j 1 j n i j 空格 printf for j 1 j i j 显数字 printf d i 每个数字的前后各有一个空格 putchar n 122333444455555 注意 1 函数中可以有多个return语句 2 函数的类型 应该和return语句表达式的类型保持一致 若函数类型与return语句中表达式值的类型不一致 以函数类型为准 自动转换 3 若函数的类型为void 则函数可以无return语句 或者return语句的表达式为空 4 若无return语句 遇到函数结束 时 自动返回主函数 引例 返回两个数中的较大值 main floata b intc scanf f f 输入32 0 25 0 4 3函数的调用 调用自定义函数时 程序中必须有与调用函数相对应的函数定义 1 若自定义函数的编写在main之前 则无需声明该自定义函数2 若自定义函数的编写在main之后 则必需声明该自定义函数 可以用三种方式调用函数 1 函数表达式 必须有一个明确的返回值 可以出现在任何允许表达式出现的地方 参与运算 2 一条独立函数调用语句 例如 func1 printf d a 例如 y power 2 3 3 函数参数 例如 y pow 5 pow 4 3 对被调函数的说明 1 对用户自定义函数在某些情况下需要进行函数说明 2 对于系统标准函数 库函数 一般注意相关的头文件 main func 结束 返回 func 1 函数原型声明 函数类型函数名 参数表 doublecylinder doubler doubleh voidpyramid intn 函数必须先定义后调用 将主调函数放在被调函数的后面 就像变量先定义后使用一样 只写函数定义中的第1行 函数首部 并以分号结束 如果自定义函数在主调函数的后面 就需要在函数调用前 加上函数原型声明 函数声明 说明函数的类型和参数的情况 以保证程序编译时能判断对该函数的调用是否正确 只写函数定义中的第1行 函数首部 并以分号结束 与之相应的函数声明应为 doublefunc doublex inty floatz 也可以不写形参名 doublefunc double int float 不能只写形参名而不写类型 doublefunc x y z 注意 只有函数返回值为int或char时 函数类型标识符才可以省略 形参的次序也不能写错 不能写成 doublefunc inty floatz doublex 例如 floatf floatx inty main fun1 f a b fun2 f c d floatf floatx inty 放在所有函数之前 作统一声明 floatadd floatx floaty floatz z x y return z main floata b c scanf f f 被调函数出现在主调函数之前 不必函数说明 引例返回两个数中的较大值 main floata b intc scanf f f main floata b c floatc floatmax floatx floaty scanf f f 2 函数调用的形式和过程 使用返回值 volume cylinder radius height printf f n cylinder radius height 完成操作 pyramid 5 常用于void类型函数的调用 常用于返回结果的函数的调用 常量 变量 表达式 函数名 实参表 intmain void doubleheight radius volume doublecylinder doubler doubleh printf Enterradiusandheight scanf lf lf 调用函数 实参 形参 执行函数中的语句 返回调用它的地方 函数声明 3 参数传递 函数定义时的参数被称为形式参数 简称形参 doublecylinder doubler doubleh 函数调用时的参数被称为实际参数 简称实参 volume cylinder radius height 1 形参与实参各占一个独立的存储空间 2 形参的存储空间是函数被调用时才分配的 实参 x y 3 4 形参 a b 值结合 3 函数返回时 临时存储区也被撤销 3 4 传值调用的特点是 函数中对形参变量的操作不会影响到调用函数中的实参变量 即形参值不能传回给实参 实参 形参在参数传递过程中 实参把值复制给形参 形参和实参一一对应 数量一致 类型一致 顺序一致形参 变量 用于接受实参传递过来的值实参 常量 变量或表达式 且必须有确定的值 单向传递虚实结合 例4交换两个数 includemain inta 3 b 5 printf a d tb d n a b printf swapped n swap a b printf a d tb d n a b swap intx inty inttemp temp x x y y temp 1 传值调用方式 函数只有一个入口 实参传值给形参 一个出口 函数返回值 说明 2 实参与形参在个数 类型上要匹配 3 函数声明的作用是为编译系统对参数进行类型检查提供依据 并且在出现同名函数时 系统将根据类型和参数不同 对它们加以区别 intsum intx inty intz intm m x y z returnm includemain inti j k s printf inputthreeintegers scanf d d d 例 编写程序 计算3个不为0的整数之和 无参函数 例无参函数printstar printf n 或printstar void printf n 空函数 返回语句形式 return 表达式 或return表达式 功能 使程序控制从被调用函数返回到调用函数中 同时把返值带给调用函数 4 函数结果返回 例 求一个整数的绝对值的函数 intabsolute value intx return x 0 x x return语句返回一个表达式的值 在一个函数中允许有一个或多个return语句 流程执行到其中一个return时即返回主调函数 floaty floatx if x 0 return x x x 1 elsereturn x x x x 3 注意 如果有多个return语句 每个return后面的表达式的类型应相同 例5 判断奇偶数的函数even n 要求 定义一个判断奇偶数的函数even n 当n为偶数时返回1 否则返回0 判断奇偶数的函数 inteven intn 函数首部 if n 2 0 判别奇偶数 return1 偶数返回1 elsereturn0 奇数返回0 如何调用该函数 intmain intx inteven intn printf Pleaseinputx scanf d 例求100以内的全部素数 每行输出10个 素数就是只能被1和自身整除的正整数 1不是素数 2是素数 要求定义和调用函数prime m 判断m是否为素数 当m为素数时返回1 否则返回0 算法描述 对2 100之间的每个数进行判断 若是素数 则输出该数 for m 2 m 100 m if m是素数 printf d m prime m 0 include includeintmain void intcount m intprime intm count 0 for m 2 m 100 m if prime m 0 printf 6d m count if count 10 0 printf n printf n intprime intm inti n if m 1 return0 n int sqrt m for i 2 i n i if m i 0 return0 return1 C程序结构函数调用的过程 计算机在执行程序时 从主函数main开始执行 如果遇到某个函数调用 主函数被暂停执行 转而执行相应的函数 该函数执行完后 将返回主函数 然后再从原先暂停的位置继续执行 函数遇return或最后的大括号 返回主函数 1 自定义函数的功能2 函数的定义方法3 函数的声明4 函数的调用5 函数结果的返回6 函数的调用 基本应用 主要内容回顾 函数的嵌套调用函数的递归调用 提高 4 5函数的嵌套调用 4 5 1函数的嵌套调用函数的嵌套调用是指 在执行被调用函数时 被调用函数又调用了其它函数 这与其它语言的子程序嵌套调用的情形是类似的 案例1 求三个数中最大数和最小数的差值 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 计算s 1k 2k 3k Nk 计算n的k次方 longf1 intn intk longpower n inti for i 1 i k i power n returnpower 计算1到n的k次方之累加和 longf2 intn intk longsum 0 inti for i 1 i n i sum f1 i k returnsum main intN K scanf d d 案例3 计算s 1 2 3 n 功能 函数的嵌套调用 计算n的阶乘 longn f1 intn longpower 1 inti for i 1 i n i power i returnpower 计算1到n的k次方之累加和 longsum f2 intn longsum 0 inti for i 1 i n i sum n f1 i returnsum main intn printf Pleaseinputanumber scanf d 函数的递归调用是指 一个函数在它的函数体内 直接或间接地调用它自身 函数的递归调用 什么是递归调用 如果函数funA在执行过程又调用函数funA自己 则称函数funA为直接递归 如果函数funA在执行过程中先调用函数funB 函数funB在执行过程中又调用函数funA 则称函数funA为间接递归 递归的实质 把需要求解的问题转换成与原有问题类似的问题 按这一原则将问题分解下去 最终分解出来的问题是一个已知解的问题 这便是有限的递归 注意 每个递归过程都必须有一个 出口 函数变化的趋势应靠近该出口 避免陷入无限循环 递归的过程有两个阶段 第一阶段 递推 将原问题分解成新的问题 最终到达已知条件 递推阶段结束 第二阶段 回归 从已知的条件出发 按照递推的逆过程 逐一求值回归 最后到达递推的开始处 结束回归阶段 完成递归调用 例有4个人站在一起 问第4个人多少岁 他说比第3人大2岁 问第3个人多少岁 他说比第2人大2岁 问第2个人多少岁 他说比第1人大2岁 问第1个人多少岁 他说是10岁 请问第4个人多大 10岁 第i个人的岁数 10 2 i 1 递推 递归 例4有4个人站在一起 问第4个人多少岁 他说比第3人大2岁 问第3个人多少岁 他说比第2人大2岁 问第2个人多少岁 他说比第1人大2岁 问第1个人多少岁 他说是10岁 请问第4个人多大 10岁 age 4 age 3 2age 3 age 2 2age 2 age 1 2age 1 10 age n 求第n个人年龄 递归算法 10 n 1 age n 1 2 n 1 age n intage intn intc if n 1 c 10 elsec age n 1 2 returnc 递归结束条件 递归出口 递归表达式 写递归算法的两个要素 includevoidmain printf d n age 4 age 4 c age 3 2 returnc age 4 16 age函数n 4 c age 2 2 returnc age 3 14 age函数n 3 c age 1 2 returnc age 2 12 age函数n 2 c 10 age 1 10 returnc age函数n 1 main函数 递归函数age的执行过程 输出age 4 intage intn intc if n 1 c 10 elsec age n 1 2 returnc includevoidmain printf d n age 4 递推 例有些数学问题本身就具有很好的递归性质 如求阶乘问题 求n的阶乘问题可以转化为求n 1的阶乘问题 而求n 1的阶乘问题又可转化为求n 2的阶乘问题 这样一步步化简 最后当n 1时就可由第一式直接给出结果 includelongintrfact intn voidmain intn longintsum printf Pleaseinputn scanf d longintrfact intn intx longinty if n 0 printf error if n 0 return1 x n 1 y rfact x return n y 假设n 5 rfact 5 的调用和回代过程 其值的求解过程如图所示 main函数 rfact 5 rfact 4 rfact 3 rfact 2 rfact 1 输出rfact 5 120 返回值120 返回值24 返回值6 返回值2 返回值1 总结 1 递归过程不应无限制地进行下去 2 在设计递归函数时应当考虑到递归的终止条件 上例中使递归终止的条件 if n 1 return 1 所以 任何有意义的递归总是由两部分组成的 递归方式与递归终止条件 例 已知有如下某数学函数 有一只猴子 第一天摘了2个桃子 以后每天摘的桃子比前一天多3个 试问 第5天猴子摘了多少桃子 数学公式为 f n intfun intn intval if n 1 val 2 elseval 3 fun n 1 return val 2 n 1 3 f n 1 n 1 includeintfun intn main printf d n fun 5 主程序 fun 5 intfun intn intval if n 1 val 2 elseval 3 fun n 1 return val intfun 5 val 3 fun 4 intfun 4 val 3 fun 3 intfact 3 val 3 fun 2 intfact 2 val 3 fun 1 val 3 2 return 5 val 3 5 return 8 val 3 8 return 11 val 3 11 return 14 fun 5 14 intfact 1 val 2 val 2 return 2 20 02 72 49 例 求Fibonacci数列第i项的值 Fibonacci数列 0 1 1 2 3 5 8 13 21 其数字表达式为 fibonacci 0 0fibonacci 1 1fibonacci n fibonacci n 1 fibonacci n 2 n 1 设计一个函数 longfibonacci intn 用于计算数列中第n项的值 20 02 73 49 程序如下所示 求第n项Fibonacci数列的值 includelongfibonacci intn main intx 0 longresult do result fibonacci x printf fibonacci d ld n x result scanf d 20 02 74 49 longfibonacci intn if n 0 n 1 returnn elsereturnfibonacci n 1 fibonacci n 2 程序运行结果 fibonacci 0 03 fibonacci 3 24 fibonacci 4 36 20 02 75 49 以x 4为例 下图说明了fibonacci函数是怎样计算fibonacci 4 的 图中把fibonacci简写成f 4 3变量的作用域和存储类别 知识要点 局部变量和全局变量 按作用域分 静态存储变量 动态存储变量 按生存期分 局部自动类型 静态局部类型 静态全局类型 全局类型 按存储类型分 编译或函数调用时为其分配内存单元 10 程序中使用变量名对内存操作 变量是对程序中数据的存储空间的抽象 4 3 1局部变量和全局变量 局部变量在函数内定义的变量 包括形参 作用范围 本函数内部定义在复合语句内的变量作用范围 复合语句内部全局变量在函数以外定义的变量 不从属于任一函数 作用范围 从定义处到源文件结束 包括各函数 intf1 inta 函数f1 intb c a b c作用域 仅限于函数f1 中intf2 intx 函数f2 inty z x y z作用域 仅限于函数f2 中 main intm n m n作用域 仅限于函数main 中 局部变量的作用域说明 1 主函数main 中定义的局部变量 也只能在主函数中使用 其它函数不能使用 同时 主函数中也不能使用其它函数中定义的局部变量 因为主函数也是一个函数 与其它函数是平行关系 这一点是与其它语言不同的 应予以注意 2 形参变量也是局部变量 属于被调用函数 实参变量 则是调用函数的局部变量 3 允许在不同的函数中使用相同的变量名 它们代表不同的对象 分配不同的单元 互不干扰 也不会发生混淆 4 在复合语句中也可定义变量 其作用域只在复合语句范围内 例在复合语句中定义局部变量 includeintmain void inta a 1 复合语句开始 intb 2 b a b a a b 复合语句结束 printf d a return0 b 小范围内的临时变量 4 main inta b a 3 b 4 printf main a d b d n a b sub printf main a d b d n a b sub inta b a 6 b 7 printf sub a d b d n a b 运行结果 main a 3 b 4sub a 6 b 7main a 3 b 4 例不同函数中同名变量 全局变量 在函数外部定义的变量称为外部变量 外部变量不属于任何一个函数 其作用域是 从外部变量的定义位置开始 到本文件结束为止 外部变量可被作用域内的所有函数直接引用 所以外部变量又称全局变量 include stdio h intx 定义全局变量x intf intx 4 x为局部变量 returnx intmain void inta 1 x a 对全局变量x赋值1 a f a的值为4 intb 2 b a b b的值为6 x x b 全局变量运算 printf d d a x return0 4 7 若局部变量与全局变量同名 局部变量优先 案例3 输入长方体的长 l 宽 w 高 h 求长方体体积及正 侧 顶三个面的面积 功能 利用全局变量计算长方体的体积及三个面的面积 ints1 s2 s3 intvs inta intb intc intv v a b c s1 a b s2 b c s3 a c returnv main intv l w h printf ninputlength widthandheight scanf d d d floatmax min floataverage intn inti floatx sum 0 scanf f inta 3 b 5 max inta intb intc c a b a b return c main inta 8 printf a d n b d n max d n a b max a b 外部变量与局部变量同名时 在内部变量的作用域中 外部变量被屏蔽 例 运行结果 a 8 main中的a b 5 main中的b max 8 inti main voidprt for i 0 i 5 i prt voidprt for i 0 i 5 i printf c printf n 外部变量使用不当时 会引起副作用 运行结果 for i 0 i 5 i for i 0 i 5 i printf c printf n 对于多文件程序 在一个源文件中定义的外部变量还可以在其它的文件中使用 这时需要在使用它的文件中用extern进行说明 这样的变量称为程序级的变量 应尽量少使用全局变量 因为 全局变量在程序全部执行过程中占用存储单元降低了函数的通用性 可靠性 可移植性降低程序清晰性 容易出错 定义说明次数 只能1次可说明多次位置 所有函数之外函数内或函数外分配内存 分配内存 可初始化不分配内存 不可初始化 外部变量说明 extern数据类型变量表 全局变量的几点说明 1 外部变量可加强函数模块之间的数据联系 但又使这些函数依赖这些外部变量 因而使得这些函数的独立性降低 从模块化程序设计的观点来看这是不利的 因此不是非用不可时 不要使用外部变量 2 在同一源文件中 允许外部变量和内部变量同名 在内部变量的作用域内 外部变量将被屏蔽而不起作用 3 外部变量的作用域是从定义点到本文件结束 如果定义点之前的函数需要引用这些外部变量时 需要在函数内对被引用的外部变量进行说明 外部变量说明的一般形式为 extern数据类型外部变量 外部变量2 注意 外部变量的定义和外部变量的说明是两回事 外部变量的定义 必须在所有的函数之外 且只能定义一次 而外部变量的说明 出现在要使用该外部变量的函数内 而且可以出现多次 intmax intx inty intz z x y x y return z main externinta b printf max d max a b inta 13 b 8 运行结果 max 13 externinta b intmax intz z a b a b return z main printf max d max inta 13 b 8 main voidgx gy externintx y printf 1 x d ty d n x y y 246 gx gy voidgx externintx y x 135 printf 2 x d ty d n x y intx y voidgy printf 3 x d ty d n x y 运行结果 1 x 0y 02 x 135y 2463 x 135y 246 程序代码区数据区静态存储区编译时分配自动存储区局部变量动态分配区程序员分配管理 4 3 2变量的动态存储与静态存储 变量的属性数据类型 变量所持有的数据的性质 操作属性 存储属性存储器类型 寄存器 静态存储区 动态存储区 程序编译时分配 自动初始化 不初始化 临时创建 变量的属性存储属性生存期 变量在某一时刻存在 静态变量与动态变量作用域 变量在某区域内有效 局部变量与全局变量 变量的生存期 静态变量与动态变量 全局变量的生存期是静态的 全局变量的static表明链接类型 不是存储期 静态变量存储期在程序执行期间一直存在 动态的一般是代码块的变量 内存分配灵活 变量的存储类别 动态变量与静态变量 生存期 变量存在 在内存有存储空间 的时间段 静态变量 从程序开始执行到程序结束动态变量 从包含该变量定义的函数开始执行至函数执行结束 在 语言中 对变量的存储类型说明有以下四种 自动变量 auto 寄存器变量 register 外部变量 extern 静态变量 static 自动变量和寄存器变量属于动态存储方式 外部变量和静态内部变量属于静态存储方式 内部变量可以定义为 自动的 auto 寄存器 register 静态的 static 自动的 auto 在函数内定义的变量都是自动的 main inta 等价于 autointa 寄存器变量 register 如 registerinti 4 3 3内部变量的存储类别 如 intsum autointa b c registerinti staticfloatx y auto型变量和register型变量只用于定义局部变量 static型变量即可定义成局部变量 又可定义成全局变量 变量定义格式 存储类型 数据类型变量表 auto型变量 1 auto型变量 不会自动的初始化 2 代码块不同 可以同名 3 同名时注意变量的覆盖 自动变量属于动态存储方式 在函数中定义的自动变量 只在该函数内有效 函数被调用时分配存储空间 调用结束就释放 在复合语句中定义的自动变量 只在该复合语句中有效 退出复合语句后 也不能再使用 否则将引起错误 定义而不初始化 则其值是不确定的 如果初始化 则赋初值操作是在调用时进行的 且每次调用都要重新赋一次初值 由于自动变量的作用域和生存期 都局限于定义它的个体内 函数或复合语句 因此不同的个体中允许使用同名的变量而不会混淆 即使在函数内定义的自动变量 也可与该函数内部的复合语句中定义的自动变量同名 建议 系统不会混淆 并不意味着人也不会混淆 所以尽量少用同名自动变量 例auto变量的作用域 main intx 1 voidprt void intx 3 prt printf 2ndx d n x printf 1stx d n x voidprt void intx 5 printf 3thx d n x includeintmain intx 30 originalx printf xinouterblock d n x intx 77 newx hidesfirstx printf xininnerblock d n x printf xinouterblock d n x while x 33 originalx intx 100 newx hidesfirstx x printf xinwhileloop d n x printf xinouterblock d n x return0 includeintmain intn 10 printf Initially n d n n intn for n 1 n 3 n printf loop1 n d n n printf Afterloop1 n d n n intn for n 1 n 3 n printf loop2indexn d n n intn 30 printf loop2 n d n n n printf Afterloop2 n d n n return0 别走神 快想想是什么结果吧 register寄存器型变量 1 比一般变量访问更快 因为一般存在寄存器中 不是内存中 2 不能取地址运算 寄存器是中央处理器内的组成部分 寄存器是有限存贮容量的高速存贮部件 它们可用来暂存指令 数据和位址 在中央处理器的控制部件中 包含的寄存器有指令寄存器 IR 和程序计数器 PC 在中央处理器的算术及逻辑部件中 包含的寄存器有累加器 ACC 说明 1 只有局部变量才能定义成寄存器变量 即全局变量不行 2 对寄存器变量的实际处理 随系统而异 例如 微机上的MSC和TC将寄存器变量实际当作自动变量处理 3 允许使用的寄存器数目是有限的 不能定义任意多个寄存器变量 static型变量 局部static型变量作用域与动态局部相同 静态局部变量在函数内定义 静态局部变量属于内部变量 其作用域仅限于定义它的函数内 虽然生存期为整个源程序 但其它函数是不能使用它的 存储期是静态的 仅在第1次调用它所在的函数时被初始化 当再次调用定义它的函数时 不再初始化 而是保留上1次调用结束时的值 函数参数不能用static 外部static型变量只允许被与它在同一个文件中的函数使用 其作用域为定义它的源文件内 生存期为整个源程序 但其它源文件中的函数也是不能使用它的 定义在所有函数体之外 不存在静态内部变量的 重复 初始化问题 其当前值由最近1次给它赋值的操作决定 务必牢记 把局部变量改变为静态内部变量后 改变了它的存储方式 即改变了它的生存期 把外部变量改变为静态外部变量后 改变了它的作用域 限制了它的使用范围 因此 关键字 static 在不同的地方所起的作用是不同的 静态的 static 如 staticinti 分配内存后 赋初值 并且只被赋初值一次 未赋值的内部staic变量 系统自动给它赋值为0 整型和实型 或 0 字符型 下次再调用该函数时 staic变量仍使用原来的存储单元 仍使用原来存储单元中的值 被分配在内存的静态存储区中 何时使用静态内部变量 1 需要保留函数上一次调用结束时的值 2 变量只被引用而不改变其值 voidauto static void intav 0 自动变量 每次调用都重新初始化 staticintsv 0 静态局部变量 只初始化1次 printf av d sv d n av sv av sv main inti for i 0 i 5 i auto static 自动变量与静态局部变量的存储特性 main voidincrement void increment increment increment voidincrement void intx 0 x printf d n x 例局部静态变量值具有可继承性 运行结果 111 main voidincrement void increment increment increment voidincrement void staticintx 0 x printf d n x 运行结果 123 includevoidtrystat void intmain void intn for n 1 n 3 n printf Herecomesiteration d n n trystat return0 voidtrystat void intfade 1 staticintstay 1 printf fade dandstay d n fade stay 别走神 快想想是什么结果吧 includevoidfun intk intmain void intk for k 1 k 3 k fun k return0 voidfun intk staticinta printf d a a k 0 1 3 静态变量会记住前一次调用时留下来的值 静态变量的初值为0 别走神 快想想是什么结果吧 例计算1 2 3 n n的值由键盘输入 不利用静态变量的情况 longfunc longn longk 1 inti for i 1 i n i k k i return k main longn m printf n scanf ld 利用静态变量的情况 longfunc longi staticlongk 1 k k i return k main longn m printf n scanf ld 外部变量只能存放在内存的静态存储区 它在整个程序的运行期间一直占用内存单元 外部变量的作用域可以通过关键字 extern 来扩展 扩展至某个文件 甚至被其它源程序文件使用 用static声明的外部变量能够限制它的作用域的扩展 达到信息隐蔽的目的 4 3 4外部变量的存储类别 例文件file1 cinta main f2 f1 f1 autointb f2 f2 staticintc 变量存储类型 局部变量默认为auto型register型变量个数受限 且不能为long double float型局部static变量具有全局寿命和局部可见性局部static变量具有可继承性extern不是变量定义 可扩展外部变量作用域 例变量的寿命与可见性 includeinti 1 main staticinta registerintb 10 intc 0 printf MAIN n printf i da d b dc d n i a b c c c 8 other printf MAIN n printf i da d b dc d n i a b c i i 10 other other staticinta 2 staticintb intc 10 a a 2 i i 32 c c 5 printf OTHER n 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 例引用其它文件中的变量 输出a b和a的m次方 includevoidfun inti inty voidmain inti j x y n g i 2 j 3 g x 5 y 9 n 7 fun n 6 printf g d i d j d n g i j printf x d y d n x y fun n 6 voidfun inti intj intx y g g 8 x 7 y 2 printf g d i d j d n g i j printf x d y d n x y x 8 y 6 别走神 快想想是什么结果吧 4 4编译预处理 作用 对源程序编译之前做一些处理 生成扩展C源程序种类宏定义 define文件包含 include条件编译 if else endif等格式 开头占单独书写行语句尾不加分号 引例 从键盘连续读入字符 并统计其中数字的个数 直到读入a字符为止 include defineESC97main intcount 0 charc while 1 c getchar if c ESC break if c 0 使用宏定义的优点 1 可提高源程序的可维护性 2 可提高源程序的可移植性 3 减少源程序中重复书写字符串的工作量 常见符号
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025江苏无锡商业职业技术学院招聘人事代理制人员6人考前自测高频考点模拟试题及答案详解(夺冠系列)
- 2024年江苏省江南大学附属医院招聘真题
- 2025海南乐东县机关事务服务中心招聘保安人员2人考前自测高频考点模拟试题附答案详解(突破训练)
- 2025年福建省厦门市湖里保安集团有限公司招聘1人模拟试卷及参考答案详解一套
- 2025年4月浙江杭州高新区(滨江)教育系统直接考核招聘编外人员考前自测高频考点模拟试题及一套完整答案详解
- 2025湖南张家界市永定区南庄坪街道办事处便民服务中心招聘公益性岗位人员1人考前自测高频考点模拟试题及答案详解(典优)
- 2025广东中山市城市管理和综合执法局招聘雇员5人考前自测高频考点模拟试题完整参考答案详解
- 2025年春季北燃实业集团校园招聘考前自测高频考点模拟试题及参考答案详解一套
- 2025广西防城港市防城区政务服务监督管理办公室招聘1人考前自测高频考点模拟试题及答案详解参考
- 2025广东深圳大学人文学院董理副教授博士后招聘1人考前自测高频考点模拟试题及参考答案详解
- 省级人文社科课题申报书
- 高考物理力学专题复习指导方案
- 2025年少先队大队委笔试试卷及答案
- 证券业反洗钱培训课件
- GJB3165A-2020航空承力件用高温合金热轧和锻制棒材规范
- 2025年执业药师考试题库大全-附答案
- 退换货方案及措施
- 2025年食药监局考试题库
- 密室逃脱消防应急预案
- 伟星PPR培训课件
- 2025年协作机器人产业发展蓝皮书-高工咨询
评论
0/150
提交评论