计算机本科c语言讲稿-编译预处理教学教材.ppt

上传人:豆**** 文档编号:77728140 上传时间:2023-03-16 格式:PPT 页数:60 大小:198.50KB
返回 下载 相关 举报
计算机本科c语言讲稿-编译预处理教学教材.ppt_第1页
第1页 / 共60页
计算机本科c语言讲稿-编译预处理教学教材.ppt_第2页
第2页 / 共60页
点击查看更多>>
资源描述

《计算机本科c语言讲稿-编译预处理教学教材.ppt》由会员分享,可在线阅读,更多相关《计算机本科c语言讲稿-编译预处理教学教材.ppt(60页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、计算机本科C语言讲稿-编译预处理2 可执行程序形成的三个过程 预处理、编译和连接是形成可执行程序的三个 重要过程,这三个过程的每一步都可将一种形 式的程序代码改变成另一种形式的程序代码。1)预处理程序负责处理组成程序的预处理命 令,从而将带有预处理命令的程序文件转 化为纯粹的C程序。c:turboc2zxjc1.cvoidp1()printf(“*n”);c:turboc2zxjc2.cvoidp2()printf(“mynameiszxjn”);c:turboc2zxjc3.c#include“c1.c”#include“c2.c”main()p1();p2();p1();经过预处理程序(经

2、过预处理程序(预编译程序预编译程序)的处理,从而将)的处理,从而将带有预处理命令的程序文件带有预处理命令的程序文件c3.c转化为:转化为:void p1()void p1()printf(“*n”);printf(“*n”);void p2()void p2()printf(“my name is zxjn”);printf(“my name is zxjn”);main()main()p1();p1();p2();p2();p1();p1();2)2)编译程序:编译程序:将一个个将一个个C C源程序翻译成对应的二进源程序翻译成对应的二进 制代码文件制代码文件(后缀名为后缀名为.obj.obj

3、的文件的文件)。3)3)连接程序:连接程序:将组成程序的所有将组成程序的所有.obj.obj和用到的库和用到的库 文件连接起来,形成一个完整的可执行程序。文件连接起来,形成一个完整的可执行程序。6.2宏定义宏定义 在语言源程序中允许用一个标识符来表示一个字符串,称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。在语言中,“宏”分为有参数和无参数两种。6.2.1无参宏定义无参宏定义其定义的一般形式为:#define 标识符 字符

4、串其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。例如:#define N 100#define M(y*y+3*y)#define PR printf【例【例6.16.1】#define M#define M(y*y+3*y)(y*y+3*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*M+4*M+5*M;s=

5、3*M+4*M+5*M;printf(s=%dn,s);printf(s=%dn,s);宏定义宏调用经过预处理程序处理(宏展开)之后纯粹的经过预处理程序处理(宏展开)之后纯粹的C C代码代码 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*(y*y+3*y)(y*y+3*y)+4*+4*(y*y+3*y)(y*y+3*y)+5*+5*(y*y+3*y)(y*y+3*y);printf(s=%dn,s);printf(s=%d

6、n,s);对于宏定义还要说明以下几点:1)宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。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()

7、#undef PI#undef PI f1()f1()4)宏名在源程序中若用引号括起来,则预处理程序不对其作宏代换。【例9.2】#define OK 100main()printf(OK);printf(n);5)5)宏宏定定义义允允许许嵌嵌套套,在在宏宏定定义义的的字字符符串串中中可可以以使使用用已已经经定定义义的的宏宏名名。在在宏宏展展开开时时由由预预处处理理程程序序层层代换。层层代换。例如:例如:#define PI 3.1415926#define PI 3.1415926#define S PI*y*y#define S PI*y*y /*PI/*PI是已定义的宏名是已定义的宏名*/

8、*/对语句:对语句:printf(%f,S);printf(%f,S);在宏代换后变为:在宏代换后变为:printf(%f,3.1415926*y*y);printf(%f,3.1415926*y*y);6)6)习习惯惯上上宏宏名名用用大大写写字字母母表表示示,以以便便于于与与变变量量区区别别;但也允许用小写字母。但也允许用小写字母。7)7)对对“输出格式输出格式”作宏定义,可以减少书写麻烦。作宏定义,可以减少书写麻烦。【例【例6.36.3】中就采用了这种方法。】中就采用了这种方法。#define P printf#define P printf#define D%dn#define D%dn

9、#define F%fn#define F%fnmain()main()int a=5,c=8,e=11;int a=5,c=8,e=11;float b=3.8,d=9.7,f=21.08;float 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 宏名(形参

