资源描述:
《c语言第9章预处理》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、教学内容:9.1宏处理9.2文件包含9.3条件编译教学要求:1.理解预处理功能在程序设计中的作用。2.掌握宏定义的使用。3.掌握文件包含、条件编译的应用。第9章预处理编译预处理编译预处理是指,在对源程序进行编译之前,系统将自动引用预处理程序对源程序中的预处理部分作处理;然后再将处理的结果,和源程序一起进行编译,以得到目标代码。编辑编译连接运行预处理宏定义是由源程序中的宏定义命令完成的。宏代换(宏展开)字符串的工作量1.不带参数的宏定义(1)无参宏定义的一般格式#define标识符语言符号字符串9.1宏处理define:为宏定义关键字;标识符:定义
2、的宏名,通常用大写字母取名,以便于与变量区别;语言符号字符串:即宏体,可以是常数、表达式、格式串等。例如:#definePI3.1415926定义了一个符号常量PI,表示用标识符PI替换3.1415926。在编译预处理时,会将程序代码中所有的PI都用3.1415926替换。2.关于不带参数的宏定义的几点说明:(1)宏名一般用大写字母表示,便于与变量名区别;一般将字符个数较多的字符串用一个宏名替换,减少程序中多处引用字符串书写错误。(2)宏定义是用宏名来表示一个字符串,在宏展开时以该字符串取代宏名,这只是一种简单的代换,预处理程序对它不作任何检查。
3、如有错误,只能在编译源程序时才能发现。(3)宏定义不是语句,在行末不加分号,如加上分号则连分号也一起置换。(4)宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。例如:#definePI3.14159main(){……}#undefPI/*终止宏定义PI*/min(){....}表示PI只在main函数中有效,在min中无效。(5)在源程序中用双引号括起来宏名,预处理程序不对其作宏代换。(6)宏定义可以嵌套,但嵌套的宏定义名要是已经定义的宏名。在宏展开时由预处理程序层层替换。例如:#defineR
4、14.256#definePI3.1415926#defineSPI*R*R/*PI、R是已定义的宏名*/则语句printf("%f",s);在宏代换后变为:printf("%f",3.1415926*14.256*14.256);例9.1不带参数的宏的程序#include#definePI3.115926#defineSTRINGThisisatestmain(){floatr,s;printf("STRING");scanf("%f",&r);while(r>0){s=PI*r*r;printf("s=%10.3f"
5、,s);scanf("%f",&r);}}宏定义不是C语句,所以不能在行尾加分号。否则,宏展开时,会将分号作为宏体中的1个字符。在宏展开时,预处理程序仅以宏体替换宏名,而不作任何检查例9.2#defineN2#defineMN+1#defineNUM2M+1main(){inti;for(i=1;i<=NUM;i++)printf(“%d”,i);}宏展开后的等价程序如下:main(){inti;/*NUM展开后2*2+1+1*/for(i=1;i<=6;i++)printf(“%d”,i);}NUM宏展开:2*N+1+1再宏展开:2*
6、2+1+13.带参宏定义(1)带参宏定义格式:#define宏名(形参表)宏体(2)带参宏调用格式:宏名(实参表)(3)宏展开:用宏调用提供的实参字符串,直接置换宏定义命令行中相应形参字符串,非形参字符保持不变带参宏定义说明(1)定义有参宏时,宏名与左圆括号之间不能留有空格。否则,C编译系统将空格以后的所有字符均作为替代字符串,而将该宏视为无参宏。(2)有参宏的展开,只是将实参作为字符串,简单地置换形参字符串,而不做任何语法检查。例9.3带参数的宏#include#defineF(a)a*a/*宏名F,形参a*/main(){i
7、ntx=3,y=4,b,z;b=x+y;z=F(x+y);/*展开为:z=x+y*x+y;*/printf("b=%dz=%d",b,z);}4.带参的宏和带参函数区别(1)在函数调用时,是先求出实参表达式的值,再传递给形参,而宏定义只是简单的字符替换;(2)函数调用是在程序运行时处理的,分配存储单元,而宏展开(调用)是在编译预处理时进行的,展开时不分配内存单元,不进行值传递,没有返回值的概念;(3)对函数实参和形参都要定义类型,而宏不存在类型,宏定义时字符串可以是任何类型数据,一律看成字符串,宏名也没类型,只是一个符号表示,展开时代入指
8、定的符号即可。(4)定义带参数的宏,可以实现一些简单的函数功能。#defineMAX(x,y)(x)>(y)?(x):(y)main(