C程序设计第九章

上传人:s9****2 文档编号:569392248 上传时间:2024-07-29 格式:PPT 页数:23 大小:104KB
返回 下载 相关 举报
C程序设计第九章_第1页
第1页 / 共23页
C程序设计第九章_第2页
第2页 / 共23页
C程序设计第九章_第3页
第3页 / 共23页
C程序设计第九章_第4页
第4页 / 共23页
C程序设计第九章_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《C程序设计第九章》由会员分享,可在线阅读,更多相关《C程序设计第九章(23页珍藏版)》请在金锄头文库上搜索。

1、第九章第九章 预处理命令预处理命令1 .掌握编译预处理的概念和特点掌握编译预处理的概念和特点;2. 掌握掌握“文件包含文件包含”的概念和使用的概念和使用;3. 掌握不带参数的宏定义及其使用,掌握不带参数的宏定义及其使用, 了解带参数的宏定义及其使用。了解带参数的宏定义及其使用。概概 述述一、编译预处理的概念一、编译预处理的概念 C语言允许在程序中使用几种特殊的命令语言允许在程序中使用几种特殊的命令(它们不是一般的(它们不是一般的C语句),在语句),在C编译系统对编译系统对程序进行通常的编译之前,先对程序中这些特程序进行通常的编译之前,先对程序中这些特殊命令进行殊命令进行“预处理预处理”,然后将

2、预处理的结果,然后将预处理的结果和源程序一起再进行通常的编译处理,以得到和源程序一起再进行通常的编译处理,以得到目标代码。目标代码。二、主要预处理功能二、主要预处理功能宏定义宏定义 ; 文件包含;文件包含; 条件编译条件编译一、不带参数的宏定义及宏替换一、不带参数的宏定义及宏替换作用:作用: 用标识符来代表一个字符串。用标识符来代表一个字符串。9.1 宏定义宏定义宏名宏名宏内容宏内容无分号无分号宏宏:是对正文进行代入或嵌入的一种功能。即从是对正文进行代入或嵌入的一种功能。即从 一字符流中取出某个字符串去代替源程序里一字符流中取出某个字符串去代替源程序里 的标识符。的标识符。1.一般形式一般形式

3、: #define #define 标识符标识符 字符串字符串引例引例:#define PI 3.1415926main() float l,s,r,v; printf(“input radius :”); scanf(“%f”,&r); l=2.0*PI*r; s=PI*r*r; v=3.0/4*PI*r*r*r; printf(“l=%10.4fns=%10.4fnv=%10.4fn”,l,s,v); 其中其中 #define PI 3.1415926 作用是指定标识符作用是指定标识符PI来代表来代表“3.1415926”宏宏名用做代替一个字符串,不作语法检查;名用做代替一个字符串,不作语

4、法检查;宏定义的字符串不能以宏定义的字符串不能以“;”结尾,字符串结束后结尾,字符串结束后一一 定要换行定要换行;宏定义的有效范围为定义之处到宏定义的有效范围为定义之处到#undef命令终止,命令终止, 如果没有如果没有#undef命令,则有效范围到本文结束;命令,则有效范围到本文结束;C语言允许宏定义出现在程序中函数外面的任何语言允许宏定义出现在程序中函数外面的任何 位置,但一般情况下它总写在文件的开头。位置,但一般情况下它总写在文件的开头。说明:说明:宏名一般习惯用大写字母,以便与变量名相区别;宏名一般习惯用大写字母,以便与变量名相区别;#undef命令形式:命令形式:#undef 标识符

5、标识符在进行宏定义时,可以引用已定义的宏名;在进行宏定义时,可以引用已定义的宏名; 说明:说明:宏替换由编译程序预先进行;宏替换由编译程序预先进行; 宏替换范围是宏替换范围是除字符串以外除字符串以外的所有宏名字;的所有宏名字;若替换后文本串中仍含有宏名字,将再次进若替换后文本串中仍含有宏名字,将再次进 行替换,直到程序中不含宏名字为止。行替换,直到程序中不含宏名字为止。 #define PI 3.1415926#define R 3.0#define L 2*PI*R#define S PI*R*R宏替换宏替换(宏展开宏展开) :用宏内容(字符串)原样代:用宏内容(字符串)原样代 换程序中的所

6、有宏名字的过程。换程序中的所有宏名字的过程。 第一次替换:第一次替换:printf(l=%f ns=%fn, 2*PI*R, PI*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);二、带参数的宏定义及宏替换二、带参数的宏定义及宏替换 一般形式一般形式: #define #define 宏名(宏形参数表)宏名(宏形参数表) 字符串字符串作用:作用: 宏替换时以实参数替代形参数。宏替换时以实参数替代形参数。#define PI 3.1415926#def