10、表)字符串带参宏调用的一般形式为:宏名(实参表);例如:例如:#define#define M(y)M(y)y*y+3*y /*y*y+3*y /*宏定义宏定义*/*/k=k=M(5)M(5);/*;/*宏调用宏调用*/*/经经预预处处理理程程序序的的预预编编译译,在在宏宏展展开开时时,用用实实参参5 5去去代替形参代替形参y y,宏展开后的语句为:,宏展开后的语句为:k=5*5+3*5 k=5*5+3*5【例6.4】#define MAX(a,b)(ab)?a:bmain()int x,y,max;printf(input two numbers:);scanf(%d%d,&x,&y);ma

11、x=MAX(x,y);printf(max=%dn,max);经预编译后:main()int x,y,max;printf(input two numbers:);scanf(%d%d,&x,&y);max=(xy)?x:y;printf(max=%dn,max);对于带参的宏定义有以下问题需要说明:1.带参宏定义中,宏名和形参表之间不能有空格出现。例如把:#define MAX(a,b)(ab)?a:b写为:#define MAX (a,b)(ab)?a:b2.带参宏定义与函数区别:1)在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。函数的形参有类型,当它所在函数调用时得到存储空

12、间。2)宏展开时实参对形参只是简单的代换,而函数调用时实参值要传给形参,进行“值传递”。3.在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。【例9.5】#define SQ(y)(y)*(y)main()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);prin

13、tf(sq=%dn,sq);运行结果为:input a number:3sq=7【例6.8】#define SQ(y)(y)*(y)main()int a,sq;printf(input a number:);scanf(%d,&a);sq=160/SQ(a+1);printf(sq=%dn,sq);对于宏定义不仅应在参数两侧加括号,也应在整个字符串外加括号。5.宏定义也可用来定义多个语句,在宏展开时,把这些语句又代换到源程序内。看下面的例子。【例【例9.119.11】#define V(s1,s2,s3,v)s1=l*w;s2=l*h;s3=w*h;v=w*l*h#define V(s1,s

14、2,s3,v)s1=l*w;s2=l*h;s3=w*h;v=w*l*hmain()main()int l=3,w=4,h=5,sa,sb,sc,vv;int l=3,w=4,h=5,sa,sb,sc,vv;V(sa,sb,sc,vv);V(sa,sb,sc,vv);printf(sa=%dnsb=%dnsc=%dnvv=%dn,printf(sa=%dnsb=%dnsc=%dnvv=%dn,sa,sb,sc,vv);sa,sb,sc,vv);6.3文件包含文件包含 文件包含是C预处理程序的另一个重要功能。#include命令告诉预处理程序,将其后面所跟的文件的内容插入到当前文件中。即把指定的文

15、件插入该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连成一个源文件。#include命令行的两种形式为:#include#include 文件名 例如:#include stdio.h#include math.h 对文件包含命令还要说明以下几点:1.包含命令中的文件名可以用双引号括起来,也可以用尖括号括起来。例如以下写法都是允许的:#include stdio.h#include 但是这两种形式是有区别的:使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的),而不在源文件目录去查找;使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找

16、。用户编程时可根据自己文件所在的目录来选择某一种命令形式。2.一个include命令只能指定一个被包含文件,若有多个文件要包含,则需用多个include命令。3.文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。#includevoidp().File1.c#includevoids().File2.c#includevoidmain().File3.c6.4条件编译条件编译 预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。条件编译有三种形式,下面分别介绍:1.第一种形式:#ifdef 标识符 程序

17、段1#else 程序段2#endif#ifdef 标识符 程序段#endif2.第二种形式:#ifndef 标识符 程序段1#else 程序段2#endif 与第一种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。这与第一种形式的功能正相反。3.第三种形式:#if 常量表达式 程序段1#else 程序段2#endif它的功能是,如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。【例6.12】#define R 1main()f

18、loat c,r,s;printf(input a number:);scanf(%f,&c);#if R r=3.14159*c*c;printf(area of round is:%fn,r);#else s=c*c;printf(area of square is:%fn,s);#endif本例中采用了第三种形式的条件编译。在程序第一行宏定义中,定义R为1,因此在条件编译时,常量表达式的值为真,故计算并输出圆面积。上面介绍的条件编译当然也可以用条件语句来实现。但是用条件语句将会对整个源程序进行编译,生成的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目

