第7章 编译预处理.ppt

上传人:本田雅阁 文档编号:2120983 上传时间:2019-02-18 格式:PPT 页数:28 大小:176.01KB
返回 下载 相关 举报
第7章 编译预处理.ppt_第1页
第1页 / 共28页
第7章 编译预处理.ppt_第2页
第2页 / 共28页
第7章 编译预处理.ppt_第3页
第3页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《第7章 编译预处理.ppt》由会员分享,可在线阅读,更多相关《第7章 编译预处理.ppt(28页珍藏版)》请在三一文库上搜索。

1、第7章 编译预处理,本章要点 文件包含 宏定义 条件编译 实训指导,概 述,一、编译预处理的概念,C语言允许在程序中使用几种特殊的命令(它们不是一般的C语句),在C编译系统对程序进行通常的编译之前,先对程序中这些特殊命令进行“预处理”,然后将预处理的结果和源程序一起再进行通常的编译处理,以得到目标代码。,二、主要预处理功能,宏定义 ; 文件包含; 条件编译,7.1 文件包含,C语言提供#include命令来实现“文件包含”的操作,其一般形式为:,作用:使编译系统把指定的被包含文件嵌入 到带有#include的源文件中。,“文件包含”示意图,file1.c file2.c file1.c 包含

2、#include“file2.c” B A B A (a) (b) (c),假如file1.c文件中的内容如下: int a,b,c; float m,n,p; char r,s,t; file2.c文件的内容如下: #include“file1.c“ main() 经过编译预处理后,file2.c文件的内容为: int a,b,c; float m,n,p; char r,s,t; main() ,#include “文件名”,先在当前工作目录中去查找,若找不到再到指定的标准目录中去查找。,如:对Turbo C编译系统,先在用户目录下 查找,然后在TCinclude文件夹中查找。,#incl

3、ude ,直接到系统指定的标准目录中去查找。,如:对Turbo C编译系统,直接在TCinclude 文件夹中查找。,在使用编译预处理#include语句时,需要注意的几个问题如下:,(1) 当#include语句指定的文件中的内容发生改变时,包含文件的所有源文件都应该注意重新进行编译等处理。 (2) 文件包括可以嵌套使用,即被包括的文件中还可以使用#include语句。 (3) 由#include语句指定文件中可以包含任何语言成分,通常将经常使用的、具有公共性质的符号常量、带参数的宏定义以及外部变量等集中起来放在这种文件中,这样可以避免一些重复操作。 (4)被包含的文件通常是源文件,而不是目

4、标文件。,根据经验的总结,以下内容放在头文件中比较合适。需要说明的是C语言对此没有强行的规定。 包含指令(嵌套),如: #include 函数声明,如: extern float fun(float x); 类型说明,如: enum bool false,true 常量定义,如: const float pi=3.14159; 数据声明,如: extern int m; 宏定义,如: #define PI 3 .1415926;,7.2.1 无参宏定义,7.2 宏定义,宏名,宏内容,无分号,引例:,#define PI 3.1415926 main() float l,s,r,v; print

5、f(“input radius :”); scanf(“%f”, ,其中 #define PI 3.1415926 作用是指定标识符PI来代表“3.1415926”,宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开中由预处理程序层层代换。 例如: #define N 2 #define M N+1 #define NUM (M+1)*M/2,替换的过程为;NUM=(M+1)*M/2;而M=M+1,也就是说NUM=(N+1+1)*N+1/2。,宏名用做代替一个字符串,不作语法检查;,宏定义的字符串不能以“;”结尾,字符串结束后一 定要换行;, C语言允许宏定义出现在程序中函数外

6、面的任何 位置,但一般情况下它总写在文件的开头。,说明:,宏名一般习惯用大写字母,以便与变量名相区别;,在进行宏定义时,可以引用已定义的宏名;,(6)宏名的前后应有空格,以便准确地辨认宏名,如果没有留空格,则程序运行的结果会出错。,说明:,宏替换由编译程序预先进行;,宏替换范围是除字符串以外的所有宏名字;,若替换后文本串中仍含有宏名字,将再次进 行替换,直到程序中不含宏名字为止。,#define PI 3.1415926 #define R 3.0 #define L 2*PI*R #define S PI*R*R,第一次替换:printf(“l=%f ns=%fn“, 2*PI*R, PI*

7、R*R); 二:printf(“l=%f ns=%fn“, 2*3.1415926*3.0, 3.1415926*3.0*3.0);,main() printf(“l=%f ns=%fn“,L,S); ,7.2.2 有参宏定义,#define PI 3.1415926 #define S(r) PI*r*r main() float r1=3.6, area; area=S(r1); /* S(r1)用PI*r1*r1替换 */ printf(“r=%f area=%fn“,r1,area); ,#define PF(x) x*x /*#define PF(x) (x)*(x) */ /*#d