7、ine S(r) PI*r*rmain()float r1=3.6, area;area=S(r1); /* S(r1)用PI*r1*r1替换 */printf(r=%f area=%fn,r1,area);(1)对带参数的宏展开只是将语句中的宏名后对带参数的宏展开只是将语句中的宏名后面括号内的实参字符串代替面括号内的实参字符串代替#define命令行命令行中的行参。中的行参。(2)有时候为了得到正确结果,在字符串中的有时候为了得到正确结果,在字符串中的形式参数外面加一个括弧。形式参数外面加一个括弧。(3)宏名与带参数的括弧之间不加空格,否则宏名与带参数的括弧之间不加空格,否则将空格以后的字符

8、都作为替代字符串一部分。将空格以后的字符都作为替代字符串一部分。例:例: define S_(r)_ PI*r*r area = S_(a);相当于:相当于: area = (r)_ PI*r*r_(a);说明:说明:注意:注意: 宏替换后,程序的原意表达。宏替换后,程序的原意表达。#define PF(x) x*x /* #define PF(x) (x)*(x) */* #define 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;按

9、第二种宏定义:c=(a+b)*(a+b)/(a+1)*(a+1);按第三种宏定义:c=(a+b)*(a+b)/(a+1)*(a+1);注意替换时不求值,注意替换时不求值,只是字符串的原样替换只是字符串的原样替换例例: :分析程序写出结果分析程序写出结果. .#define M#define M3 3#define N#define NM+2M+2#define S(N)#define S(N)N*N*NN*N*Nmain()main() printf(“%dn”,S(Nprintf(“%dn”,S(N););3+2*3+2*3+23+2* *3+23+2运行结果为:运行结果为:17三、带参数的

10、宏替换与函数的主要区别三、带参数的宏替换与函数的主要区别函数调用时,先求出实参表达式的值,然后代入函数调用时,先求出实参表达式的值,然后代入 形参。而使用带参的宏只是进行简单的字符替换。形参。而使用带参的宏只是进行简单的字符替换。函数调用是在程序运行时处理的,分配临时的内函数调用是在程序运行时处理的,分配临时的内 存单元。而宏替换则是在编译时进行的,在展开存单元。而宏替换则是在编译时进行的,在展开 时并不分配内存单元,不进行值的传递处理,也时并不分配内存单元,不进行值的传递处理,也 没有没有“返回值返回值”的概念。的概念。函数中函数名及参数均有一定的数据类型,而宏函数中函数名及参数均有一定的数

11、据类型,而宏 不存在类型问题,宏名及其参数无类型。不存在类型问题,宏名及其参数无类型。宏替换不占运行时间,只占编译时间,而函数调宏替换不占运行时间,只占编译时间,而函数调 用则占运行时间。用则占运行时间。#define MAX(x,y) xy?x:ymain()int n1,n2;float f1,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

12、?n1:n2, f1f2?f1:f2);例例: :分析程序写出结果:分析程序写出结果:#define PR #define PR printfprintf#define NL “n”#define NL “n”#define D “%d”#define D “%d”#define D1 D NL#define D1 D NL#define D2 D D NL#define D2 D D NL#define D3 D D D NL#define D3 D D D NL#define D4 D D D D NL#define D4 D D D D NL#define S “%s”#define S

13、 “%s”main()main() intint a,b,c,d; a,b,c,d; char char strstr=“CHINA”;=“CHINA”; a=1,b=2,c=3,d=4; a=1,b=2,c=3,d=4; PR(D1,a); PR(D1,a); PR(D2,a,b); PR(D2,a,b); PR(D3,a,b,c); PR(D3,a,b,c); PR(D4,a,b,c,d); PR(D4,a,b,c,d); PR(S,strPR(S,str);); 9.2 “文件包含文件包含”处理处理“文件包含文件包含”:是指一个源文件可以将另外一是指一个源文件可以将另外一个个 源文件的全

14、部内容包含进来。源文件的全部内容包含进来。C语言提供语言提供#include命令来实现命令来实现“文件包含文件包含”的操作,其一般形式为:的操作,其一般形式为: #include “文件名文件名” #include 或或作用:作用:使编译系统把指定的被包含文件嵌入使编译系统把指定的被包含文件嵌入 到带有到带有#include的源文件中。的源文件中。“文件包含文件包含”示意图示意图 file1.c file2.c file1.c 包含包含#include“file2.c” B A B A (a) (b) (c)1 1、一个、一个#include#include命令只能指定一个被包含的命令只能指定

