付费下载
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第九章 预编译处理综述编译:(Alt+F9)对源程序进行词法和语法分析、优化、生成目标代码等。编译预处理(预编译) :在编译前为编译做的准备工作,这是由于预编译命令的要求。C提供三方面的预处理(预编译)功能: 宏定义 文件包含 条件编译所有的预处理命令都是由#开头。8.1 宏定义 不带参数的宏定义一般形式:#define 标识符 字符串例如:#define PI 3.14159注意:没有分号其作用是把源程序中该定义后的所有“标识符”(如PI)都用“字符串”(3.14159)替换。area=a*barea=3*2;2. 带参数的宏定义(宏函数)带参数的宏不是简单的字符串替换,还要进行参数替换。定
2、义形式:#define 宏名(参数表)字符串例如:#define S(a, b) a*b area=S(3, 2); 带参数的宏展开过程是:1)用字符串替换程序中的宏名。2)用实参替换字符串中的形参。返回 宏定义说明:1 习惯上宏名用大写字母。2 宏定义是用宏名代替字符串,是简单置换,不做语法检查。如#define PI 3.14edf。语法上也是对的。3 宏定义不是语句,不加分号,因为分号也会成为替换的一部分。4 #define命令出现在程序中函数的外面,宏名的有效范围是定义之后到本源文件结束。通常#define写在文件开头,函数之前。5 可以用#undef命令终止宏定义的作用域。6 在定义
3、宏时,可以引用已定义的宏名,层层置换。例:#include#define R 3.0#define PI 3.14159#define L 2*PI*R#define S PI*R*Rvoid main()printf(“L=%fnS=%fn”, L, S);7 对程序中用双引号引起的显式字符串即便和宏名相同也不进行置换。8. 宏定义与变量定义不同,只做字符串替换,不占内存单元。返回宏定义例题#include#define PI 3.1415926#define S(r) PI*r*rvoid main() float a, area; a=3.6; area=S(a); printf(“r=
4、%fnarea=%fn”, a, area);area=S(a);展开得结果是area=3.1415926*a*a;S(r)=PI*r*rArea=S(a)=PI*a*a=3.1415926*3.6*3.6说明:1 宏展开是简单的替换,带参数的宏同样如此。#define S(r) PI*r*r area=S(a+b); area=PI*a+b*a+b; #define S(r) PI*(r)(r) area=S(a+b); area=PI*(a+b)*(a+b);2 在宏定义时,在宏名和参数的括弧间不应加空格,否者系统会把括弧、参数及后面的字符串都理解为进行替换的字符串。 #define S
5、(r) PI*r*r -作为字符串替换调用时,若宏名和参数的括弧间有空格area=S (a); 则,area= (r) PI*r*r (a)无参宏定义说明宏函数和普通函数机制上的不同:1 普通函数调用时,先求出实参表达式的值,再带入形参;而宏函数只是进行简单替换。如:area=S(a+b); 如果S( )是普通函数,先求出a+b的值再带入形参; 如果S( )是宏,直接进行a+b的替换。2 函数调用是在程序运行时完成的,动态分配临时内存单元。宏展开则是在编译时进行的,在展开时并不分配内存,不进行值的传递处理,也没有“返回值”的概念。内存单元的分配也是运行时完成的,回顾宏展开的过程便可理解。3 函
6、数中形参和实参要求类型一致,函数也有返回值类型,而宏定义中没有任何类型问题,只是一个符号代表,展开时是简单的替换。因为宏定义中,宏名也应理解为字符串。4 调用普通函数只可以得到一个返回值,而宏可以设法得到几个结果。#define PI 3.1415926#define CIRCLE(R, L, S, V) L=2*PI*R; S=PI*R*R; V=4.0/3.0*PI*R*R*Rvoid main()float r, l, s, v;scanf(“%f”, &r);CIRCLE(r,l,s,v);printf(“r=%6.2f, l=%6.2f, v=%6.2fn”, r, l, s, v)
7、;宏CIRCLE(r, l, s, v);的过程是:1) L=2*PI*R; S=PI*R*R; V=4.0/3.0*PI*R*R*R 2) l=2*3.1415926*r; s=3.1415926*r*r; v=4.0/3.0*3.1415926*r*r*r;可以通过宏带回l, s, v三个值。5 过多的宏,展开后源程序会变长,而函数调用不会使源程序变长。6 宏替换不占用运行时间,只占用编译时间。而函数调用占用较多的运行时间(分配单元、保留现场-调用点的地址、值传递、返回)。一般来说,用宏代表简单的表达式,而有些用宏和函数均可。#define MAX(x,y) (x)(y)?(x):(y)M
8、ain()int a,b,c,d,t;t=MAX(a+b,c+d);Int max(int x,int y)return(xy?x:y);Main()int a,b,c,d,t;t=max(a+b,c+d);展开后 t=(a+b)(c+d)?(a+b):(c+d)如果善于利用宏,可以使程序简单化。#define PR printf #define NL n #define D %dt #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S %s #include void mai
9、n() int a, b, c,d; char string=CHINA; a=1; b=2; c=3; d=4; PR(D1, a); PR(D2, a, b); PR(D3, a, b, c); PR(D4, a, b, c, d); PR(S, string); 1121231234CHINA返回9.2 “文件包含”处理 “文件包含”处理是指一个源文件可以将另一个源文件包含(插入)进来的处理。它等价于先将两个源文件合并成一个源文件,然后再编译。两个编译后的目标文件是完全一样的。 一般形式是:#include “文件名” #include #include ABBA相当于File1.cFi
10、le2.cFile1.c包含注意:包含处理是在编译时完成的,当被包含的文件修改后,所有包含它的文件必须全部重新编译。#define PR printf #define NL n #define D %dt #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S %s #include #include “format.h”void main() int a, b, c,d; char string=CHINA; a=1; b=2; c=3; d=4; PR(D1, a); PR(
11、D2, a, b); PR(D3, a, b, c); PR(D4, a, b, c, d); PR(S, string); format.h文件:file1.c文件:说明:1 一个include命令只能指定一个被包含的文件,如果要包含多个文件,要用多个include命令。2 如果file1包含file2,file2用到file3的内容,则可在file1中分别include file2和file3,且file3在file2之前包含(因为file2中用到file3)。即file1中应是: #include “file3.c” #include “file2.c”3 在一个被包含文件中可以包含另一
12、个被包含文件,即文件包含是可以嵌套的。上一个问题可以是: 在 file1中有预处理命令 #include “file2.c” 在 file2中有预处理命令 #include “file3.c”返回 4. 在#include命令中,文件名可以用双引号或尖括号,二者的区别是: 用双引号:系统先在引用被包含文件的源程序文件(file1)所在目录中寻找被包含文件,若找不到,再按系统指定的方式检索其它目录。 而用尖括号:不检索file1所在目录,直接检索系统指定的目录。 5. 被包含文件(file2)与包含文件(file1)在预编译后成为一个文件,因此,如果file2中有全局静态变量,它也在file1中
13、有效,不必用extern说明。9.3 条件编译通常源程序的所有语句都被编译,但有时希望根据不同条件编译不同部分,这就是条件编译。条件编译命令有以下几种形式:1#ifdef 标识符 (判断此前是否用#define定义过了“标识符”) 程序段1 #else程序段2 #endif 功能:当所指定的标识符已经被#define定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。其中部分#else可以省略。 这种条件编译对于提高C源程序的通用性是很有用的。如我们编写一个可能应用于不同机型的应用程序,但不同机型的整型数位数不同,我们可以用如下的条件编译:#ifdefIBM-PC (判断此前是否用#define定义过“IBM-PC”)#defineINTEGER_SIZE16#else#defineINTEGER_SIZE32#endif定义过未定义过功能:当所指定的标识符未被#define定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。2#ifndef标识符程序段1 #else程序段2 #endif3#if表达式程序段1 #else程序段2 #endif功能:当表达式的值为真,编译程序段1,否则编译程序段2。例题:输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 儿童噎食的预防与家庭护理
- 2026年山谷中的秘密 测试题及答案
- 2026年共角模型测试题及答案
- 2026年自我监控量表测试题及答案
- 2026年学习《特种作业人员安全技术培训考核管理规定》心得感悟
- 2026年非法智慧测试题加答案
- 2026年北大博雅计划英语测试题及答案
- 呼吸衰竭的紧急处理流程
- 装修公司毕业论文
- 2026年飞行员性格测试题及答案
- 2026新教材语文 22《〈礼记〉二则-大道之行也》教学课件
- 浙江省Z20联盟2026届高三年级第三次学情诊断日语+答案
- 2026湖北供销集团有限公司招聘66人考试模拟试题及答案解析
- 2025年书记员速录技能考试真题及答案
- 2026年卫生统计学模拟试题+参考答案
- (2026年)共青团入团考试试题(含答案)
- 2026年夏令营行业分析报告及未来发展趋势报告
- 总包对分包的管理排查清单
- 2026中考英语:历年中考易错题
- 2026年湖南娄底市中考生物试题及答案
- 政治(广东卷02)(考试版及全解全析)-2026年高考考前预测卷
评论
0/150
提交评论