第9章_宏定义1_第1页
第9章_宏定义1_第2页
第9章_宏定义1_第3页
第9章_宏定义1_第4页
第9章_宏定义1_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

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

文档简介

第9章 编译预处理 学习目标 编译预处理 编译预处理是指 在对源程序进行编译之前 系统将自动引用预处理程序对源程序中的预处理部分作处理 然后再将处理的结果 和源程序一起进行编译 以得到目标代码 具体过程如下 语言提供了多种预处理功能 如宏定义 文件包含 条件编译等 合理地使用预处理功能编写的程序便于阅读 修改 移植和调试 也有利于模块化程序设计 预处理的命令有以下几个特点 1 预处理命令均以 开头 结尾不加分号 2 预处理命令可以放在程序中任何位置 作用范围从定义处到文件结尾 编译预处理 宏定义 1 不带参数的宏定义1 用一个指定的标识符来代替一个字符串2 它的一般形式 define标识符字符串3 作用 把标识符定义为字符串 在进行编译预处理时 编译系统就能够把程序中出现的标识符 一律用字符串去替换 然后再对替换处理后的源程序进行编译 例 使用不带参数的宏定义 include definePI3 1415926voidmain floats v r l printf 请输入半径长度 scanf f 1 宏名一般用大写字母表示 便于与变量名区别 一般将字符个数较多的字符串用一个宏名替换 减少程序中多处引用字符串书写错误 2 宏定义是用宏名来表示一个字符串 在宏展开时以该字符串取代宏名 这只是一种简单的代换 预处理程序对它不作任何检查 如有错误 只能在编译已被宏展开后的源程序时发现 3 宏定义不是语句 在行末不加分号 如加上分号则连分号也一起置换 2 关于不带参数的宏定义的几点说明 4 宏定义必须写在函数之外 其作用域为宏定义命令起到源程序结束 如 例如 defineG9 8 voidmain G的有效范围 undefGf1 2 关于不带参数的宏定义的几点说明 5 宏定义可以嵌套 但嵌套的宏定义名要是已经定义的宏名 在宏展开时由预处理程序层层替换 例如 defineR14 256 definePI3 1415926 defineSPI R R PI R是已定义的宏名 则语句printf f s 在宏代换后变为printf f 3 1415926 14 256 14 256 6 可用宏定义表示数据类型 使书写方便 例如 defineSTUint在程序中可用STU替换数据类型int 7 宏定义只作字符替换 不分配内存空间8 对程序中用双撇号括起来的字符串原样输出 3 无参宏的应用举例 例9 1不带参数的宏的程序 include definePI3 115926 defineSTRINGThisisatestmain floatr s printf STRING n scanf f 宏定义不是 语句 所以不能在行尾加分号 否则 宏展开时 会将分号作为宏体中的1个字符 在宏展开时 预处理程序仅以宏体替换宏名 而不作任何检查 提问 以下这道题目的结果是多少 例9 3 defineN2 defineMN 1 defineNUM2 M 1main inti for i 1 i NUM i printf d n i 宏展开后的等价程序如下 main inti for i 1 i 6 i printf d n i NUM宏展开 2 N 1 1再宏展开 2 2 1 1 带参数的宏定义 1 带参数的宏定义不是简单的字符替换 还要进行参数替换 它的一般定义形式 define宏名 参数表 字符串字符串中包含在括弧中所指定的参数 如 defines a b a barea s 3 2 定义矩形面积S a和B是边长 在程序中用了s 3 2 把3 2分别代替宏定义中的形式 例 使用带参数的宏 include definePI3 1415926 defines r PI r rvoidmain floata area a 3 6 area s a printf r f narea f n a area 运行结果如下 r 3 600000area 40 715038 带参宏定义说明 1 对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替 define命令行中的形参 但是 如果有以下语句 area S a B 这时把实参a B代替PI r r中的形参r 成为area PI a B a B 请注意在a B外面没有括弧 显然这与程序设计者的原意不符 原意希望得到area PI a B a B 为了得到这个结果 应当在定义时 在字符串中的形式参数外面加一个括弧 即 defineS r PI r r 在对S a B 进行宏展开时 将a B代替r 就成了PI a B a B 这就达到了目的 2 在宏定义时 在宏名与带参数的括弧之间不应加空格 否则将空格以后的字符都作为替代字符串的一部分 例如 如果有 defines r PI r r被认为s是符号常量 不带参的宏名 它代表字符串 r PI r r 如果在语句中有area S a 则被展开为area r PI r r a 显然不对了 1 在函数调用时 是先求出实参表达式的值 再传递给形参 而宏定义只是简单的字符替换 例如上面的S a b 在宏展开时并不求a b的值 而只将实参字符 a b 代替形参r 2 函数调用是在程序运行时处理的 分配存储单元 而宏展开 调用 是在编译预处理时进行的 展开时不分配内存单元 不进行值传递 没有返回值的概念 3 对函数实参和形参都要定义类型 而宏不存在类型 宏定义时字符串可以是任何类型数据 一律看成字符串 宏名也没类型 只是一个符号表示 展开时代入指定的符号即可 如 defineCHAR1CHINA 字符 definea3 6 数值 5 带参的宏和带参函数区别 4 调用函数只可得到一个返回值 而用宏可以设法得到几个结果 definePI3 1415926 defineCIRCLE r l s v L 2 PI R S PI R R v 4 0 3 0 PI R R Rmain floatr l s v scanf f 5 带参的宏和带参函数区别 运行情况如下 3 5 r 3 50 l 21 99 S 38 48 v 179 59 注意 实参r的值已知 可以从宏带回3个值 l S v 其实 只不过是字符代替而已 将字符r代替R l代替L S代替S v代替 而并未在宏展开时求出l S v的值 5 使用宏次数多时 宏展开后源程序长 因为每展开一次都使程序增长 而函数调用不使源程序变长 6 宏替换不占运行时间 只占编译时间 而函数调用则占运行时间 分配单元 保留现场 值传递 返回 一般用宏来代表简短的表达式比较合适 有些问题 用宏和函数都可以 如 defineMAX x y x y x y main inta b c d t t MAX a b c d 5 带参的宏和带参函数区别 赋值语句展开后为t a b c d a b c d 注意 MAX不是函数 这里只有一个main函数 中就能求出t的值 例9 5 用宏代表输出格式 definePRprintf defineNL n defineD D defineD1DNL defineD2DDNL defineD3DDDNL defineD4DDDDNL defineS S main inta B C D charstring CHINA a 1 B 2 C 3 D 4 PR D1 a PR D2 a B PR D3 a B C PR D4 a B C D PR S string 1121231234CHINA 文件包含 1 所谓 文件包含 处理是指一个源文件可以将另外一个源文件的全部内容包含进来 即将另外的文件包含到本文件之中 C语言提供了 inClude命令用来实现 文件包含 的操作 其一般形式为2 一般表达形式 include 文件名 或 include 注意 当使用文件包含在编译时并不是对两个文件分别进行编译 然后链接得到目标程序 而是在经过编译预处理后将头文件包含到主文件中 得到一个新的源程序 然后对这个文件进行编译 得到一个目标程序 被包含的文件成为新的源文件的一部分 而单独生成目标文件 说明 1 一个 include命令只能指定一个被包含文件 如果要包含 个文件 要用 个 include命令 2 如果文件 包含文件 而在文件 中要用到文件 的内容 则可在文件 中用两个include命令分别包含文件 和文件 而且文件 应出现在文件 之前 3 在一个被包含文件中又可以包含另一个被包含文件 即文件包含是可以嵌套的 4 文件包含可用双撇号 也可用尖括号 它们的区别是 尖括号 系统到存放c库函数头文件的目录中寻找要包含的文件双撇号 系统先在用户当前目录中寻找 找不到再按尖括号的方式寻找 5 被包含的文件与其所在的文件在预编译后已变成同一文件 说明 条件编译 1 一般情况下 源程序中所有的行都参加编译 但是有时希望对其中一部分内容只在满足一定条件才进行编译 也就是对一部分内容指定编译的条件 这就是 条件编译 2 表达形式 条件编译实例1 include defineTED10main ifdefTEDprintf Hi Ted n elseprintf Hi Anyone n endif ifndefRALPHprintf RAPLHnotdefined n e

温馨提示

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

评论

0/150

提交评论