8、efine PF(x) (x)*(x) */ main() int a=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);,注意替换时不求值, 只是字符串的原样替换,#define MAX(x,y) xy?x:y main() int n1,n2; float f1,f2; scanf(“%d%d%f%f“, ,程序举例:,经预编译宏替换后的printf

9、语句如下:,printf(“maxi=%dmaxf=%f“,n1n2?n1:n2, f1f2?f1:f2);,7.2.3 终止宏定义,宏命令#undef用于终止宏定义的作用域。一般形式为: #unfine 宏名 例如: #define area(r) (PI*r*r) main() #undef area(r) func() 由于在函数func()之前,使用#undef终止宏名area(r)的作用,在函数func()中area(r)不再起作用。#undef也可以用于函数内部。,7.2.4 带参数的宏替换与函数的主要区别,函数调用时,先求出实参表达式的值,然后代入 形参。而使用带参的宏只是进行简

10、单的字符替换。,函数调用是在程序运行时处理的,分配临时的内 存单元。而宏替换则是在编译时进行的,在展开 时并不分配内存单元,不进行值的传递处理,也 没有“返回值”的概念。,函数中函数名及参数均有一定的数据类型,而宏 不存在类型问题,宏名及其参数无类型。,宏替换不占运行时间,只占编译时间,而函数调 用则占运行时间。,例 宏替换与函数调用的区别。 #define MUL(a,b) a+b int m(int a,int b) return (a*b); main() printf(“%dn”,MUL(1+2,5-4); printf(“%dn”,m(1+2,5-4); 程序的运行结果为: 7 3

11、原因显而易见,调用MUL宏时,计算的表达式是1+2*5-4,而调用m函数时,计算的表达式的是(1+2)*(5-4)。,7.3 条 件 编 译,一、使用宏定义的标识符作为编译条件,作用:当所指定的标识符已经被#define 命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。,作用:当所指定的标识符已经被#define 命令定义过,则在程序编译阶段只编译程序段1,,作用:当所指定的标识符未被#define 命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。,例1: #ifdef TURBO #define int int #else #define int short #e

12、ndif,可用于实现程序在不同环境下的兼容性。,例2: #ifdef DEBUG printf(“x=%d,y=%dn”,x,y); #endif,可用于进行程序的调试。,调试过程中,在程序前面加#define DEBUG 调试完成后,将前面的#define DEBUG删除掉,二、使用常量表达式的值作为编译条件,作用:当所指定的表达式为真(非零)时就编译程序段1,否则编译程序段2。,可以事先给定一定条件,使程序在不同的条件下执行不同的功能。,注意:#if和#endif必须配对使用。,带有#elif的条件编译,定义的一般形式为: #if 表达式1 程序段1 #elif表达式2 程序段2 #eli

13、f表达式3 程序段3 #else 程序段n #endif 这里的#elif的含义是“else if”。,程序举例:用同一程序实现大小写字母转换(若定义UP转换为大写),#include “stdio.h“ #define UP main() char s128; gets(s); #ifdef UP strupr(s); #else strlwr(s); #endif puts(s); ,例 输入一个口令,根据需要设置条件编译,使之在调试程序时,按原码输出;在使用时输出“*”号。,#define DEBUG void main() char pass80;int i=1; printf(“np

14、lease input password:“); doi+; passi=getchar(); #ifdef DEBUG putchar(passi); #else putchar(*); #endif while(passi!=r); ,例 #ifdef和#ifndef的使用。 #define TED 10 main() #ifdef TED printf(“hi tedn”); #else printf(“hi anyonen); #endif #ifndef RALPH printf(“RALPH not definedn”); #endif ,程序运行结果为: hi ted RALPH

15、 not defined,7.4 实训指导,实训内容 运行下面的代码,查看不同宏定义所带来的结果。 #include #define area1(a) a*a /*面积错误的宏定义*/ #define area2(a) (a)*(a) /*面积正确的宏定义*/ #define sum1(a) (a)+(a) /*求和错误的宏定义*/ #define sum2(a) (a)+(a) /*求和正确的宏定义*/ #define max(x, y) (x)(y) ? (x) : (y) /*求最大值*/ #define start 1 #define stop 3 #define step 1 voi

16、d main() int i, offset; offset = 2; for(i=start; i=stop; i+=step) /*输出正确的面积值*/ printf(“The right square of%d=%dn“, i+offset, area2(i+offset); /*输出错误的面积值*/ printf(“The wrong square of%d=%dn“, i+offset, area1(i+offset); for(i=start; i=stop; i+=step) printf(“Error add=%d,Right add=%dn“, 5*sum1(i), 5*sum2(i); printf(“Maximum of 2.8 and 3.2 is %fn“, max(2.8, 3.2); /*预处理判断C编译器是否定义了宏_STDC_*/ #ifdef _STDC_ printf(“ ANSI C compliancen“); #else printf(“Not in ANSI C modeln“); #endif ,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1