已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
时间 1次课 2学时 第9章编译预处理 第9章编译预处理 本章主要内容1 掌握三种编译预处理命令 宏定义 文件包含和条件编译 的功能2 宏定义及文件包含命令的应用3 了解分割编译的过程 9 1编译预处理命令 1 编译预处理在C编译系统中 包含有对C源程序进行预处理的程序 利用这些预处理程序 在编译源程序之前 先对其进行一些预加工 如通过宏定义可以置换源程序文件中的特定标识符 通过文件包含命令可以把指定的头文件或用户自己编制的程序文件嵌入到被编译的源文件中 通过条件编译可以根据需要只编译源程序的部分代码等 我们称这些编译之前的预处理为编译预处理 编译预处理是由编译系统中的预处理命令进行的 这是C 语言的一个重要特点 它能改善程序设计环境 有助于编写易移植 易调试的程序 也是模块化程序设计的一个工具 2 编译预处理命令编译预处理命令主要有三种 即宏定义 文件包含和条件编译 编译预处理命令不属于C语句的范畴 所使用的命令动词也不是C关键字 为表示区别 所有的编译预处理命令均以 符号开头 各占用一个单独的书写行 末尾不用分号作结束符 如果一行书写不下 可用反斜线 和回车键结束 然后在下一行继续书写 编译预处理命令可以出现在程序的任何位置 其作用域是自出现的地方开始知道源程序的末尾 1 不带参数的宏定义 define标识符字符串标识符又称宏名 为了区别于一般变量 通常用英文大写字母表示 字符串又称宏体 可以是常数 关键字 语句 表达式 还可以是空白 在源程序编译前 宏名被宏体替换 这一过程称为宏展开 例如 定义 printf EMS 在编译预处理阶段被展开成 printf standarderroroninput n 宏展开只是简单地用定义的宏体去替换宏名 既不对宏体进行任何检查和识别 也不进行任何计算 9 2宏定义 一个 define只能定义一个宏 若需要定义多个宏就要用多个 define 若宏定义中只有宏名没有宏体 表示该标识符已被定义 不能再作其它用途 例如 定义 defineBEG后 BEG就被保护起来 不能将它作为标识符使用 宏体中可包含已定义过的宏名 即用已定义的宏名再去定义另外的宏名 称之为嵌套宏定义 思考 若有 下列两个宏定义 defineWIDTH80 defineLENGTH WIDTH 40 和 defineWIDTH80 defineLENGTHWIDTH 40若程序中出现 var LENGTH 20 则经过编译预处理后 其结果有何差别 若双引号中有与宏名相同的字符串 则在编译预处理时 将不会对它进行宏替换 例如程序段 defineYES1char ps x YES printf s n ps 中 YES被定义为1 但赋值语句ps x YES 中的YES只被视为普通的字符串 而不会被替换为1 因此 printf 的输出为 x YES 而不是 x 1 2 带参数的宏定义带参数的宏是指宏名带有一个或多个形式参数 define标识符 形参表 宏体例如 definePOWER X X X 其中 POWER X 称为带参数的宏 x是它的形式参数 x x 为宏体 宏展开时 程序中凡出现POWER x 的地方都用 x x 来替换 而且形参x将被实参替换 圆括号予以保留 例如 inta 5 b 3 printf d a POWER a b 中 POWER i 被替换成 a b a b 显然 该程序段可打印5 5 3 5 3 的值 带参数的宏有以下特点 程序中使用带参数的宏 由于不存在控制的转移和参数的传递 因而可以得到较高的程序执行速度 但由于定义代码的反复使用而使程序变大 因而在对源程序进行编译时 要花费较多的时间 宏替换不象函数调用一样 要进行参数传递 保存现场 返回函数值等操作 因此 对简短的表达式以及调用频繁 要求快速响应的场合 采用宏替换较好些 宏替换只是简单的字符替换而不进行计算 因而一些过程是不能用宏替换去代替函数调用的 例如递归调用 带参数的宏 除了使用运算表达式定义之外 还可以使用函数 在标准函数库中 经常使用这种形式 例如 definegetchar fgetc stdin 在这里 getchar 实质上是用另一个函数定义的宏 这样定义的宏替换与定义它的函数 在性质上是相同的 宏定义如果使用不当 会产生不易觉察的错误 例9 1 分别用函数调用和带参数的宏定义两种方法编制打印整数1 10的平方的程序 采用函数调用的程序 includemain inti 1 while i 10 printf d n square i square intn return n n 采用宏定义的程序 defineSQUARE n n n main inti 1 while i 10 printf d n SQUARE i 思考 上述两个程序的运行结果分别是多少 3 宏定义的解除 undef宏名其中 宏名是在此之前已定义过的 undef的功能是解除前已定义的宏 使之不再起作用 definePDP1 defineMUL x x x undefPDP undefMUL使宏PDP和MUL x 只在 undef之前的程序中有效 在 undef之后就不能再使用这两个宏 注意 解除带参数的宏定义时 只需给出宏名 而不必给出宏体 程序中将 define和 undef配合使用 就可以把宏定义的使用限制在二者之间的范围内 因此也称之为局部宏定义 4 重新宏定义 undef的另一个作用是重新进行宏定义 C语言规定 程序中不能定义同名的宏 使用undef解除宏定义后 就可以重新定义该宏名 defineSIZE256 undefSIZE defineSIZE512当SIZE为256的宏定义不再使用是 解除宏定义后 再重新定义512的宏 在实际应用时 由多个源文件组成的程序 在不同的源文件中可能会出现同一个宏名被定义为不同的宏体 若将这些源文件合并在一起时 就会出现重复宏定义的错误 可以在每个源文件的末尾把使用过的宏定义均用 undef解除 1 文件包含的一般格式 include或 include 文件名 其中 被包含的文件可以是系统提供的标题文件 也可以是用户自行编制的程序文件 它们都是文本文件 标题文件的扩展名一般是 h 用户自己编制的程序文件不一定用 h 作扩展名 被包含的文件用尖括号括住 include系统将只在系统的include标准子目录下查找 如果标准子目录下不存在 编译系统会发出错误信息 并停止编译过程 被包含的文件用双引号括住 include prog h 系统将在当前盘的当前目录下查找 若未找到 再到include子目录下查找 被包含的文件带有路径 并用双引号括住 include c user user h 系统将按指定的文件路径去查找 9 3文件包含 2 文件包含的功能在编译预处理时 命令行将被包含进来的文件内容所替换 也就是说 原来命令行的位置上变成了被包含文件的文本 它们连同源程序的其他代码一起参加编译 源程序文件就可以直接调用被包含文件中的程序 例9 2 下面的数学演示程序 用来接收用户输入的半径 并计算和显示该半径对应的圆周长 圆面积 球表面积和球体积 将计算圆的周长和面积 球的表面面积和体积的计算公式定义为带参数的宏 并将这些宏定义单独存放在文件circle c中 假设文件circle c放在C TC INCLUDE子目录中 只要在主程序中将circle c包含进来 就可以直接调用这些宏来计算 includemain floatr printf InputR scanf f 文件circle c的内容如下 definePI3 141593 defineCIRCLE r 2 PI r defineAREA r PI r r defineSURFICE r AREA r 4 defineVOLUME r SURFICE r r 3 3 文件包含的嵌套C语言允许嵌套使用 include 即被包含的文件中又使用 include包含另一个文件 在例10 3中 当前要编译的源程序中有如下命令 include而在文件file1 h中 又有命令 include在对源程序进行编译预处理时 首先把文本文件file1 h包含到源程序中 然后 再进一步把文件file2 h包含到源程序的file1 h中去 10 2 2文件包含的嵌套C语言允许嵌套使用 include 即被包含的文件中又使用 include包含另一个文件 在例10 3中 当前要编译的源程序中有如下命令 include而在文件file1 h中 又有命令 include在对源程序进行编译预处理时 首先把文本文件file1 h包含到源程序中 然后 再进一步把文件file2 h包含到源程序的file1 h中去 条件编译的功能是只对源程序中的必要部分进行编译 而对其余部分不进行编译 不产生目标代码 在编译源文件之前 根据给定的条件 决定编译的范围 可使程序适应不同系统和不同硬件 9 4条件编译 1 条件编译的形式 if else endif if endif if elif else endif它们相当于if else endif结构 defineMAX100main inti 10 floatx 25 8 ifMAX 99printf d n i elseprintf f n x endifprintf d f n i x 本程序编译后的运行结果是 1010 25 800000 ifdef else endif ifndef else endif形式这两种形式分别表示 如果定义 和 如果不定义 它们与 define和 undef配合使用来实现是否编译的条件 defineATmain inti j ifdefATprintf Startingtest n endiffor i 0 i 10000 i for j 0 j 10000 j undefAT ifndefATprintf Stoptest n elseprintf Done n endif 请读者自行分析该程序的运行结果 2 条件编译的功能 便于程序的调试在程序调试时 经常需要查看某些变量的中间结果 这时 可以使用条件编译在程序中设置若干个调试用语句 defineDEBUG1 defineDEBUGprintf a d n a endif在这里 条件编译用于调试时查看变量a的中间结果值 在调试完成后 只需要把符号常量DEBUG的宏定义稍加改动 defineDEBUG0则再次编译该源程序时 这些测试用的语句就不再参加编译了 可以看出 使用条件编译省去了在源程序中增删测试用语句的麻烦 在程序正式
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 游戏策划与设计师产品品质与开发周期绩效评定表
- 2025年七年级数学兴趣小组选拔赛试题(含答案)
- 2025年公开选拔领导干部面试试题含参考答案
- 人力资源管理流程及方法工具
- 电子商务项目经理电商运营绩效评定表
- 2025年环境健康素养理论知识考核试题及答案
- 上海2025年教师职称考试(教育基础知识)手机备考题库(小学)
- 语文作文辅导记叙文写作系列训练细节描写
- 教育咨询师辅导教师学生增长考核表
- 娱乐行业艺人表演能力与影响力绩效评定表
- (完整文本)乌有先生传(原文+注释+译文)
- 儿童流感的预防与治疗
- 三年级数学专项思维训练习题11套原卷+答案解析
- 事故油池基坑开挖专项施工方案
- 2021级数据科学与大数据技术专业培养方案(本科)
- 《量子力学》全本课件
- 《我弥留之际》读书笔记思维导图PPT模板下载
- 病毒性肝炎的免疫学检查
- 环境催化-课件1
- 旭辉地产年度品牌整合传播规划方案
- GB/T 27924-2011工业货架规格尺寸与额定荷载
评论
0/150
提交评论