您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 电工电子技术基础教程(第2版)第8章
第8章编译预处理本章要点熟练掌握include命令的含义和用法理解#define命令的使用了解各种条件编译(#if、#else、#endif、#ifdef和#undef等)的意义及用法本章难点文件包含命令#include的使用带参宏与函数的区别区分条件编译预处理指令的使用场合概述一、编译预处理的概念C语言允许在程序中使用几种特殊的命令(它们不是一般的C语句),在C编译系统对程序进行通常的编译之前,先对程序中这些特殊命令进行“预处理”,然后将预处理的结果和源程序一起再进行通常的编译处理,以得到目标代码。二、主要预处理功能⑴宏定义;⑵文件包含;⑶条件编译8.1.1无参宏作用:用标识符来代表一个字符串。8.1宏定义宏名宏内容无分号宏:是对正文进行代入或嵌入的一种功能。即从一字符流中取出某个字符串去代替源程序里的标识符。1.一般形式:#define标识符字符串引例:#definePI3.1415926main(){floatl,s,r,v;printf(“inputradius:”);scanf(“%f”,&r);l=2.0*PI*r;s=PI*r*r;v=3.0/4*PI*r*r*r;printf(“l=%10.4f\ns=%10.4f\nv=%10.4f\n”,l,s,v);}其中#definePI3.1415926作用是指定标识符PI来代表“3.1415926”⑵宏名用做代替一个字符串,不作语法检查;⑶宏定义的字符串不能以“;”结尾,字符串结束后一定要换行;⑸C语言允许宏定义出现在程序中函数外面的任何位置,但一般情况下它总写在文件的开头。说明:⑴宏名一般习惯用大写字母,以便与变量名相区别;⑷在进行宏定义时,可以引用已定义的宏名;说明:⑴宏替换由编译程序预先进行;⑵宏替换范围是除字符串以外的所有宏名字;⑶若替换后文本串中仍含有宏名字,将再次进行替换,直到程序中不含宏名字为止。#definePI3.1415926#defineR3.0#defineL2*PI*R#defineSPI*R*R•宏替换(宏展开):用宏内容(字符串)原样代换程序中的所有宏名字的过程。第一次替换:printf(l=%f\ns=%f\n,2*PI*R,PI*R*R);二:printf(l=%f\ns=%f\n,2*3.1415926*3.0,3.1415926*3.0*3.0);main(){printf(l=%f\ns=%f\n,L,S);}8.1.2带参宏一般形式:#define宏名(宏形参数表)字符串作用:宏替换时以实参数替代形参数。#definePI3.1415926#defineS(r)PI*r*rmain(){floatr1=3.6,area;area=S(r1);/*S(r1)用PI*r1*r1替换*/printf(r=%farea=%f\n,r1,area);}注意:宏替换后,程序的原意表达。#definePF(x)x*x/*#definePF(x)(x)*(x)*//*#definePF(x)((x)*(x))*/main(){inta=2,b=3,c;c=PF(a+b)/PF(a+1);printf(\nc=%d,c);}按第一种宏定义:c=a+b*a+b/a+1*a+1;按第二种宏定义:c=(a+b)*(a+b)/(a+1)*(a+1);按第三种宏定义:c=((a+b)*(a+b))/((a+1)*(a+1));注意替换时不求值,只是字符串的原样替换带参数的宏替换与函数的主要区别⑴函数调用时,先求出实参表达式的值,然后代入形参。而使用带参的宏只是进行简单的字符替换。⑵函数调用是在程序运行时处理的,分配临时的内存单元。而宏替换则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。⑷函数中函数名及参数均有一定的数据类型,而宏不存在类型问题,宏名及其参数无类型。⑶宏替换不占运行时间,只占编译时间,而函数调用则占运行时间。#defineMAX(x,y)xy?x:ymain(){intn1,n2;floatf1,f2;scanf(%d%d%f%f,&n1,&n2,&f1,&f2);printf(maxi=%dmaxf=%f,MAX(n1,n2),MAX(f1,f2));}程序举例:经预编译宏替换后的printf语句如下:printf(maxi=%dmaxf=%f,n1n2?n1:n2,f1f2?f1:f2);8.1.3终止宏定义宏命令#undef用于终止宏定义的作用域。一般形式为:#unfine宏名例如:#definearea(r)(PI*r*r)main(){……}#undefarea(r)func(){……}由于在函数func()之前,使用#undef终止宏名area(r)的作用,在函数func()中area(r)不再起作用。#undef也可以用于函数内部。8.2文件包含命令“文件包含“:是指一个源文件可以将另外一个源文件的全部内容包含进来。C语言提供#include命令来实现“文件包含”的操作,其一般形式为:#include“文件名”#include文件名或作用:使编译系统把指定的被包含文件嵌入到带有#include的源文件中。“文件包含”示意图file1.cfile2.cfile1.c包含#include“file2.c”BABA(a)(b)(c)假如file1.c文件中的内容如下:inta,b,c;floatm,n,p;charr,s,t;file2.c文件的内容如下:#includefile1.cmain(){……}经过编译预处理后,file2.c文件的内容为:inta,b,c;floatm,n,p;charr,s,t;main(){……}包含文件的查找方法:#include“文件名”先在当前工作目录中去查找,若找不到再到指定的标准目录中去查找。如:对TurboC编译系统,先在用户目录下查找,然后在TC\include文件夹中查找。#include文件名直接到系统指定的标准目录中去查找。如:对TurboC编译系统,直接在TC\include文件夹中查找。在使用编译预处理#include语句时,需要注意的几个问题如下:(1)当#include语句指定的文件中的内容发生改变时,包含文件的所有源文件都应该注意重新进行编译等处理。(2)文件包括可以嵌套使用,即被包括的文件中还可以使用#include语句。(3)由#include语句指定文件中可以包含任何语言成分,通常将经常使用的、具有公共性质的符号常量、带参数的宏定义以及外部变量等集中起来放在这种文件中,这样可以避免一些重复操作。(4)被包含的文件通常是源文件,而不是目标文件。8.3条件编译条件编译:根据条件选择被编译的源程序行。•使用宏定义的标识符作为编译条件•使用常量表达式的值作为编译条件一、使用宏定义的标识符作为编译条件#ifdef标识符程序段1#else程序段2#endif形式一:作用:当所指定的标识符已经被#define命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。#ifdef标识符程序段1#endif形式二:作用:当所指定的标识符已经被#define命令定义过,则在程序编译阶段只编译程序段1,#ifndef标识符程序段1#else程序段2#endif形式三:作用:当所指定的标识符未被#define命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。例1:#ifdefTURBO#defineintint#else#defineintshort#endif可用于实现程序在不同环境下的兼容性。例2:#ifdefDEBUGprintf(“x=%d,y=%d\n”,x,y);#endif可用于进行程序的调试。调试过程中,在程序前面加#defineDEBUG调试完成后,将前面的#defineDEBUG删除掉二、使用常量表达式的值作为编译条件#if表达式程序段1#else程序段2#endif形式:作用:当所指定的表达式为真(非零)时就编译程序段1,否则编译程序段2。可以事先给定一定条件,使程序在不同的条件下执行不同的功能。注意:#if和#endif必须配对使用。带有#elif的条件编译定义的一般形式为:#if表达式1程序段1#elif表达式2程序段2#elif表达式3程序段3……#else程序段n#endif这里的#elif的含义是“elseif”。程序举例:用同一程序实现大小写字母转换(若定义UP转换为大写)#includestdio.h#defineUPmain(){chars[128];gets(s);#ifdefUPstrupr(s);#elsestrlwr(s);#endifputs(s);}例输入一个口令,根据需要设置条件编译,使之在调试程序时,按原码输出;在使用时输出“*”号。#defineDEBUGvoidmain(){charpass[80];inti=1;printf(\npleaseinputpassword:);do{i++;pass[i]=getchar();#ifdefDEBUGputchar(pass[i]);#elseputchar('*');#endif}while(pass[i]!='\r');……}8.4小结(1)C语言的宏定义可以分为两种形式:一种是带参数的宏定义;另一种是不带参数的宏定义。(2)所谓文件包含预处理,是指在一个文件中将另外一个文件的全部内容包含进来的处理过程,即将另外的文件包含到本文件中。(3)一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只有在满足一定条件下才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。
本文标题:电工电子技术基础教程(第2版)第8章
链接地址:https://www.777doc.com/doc-1738540 .html