15、一个被包含的文件,若要包含文件,若要包含n n个文件,应使用个文件,应使用n n个个#include#include命令;命令;2 2、若文件、若文件1 1包含文件包含文件2 2,而文件,而文件2 2中要用到文中要用到文件件3 3的内容,则可在文件的内容,则可在文件1 1中用中用2 2个个#include#include命令分别包含文件命令分别包含文件2 2和文件和文件3 3,而且文件,而且文件3 3应应出现在文件出现在文件2 2之前,如下表示:之前,如下表示:file1.cfile1.c#include “file3.h”#include “file3.h”#include “file2.h

16、”#include “file2.h”.3 3、文件包含可以嵌套。、文件包含可以嵌套。4 4、“”“”与与在在#include#include中的不同:中的不同:使用使用时,系统只按指定的标准方式检索其他时,系统只按指定的标准方式检索其他目录;目录;一般用来调用库函数。一般用来调用库函数。使用使用“”“”时,系统若在源程序文件目录中找不时,系统若在源程序文件目录中找不到被包含的文件,到被包含的文件,则则将按系统指定的标准方式将按系统指定的标准方式检索其他目录;检索其他目录;一般用来调用自定义文件。一般用来调用自定义文件。5 5、预编译后的被包含文件和其所在文件成为同一、预编译后的被包含文件和其

17、所在文件成为同一个文件,所有的全局静态变量将在整个文件中有个文件,所有的全局静态变量将在整个文件中有效。效。包含文件的查找方法:包含文件的查找方法:#include “文件文件名名” 先在当前工作目录中去查找,若找不先在当前工作目录中去查找,若找不到再到指定的标准目录中去查找。到再到指定的标准目录中去查找。如:对如:对Turbo CTurbo C编译系统,先在用户目录下编译系统,先在用户目录下 查找,然后在查找,然后在TCincludeTCinclude文件夹中查找。文件夹中查找。#include 直接到系统指定的标准目录中去查找。直接到系统指定的标准目录中去查找。如:对如:对Turbo CT

18、urbo C编译系统,直接在编译系统,直接在TCincludeTCinclude 文件夹中查找。文件夹中查找。9.3 条件编译条件编译条件编译:根据条件选择被编译的源程序行。条件编译:根据条件选择被编译的源程序行。使用宏定义的标识符作为编译条件使用宏定义的标识符作为编译条件 使用常量表达式的值作为编译条件使用常量表达式的值作为编译条件 一、使用宏定义的标识符作为编译条件一、使用宏定义的标识符作为编译条件 # ifdef 标识符标识符 程序段程序段1 # else 程序段程序段2 #endif 形式一:形式一:作用:作用:当所指定的标识当所指定的标识符已经被符已经被#define 命令定命令定义

19、过,则在程序编译阶义过,则在程序编译阶段只编译程序段段只编译程序段1,否则,否则编译程序段编译程序段2。# ifdef 标识符标识符 程序段程序段1 #endif 形式二:形式二:作用:作用:当所指定的标识当所指定的标识符已经被符已经被#define 命令定命令定义过,则在程序编译阶义过,则在程序编译阶段只编译程序段段只编译程序段1,# ifndef 标识符标识符 程序段程序段1 # else 程序段程序段2 #endif 形式三:形式三:作用:作用:当所指定的标识当所指定的标识符符未未被被#define 命令定义命令定义过,则在程序编译阶段过,则在程序编译阶段只编译程序段只编译程序段1,否则

20、编,否则编译程序段译程序段2。例例1: #ifdef COMPUTER_A #define INTEGER_SIZE 16 #else #define INTEGER_SIZE 32 #endif可用于实现程序可用于实现程序在不同环境下的在不同环境下的兼容性。兼容性。例例2: #ifdef DEBUG printf(“x=%d,y=%dn”,x,y);#endif可用于进行程序可用于进行程序的调试。的调试。 调试过程中,在程序前面加调试过程中,在程序前面加#define DEBUG 调试完成后,将前面的调试完成后,将前面的#define DEBUG删除掉删除掉二、使用常量表达式的值作为编译条件

21、二、使用常量表达式的值作为编译条件 # if 表达式表达式 程序段程序段1 # else 程序段程序段2 #endif 形式:形式:作用:作用:当所指定的表达当所指定的表达式为真(非零)时就编式为真(非零)时就编译程序段译程序段1,否则编译程,否则编译程序段序段2。 可以事先给定一定条件,使程序在不可以事先给定一定条件,使程序在不同的条件下执行不同的功能。同的条件下执行不同的功能。程序举例:用同一程序实现大小写字母转换程序举例:用同一程序实现大小写字母转换(若定义(若定义UP转换为大写)转换为大写) #include stdio.h#define UPmain() char s128; gets(s); #ifdef UP strupr(s); #else strlwr(s); #endifputs(s);减少目标程序长度。减少目标程序长度。减少运行时间。减少运行时间。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 资格认证/考试 > 自考

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号