19、标程序较短。如果条件选择的程序段很长,采用条件编译的方法是十分必要的。6.5本章小结本章小结1.预处理功能是语言特有的功能,它是在对源程序正式编译前由预处理程序完成的。程序员在程序中用预处理命令来调用这些功能。2.宏定义是用一个标识符来表示一个字符串,这个字符串可以是常量、变量或表达式。在宏展开时用该字符串代换宏名。3.宏定义可以带有参数,宏展开时是以实参代换形参。而不是“值传送”。4.为了避免宏代换时发生错误,宏定义中的字符串应加括号,字符串中出现的形式参数两边也应加括号。5.文件包含是预处理的一个重要功能,它可用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。6.条件编译允

20、许只编译源程序中满足条件的程序段,使生成的目标程序较短,从而减少了内存的开销并提高了程序的效率。7.使用预处理功能便于程序的修改、阅读、移植和调试,也便于实现模块化程序设计。再见!本章练习一、选择题以下叙述不正确的是_A)预处理命令行都必须以#号开始B)在程序中凡是以#号开始的语句行都是预处理命令行C)C程序在执行过程中对预处理命令行进行处理D)以下是正确的宏定义E)#defineIBM_PC2.以下叙述中正确的是_A)在程序的一行上可以出现多个预处理命令行B)使用带参的宏时,参数的类型应与宏定义时的一致C)宏替换不占用运行时间,只占编译时间D)在以下定义中CR是称为“宏名”的标识符E)#de

21、fineCR0453.请读程序:#defineADD(x)x+xmain()intm=1,n=2,k=3;intsum=ADD(m+n)*k;printf(“sum=%d”,sum);上面程序的运行结果是_A)sum=9B)sum=10C)sum=12D)sum=184.以下程序的运行结果是_#defineMIN(x,y)(x)(y)?(x):(y)main()inti=10,j=15,k;k=10*MIN(i,j);printf(“%dn”,k);A)10B)15C)100D)1505.在宏定义#definePI3.14159中,用宏名PI代替一个_A)常量B)单精度数C)双精度数D)字符串

22、E)6.以下有关宏替换的叙述不正确的是_F)宏替换不占用运行时间G)宏名无类型H)宏替换只是字符替换I)宏名必须用大写字母表示7.以下程序的运行结果是_#include“stdio.h”#defineFUDGE(y)2.84+y#definePR(a)printf(“%d”,(int)(a)#definePRINT1(a)PR(a);putchar(n)/*宏定义可以嵌套*/main()intx=2;PRINT1(FUDGE(5)*x);A)11B)12C)13D)158.C语言的编译系统对宏命令的处理是_A)在程序运行时进行的B)在程序连接时进行的C)和C程序中的其它语句同时进行编译的D)在

23、对源程序中其它成份正式编译之前进行的9.若有宏定义如下:#defineX5#defineYX+1#defineZY*X/2则执行以下printf语句后,输出结果是_inta;a=Y;printf(“%dn”,Z);printf(“%dn”,-a);A)7B)12C)12D)7B)665510.若有以下宏定义:#defineN2#defineY(n)(N+1)*n)则执行语句z=2*(N+Y(5);后的结果是_A)语句有错误B)z=34C)z=70D)z无定值11.若有宏定义:#defineMOD(x,y)x%y则执行以下语句后的输出为_intz,a=15,b=100;z=MOD(b,a);pr

24、intf(“%dn”,z+);A)11B)10C)6D)宏定义不合法12.#include#defineMUL(x,y)(x)*ymain()inta=3,b=4,c;c=MUL(a+,b+);printf(“%dn”,c);上面程序的输出结果是_A)12B)15C)20D)16#defineLETTER0main()charstr20=“Clanguage”,c;inti;i=0;while(c=stri)!=0)i+;#ifLETTERif(c=A&c=a&c=z)c-=32;#endifprintf(“%c”,c);13.程序的运行程序的运行结果是:结果是:A)ClanguageB)cl

25、anguageC)CLANGUGED)cLANGUGE二、填空题1C语言提供了三种预处理语句,它们是_、_和条件编译。2下面程序中for循环的执行次数是_8_.3#include4#defineN25#defineMN+16#defineNUM(M+1)*M/27voidmain()8intt;9for(t=1;t=NUM;t+)10;113下面程序的输出是_4#definePR(ar)printf(“%d”,ar)5main()6intj,a=1,3,5,7,9,11,13,15,*p=a+5;7for(j=3;j;j-)8switch(j)9case1:10case2:PR(*p+);br

