• / 52
  • 下载费用:10 金币  

C语言程序设计(模块化程序设计II)

关 键 词:
语言程序设计 模块化 程序设计 II
资源描述:
第第7 7章章 模块化程序设计模块化程序设计I II I C语言程序设计课程组语言程序设计课程组 赵赵 宏宏 2 第一单元第一单元 变量作用域和存储类别变量作用域和存储类别 第二单元第二单元 函数的递归调用函数的递归调用 第三单元第三单元 编译预处理编译预处理 第四单元第四单元 多文件程序的运行多文件程序的运行 第五单元第五单元 案例学习案例学习 本章内容 本章内容 3 第一单元第一单元 变量作用域和存储类别变量作用域和存储类别 1 1 变量作用域变量作用域 2 2 变量存储类别变量存储类别 本单元内容 本单元内容 1 1 变量作用域变量作用域 变量的作用域 变量的作用域 指变量的作用范围 分为全局变量指变量的作用范围 分为全局变量 和局部变量 和局部变量 局部变量局部变量 可以简单理解为定义在可以简单理解为定义在 和函数参数列和函数参数列 表中的变量就是表中的变量就是局部变量局部变量 全局变量全局变量 定义在函数体外的变量叫做定义在函数体外的变量叫做全局变量全局变量 5 变 量 的 存 储 器 类 别 变 量 的 存 储 器 类 别 寄存器寄存器 静态存储区静态存储区 内 存 内 存 动态存储区动态存储区 CPUCPU 局部变量作用域局部变量作用域 局部变量的作用域是指变量的作用范围仅仅局限在从变量定 义处开始 到变量定义所在的那个块结束 void main int n void fun int x int y int n 局部于局部于mainmain 的局部变量的局部变量 局部于局部于funfun的的 局部变量局部变量 分析下面程序运行结果 include void func int main int num 30 printf From main num d n num func printf From main num d n num return 0 void func int num num 10 printf From func num d n num 程序输出结果为 From main num 30 From func num 10 From main num 30 8 注意注意 形式参数也为局部变量 其作用范围是形式 形式参数也为局部变量 其作用范围是形式 参数所在的整个函数 例如 参数所在的整个函数 例如 void main printf d d x y error void fun int x int y 全局变量作用域全局变量作用域 全局变量的作用范围是从变量定义处开始到所定义的源文件结束处 即从全局变量定义所在处开始到源文件结束处之间的所有函数都可 以访问该变量 int n 1 void main float m void func 分析下面程序运行结果 include void swap int a b void main scanf d d printf 交换前的 a和 b是 d d n a b swap printf 交换后的 a和 b是 d d n a b void swap int t t a a b b t 输入 5 6 交换前的a和b是5 6 交换后的a和b是6 5 局部变量与全局变量同名时的处理局部变量与全局变量同名时的处理 C语言遵循小范围优先的原则 即在多个同名变量都可以被 访问时 使用这个变量名访问的是同名变量中作用范围最小 的那个变量所对应的存储空间 假如在某个全局变量的有效作用范围内有函数定义了同该全 局变量同名的局部变量 则在该函数中全局变量暂时被屏蔽 掉了 用此变量名访问的是局部变量 分析下面程序运行结果 include int test int i 1 void main printf 主函数中变量 i是 d n i i test 1 printf 主函数变量 i是 d n i int test int i printf test 中变量 i是 d n i i 2 printf test 中变量 i是 d n i return i 该程序运行结果 主函数变量 i是1 test 中变量 i是28345 test 中变量 i是2 主函数中变量 i是3 13 第一单元第一单元 变量作用域和存储类别变量作用域和存储类别 1 1 变量作用域变量作用域 2 2 变量存储类别变量存储类别 本单元内容 本单元内容 2 2 变量存储类别变量存储类别 除了范围这个空间维度外 变量也有时间维度 时间维度指 的是一个变量占用存储时间的长短 也称为变量的生命周期 一个变量存储在哪 存储多长时间 都是由存储类别来决 定的 局部变量的存储类别局部变量的存储类别 1 自动变量 用关键字 auto 作存储类型说明的是自动变量 自动变量 在动态存储区内分配空间 如在某函数中有定义 int a auto float b 自动变量是短生命期的局部变量 安排在动态存储区 由系 统自动分配和释放 用到时分配内存 不用时释放内存 以 节省程序执行时的内存资源 局部变量的存储类别局部变量的存储类别 2 局部静态变量 用关键字static 加以说明的局部变量为局部静态变量 局部静 态变量在静态存储区分配空间 局部静态变量是长生命期的局部变量 函数执行结束 变量 的内容hui保留 局部静态变量安排在静态存储区 3 寄存器变量 用关键字register说明的局部变量为寄存器变量 寄存器变量的值存放在CPU的寄存器中 可以提高程序的执 行效率 17 局部变量的存储类别局部变量的存储类别 CPUCPU 寄存器寄存器 内内 存存 静态存储区静态存储区 动态存储区动态存储区 registerregister int a int a autoauto float b float b staticstatic int c int c 格式 格式 存储类别存储类别 类型标识符类型标识符变量名变量名 例7 4 分析下面程序运行结果 include int fun1 int int fun2 int int main int i for i 2 i 5 i printf fun1 d d t i fun1 i printf n for i 2 i 5 i printf fun2 d d t i fun2 i printf n return 0 int fun1 int x int f 1 return f x int fun2 int x static int f 1 return f x 程序执行结果为 fun1 2 2 fun1 3 3 fun1 4 4 fun2 2 2 fun2 3 6 fun2 4 24 全局变量的存储方式全局变量的存储方式 1 使用关键字 static 的全局变量 该变量就只能被定义所在的源文件中的所有函数访问 同一程序的其它源 文件中的函数都不能访问该变量 因此它是文件内部的全局变量 把这类 全局变量称为静态全局变量 2 使用缺省关键字的全局变量 该变量不仅能被定义所在的源文件中的所有函数访问 而且组成程序的其 它源文件中的所有函数也都能访问该变量 因此 从作用范围看 缺省关 键字的全局变量要比使用关键字 static 的静态全局变量大 3 关键字 extern 的作用 关键字 extern 的作用是在对全局变量进行说明 该全局变量可以是在该源 文件中定义的全局变量 或者是在另一个源文件中使用缺省关键字定义的 全局变量 程序在编译 连接时 对扫描到使用关键字 extern 的全局变量 就把它作 为变量说明 不再在静态存储区给该同名变量分配存储空间 因此 若一个 C源文件要使用在另一个C文件中定义的 存储类别关键字 缺省的全局变量 则在该源文件中应该使用 extern 对该变量作说明 例7 5 分析程序运行结果 程序名 7 5 c include extern int a void fun1 void fun2 int main fun1 fun2 printf 函数 main 中的 a是 d n a return 0 程序名 7 5 1 c include static int a void fun1 a 2 printf 函数 fun1 中的 a是 d n a 程序名 7 5 2 c include int a void fun2 a 4 printf 函数 fun2 中的 a是 d n a 22 第一单元第一单元 变量作用域和存储类别变量作用域和存储类别 第二单元第二单元 函数的递归调用函数的递归调用 第三单元第三单元 编译预处理编译预处理 第四单元第四单元 多文件程序的运行多文件程序的运行 第五单元第五单元 案例学习案例学习 本章内容 本章内容 23 第二单元第二单元 函数的递归调用函数的递归调用 1 1 递归的概念和条件递归的概念和条件 2 2 递归应用举例递归应用举例 本单元内容 本单元内容 1 1 递归的概念和条件递归的概念和条件 函数的递归调用指的是一个函数执行过程中出现了直接或间 接调用函数本身的调用方式 如果直接调用函数本身称为直 接递归 如果调用了另外一个函数 那个函数又调用该函数 则称为间接递归 递归方法的基本思想是将一个问题向下分解具有同样解决方 法但规模不断缩小的子问题 不断进行这样的分解 直到分 解的子问题有一个已知解 例如 某数列为k n 的定义为 1 n 1 k n 2 k n 1 n为偶数 3 k n 1 n为奇数 求该数列的第四项k 4 k 4 k 3 2 k 3 k 2 3 k 2 k 1 2 k 1 1 k 2 1 2 2 k 3 2 3 6 k 4 6 2 12 图7 2 回推和递推过程 可以用一个函数描述上面的递归过程 int k int n 递归计算函数 int m m存放函数的返回值 if n 1 m 1 else if n 2 0 m k n 1 2 调用自身 n为偶数 else m k n 1 3 调用自身 n为奇数 return m 递归的条件 1 必须有完成函数任务的语句 int fact int n int m if n 1 m 1 else m fact n 1 n return m 2 一个确定是否能终止递归调用的语句 if n 1 m 1 else m fact n 1 n 3 一个递归调用语句 m fact n 1 n 28 第二单元第二单元 函数的递归调用函数的递归调用 1 1 递归的概念和条件递归的概念和条件 2 2 递归应用举例递归应用举例 本单元内容 本单元内容 例7 6 求Fibonacci数列第n项的值 Fibonacci数列以1 1开头 以后每 一项都是前两项之和 1 1 2 3 5 8 13 21 程序设计思路 1 求Fibonacci数列第n项的值可用递归形式定义为 fibonacci 0 1 fibonacci 1 1 fibonacci n fibonacci n 1 fibonacci n 2 上述定义将求解第n项化简为求解第n 1和n 2项 求解在规模上缩小了 但 求解的方法是一致的 include int fibonacci int int main int n printf 请输入一个整数 scanf d printf Fibonacci d ld n fibonacci n return 0 int fibonacci int n if n 0 n 1 return 1 else return fibonacci n 1 fibonacci n 2 例7 7 计算两个整数的最大公约数 程序设计思路 利用辗转相除法计算两个整数的最大公约数的算法如下 1 如果x除以y的余数为0 则y即为最大公约数 返回y值 算法结束 2 如果x除以y的余数不为0 则用y和x y做参数再重复求最大公约数 反 复进行 1 2 的操作 例如x 341 y 132 341除以132 商是2 余数为77 因为余数 0 所以 置x 132 y 77 依次类推 最后22除以11时 余数为0 算法终止 132 和341的最大公因数是11 include int gcd int int int main int a b printf 请输入两个整数 scanf d d printf d d的最大公约数是 d a b gcd a b return 0 int gcd int x int y if x y 0 return y else return gcd y x y 递推 int gcd int x int y int r r x y while r 0 x y y r r x y return y 33 递归 int gcd int x int y if x y 0 return y else return gcd y x y 34 第一单元第一单元 变量作用域和存储类别变量作用域和存储类别 第二单元第二单元 函数的递归调用函数的递归调用 第三单元第三单元 编译预处理编译预处理 第四单元第四单元 多文件程序的运行多文件程序的运行 第五单元第五单元 案例学习案例学习 本章内容 本章内容 语言提供了多种预处理功能 主要包括文件包含 include 宏定义 define和条件编译 if等 分别用对应的命 令实现 称为预处理命令 区别于C语句 预处理命令都是 以符号 开头 以回车作为结束 并且不包含分号 文件包含 include 文件包含 是指一个源文件可以将另一个文件的全部内容包含进来 在 编译预处理时 include指令让预处理器在程序该点处加入指定文件内容 然后作为一个源文件编译形成新文件 文件包含有两种形式 1 include 预处理器遇到该指令 系统会到include文件夹下寻找该文件 并把它 嵌入当前文件中 2 include 文件名 系统首先在当前文件所在的目录下查找要包含的文件 若找不到 再 按系统指定的标准方式查找 这种方式适合用户自己建立的头文件 宏定义 define C语言源程序中用一个标识符来表示一个字符串 称为宏 1 无参宏 无参宏定义的宏名后不带参数 定义的一般形式为 define 标识符 字符串 这就是曾经介绍过的定义符号常量 如前面已见过的 define PI 3 14159 2 带参宏 define 宏名 参数表 字符串 字符串中含有在括号中所指定的参数 如 define S a b a b 例7 9 编写一个求平方的宏 include define SQR n n n int main int iNumber 5 iSquare iSquare SQR iNumber printf The square of d is d n iNumber iSquare return 0 在例7 9定义的宏中用了很多括号 这些括号是必须的吗 假设把求平 方的宏定义如下 define SQR n n n 然后在程序中使用该宏 iSquare SQR iNumber 5 由于宏定义的方式 iSquare SQR iNumber 5 展开后为 iSquare SQR iNumber 5 iNumber 5 因而结果为 iSquare 5 5 5 5 35 100 带参的宏与函数的区别 宏宏函数函数 宏调用在编译前进行函数调用在程序运行时 使用宏的代码比较长多次调用 代码只有一次 简单字符串替换函数调用先求值再传递 宏无类型有类型 对不同类型的数据要写多个函数 条件编译 条件编译就是按条件对C程序的一部分进行编译 其它部分不编译 条件编译的目的是使源代码能更迅速 更容易地进行修改 并使目标代码 缩短 例如 if MAX 99 printf Compiled for array greater than 99 n else printf Compiled for small array n endif 条件编译的另一个有效的使用是协调多个头文件 避免一个符号或一个头 文件被多次包含 例如 ifndef INCFILE H define INCFILE H The actual contents of the header file incfile h are here endif INCFILE H 42 第一单元第一单元 变量作用域和存储类别变量作用域和存储类别 第二单元第二单元 函数的递归调用函数的递归调用 第三单元第三单元 编译预处理编译预处理 第四单元第四单元 多文件程序的运行多文件程序的运行 第五单元第五单元 案例学习案例学习 本章内容 本章内容 43 库存系统总体设计 文件及函数组成 源文件源文件函数名或其他成分函数名或其他成分功能模块功能模块 record cmain总控函数总控函数 menu select菜单选择菜单选择 input creadin1 readin2 按编号输入记录按编号输入记录 按类型输入记录按类型输入记录 delete cdel删除记录删除记录 display cdisplay显示记录内容显示记录内容 record h结构声明结构声明结构类型定义结构类型定义 库函数及函数声明库函数及函数声明引用库函数及其他函数引用库函数及其他函数 如何把若干程序文件组成一个程序 一种方法是采用文件包含的方法 例如 一个C程序由3个文件file1 c file2 c和file3 c组成 main 函数在file3 c中 在file3 c文件的首部加上 include file1 c include file2 c 这样就将文件file1 c和file2 c包含在file3 c中 对文件file3 c进行编译和 连接生成可执行程序 如果file1 c file2 c与file3 c不在同一个文件夹下 在进行文件包含时 需要加上文件路径 另一种方法是利用开发工具提供的工程文件功能 即定义一个工程文件 把需要连接到一起的文件名加入到该工程中 创建好工程后 就可以像其 他文件程序一样编译 连接和运行了 C程序的文件有两种类型 分别以 c和 h为后缀名 c文件是源程序文件 主要包括以函数为单位的程序代码 它可以独立存在 h称为头文件 主 要包括函数原型说明 全局变量声明 由struct和typedef定义的类型 编 译预处理命令 define定义的宏等说明性内容 头文件不能独立存在 file1 cfile2 c include include include ifndef RECORD H define RECORD H The actual contents of the header file record h are here endif 46 第一单元第一单元 变量作用域和存储类别变量作用域和存储类别 第二单元第二单元 函数的递归调用函数的递归调用 第三单元第三单元 编译预处理编译预处理 第四单元第四单元 多文件程序的运行多文件程序的运行 第五单元第五单元 案例学习案例学习 本章内容 本章内容 求解汉诺塔问题 汉诺塔问题是最著名的经典问题之一 相传在古印度的一座神庙內有一座汉诺 塔 上面插着三根钻石棒 在其中的一 根钻石棒上 有64块金盘 将64枚金 盘移到另一根钻石棒上 每次只能移动 一个金盘 大的金盘不能压在小的金盘 上 等到婆罗门完成这项工作 寺庙和 婆罗门本身都崩溃了 世界在一声霹雳 中也毁灭了 如图7 6所示 图7 6 汉诺塔 ABC 程序设计思路 移动64块圆盘需要264 1步 如果每秒钟移动一只盘子 不停的移动也要 5849亿年 用递归解决该问题的主要思想是 要想移动64个盘子 只要能把前63个盘子从A移到B 这个问题就解决了 具体说 1 将63个盘子从A移到B 2 将最后一个盘子直接从A移到C 3 再将63个盘子从B移到C 这时问题就简化为移动63个盘子的问题 要想把63个盘子从A移动到B 只 需要将62个盘子移到C上 具体做法如下 1 将62个盘子从A移到C 2 将第63个盘子直接从A移到B 3 再将62个盘子从C移到B 首先来看3个盘子从A移到C的过程 1 将1 2号盘作为整体从A移到B 具体步骤 将1号盘从A移到C 将2号盘从A移到B 将1号盘从C移到B 2 将3号盘从A移到C 3 将1 2号盘整体从B移到C 具体 步骤 将1号盘从B移到A 将2号盘从B移到C 将1号盘从A移到C ABC 1 2 3 图7 7 3只盘子的移动 从上面的分析可知 将n个盘子从A移到C上可以分解为以下3个步骤 1 将n 1个盘子作为整体从A借助C移到B上 2 将A上的第n只盘子从A移到C 3 再将B上的n 1个盘子整体从B借助A移到C上 定义一个函数move n a b c 表示将n个盘子从a借助b移到c 则上面的 3个步骤可表示为 1 move n 1 a c b 2 输出将A上的第n只盘子从A移到C 3 move n 1 b a c void move int m char a char b char c if m 1 printf 将 1号 盘子从 c 移动到 c n a c else move m 1 a c b printf 将 d号 盘子从 c 移动到 c n m a c move m 1 b a c 本章小结 本章中读者学会了函数的定义和调用方法 一般的 递归 嵌套 掌握了编译预处理的使用以及模块化程序设计 程 序设计方法本身掌握起来没有太大难度 本章的难点是在那些定义在函数内 外的变量 这些变量有 的穿插于函数 文件之间 有的变量负责模块之间 文件之 间的衔接 情况较为复杂
展开阅读全文
  麦档网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
0条评论

还可以输入200字符

暂无评论,赶快抢占沙发吧。

关于本文
本文标题:C语言程序设计(模块化程序设计II)
链接地址:https://www.maidoc.com/p-16761827.html

当前资源信息

陈森强

编号: 20200626154720177246

类型: 共享资源

格式: PDF

大小: 2.35MB

上传时间: 2020-06-26

关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

[email protected] 2018-2020 maidoc.com版权所有  文库上传用户QQ群:3303921 

麦档网为“文档C2C模式”,即用户上传的文档所得金币直接给(下载)用户,本站只是中间服务平台,本站所有文档下载所得的金币归上传人(含作者)所有。
备案号:蜀ICP备17040478号-3  
川公网安备:51019002001290号 

本站提供办公文档学习资料考试资料文档下载


收起
展开