计算机本科C语言讲稿-编译预处理课件.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《计算机本科C语言讲稿-编译预处理课件.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 本科 语言 讲稿 编译 预处理 课件
- 资源描述:
-
1、第六章第六章 预处理命令预处理命令宏定义宏定义文件包含文件包含条件编译条件编译6.1 概述概述 1.所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。它由预处理程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的编译。语言提供了多种预处理功能,如宏定义、文件包含、条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。2 可执行程序形成的三个过程 预处理、编译和连接是形成可执行程序的三个 重要过程,这三个过程的每一步都可将一种形 式的程序代码改变成另一种形式的程序代
2、码。1)预处理程序负责处理组成程序的预处理命 令,从而将带有预处理命令的程序文件转 化为纯粹的C程序。c:turboc2zxjc1.cvoid p1()printf(“*n”);c:turboc2zxjc2.cvoid p2()printf(“my name is zxjn”);c:turboc2zxjc3.c#include“c1.c”#include“c2.c”main()p1();p2();p1();经过预处理程序(经过预处理程序(预编译程序预编译程序)的处理,从而将)的处理,从而将带有预处理命令的程序文件带有预处理命令的程序文件c3.c转化为:转化为:void p1()void p1(
3、)printfprintf(“(“*n”);n”);void p2()void p2()printfprintf(“my name is zxjn”);(“my name is zxjn”);main()main()p1();p1();p2();p2();p1();p1();2)2)编译程序:编译程序:将一个个将一个个C C源程序翻译成对应的二进源程序翻译成对应的二进 制代码文件制代码文件(后缀名为后缀名为.obj.obj的文件的文件)。3)3)连接程序:连接程序:将组成程序的所有将组成程序的所有.obj.obj和用到的库和用到的库 文件连接起来,形成一个完整的可执行程序。文件连接起来,形成一
4、个完整的可执行程序。6.2宏定义宏定义 在语言源程序中允许用一个标识符来表示一个字符串,称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。在语言中,“宏”分为有参数和无参数两种。6.2.1无参宏定义无参宏定义其定义的一般形式为:#define 标识符 字符串其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。例如:
5、#define N 100#define M(y*y+3*y)#define PR printf【例【例6.16.1】#define M#define M(y(y*y+3y+3*y)y)main()main()int s,y;int s,y;printf(input a number:);printf(input a number:);scanf(%d,&y);scanf(%d,&y);s=3 s=3*M+4M+4*M+5M+5*M;M;printf printf(s=%dn,s);(s=%dn,s);宏定义宏调用经过预处理程序处理(宏展开)之后纯粹的经过预处理程序处理(宏展开)之后纯粹的C
6、C代码代码 main()main()int s,y;int s,y;printf(input a number:);printf(input a number:);scanf scanf(%d,&y);(%d,&y);s=3 s=3*(y(y*y+3y+3*y)y)+4+4*(y(y*y+3y+3*y)y)+5+5*(y(y*y+3y+3*y)y);printf printf(s=%dn,s);(s=%dn,s);对于宏定义还要说明以下几点:1)宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源
7、程序时发现。2)宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。3)宏定义其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。例如:例如:#define PI 3.14159#define PI 3.14159 main()main()f1()f1()例如:例如:#define PI 3.14159#define PI 3.14159 main()main()#undef#undef PI PI f1()f1()4)宏名在源程序中若用引号括起来,则预处理程序不对其作宏代换。【例9.2】#define OK 100main()printf(OK);p
8、rintf(n);5)5)宏定义允许嵌套,宏定义允许嵌套,在宏定义的字符串中可以在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程使用已经定义的宏名。在宏展开时由预处理程序层层代换。序层层代换。例如:例如:#define PI 3.1415926#define PI 3.1415926#define S PI#define S PI*y y*y y /*PI PI是已定义的宏名是已定义的宏名*/对语句:对语句:printfprintf(%f,S);(%f,S);在宏代换后变为:在宏代换后变为:printf(%f,3.1415926printf(%f,3.1415926*y y*y)
9、;y);6)6)习惯上宏名用大写字母表示,习惯上宏名用大写字母表示,以便于与变量以便于与变量区别区别;但也允许用小写字母。但也允许用小写字母。7)7)对对“输出格式输出格式”作宏定义,可以减少书写麻烦。作宏定义,可以减少书写麻烦。【例【例6.36.3】中就采用了这种方法。】中就采用了这种方法。#define P printf#define P printf#define D%dn#define D%dn#define F%fn#define F%fnmain()main()int int a=5,c=8,e=11;a=5,c=8,e=11;float b=3.8,d=9.7,f=21.08;f
10、loat b=3.8,d=9.7,f=21.08;P(D F,a,b);P(D F,a,b);P(D F,c,d);P(D F,c,d);P(D F,e,f);P(D F,e,f);6.2.2带参宏定义带参宏定义 语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。带参宏定义的一般形式为:#define 宏名(形参表)字符串带参宏调用的一般形式为:宏名(实参表);例如:例如:#define#define M(y)M(y)y y*y+3y+3*y /y /*宏定义宏定义*/k=k=M(5)M(5);/;/*
11、宏调用宏调用*/经预处理程序的预编译,在宏展开时,用实参经预处理程序的预编译,在宏展开时,用实参5 5去代替形参去代替形参y y,宏展开后的语句为:,宏展开后的语句为:k=5k=5*5+35+3*5 5【例6.4】#define MAX(a,b)(ab)?a:bmain()int x,y,max;printf(input two numbers:);scanf(%d%d,&x,&y);max=MAX(x,y);printf(max=%dn,max);经预编译后:main()int x,y,max;printf(input two numbers:);scanf(%d%d,&x,&y);max=
12、(xy)?x:y;printf(max=%dn,max);对于带参的宏定义有以下问题需要说明:1.带参宏定义中,宏名和形参表之间不能有空格出现。例如把:#define MAX(a,b)(ab)?a:b写为:#define MAX (a,b)(ab)?a:b2.带参宏定义与函数区别:1)在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。函数的形参有类型,当它所在函数调用时得到存储空间。2)宏展开时实参对形参只是简单的代换,而函数调用时实参值要传给形参,进行“值传递”。3.在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。【例9.5】#define SQ(y)(y)*(y)main
13、()int a,sq;printf(input a number:);scanf(%d,&a);sq=SQ(a+1);printf(sq=%dn,sq);4.在宏定义中,字符串内的形参通常要用括号括起来以避免出错。【例9.6】#define SQ(y)y*ymain()int a,sq;printf(input a number:);scanf(%d,&a);sq=SQ(a+1);printf(sq=%dn,sq);运行结果为:input a number:3sq=7【例6.8】#define SQ(y)(y)*(y)main()int a,sq;printf(input a number:)
14、;scanf(%d,&a);sq=160/SQ(a+1);printf(sq=%dn,sq);对于宏定义不仅应在参数两侧加括号,也应在整个字符串外加括号。5.宏定义也可用来定义多个语句,在宏展开时,把这些语句又代换到源程序内。看下面的例子。【例【例9.119.11】#define V(s1,s2,s3,v)s1=l#define V(s1,s2,s3,v)s1=l*w;s2=lw;s2=l*h;s3=wh;s3=w*h;v=wh;v=w*l l*h hmain()main()int int l=3,w=4,h=5,sa,sb,sc,vv;l=3,w=4,h=5,sa,sb,sc,vv;V(sa
15、,sb V(sa,sb,sc,vv);,sc,vv);printf(sa=%dnsb=%dnsc=%dnvv printf(sa=%dnsb=%dnsc=%dnvv=%dn,=%dn,sa,sb sa,sb,sc,vv);,sc,vv);6.3文件包含文件包含 文件包含是C预处理程序的另一个重要功能。#include命令告诉预处理程序,将其后面所跟的文件的内容插入到当前文件中。即把指定的文件插入该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连成一个源文件。#include命令行的两种形式为:#include#include 文件名 例如:#include stdio.h#incl
16、ude math.h 在程序设计中,文件包含是很有用的。一个大的程序可以分为多个模块,由多个程序员分别编程。有些公用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使用。这样,可避免在每个文件开头都去书写那些公用量,从而节省时间,并减少出错。对文件包含命令还要说明以下几点:1.包含命令中的文件名可以用双引号括起来,也可以用尖括号括起来。例如以下写法都是允许的:#include stdio.h#include 但是这两种形式是有区别的:使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的),而不在源文件目录去查找;使用双引号则表示首先在当前的源
17、文件目录中查找,若未找到才到包含目录中去查找。用户编程时可根据自己文件所在的目录来选择某一种命令形式。2.一个include命令只能指定一个被包含文件,若有多个文件要包含,则需用多个include命令。3.文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。#include void p().File1.c#include void s().File2.c#include void main().File3.c 6.4条件编译条件编译 预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。条件编译有三种形式
展开阅读全文