26、eak;11case3:PR(*(-p);12134分析下面的程序,给出结果var.h文件intM1,M2;/*通过全局变量可以在主调函数和被调用函数之间可以数据传递*/inta55;disp.c文件的内容如下所示:#include#includevar.hmain()voidsolve();inti,j;for(i=0;i5;i+)for(j=0;j5;j+)scanf(“%d”,&aij);solve();printf(“M1=%d,M2=%d”,M1,M2);voidsolve()inti,j;M1=a00;M2=a00;for(i=0;i5;i+)for(j=0;j5;j+)if(M1

27、aij)M2=aij;课后习题9.1定义一个带参数的宏,使两个参数的值互换,并写出定义一个带参数的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参,输出已交换程序,输入两个数作为使用宏时的实参,输出已交换后的值。后的值。#defineM(x,y)t=x;x=y;y=t#includevoidmain()inta,b,t;printf(请输入两个整数给请输入两个整数给a和和bn);scanf(%d%d,&a,&b);printf(输入输入a和和b的值为:的值为:%4d%4dn,a,b);M(a,b);printf(交换后交换后a和和b的值为:的值为:%4d%4dn,a,b);9.

28、2输入两个整数,求它们相除的余数,用带参输入两个整数,求它们相除的余数,用带参的宏来实现,编程序。的宏来实现,编程序。#defineM(x,y)x%y#includevoidmain()inta,b;printf(请输入两个整数给请输入两个整数给a和和bn);scanf(%d%d,&a,&b);printf(“a和和b相除的余数为:相除的余数为:%4dn,M(a,b);9.3三角形的面积为三角形的面积为area=sqrt(s*(s-a)*(s-b)*(s-c);其中其中s为周长;为周长;定义两个带参的宏,一个用来求定义两个带参的宏,一个用来求s,另一个宏用来求,另一个宏用来求area,写程序,

29、写程序,在程序中用带实参的宏名来求面积。在程序中用带实参的宏名来求面积。#include#include#defineS(x,y,z)(1.0/2*(x+y+z)#defineAREA(x,y,z)sqrt(S(x,y,z)*(S(x,y,z)-x)*(S(x,y,z)-y)*(S(x,y,z)-z)voidmain()inta,b,c;printf(“请输入三个整数给请输入三个整数给a、b和和c:n”);scanf(%d%d%d,&a,&b,&c);printf(“面积为:面积为:%fn,AREA(a,b,c);9.4给年份给年份year定义一个宏,以判别该年份是否为闰年定义一个宏,以判别该

30、年份是否为闰年#include#defineS(y)(y%4=0&y%100!=0)|(year%400=0)voidmain()intyear;printf(“请输入一个年份请输入一个年份:n”);scanf(%d,&year);if(S(year)printf(“%d是闰年是闰年n”,year);elseprintf(“%d不是闰年不是闰年n”,year);9.6请设计输出实数的格式,包括:请设计输出实数的格式,包括:1)一行输出一行输出1个实数,个实数,2)一行一行输出输出2个实数,个实数,3)一行输出一行输出3个实数。实数用个实数。实数用%6.2f格式输出。格式输出。#include#

31、definePRprintf#defineN“n”#defineD“%6.2f”#defineD1DN#defineD2DDN#defineD3DDDNvoidmain()floata,b,c;printf(“请输入请输入a,b,c的值的值:n”);scanf(“%f%f%f”,&a,&b,&c);PR(D1,a);PR(D2,a,b);PR(D3,a,b,c);9.8分别用函数和带参的宏,从分别用函数和带参的宏,从3个数中找出最大数。个数中找出最大数。/*用带参的宏来实现用带参的宏来实现*/#include#defineMAX(x,y,z)if(xy)max=x;elsemax=y;if(m

32、axy)max=x;elsemax=y;if(max=z)max=z;returnmax;voidmain()inta,b,c;printf(“请输入请输入a,b,c的值的值:n”);scanf(“%d%d%d”,&a,&b&c);printf(“a,b,c的最大值为的最大值为:%dn”,max(a,b,c);9.10用条件编译方法实现以下功能:用条件编译方法实现以下功能:输入一行电报文字,可以任选两种输出:一为原输入一行电报文字,可以任选两种输出:一为原文输出;二为将字母变成其下一字母。用文输出;二为将字母变成其下一字母。用#define命令来控制是否要译成密码,例如:命令来控制是否要译成密

33、码,例如:#defineCHANGE1则输出密码,若则输出密码,若#defineCHANGE0,按原码输出。,按原码输出。#defineCHANGE1#defineN100#includevoidmain()charsN,t;printf(请输入一行字母请输入一行字母n);scanf(%s,s);#ifdefCHANGEfor(t=0;st!=0;t+)st+;if(st=Z&st=z)st-=26;puts(s);#elseputs(s);#endif此课件下载可自行编辑修改,仅供参考!此课件下载可自行编辑修改,仅供参考!感谢您的支持,我们努力做得更好!谢谢感谢您的支持,我们努力做得更好!谢谢

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

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

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