c语言程序设计11第十一讲(第五章下).ppt_第1页
c语言程序设计11第十一讲(第五章下).ppt_第2页
c语言程序设计11第十一讲(第五章下).ppt_第3页
c语言程序设计11第十一讲(第五章下).ppt_第4页
c语言程序设计11第十一讲(第五章下).ppt_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

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

文档简介

1 事上那些最容易的事情中 拖延时间最不费力 2 高级语言程序设计 主讲教师 贾彩燕计算机与信息技术学院计算机科学与技术系cyjia 3 第五章C程序结构 4 主要内容 数值类型函数和标准库函数函数定义和程序的函数分解C程序结构与变量预处理命令定义常量字位运算符编程实例 5 知识回顾及提升 最重要的思想模块化程序设计思想函数分解及其思想C程序的组成对象 变量 函数 的存在 声明与使用变量的生命周期和作用域 6 复杂问题 分解 整合 整个问题的解 复杂问题分解与问题解决 7 解决问题的办法 化整为零 把复杂程序分解成不同的小模块 分别实现 长程序 划分 8 模块化程序设计思想 总体功能 自顶向下逐步细化 重要的软件开发手段软件工程管理理念 问题 高级语言提供了什么机制来支持模块化程序设计 9 高级语言常见的抽象机制 子程序 sub program sub routine过程 procedure函数 function类 class包 package模块 module组件 component程序 program C语言提供的最基本的代码抽象机制 10 小模块2 小模块1 函数 一般可以传递数据 通过参数传 模块间调用返回结果 共处 大模块1 大模块2 打包 应用于 xx caa c 组件 包 模块 程序 11 main AvgMultiply 1000 AvgMultiply 100 AvgMultiply 10000 doubleAvgMultiply doublearray intn doubley 计算n个数的平均值 Y 返回结果 名字 从外部获取数据 返回结果 C语言把功能独立或相同 相似的片段抽象成一个函数 重复的片段用函数调用代替 合称为 Interface接口 Acommonboundarybetweentwodistinctentities 独立定义独立实现 独立使用 效率 2 一改全改 12 函数说明规范 接口说明 函数名称 写出函数的名称功能描述 描述出函数具有的功能函数参数 输入输出参数说明 对每个参数都需要作出仔细说明返回值 返回值说明 或者标明无返回值模块历史 谁于某年某月某日创建本模块 创建人email谁于某年某月某日修改本模块 修改人email修改原因 可有可无 根据需要添加 用处 13 C的模块和C程序结构 一组函数构成一个函数模块 在C程序里 一个 c或 cpp文件就是由多个函数构成的一个功能模块 每个功能模块编译后构成一个独立的目标模块 obj多个目标模块绑定在一起构成一个 exe文件 14 a c b c c 一个C程序的组成 a obj b obj obj 编译 MyProg exe 编译 编译 链接 组织成一个项目 项目的中间结果 项目的最终结果 模块 15 模块文件 16 exe文件 obj文件 17 变量的作用域与存在期 变量定义确定了变量何处 何时能使用何处能使用 作用域能够使用变量的范围 代码段何时能使用 存在期确定变量建立和销毁时间 时间段 各种变量的存在期可能不同 变量实现的基础是内存单元 存在期就是变量被分配内存空间到撤消的期间 18 存储区示意图 内存 静态存储区 动态存储区 程序代码 程序占用的存储区 19 存储区用途 静态存储区主要用途保存采用静态分配方式的变量的内容外部变量 全局变量 静态内部变量保存程序中的字符串常量动态存储主要用途供自动型内部变量的空间分配使用供显式动态分配的存储空间分配 见后续内容 20 变量类别及其存在期 内部变量的类别auto 默认的内部变量类别 可以不用写 存储单元在运行过程中动态分配和释放static 静态内部变量 保存在静态存储区 存储单元在程序启动时分配 程序结束时释放 外部变量在函数之外定义的变量称为外部变量 全局变量 Externalvariable全部保存静态存储区 程序启动时分配 程序结束时释放 在外部变量前加static只影响对应变量的可见范围 但不影响变量的生命周期 21 函数中的参数 形式参数和实际参数formalargument 形式参数定义函数时给出的参数 称为形式参数Argumentsoccurredinfunctionlistwhendefiningafunctionactualargument 实际参数调用函数时给出的参数 称为实际参数ArgumentsoccurredinfunctionlistwhencallingafunctionC函数的参数是值参数 函数调用时先计算实参表达式的值把值复制给对应形参而后执行函数体 函数内对形参的操作与实参无关 22 C语言的函数原型 函数存在信息 函数原型 functionprototype声明某一个函数的存在在使用某个函数以前 用函数原型来声明某个函数已经是一个合法的 有定义的函数 请声明之后的代码放心使用该函数 Usefunctionprototypetodeclaretheexistenceofafunction原型说明的形式与函数头部类似 加分号 参数名可省略 可与函数定义用的名字不同 原型的参数名最好用有意义的名字 有利于写注释 提倡把原型说明都放在程序文件最前面 23 另外一种组织写函数原型办法 将自己写的所有的函数的函数原型都写在一起 组织成一个扩展名为 h的headerfile 即头文件 如abc h然后在 c或 cpp程序模块的首部用文件包含命令包含该头文件 如 include abc h 思考 有什么好处 24 主要内容 数值类型函数和标准库函数函数定义和程序的函数分解C程序结构与变量预处理命令定义常量字位运算符编程实例 25 C语言源程序 编译 目标模块 连接 可执行程序 函数库 C程序加工过程 编译之前还有一个源代码预加工的过程 5 5预处理 26 有预处理命令的C源程序 编译 目标模块 连接 可执行程序 函数库 C程序加工过程包含有编译前的预处理的功能 预处理 没有预处理命令的C源程序 最先做的步骤 预处理程序负责处理源程序里的所有预处理命令 生成不含预处理命令的源程序 预处理命令 加在程序中指示预处理程序进行代码处理工作的指令 预处理命令作用 简化编程工作 27 预处理命令 C源程序中以字符 开始的命令即为预处理命令常见的预处理命令包括 include define undef if else elif endif 28 把指定文件内容包含到当前源文件 include形式1 include 文件名 形式2 形式1 用于包含系统头文件 预处理程序到指定目录找文件 通常指定几个系统文件目录 形式2 用于包含自己的文件 预处理程序先在源文件所在的目录里找 找不到时再到系统指定目录中去找 文件包含命令 处理过程 在文件系统中查找指定的文件 如果找到 就用找到的文件的内容取代该命令行 被包含文件里如有预处理行也会处理 29 stdio h或math h为标准头文件 h扩展名 它们在系统子目录里 目录名为include或h 内容包括标准函数原型 系统使用的符号常量定义等 预处理时 文件内容插入到预处理命令行处 相当于在源文件中写这些函数原型 使编译程序能正确完成对标准库函数调用的处理 include include 注意 写程序时一定要包含必要的系统头文件 30 include abc h doublearea doubler returnPI r r abc cpp 系统目录中的头文件 如果找到 用相应的头文件里的内容替代包含命令 doublearea doubler intfunc2 voidfunc3 enum YES NO definePI3 14159 继续处理 abc h 文件包含处理过程及示例 doublearea doubler intfunc2 voidfunc3 enum YES NO definePI3 14159 doublearea doubler returnPI r r 处理后的abc cpp 31 1 一个 include命令只能指定一个被包含的文件 若要包含n个文件 应使用n个 include命令 2 若文件1包含文件2 而文件2中要用到文件3的内容 则可在文件1中用2个 include命令分别包含文件2和文件3 而且文件3应出现在文件2之前 如下表示 file1 c include file3 h include file2 h 3 文件包含可以嵌套 4 预编译后的包含文件和源程序文件成为一个文件 所有的extern变量将成为源程序文件中的全局静态变量 说明 32 include flie2 h file1 c file2 h include flie3 h 不包含 include命令 file3 h include flie3 h include flie2 h file1 c 不包含 include命令 不包含 include命令 file2 h file3 h 等价 33 define开始 两种形式 简单宏定义 形式 define宏名字替代正文替代正文可以是任意正文序列 到换行为止 如最后是 下一行还作为宏定义的继续 作用 为宏名字定义替代 由整个替代正文构成 预处理程序记录宏名字及其替代 在源程序中遇到宏名字标识符时 就用替代正文替换 这种操作称为宏展开或宏替换 宏定义与宏替换 34 defineNUM30 defineSLDstaticlongdouble defineNOSTOPwhile 1 程序中的 SLDx 2 4 y 9 16 替换后变成 staticlongdoublex 2 4 y 9 16 预处理程序做正文替换 替代正文可以是任何内容 后无 35 带参数宏定义 形式 define宏名字 参数列表 替代正文宏名字与括号间不能有空格 逗号分隔的标识符看作参数 替换正文为任意正文序列 宏调用的替换分两步展开 先用各实参替代宏定义替代正文里的参数 再将代换的结果代入宏调用位置 预处理中将被展开为 z x y x y x y x y 使用形式与函数调用类似 以类似参数的形式给出宏参数的替代段 用逗号分隔 称为宏调用 definemin A B A B A B z min x y x y 36 注意 宏展开可能引起参数多次计算 如 z min n m 展开后的形式是 z n m n m 替代正文各参数和整段应括起 避免出错 例 definesquare x x x在特定环境下可能出问题 例如 z square x y 展开后的形式 z x y x y 使用带参宏与调用函数的意义不同 程序加工中在 当地 展开 程序执行中并没有调用动作 宏定义 调用中没有类型问题 一个宏能否使用 使用中发生什么 能否得到预期效果 完全看展开后的情况 37 人们有时用宏定义简化程序书写 带参宏的展开可避免函数调用开销 但使程序变长 复杂宏定义展开后出错很难定位 应谨慎使用 尽量少使用 宏 写宏定义的常见错误是在定义行最后写分号 该分号将被代入程序 有可能引起语法错误 宏定义从定义处起作用直到文件结束 一个文件里不允许对同一宏名字重复定义 undef取消已有定义 undef宏名字 38 1 宏名一般都用大写字母表示 以区别于变量 2 宏定义只是替代 减少了在程序中书写的工作量 只是一个简单的代替 不作语法检查 3 宏定义不是语句 不必再其后加上 4 在宏定义中可以进行多层的替代 definreR3 0 definePI3 1415 defineL2 PI R defineSPI R Rmain printf L f nS f n L S 说明 39 例 include definePI3 1415 defineS r PI r rintmain doublea area a 3 6 area S a printf r f narea f n a area return0 或enum PI 3 1415 40 例 include defineM3 defineNM 2 defineS N N N Nintmain printf d n S N return0 运行结果为 17 41 条件编译 一 引入条件编译的原因 只对源程序中满足条件的部分内容进行编译 可以减少被编译的语句 从而减少目标程序的长度 二 定义形式 42 程序段可以是语句串 也可以是命令行方式3为嵌套定义 方式2 if整型表达式程序段1 else程序段2 endif 方式1 if整型表达式程序段1 endif 方式3 if整型表达式程序段1 elif整型表达式程序段2 elif整型表达式程序段3 else程序段n endif 43 谓词defined 使用形式 defined标识符或defined 标识符 标识符是有宏定义时 defined 标识符 得到1 否则得0 ifdef标识符相当于 ifdefined 标识符 ifndef标识符相当于 if defined 标识符 方式4 ifdef标识符程序段1 else程序段2 endif 方式5 ifndef标识符程序段1 else程序段2 endif 44 defineCOMPUTER A1 ifdefCOMPUTER A defineINTEGER SIZE16 else defineINTEGER SIZE20 endif defineDEBUG1 ifdefDEBUGprintf x d y d z d n x y z endif 预处理后只剩下 defineINTEGER SIZE16参与编译 预处理后printf参与编译 若不在希望编译printf得到输出 则删除 defineDEBUG1命令行 45 例 defineLETTER1intmain charc inti 0 while c getchar n i ifdefLETTERif c a 46 主要内容 数值类型函数和标准库函数函数定义和程序的函数分解C程序结构与变量预处理命令定义常量字位运算符编程实例 47 定义 常量 有三种方式 用enum定义枚举常量 用预处理命令 定义常量 用const定义常值变量 C程序设计界的一般看法 宏定义是简单正文代换 无语法和语义限制 可将标识符代换为任何东西 容易使源程序意义难以理解 原则是 能用其他方式的地方绝不应该用宏 因为宏定义没有类型的概念 5 6定义常量 48 const是变量 但不能赋值 const可为任何类型的 const不能用于常量表达式 如不能用作case标号 不能用于初始化外部变量或枚举常量 许多书籍用宏定义的方式定义常量 如写 definelen20 definePi3 14159265建议尽可能用枚举常量和const 枚举常量值为int 只能用于定义int常量 可用在需要 常量表达式 的地方 如作为case标号 初始化其他枚举常量和外部变量等 49 枚举是int值 如果需要整数类型的常量 应该用枚举定义需要其他类型的 常量 可考虑const constdoublePi 3 14159265 constdoubleE 2 71828 只有在这两种方式都不合适 而用宏定义又能带来特别的方便时 才应考虑它 50 主要内容 数值类型函数和标准库函数函数定义和程序的函数分解C程序结构与变量预处理命令定义常量字位运算符编程实例 51 简单程序很少用位是最小数据单位 有些数据用几个位就能表示 如单词统计程序中state可用一位表示 可考虑把多个这类数据存入一个变量里 系统程序常需直接操作位数据 硬设备的状态常用二进制串表示 操作它们常需用二进制位串发命令 C提供了位操作和字位 按位 运算符 可用于各种整型数据 把整数看成二进制序列实现位运算 5 7字位运算符 52 位运算 从一两个0 1值计算出一个0 1结果 常见 1 位否定 参数值1时得0 0时得1 2 位与 两参数都是1时得1 否则0 3 位或 两参数都是0时得0 否则1 4 位异或 恰有一参数为1时得1 否则0 字位运算符基于上面位运算 用于整型得到整型结果 字位否定 字位与 字位或 字位异或 对各位求否定 二元从两数的各位算出结果的各位 53 例 设x和y都是16位的整变量 值分别是 x 0010 1001 0101 0111y 1001 1100 1111 1010对x和y的各种字位运算 x1101 0110 1010 1000 x y0000 1000 0101 0010 x y1011 1101 1111 1111x y1011 0101 1010 1101 54 掩码的概念 掩码 mask 为做位运算而构造的二进制串 例如通过将掩码与运算对象进行位运算 获取运算对象的某位的状态 而将其它不关心的位屏蔽掉 若想在设置运算对象部分位的值同时不影响其它位的值 也需要用掩码 类似于交警在道路上画标志的时候用的模子 掩码常用十六进制 八进制形式书写 为什么要叫掩码 mask 55 例 设x是16位整型 写表达式判断x的第5位和第8位是否都为0 整数从低位向高位顺序为第0到第15位 150位x1011011010101101掩码0000000100100000用掩码与x做字位与 第5位和第8位的信息留下来 结果中其他位总是0 上述条件可写为 x 0 x0120 0 intisok intx return x 56 常用操作使用的掩码和运算 解释 举例 1 取出被处理二进制串的某些位 用 运算 掩码 这些位为1其他位为0 2 把某些位置设为0其他位不变 复位 清0 用 运算 掩码 要改变位为0 其他位为1 3 把某些位置设为1其他位不变 置位 置1 用 运算 掩码 要设置的位为1 其他位为0 4 翻转某些位而其他位不变 翻转 用 运算 掩码 要翻转位为1 其他位为0 这些运算总从两个整数 二进制串 求出结果 不改变原有计算对象 57 另外两个位运算 左移和右移 把数看作位序列 求这个序列左移或右移若干位得到的序列 左移 二元运算符 其左运算对象的是被左 右移的数据 右运算对象指明移位数 移空出位置补0 与二元字位运算对应赋值运算符 修改左边运算对象 掩码放在右边 例 n 0 xfffen的最低位置0 对应运算符是 左移可用于将整数值乘2的幂 右移可实现除以2的幂 例 x 4将x值乘了16 58 unsignedgetbits unsignedx intp intn return x p 1 n 例 写函数getbits以无符号数为参数 返回该数从第p位开始的n位作为结果 x p 1 n 将x右移 把所需n位移到右端 掩码 0的字位否定得到全1 左移n位使最低n位变0其余位是1 求否定得到低n位为1 高位都是0的掩码 掩码与x右移结果做字位与就取出了所需的n位 p位p n位0位x1011011010101101 59 p位p n位0位x1011011010101101 x p 1 n 0 n x0000101101101010 x p 1 n 0 1111111111111111 0 n 1111111111000000 0000000000111111 0 n 60 x p 1 n 0 n x0000101101101010 x p 1 n 0000000000111111 0 n x p 1 n 0 n x0000000000101010 61 主要内容 数值类型函数和标准库函数函数定义和程序的函数分解C程序结构与变量预处理命令定义常量字位运算符编程实例 62 5 8程序设计实例 简单猜数游戏 随机生成某范围的数要求用户猜 用户输入猜测后应答 toobig toosmall youwin 设计 用随机数生成器产生随机数 在程序开始要求范围 0到32767的整数 后进入游戏循环 用户猜后询问是否继续 程序主要部分交互输和输出 从用户得到数的生成范围do 生成一个数m交互式地要求用户猜数 直至用户猜对 while 用户希望继续 结束处理 基本设计 63 把取范围和取下一猜数定义为函数 intgetrange void intgetnumber intlimit getrange要求2到32767的值 超范围就要求重输入 getnumber的猜测值也应在范围内 否则提示重输 给用户几次重输入机会 超过次数仍不对时返回负值 交给调用程序段处理 设计思路 随机数用标准函数rand生成 若范围为0到m 1 可用如下语句得到所需的随机数 unknown rand m 将用户继续判断定义为0 1值函数 控制大循环 intnext void 64 intmain intm unknown guess if m getrange unknown printf Toobig n elseif guess unknown printf Toosmall n else printf Youwin break while next printf Gameover n return0 65 读入猜数上界的函数用常量限定用户出错次数 以免无穷循环 检查输入的合法性 合适时返回 有问题时要求用户重输 重复次数超过ERRORNUM时返回负值 enum ERRORNUM 5 intgetrange void inti n for i 0 i32767 printf Wrong Anumberin2 32767 n while getchar n elsereturnn return 1 66 读入猜测数的函数与前一个类似 需要数

温馨提示

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

评论

0/150

提交评论