c语言第六章函数与宏定义.ppt

上传人:max****ui 文档编号:6334663 上传时间:2020-02-23 格式:PPT 页数:49 大小:319KB
返回 下载 相关 举报
c语言第六章函数与宏定义.ppt_第1页
第1页 / 共49页
c语言第六章函数与宏定义.ppt_第2页
第2页 / 共49页
c语言第六章函数与宏定义.ppt_第3页
第3页 / 共49页
点击查看更多>>
资源描述
02 40 1 49 第六章函数与宏定义 6 1函数概念 6 2变量作用域和存储类型 6 3内部函数与外部函数 6 4递归函数设计和调用 6 6综合范例 02 40 2 49 6 1函数概念 C语言允许把问题设计成一个一个的模块 程序通过调用模块功能来解决问题 这些模块通常都是通过函数来实现的 又可称其为函数模块 C语言中 函数可分为两类 一类是由系统定义的标准函数 又称为库函数 其函数声明一般是放在系统的include目录下以 h为后缀的头文件中 如在程序中要用到某个库函数 必须在调用该函数之前用 include命令将库函数信息包含到本程序中 另一类函数是自定义函数 两种形式 第一种 函数声明 函数调用 函数定义 第二种 函数定义 函数调用 02 40 3 49 6 1 1函数定义 函数定义的一般形式可以有两种 形式一 存储类型符 返回值类型符 函数名 形参说明表 函数语句体 形式二 存储类型符 返回值类型型符 函数名 形参表 形参说明 函数语句体 02 40 4 49 说明 1 存储类型符 指的是函数的作用范围 它只有两种形式 static和extern static说明函数只能作用于其所在的源文件 用static说明的函数又称为内部函数 extern说明函数可被其它源文件中的函数调用 用extern说明的函数 又称为外部函数 缺省情况为extern 2 返回值类型符 指的是函数体语句执行完成后 函数返回的值的类型 如int float char等等 若函数无返回值 则用空类型void来定义函数的返回值 缺省情况为int型 02 40 5 49 3 函数名由任何合法的标识符构成 建议将函数名的命名与函数内容有一定关系 4 在第一种函数定义的形式中 形参说明表 是一系列用逗号分开的每个形参变量说明 如 intx inty intz这表示形参变量有三个 x y z 它们的类型都是int型 在第二种函数定义的形式中 形参表 是一系列用逗号分开的形参变量 如 x y z 5 函数语句体是放在一对花括号 中 由局部数据类型描述和功能实现两部分组成 02 40 6 49 6 函数返回语句的形式有以下两种 函数无返回值的情况 return 函数有返回值的情况 return 表达式的值 在第 种情况下要注意 表达式的值 的类型必须与函数返回值的类型相一致 例如 求两个任意整数的绝对值的和 用函数abs sum 实现 直接调用库函数来计算m和n的绝对值 intabs sum intm intn return abs m abs n 函数abs 是在头文件math h中声明的 02 40 7 49 函数定义如下 intabs sum intm intn if m 0 m m if n 0 n n return m n 6 1 2函数声明和调用 一 函数的声明函数声明的一般形式 存储类型符 返回值类型符 函数名 形参说明表 如 intabs sun intm intn 02 40 8 49 二 函数调用函数调用是通过函数调用语句来实现的 分两种形式 无返回值的情况 函数名 实参表 有返回值的情况 变量名 函数名 实参表 该变量名的类型必须与函数的返回值类型相同 函数调用时都会去执行函数语句中的内容 函数执行完毕后 回到函数的调用处 继续执行下面的语句 02 40 9 49 6 1 3函数的传值方式 函数的传值方式 采用实参表将每一个实参的值相应地传递给每一个形参变量 形参变量在接收到实参表传过来的值时 会在内存临时开辟新的空间 以保留形参变量的值 当函数执行完毕时 这些临时开辟的内存空间会被释放 并且形参的值在函数中不论是否发生变化 都不会影响到实参变量的值的变化 这就是函数的传值方式 自定义函数在程序中的使用顺序有两种形式 先进行函数声明 再进行函数调用 函数定义放在函数调用之后 函数声明在函数调用之前 函数定义放在函数调用之前 02 40 10 49 例6 1 编程序 通过调用函数abs sum 求任意两个整数的绝对值的和 exam6 1 c调用函数求两整数绝对值的和 includeintabs sum intm intn main intx y z scanf d d 程序运行结果 712 sumis19 02 40 11 49 用传值方式调用函数时 实参也可以是函数调用语句 例6 2 求任意三个数的绝对值的和 exam6 2 c调用函数求三个整数绝对值的和 includeintabs sum intm intn main intx y z sum scanf d d d 程序运行结果 7125 sumis24 02 40 12 49 注意 对于有返回值的函数 调用时若没有把它赋给某个变量 仍然是可以的 只是函数的返回值有可能会被丢失 例6 3 求任意两数的乘积 自定义一个函数mul 用于求两数的乘积 程序 exam6 3 c求两个数的乘积 includefloatmul floata floatb main floatx y z scanf f f 02 40 13 49 x x 2 y y 2 printf z f mul f f f n z x y mul x y floatmul floata floatb returna b 程序运行结果 56 z 30 000000 mul 30 000000 8 000000 240 000000 02 40 14 49 程序说明 注释 处调用函数后的返回值赋给变量z 注释 处调用函数后的返回值没有赋给任何变量 函数的返回值被丢失 注释 处调用函数后的返回值成为了printf 函数的参数 02 40 15 49 6 2变量作用域和存储类型 一 变量的作用域 变量的作用域 指的是变量的有效范围 针对变量不同的作用域 可把变量分为局部变量和全局变量 局部变量 在函数内部或某个控制块的内部定义的变量为局部变量 局部变量的有效范围只限于本函数内部 退出函数 该变量自动失效 全局变量 在函数外面定义的变量称为全局变量 全局变量的作用域是从该变量定义的位置开始 直到源文件结束 在同一文件中的所有函数都可以引用全局变量 02 40 16 49 局部变量和全局变量的作用域如图所示 02 40 17 49 例6 4 变量作用域应用举例 阅读下面的程序 注意区分局部变量和全局变量的作用域 exam6 4 c变量作用域举例 includevoida void voidb void voidc void intx 1 main intx 5 printf localxinouterscopeofmainis d n x 02 40 18 49 intx 7 printf localxininnerscopeofmainis d n x printf localxinouterscopeofmainis d n x a b c a b c 前三次输出结果 localxinouterscopeofmainis5localxininnerscopeofmainis7localxinouterscopeofmainis5 02 40 19 49 printf localxinmainis d n x getchar return0 voida void intx 25 printf nlocalxinais dafterenteringa n x x printf localxinais dbeforeexitinga n x 02 40 20 49 voidb void staticintx 50 printf nlocalstaticxis donenteringb n x x printf localstaticxis donexitingb n x voidc void printf nglobalxis donenteringc n x x 10 printf globalxis donexitingc n x 02 40 21 49 程序运行结果 后6次函数调用 localxinais25afterenteringalocalxinais26beforeexitingalocalstaticxis50onenteringblocalstaticxis51onexitingbglobalxis1onenteringcglobalxis10onexitingclocalxinais25afterenteringalocalxinais26beforeexitingalocalstaticxis51onenteringblocalstaticxis52onexitingbglobalxis10onenteringcglobalxis100onexitingc 最后一次输出 localxinmainis5 02 40 22 49 二 变量的存储类型 变量的存储类型 指的是变量的存储属性 它说明变量占用存储空间的区域 在内存中 供用户使用的存储区由程序区 静态存储区和动态存储区三部分组成 变量的存储类型有四种 auto型 register型 static型和extern型 auto型变量存储在内存的动态存储区 register型变量保存在寄存器中 static型变量和extern型变量存储在静态存储器 02 40 23 49 局部变量的存储类型缺省值为auto型 全局变量的存储类型缺省值为extern型 auto型变量和register型变量只用于定义局部变量 static型变量即可定义成局部变量 又可定义成全局变量 例6 5 设计一个函数 longfac intn 可用来计算1 5的阶乘 分析 可在函数中定义一个static型变量 用来保存上次的计算结果 02 40 24 49 exam6 5 c用static型变量保留上次阶乘的值 includelongfac intn staticintf 1 f f n returnf main inti for i 1 i 5 i printf d ld n i fac i 程序运行结果 1 12 23 64 245 120 局部变量f被定义成static型的 因此 它只在该函数第1次被调用的时候初始化其值为1 以后再调用该函数时 不再进行初始化 而是使用上一次调用的值 02 40 25 49 6 3内部函数与外部函数 一 内部函数 若函数的存储类型为static型 则称其为内部函数或称静态函数 它表示在同一个程序中 由多个源文件组成 该函数只能在一个文件中存在 在其它文件中不可使用 如 staticintfun name 内部函数只能被其所在的源文件调用 二 外部函数 若函数的存储类型定义为extern型 则称其为外部函数 它表示该函数能被其它源文件调用 函数的缺省存储类型为extern型 注意 在需要用到外部函数的文件中 其函数声明必须用extern进行说明 02 40 26 49 例如 有两个源文件file1 c和file2 c如下所示 file1 c调用外部函数 includeintmod inta intb externintadd intm intn 外部函数声明 main intx y result scanf d d 02 40 27 49 intmod inta intb return a d file2 c外部函数 externintadd intm intn return m n 说明 1 在文件1 file1 c 中的函数声明 intmod inta intb 实际上相当于 externintmod inta intb 02 40 28 49 2 在文件2 file2 c 中的函数定义 externintadd intm intn return m n 实际上相当于 intadd intm intn return m n 3 由多个源文件组成一个程序时 main 函数只能出现在一个源文件中 02 40 29 49 4 多个源文件的连接方式有三种 将各源文件分别编译成目标文件 得到多个目标文件 obj后缀 然后用连接命令 tlink 把多个 obj文件连接起来 在Turboc上用如下命令 tlinkfile1 obj file2 obj filen obj生成一个file1 exe的可执行文件 建立项目文件 prj后缀 具体操作可参阅各种C编译手册 使用文件包含命令 02 40 30 49 6 4递归函数设计和调用 C语言中一个函数中的语句可以是对另一个函数的调用 函数嵌套调用图例 调用过程按图中箭头所示的方向和顺序进行 属于一种线性调用关系 每次调用后 最终返回到原调用点 继续执行以下语句 02 40 31 49 C语言中还允许在函数中调用自身 或函数之间相互调用 这种调用方式称之为递归 递归又分为直接递归调用和间接递归调用 直接递归调用 函数直接调用自身 间接递归调用 函数互相调用对方 直接递归 inttemp intx inty z z temp y 02 40 32 49 间接递归 显然 递归有可能陷入无限递归状态 最终导致错误发生 因此 设计一个递归问题必须具备两个条件 1 后一部分与原始问题类似 2 后一问题是原始问题的简化 02 40 33 49 例6 6 编程 从键盘输入一个正整数n 求n n 的数字表达式为 n 定义一个求n 的函数 longfac intn longfac intn longresult if n 0 n 1 result 1 elseresult n fac n 1 return result 02 40 34 49 完整程序如下 exam6 6 c用递归法求n includelongfac intn longresult if n 0 n 1 result 1 elseresult n fac n 1 returnresult main intx longf 02 40 35 49 scanf d 程序运行结果 6 6 720 02 40 36 49 例6 7 求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项的值 02 40 37 49 程序如下所示 exam6 7 c求第n项Fibonacci数列的值 includelongfibonacci intn main intx 0 longresult do result fibonacci x printf fibonacci d ld n x result scanf d 02 40 38 49 longfibonacci intn if n 0 n 1 returnn elsereturnfibonacci n 1 fibonacci n 2 程序运行结果 fibonacci 0 03 fibonacci 3 24 fibonacci 4 36 02 40 39 49 以x 4为例 下图说明了fibonacci函数是怎样计算fibonacci 4 的 图中把fibonacci简写成f 02 40 40 49 6 6综合范例 例6 12 在屏幕上画一个18 18大小的棋盘 程序如下 exam6 12 c在屏幕上画一个棋盘 include include include 定义画棋盘所需的制表符 defineLU0 xda 左上角 defineRU0 xbf 右上角 defineLD0 xc0 左下角 defineRD0 xd9 右下角 defineL0 xc3 左边 defineR0 xb4 右边 02 40 41 49 defineU0 xc2 上边 defineD0 xc1 下边 defineCROSS0 xc5 十字叉 棋盘左上角坐标 defineMAP X5 defineMAP Y5voiddraw cross intx inty voiddraw map main textmode C40 draw map 02 40 42 49 函数定义 voiddraw map 画棋盘 inti j for i 0 i 19 i for j 0 j 19 j draw cross i j voiddraw cross intx inty gotoxy x MAP X y MAP Y textcolor GREEN if x 0 02 40 43 49 if x 0 02 40 44 49 if x 0 putch L 画左边 return if x 18 putch R 画右边 return if y 0 putch U 画上边 return 02 40 45 49 if y 18 putch D 画下边 return putch CROSS 画十字叉 程序中宏定义的制表符的值可从ASC 码表中查得 如 0 xbf为十六进制表示 它代表右上角制表符 该程序必须在纯DOS模式下运行 其运行结果是在屏幕上显示一个绿色的18 18大小的方格棋盘 如后图所示 02 40 46 49 该程序显示一个绿色的18 18大小的方格棋盘 02 40 47 49 例6 13 将一个字符串的字符反向输出到屏幕 采用递归函数调用方法 程序如下 exam6 13 c反向显示字符串 include includevoidbackwards chars intindex 函数声明 main charstr 80 定义字符数组 intindex 0 strcpy str Showthisstring 字符串拷贝 backwards str index 函数调用 02 40 48 49 voidbackwards chars intindex 函数定义 if s index printf c s index 输出字符 backwards s index 1 递归调用 printf c s index 输出字符 程序运行结果 Showthisstring gnirtssihtwohS 02 40 49 49 小结 介绍了函数的定义和传值调用函数的使用方法 注意 若用全局变量作为函数的参数 则在函数中可以使得该全局变量的值发生变化 对于递归函数的设计一定要有可使递归结束的条件 否则会使程序产生无限递归 使用预处理命令时 要注意以下几点 1 宏替换定义的末尾不能使用分号 2 在有参数的宏定义中 参数加括号和不加括号有时会有区别 3 使用文件包含时 要避免出现变量和函数发生重定义的现象 4 要区分条件编译与条件语句的作用
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


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


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

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


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