




已阅读5页,还剩23页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第九章 编译预处理 9.1 宏定义 9.2 “文件包含“处理 1 概述 1. Turbo C的编译过程 TC整个编译过程分两步:编译预处理和正式编译 ; 编译预处理根据编译预处理命令进行; 正式编译在预处理的基础上进行,包括词法、 语法分析和目标代码的生成。 由于TC采用单趟扫描编译,因而在发出编译命 令后,编译预处理和正式编译一次完成,其间不会 产生预处理后的中间文件。 2 2. 预处理命令的分类 主要有三类:宏定义 文件包含 条件编译(改善程序的可移植性) 3. 预处理命令的使用要求 1)以#号打头; 2)不是C语句,而不必以分号结束; 3)通常书写在函数之外、源文件开头; 3 9.1 宏定义 用一个标识符来代表一个字符串; 宏定义分为不带参数和带参数的宏定义。 1. 无参宏定义 一般形式:#define 宏名 宏字符串 其中: 1)define是宏定义命令名; 2)宏名按C标识符命名规则命名,通常字母大写; 3)宏串是不加双引号的字符序列; 4)当宏串为数字串时,宏名又称为符号常量。 4 作用: 在编译预处理阶段,将定义点之后的宏名全部 用宏串替换;替换过程也称为宏展开。 意义: 1)便于参数的修改,一改全改; 2)一次定义可多处引用。 5 例:输入半径r,求圆周长和圆面积。 #define PI 3.141592 main( ) float r, c, s; printf(“Enter radius:“); scanf(“%f“, c=2.0*PI*r; /*展开后: c=2.0*3.141592*r;*/ s=PI*r*r; /*展开后: s=3.141592*r*r;*/ printf(“C=%-10.2fnS=%-10.2fn“, c, s); Enter radius: 1 C=6.28 S=3.14 6 使用说明: 1)利用TC的预处理实用程序CPP.EXE,可仅完成预 编译并产生预编译的中间文件,其扩展名为.i 对上例: 执行CPP.EXE程序对EXA91.C进行预处理: C:TC30CPP C:ZYCCPRGEXA91.C 显示预编译中间文件的内容: C:TC30TYPE EXA91. I 7 2)一个宏命令只能定义一个宏名; 3)宏串中的每个字符都是有效字符; 下例多余字符均导致编译出错: #define PI “3.141592“ 宏展开结果:c=2.0*“3.141592“*r; #define PI 3.141592; 宏展开结果:c=2.0*3.141592; *r; 8 4)宏定义可书写在函数之外的任何位置;一个宏名 的有效范围是定义点开始直到本源文件结束;但 可利用宏终止命令加以限定; 如:#define G 9.8 main( ) 宏名G有效; fun1() main、fun1可引用。 #undef G fun2() 9 5)字符串中与宏名相同的字符不被替换; 6)宏串中可出现已定义的宏名,这种现象称为宏的 嵌套定义; 如:#define R 3.0 #define PI 3.141592 #define C 2.0*PI*R #define S PI*R*R main( ) printf(“C=%fnS=%fn“, C, S); 最终输出项C替换为:2.0*3.141592*3.0 S替换为:3.141592*3.0*3.0 10 例:一程序多处使用相同的输入提示、多处使用相 同的输出格式字符串,为减少书写量,使用宏 定义来实现。 #define PROMPT printf(“Please input data:“) #define FORMAT “Result: %d,%d,%d,%dn“ main( ) int a, b, c, d, e, f; PROMPT; /*宏引用*/ scanf(“%d,%d,%d“, PROMPT; scanf(“%d,%d,%d“, printf(FORMAT, a, b, c, a+b+c); printf(FORMAT, d, e, f, d+e+f); 11 2. 带参数的宏定义 定义一般形式:#define 宏名(形参字串表) 宏串 带参的宏引用:宏名(实参字串表) 其中: 1)形参字串应是宏串的子字串,长度可为1或更大 ; 2)实参字串应与形参字串个数相同; 带参的宏展开过程: 在宏串替换宏引用的过程中,将宏串从左到右 逐一展开,遇到与形参相同的字符串,则用对应的 实参字符串顶替,遇到其它字符则按顺序正常展开 。 12 例:计算以a、b为半径的圆面积之和及以a、b之和 为半径的圆面积。 #define S(r) 3.141592*r*r main( ) float a=2.0, b=3.0, area1, area2, area3; area1=S(a); /*area1=3.141592*a*a;*/ area2=S(b); /*area2=3.141592*b*b;*/ area3=S(a+b); /*area3=3.141592*(a+b)*(a+b);*/ printf(“Total area:%-7.2fn“, area1+area2); printf(“R:%-7.2fCircle area:%-7.2fn“, a+b, area3); 13 带参的宏使用说明: 1)带参的宏展开过程中出现的实参顶替形参是字符 的顶替,而不是值的顶替; 如上例宏引用S(a) : 实参字符a顶替形参字符r,不是a的值2.0顶替r ; 上例宏引用S(a+b) : 实参字符串(a+b)顶替形参字符r; 2)为了保证宏展开的结果符合设计本意,应在宏串 或实参字串中加入必要的括号; 如:#define S(r) 3.141592*(r)*(r) 14 3)宏定义中宏名与参数的括号间不能有空格; 如:#define S (r) 3.141592*(r)*(r) 宏串 由于出现了空格,则认为S是宏名而且无参。 4)TC对宏串中双引号范围内的内容不予替换; 如:#define PR(V) printf(“V=%dt“, V); main( ) int a=1, b=2; PR(a); /*printf(“V=%dt“, a);*/ PR(b); /*printf(“V=%dt“, b);*/ 15 例:计算四边形的面积。 #include “math. h“ #define S(a, b, c) (a+b+c)/2.0 #define AREA(s, a, b, c) sqrt(s*(s-a)*(s-b)*(s-c) float fun(float x, float y, float z) float area, t; t=S(x, y, z); /*t=(x+y+z)/2.0;*/ area=AREA(t, x, y, z); return(area); /*area=sqrt(t*(t-x)*(t-y)*(t-z);*/ main( ) float a, b, c, d, e, area; scanf(“%f,%f,%f,%f,%f“, area=fun(a, b, c)+fun(c, d, e); printf(“*%-7.2fn“, area); 16 例:#define N 2 #define Y(n) (N+1)*n) 执行语句 z=N*(2+Y(5); 后的z值? 宏展开后的语句:z=2*(2+15); z值为34。 例:#define MAX(x,y) (x)(y)?(x):(y) 语句t=MAX(a+b, c+d);的展开结果? 宏展开后的语句: t=(a+b)(c+d)?(a+b):(c+d); 17 9.2 “文件包含“预处理命令 命令一般形式:#include “文件名“ 其中: 1)include是文件包含命令名; 2)文件名指出需要包含的文件名;可是系统头文 件、用户头文件、用户源程序文件的名字; 3)文件名前可带盘符、路径。 作用: 在预编译阶段,将被包含文件的内容包含到本 源文件中,使正式编译的对象是包含后的整体。 18 例:输入半径r,求圆周长和圆面积。 方法:将宏定义等预处理命令编辑在一个用户头文件中 ,并保存在 c:zyccprgMY.H; 将程序函数编辑在源文件EXA95.C中; MY.H: #define PI 3.141592 EXA95.C #include “c:zyccprgmy.h“ /*预编译时将my.h的*/ main( ) /*内容包含到此处*/ float r, c, s; printf(“Enter radius:“); scanf(“%f“, c=2.0*PI*r; s=PI*r*r; DOS printf(“C=%-10.2fnS=%-10.2fn“, c, s); 19 例:求34矩阵最大元素及位置,程序的两个函数分别 编制在MYPRG.C和EXA96.C两个源文件中。 MYPRG.C int fun1(int x4) int i, j, max; max=x00; line=col=0; /*不必对外部变量声明*/ for(i=0; imax) max=xij; line=i; col=j; return(max); 20 EXA96.C int line, col; /*全局变量定义*/ #include “c:zyccprgmyprg.c“/*将myprg.c包含到此*/ main( ) int a34=1,2,3,4,5,6,7,8,9,10,11,12,i,j,max; for(i=0; i的区别 ” ”先在当前目录查找指定的头文件,未找到 再沿TC的设置查找; 仅在TC的设置中查找; 23 函数举例: 例:用自定义函数判断素数;main中输出100200 之间的全部素数。 #include “math.h“ main( ) int num, m, count=0, prime(int); for(num=101; num=199; num=num+2) m=prime(num); if(m) printf(“%5d“,num); count+; if(count%10=0)printf(“n“); 24 main( ) ; for(num=101; num=199; num=num+2) m= prime(num); if(m) ; int prime(int n) int i, k, mark=1; k=sqrt(n); for(i=2; i=k; i+) if(n%i); /*余数非零为真*/ else mark=0; break; return(mark); 25 例:用自定义函数将一方阵在原数组中转置。 #define N 5 main() void change(int a ), parray(int a N); int aNN, i, j; printf(“nEnter A array(%d):“, N*N); for(i=0; iN; i+) for(j=0; jN; j+) scanf(“%d“, printf(“nOld A array:“); parray(a); change(a); /*数组名作实参*/ printf(“nNew A array:“); parray(a); 26 void change(int aNN) int i, j, t; for(i=0; iN; i+) /*以对角线为对称轴交换*/ for(j=0; ji; j+) t=aij; aij=aji; aji=t; return; void parray(int aN) int i, j; for(i=0;iN;i+) printf(“n“); for(j=0;jN;j+) printf(“%5d“, aij); 27
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业危机管理中的创新思维培养研究-洞察及研究
- 环保理念与满意度提升-洞察及研究
- 珠宝品牌年轻化趋势分析-洞察及研究
- 社交媒体营销对纺织服装行业竞争态势的影响-洞察及研究
- 在线合作学习平台的协作分析-洞察及研究
- 社交电商与生鲜融合-洞察及研究
- JJF 1221-2025汽车排气污染物检测用底盘测功机校准规范
- 2025昆明市第一人民医院博士后科研工作站(国家级)招聘(1人)备考考试题库附答案解析
- 2025年9月扬州市广陵区卫生健康系统事业单位公开招聘专业技术人员5人备考考试题库附答案解析
- 2025广东湛江麻章区第二批招聘公益性岗位人员2人备考考试题库附答案解析
- GB 3452.1-1992液压气动用O形橡胶密封圈尺寸系列及公差
- 洁普利康抗HPVβ乳球蛋白高分子生物肽冷敷凝胶课件
- 工程建设项目绿色建造施工水平评价申请表
- 鸡的呼吸道疾病与防治课件
- 八年级数学平方差公式完全平方公式过关练习题
- 八年级英语完形填空解题技巧课件
- 插头插座尺寸标准
- 完整版老旧小区雨污分流改造工程施工组织设计方案
- 《基因工程》课件第一章 基因工程概论
- 德国凯尔锚固技术公司石陶幕墙设计和施工中的应用
- (高清版)外墙饰面砖工程施工及验收规程JGJ126-2015
评论
0/150
提交评论