欢迎来到优知文库! | 帮助中心 分享价值,成长自我!
优知文库
全部分类
  • 幼儿/小学教育>
  • 中学教育>
  • 高等教育>
  • 研究生考试>
  • 外语学习>
  • 资格/认证考试>
  • 论文>
  • IT计算机>
  • 法律/法学>
  • 建筑/环境>
  • 通信/电子>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 优知文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    第八章编译预处理.docx

    • 资源ID:520008       资源大小:21.63KB        全文页数:5页
    • 资源格式: DOCX        下载积分:3金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: QQ登录
    二维码
    扫码关注公众号登录
    下载资源需要3金币
    邮箱/手机:
    温馨提示:
    快捷下载时,如果您不填写信息,系统将为您自动创建临时账号,适用于临时下载。
    如果您填写信息,用户名和密码都是您填写的【邮箱或者手机号】(系统自动生成),方便查询和重复下载。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    第八章编译预处理.docx

    第八章编译预处理第一节宏定义大家好,上一节咱们讲的是“变量的存储和引用,内部和外部函数”我们主要是围绕着下列话题进行讲解:(1)变量的存储类别(2)局部变量的存储方式(3)全局变量跨文件引用(4)函数的跨文件调用(5)StatiC关键字用法总结:本节是新的一章的第一节,我们围绕如下话题来讲解:(1)不带参数的宏定义(2)带参数的宏定义大家回忆一下老师以往讲解的内容:一个项目,可以由一个或者多个源文件组成,一个项目,咱们可以通过编译、链接最终形成一个可执行文件。那么这个编译,是一个一个的源文件也就是这里的.cpp文件单位进行的,每个源文件,都会编译成一个目标文件(.。也可能是obj,这个跟操作系统有关),那如果源文件有几个,则可能就编译生成了几个目标文件,然后将这些目标文件进行链接,形成最终的一个一个的可执行文件。那么这个编译都干了什么事,笼统的说:词法,语法分析,目标代码生成,优化之类的一些东西。这个编译我们可以拆开来看它也是干了好几个事的,一般来讲他会干这么几个事:a)预处理:b)编译:词法,语法分析,目标代码生成,优化c)汇编:产生.0(.obj)目标文件;大家也不用深究这几个词是啥意思。老师本节课重点要说这个“预处理”,这个预处理是干什么的呢?咱们在源程序.cpp中加入一些特殊的代码(特殊命令),这些特殊代码有一些特殊能力,提供一些特殊功能,编译系统会先对这些特殊代码做处理,这个就叫“预处理”,处理的结果再和源程序代码一起进行上边步骤b)的编译,汇编这一系列操作。C语言一般提供三种预处理功能,1:宏定义,2:文件包含,3:条件编译,我们本节课讲解“宏定义”;这三种功能也是通过在程序代码中写代码来实现,只不过这些代码比较特殊,都是用#开头。一:不带参数的宏定义;不带参数的宏定义是用来干嘛的呢?用一个指定的标识符来代表一个字符串,一般形式:#define标识符字符串标识符也叫宏名比如:#definePl3.作用:用Pl来代替“3.”这个字符串,程序源码中,我们写的是Pl(也就是一般形式中的标识符),在编译预处理时,所有在该#加由优之后的Pl都会被替换成“3.”;好处:a)用一个简单的名字代替一个长字符串,所以这个标识符也被称为宏名。在预编译时将宏名替换成字符串的过程称为“宏展开二#define就是宏定义命令;b)增加了修改的方便性,为修改提供极大便利,这种能力被用的很频繁,如果Pl不等于3.14了,而是等于2.58了,是不是我只需要修改一行,整个程序就都等于被替换成成2.58了;这也叫提高了程序的可移植性;演示:#definePl3.intmain()(floatftmp;ftmp=2*PI;printf("ftmp=%fr,ftmp);)说明:实际上宏展开时,Pl就直接被替换成了3并不做语法检杳,所以替换完了后直接参与乘法运算,也就是ftmp=2*Pl;就#1当于ftmp=2*3.;说明:(1)宏名一般大写字母表示,这是一种习惯,建议大家遵照这个习惯。(2)宏定义不是C语句,不必在行末加分号,如果加分号则连分号一起被替换了;#definePl3.;ftmp=2*Pl;这还好,不报错,这相当于ftmp=2*3.;ftmp=Pl*2;这就报语法错了。这相当于ftmp=3.;*2;(3)Vdefine命令出现在程序中函数的外面,宏名的有效范围是#define之后到本源文件结束,不能跨文件使用,如果在另外一个文件中使用,则需要在另外一个文件中也做相同定义,或者把这些定义放到一个公共文件里,并用下节课我们要讲解的#访(把这个公共文件包含到每个源文件中去;一般来讲,#define命令都写在文件开头,函数之前;(4)可以用Jndef命令终止宏定义的作用域,这个用的相对比较少,大家先知道,以后遇到再说;演示如下:ftdefinePl3.intmain。主函数(floatftmp;ftmp=Pl*2;printf("ftmp=%fr,ftmp);Printf("断点在这里”);return0;)ftundefPlvoidfuncl()(floatftmp;ftmp=Pl*2;)(5)用#(区进行宏定义时,还可以引用己定义的宏,可以层层置换演示:#definePl3.#defineDPI2*Pl#defineDPICPIPl*DPIintmain。主函数(floatftmp;ftmp=Pl*2;ftmp=DPI;ftmp=DPICPI;)宏展开之后:DPl被替换成2*3.,DPICPI被替换成3.*2*3.;(6)字符串内的字符,即便与宏名相同,也不进行替换:接上例演示:charstmp100="DPICPI"这里的DPICPI不能被替换二:带参数的宏定义;前面我们讲的不带参数的宏定义,只是进行简单的字符串替换,那这里要讲解的带参数的宏定义,就不是进行简单的字符串替换了,还要进行参数替换,一般形式如下:#define宏名(参数表)字符串也是用右边的“字符串”代替“宏名(参数表)",但具体怎么替换,咱们后边详细讲;和不带参数的宏定义比,这里多了个参数表。在字符串中,一般都会包含参数表中所指定的参数演示:#defineS(a,b)a*bintArea=S(3,2);在程序中,我们用了宏S,系统是怎么替换的呢?在程序中用了S(3,2),把3,2分别代替宏定义中的形式参数a,b,最终用3*2替换了S2);所以等价于intArea=3*2;咱们刚才说了,一般字符串"中都会包含参数表中所指定的参数,但不包含也可以,但你若不包含,你通过参数表传进去这个参数干啥,不是没啥意义吗!比如#defineS(a,b)aintArea=S(3,2);总结:带参数的宏定义是这样展开置换的:对一般格式中这个字符串,要从左到右处理;如果字符串中有宏名后列出的形参比如(a,b),则将程序语句中相应的实参(可以是常量,变量或者表达式)代替形参,如果字符串中的字符不是参数字符,则保留,比如上边a*b中的*;演示:#definePl3.ftdefineS(r)Pl*r*rintmain。主函数(floatarea;area=S(3.6);)说明:a)如果输入S(l+5)代替后变成:Pl*1+5*1+5;,这肯定不对,咱们的原意是代替后变成Pl*(1+5)*(1+5)为解决这个问题,我们要在形式参数外面加一个括号也就是:ftdefineS(r)Pl*(r)*(r)这样才能展开成Pl*(1+5)*(1+5)b)宏定义时,宏名和带参数的括号之间不能加空格,否则,空格以后的字符都作为替代字符串的一部分了;比如如果如下定义:ftdefineS(r)Pl*(r)*(r)那这成啥了,S成为了不带参数的宏定义,代表字符串rt(r)PI*(r)*(r,这显然不对嘛;大家是不是感觉带参数的宏和函数挺像的,容易区分不开;宏也有实参形参,但他们还是有很不相同的地方:(1)函数调用是先求出实参表达式的值,然后带入形参,带参宏只进行简单的字符替换,宏展开时并不求值,比如上边的S(l+5),宏展开时并不求1+5的值,只是原样用实参替换掉形参。(2)函数调用是在程序运行时处理,分配临时内存。宏展开是在编译时进行的,展开时不分配内存单元,也不存在值传递的概念,当然也没有返回值的这个说法;(3)宏的参数没有类型这个说法,只是个符号,展开时带入指定字符;#defineS(r)Pl*(r)*(r),比如这个r,并不是个类型;(4)使用宏次数多时,宏展开后源程序长,每展开一次都是程序增长,函数调用不会使源程序变长。(5)宏替换只占编译时间,不占运行时间,而函数调用占运行时间(分配内存,传递参数,执行函数体,返回值等等);有时候会用宏替换一些很复杂的语句,比如如下相对复杂一点的,求X和y的最大值#defineMAX(x,y)(x)>(y)?(x):(y)调用的时候intresult=MAX(3,4);还有能代替多行语句的:末尾,老师讲过。这种用法在一定程度上能简化程序书写。#defineMACROTESTdoprintf("testn");while(0)宏这个东西,我们自己写代码的时候,可能用的还不太多,但有些人是频繁的使用的,比如大家有机会读读nginx开源代码,或者读一些跨平台的源码的时候,宏用的还是很多的;大家目前先掌握这么多,以后遇到更复杂的,再慢慢研究。这节课咱们就先到这,下次见。

    注意事项

    本文(第八章编译预处理.docx)为本站会员(王**)主动上传,优知文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知优知文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




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

    copyright@ 2008-2023 yzwku网站版权所有

    经营许可证编号:宁ICP备2022001189号-2

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

    收起
    展开