《C语言-条件编译》PPT课件.ppt

上传人:s9****2 文档编号:568540830 上传时间:2024-07-25 格式:PPT 页数:25 大小:439.51KB
返回 下载 相关 举报
《C语言-条件编译》PPT课件.ppt_第1页
第1页 / 共25页
《C语言-条件编译》PPT课件.ppt_第2页
第2页 / 共25页
《C语言-条件编译》PPT课件.ppt_第3页
第3页 / 共25页
《C语言-条件编译》PPT课件.ppt_第4页
第4页 / 共25页
《C语言-条件编译》PPT课件.ppt_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《《C语言-条件编译》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《C语言-条件编译》PPT课件.ppt(25页珍藏版)》请在金锄头文库上搜索。

1、C C语言语言程序设计程序设计教程教程第九章第九章条件编译C C语言语言程序设计程序设计教程教程回顾n指针是一个变量,它存储另一个对象的内存地址n指针的声明由基本类型、星号 (*) 和变量名组成n为指针赋值,赋值运算符右侧必须是一个地址。如果是普通变量需要在前面加一个取地址运算符 &;如果是另一个指针变量或者是一个数组,不需要加 &运算符n运算符 * 用于返回指针指向的内存地址中存储的值C C语言语言程序设计程序设计教程教程n指针的算术运算的含义是指针的移动,将指针执行加上或者减去一个整数值n的运算相当于指针向前或向后移动n个数据单元n指针可以执行比较相等的运算,用来判断两个指针是否指向同一个

2、变量n指向数组的指针,存储的是数组中元素的地址。C C语言语言程序设计程序设计教程教程目标n理解以“#”号开头编译预处理。n理解宏定义。n理解条件编译。C C语言语言程序设计程序设计教程教程 预处理命令是由预处理命令是由ANSI C统一规定的,但是统一规定的,但是它不是它不是C语言本身的组成部语言本身的组成部分分,不能直接对它们进行编译。必须在对程序进行通常的,不能直接对它们进行编译。必须在对程序进行通常的编译之前编译之前,先对,先对程序中这些特殊的命令进行程序中这些特殊的命令进行“预处理预处理”, 即根据预处理命令对程序作相应即根据预处理命令对程序作相应的处理。的处理。 经过预处理后程序不再

3、包括预处理命令了,最后再由编译程序对预处经过预处理后程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的理后的源程序进行通常的编译编译处理,得到可供执行的目标代码。处理,得到可供执行的目标代码。 现在使用的许多现在使用的许多C编译系统都包括了预处理、编译和连接等部分,在编译系统都包括了预处理、编译和连接等部分,在进行编译时一气呵成。因此不少用户误认为预处理命令是进行编译时一气呵成。因此不少用户误认为预处理命令是C语言的一部分,语言的一部分,甚至以为它们是甚至以为它们是C语句,这是不对的。语句,这是不对的。 C提供的预处理功能主要有以下三种:提供的预处理功能主要有以下三种: 1

4、. 宏定义宏定义 2. 文件包含文件包含 3. 条件编译条件编译 为了与一般为了与一般C语句相区别,这些命令以符号语句相区别,这些命令以符号“#”开头。开头。9.1 宏定义C C语言语言程序设计程序设计教程教程9.1 宏定义宏定义9.1.1 不带参数的宏定义不带参数的宏定义用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为:用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为:#define 标识符标识符 字符串字符串例:例:#define PI 3.1415926 把这个标识符(名字)称为把这个标识符(名字)称为“宏名宏名”; 在预编译时将宏名替换成字符串的过程称为在预编译

5、时将宏名替换成字符串的过程称为“宏展开宏展开”; #define是宏定义命令。是宏定义命令。C C语言语言程序设计程序设计教程教程例例 9.1利用不带参数的宏计算(1)圆的面积;(2)矩形面积;(3)三角形面积。 #include #define PI 3.14#define a 1.2#define b 2.4#define s2 a*b#define x 1.2#define y 2.4#define s3 x*y/2.0void main() double r,s1; printf(“请输入圆的半径请输入圆的半径r:”); scanf(“%lf”,&r); s1=PI*r*r; prin

6、tf(“圆的面积圆的面积s1=%lfn”,s1); printf(“矩形的面积矩形的面积s2=%lfn”,s2); printf(“三角形的面积三角形的面积s3=%lfn”,s3);C C语言语言程序设计程序设计教程教程9.1 宏定义宏定义【注意点注意点】(1)在预定义中已经用到的符号不能在函数中再定义,如:)在预定义中已经用到的符号不能在函数中再定义,如:double s2,s3,a,b,x,y;(2)在不带参数的宏定义中像)在不带参数的宏定义中像a,b,x,y必须先预定义后才能在后面的宏必须先预定义后才能在后面的宏定义中使用,即宏定义可以嵌套,宏定义的字符串中可以使用已定义的宏名,定义中使

7、用,即宏定义可以嵌套,宏定义的字符串中可以使用已定义的宏名,在宏展开时由预处理程序层层代换;例如:在宏展开时由预处理程序层层代换;例如:#define a 1.2#define b 2.4#define s2 a*b(3)在宏定义中,符号常量一般大写,本例中有大写也有小写。)在宏定义中,符号常量一般大写,本例中有大写也有小写。(4)编译器在编译之前把程序中出现的一切宏用其对应的表达式字符串来)编译器在编译之前把程序中出现的一切宏用其对应的表达式字符串来替代,而不是计算表达式的值后才替代,即宏定义是用宏名表示的一个字符替代,而不是计算表达式的值后才替代,即宏定义是用宏名表示的一个字符串,在宏展开

8、时又以该字符串取代宏,这只是一种简单的代换,字符串可以串,在宏展开时又以该字符串取代宏,这只是一种简单的代换,字符串可以含有任何字符,可以是常量,也可以是表达式,预处理程序对它不作任何检含有任何字符,可以是常量,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时才发现。查。如有错误,只能在编译已被宏展开后的源程序时才发现。C C语言语言程序设计程序设计教程教程9.1 宏定义宏定义(5)在)在#define语句中,宏与字符串之间用空格隔开,在表达式末尾没有分语句中,宏与字符串之间用空格隔开,在表达式末尾没有分号,不然分号也会被认为是表达式的一部分而出现在程序中

9、宏出现的位置。号,不然分号也会被认为是表达式的一部分而出现在程序中宏出现的位置。(6)如果在双引号中的字符串中出现宏名,则此字符串中的和宏名相同的)如果在双引号中的字符串中出现宏名,则此字符串中的和宏名相同的字符是普通字符不会被替换。字符是普通字符不会被替换。例如:例如:printf(“矩形的面积矩形的面积s2=%lfn”,s2);该语句中的第该语句中的第1个个s2就不会被替换。另外对就不会被替换。另外对“输出格式输出格式”作宏定义,可以减作宏定义,可以减少书写麻烦,但可读性差。少书写麻烦,但可读性差。例如:例如:#include #define P printf#define D “%dn”

10、#define F “%fn”void main() int a=1, c=2; float b=1.2, d=2.4; P(D F,a,b); P(D F,c,d); C C语言语言程序设计程序设计教程教程9.2带参数的宏定义带参数的宏定义 语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。带参宏定义的一般形式为:去代换形参。带参宏定义的一般形式为: #define 宏名宏

11、名(形参表形参表) 字符串字符串在字符串中含有各个形参。带参数的宏调用的一般形式为:在字符串中含有各个形参。带参数的宏调用的一般形式为: 宏名宏名(实参表实参表); 例如:例如:#define S2(a,b) (a)*(b) /*宏定义宏定义*/ printf(“矩形的面积矩形的面积S2=%lfn”,S2(1.2,2.4) ; /*宏调用宏调用*/ 在宏调用时,用实参在宏调用时,用实参1.2和和2.4去代替形参去代替形参a,b,经预处理宏展开后的语句为:,经预处理宏展开后的语句为:printf(“矩形的面积矩形的面积S2=%lfn”, 1.2*2.4) ; C C语言语言程序设计程序设计教程教

12、程例例 9.2 利用带参数的宏定义计算(1)圆的面积;(2)矩形面积;(3)三角形面积。 #include #define PI 3.14#define S1(r) PI*(r)*(r)#define S2(a,b) (a)*(b)#define S3(x,y) (x)*(y)/2.0void main() double r,a,b,x,y,s10,s20,s30; printf(“请输入圆的半径请输入圆的半径r:”); scanf(“%lf”,&r); printf(“请输入矩形的长和宽请输入矩形的长和宽a,b:”); scanf(“%lf%lf”,&a,&b); printf(“请输入三角

13、形的底和高请输入三角形的底和高x,y:”); scanf(“%lf%lf”,&x,&y); s10=S1(r); s20=S2(a,b); s30=S3(x,y); printf(“圆的面积圆的面积=%lfn”,s10); printf(“矩形的面积矩形的面积=%lfn”,s20); printf(“三角形的面积三角形的面积=%lfn”,s30); C C语言语言程序设计程序设计教程教程对于带参数的宏定义有以下问题需要说明:对于带参数的宏定义有以下问题需要说明:(1)带参宏定义中,宏名和形参表之间不能有空格出现。)带参宏定义中,宏名和形参表之间不能有空格出现。例如:例如: #define S2

14、(a,b) (a)*(b)写为:写为: #define S2 (a,b) (a)*(b)将被认为是无参宏定义,宏名将被认为是无参宏定义,宏名S2代表字符串代表字符串 (a,b) (a)*(b)。宏展开时,宏。宏展开时,宏调用语句成为调用语句成为: s20=(a,b) (a)*(b)(a,b);这显然是错误的。这显然是错误的。(2)在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。)在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。这与函数调用中的情况是不同的。在函数调用中,形参和实参是两个不同的这与函数调用中的情况是不同的。在函数调用中,形参和实参是两个不同的量,各有自己的

15、作用域,调用时要把实参值传递给形参,进行量,各有自己的作用域,调用时要把实参值传递给形参,进行“值传递值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。而在带参宏中,只是符号代换,不存在值传递的问题。(3) 在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。C C语言语言程序设计程序设计教程教程宏定义还可以解除,解除宏定义的一般形式为:宏定义还可以解除,解除宏定义的一般形式为:#undef 宏名宏名其中,其中,#undef是关键字,宏名是在此前定义过的。功能是解除前面已定义的是关键字,宏名是在此前定义过的。功能是解除前面已定

16、义的宏,使之不再起作用,也就是说宏有它的作用域。宏,使之不再起作用,也就是说宏有它的作用域。C C语言语言程序设计程序设计教程教程9.2文件包含文件包含 文件包含是文件包含是C预处理程序的另一个重要功能。预处理程序的另一个重要功能。文件包含命令行的一般形式为:文件包含命令行的一般形式为: #include 或或#include “文件名文件名”在前面我们已多次用此命令包含过库函数的头文件。例如:在前面我们已多次用此命令包含过库函数的头文件。例如: #include #include 在在Visual C+6 .0中,系统含有的头文件用两种形式都可以,自定义的头文中,系统含有的头文件用两种形式都

17、可以,自定义的头文件用件用#include 形式时第一次编译可能无法通过。如果不能通过请形式时第一次编译可能无法通过。如果不能通过请修改为修改为#include “文件名文件名”形式。形式。文件包含命令的功能是把指定的文件插入到该命令行位置取代该命文件包含命令的功能是把指定的文件插入到该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连成一个源文件。令行,从而把指定的文件和当前的源程序文件连成一个源文件。 文件包含命令的几点说明如下。文件包含命令的几点说明如下。(1)一个)一个#include命令只能指定一个被包含文件,若有多个文件要包含,命令只能指定一个被包含文件,若有多个文件要包

18、含,则需用多个则需用多个#include命令。命令。(2)被包含文件的扩展名可以不是)被包含文件的扩展名可以不是.h的文件。的文件。(3)文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。)文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。C C语言语言程序设计程序设计教程教程例例 9.3 利用文件包含计算(1)圆的面积;(2)矩形面积;(3)三角形面积。 把如下代码存储到一个叫把如下代码存储到一个叫“area.h”的文件中,此文件要保存在与源程序相的文件中,此文件要保存在与源程序相同的目录下。同的目录下。#define PI 3.14#define S1(r) PI*

19、(r)*(r)#define S2(a,b) (a)*(b)#define S3(x,y) (x)*(y)/2.0C C语言语言程序设计程序设计教程教程#include #include “area.h” void main() double r,a,b,x,y,s10,s20,s30; printf(“请输入圆的半径请输入圆的半径r:”); scanf(“%lf”,&r); printf(“请输入矩形的长和宽请输入矩形的长和宽a,b:”); scanf(“%lf%lf”,&a,&b); printf(“请输入三角形的底和高请输入三角形的底和高x,y:”); scanf(“%lf%lf”,&x

20、,&y); s10=S1(r); s20=S2(a,b); s30=S3(x,y); printf(“圆的面积圆的面积=%lfn”,s10); printf(“矩形的面积矩形的面积=%lfn”,s20); printf(“三角形的面积三角形的面积=%lfn”,s30);C C语言语言程序设计程序设计教程教程【注意点注意点】#include “area.h”写成:写成:#include 时,第一次编译可能产生如下时,第一次编译可能产生如下错误:错误:fatal error C1083: Cannot open include file: area.h: No such file or direc

21、toryC C语言语言程序设计程序设计教程教程9.3条件编译条件编译 预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。条件编译有三种形式:条件编译有三种形式:1. 第一种形式。第一种形式。#ifdef 标识符标识符 程序段程序段1#else 程序段程序段2#endif它的功能是,如果标识符已被它的功能是,如果标识符已被 #define命令定义过则对程序段命令定义过则对程序段1进行编

22、译;否进行编译;否则对程序段则对程序段2进行编译。如果没有程序段进行编译。如果没有程序段2(它为空它为空),本格式中的,本格式中的#else可以可以没有,即可以写为:没有,即可以写为:#ifdef 标识符标识符程序段程序段 #endifC C语言语言程序设计程序设计教程教程例例 9.4 利用条件编译形式1计算(1)圆的面积;(2)矩形面积;(3)三角形面积。#include #define PI 3.14#define S1(r) PI*(r)*(r)/#define S2(a,b) (a)*(b)/#define S3(x,y) (x)*(y)/2.0void main()#ifdef S1

23、double r,s10;printf(“请输入圆的半径请输入圆的半径r:”);scanf(“%lf”,&r);s10=S1(r);printf(“圆的面积圆的面积=%lfn”,s10);#endifC C语言语言程序设计程序设计教程教程#ifdef S2 /因因S2(a,b)没有定义,所以不能输出矩形的面积没有定义,所以不能输出矩形的面积double a,b,s20;printf(“请输入矩形的长和宽请输入矩形的长和宽a,b:”);scanf(“%lf%lf”,&a,&b);s20=S2(a,b);printf(“矩形的面积矩形的面积=%lfn”,s20);#endif#ifdef S3/因

24、因S3(a,b)没有定义,所以不能输出三角形的面积没有定义,所以不能输出三角形的面积double x,y,s30;printf(“请输入三角形的底和高请输入三角形的底和高x,y:”);scanf(“%lf%lf”,&x,&y);s30=S3(x,y);printf(“三角形的面积三角形的面积=%lfn”,s30);#endifC C语言语言程序设计程序设计教程教程【注意点注意点】(1)不带参数与带参数的宏定义在条件编译格式)不带参数与带参数的宏定义在条件编译格式1中的使用格式都一样:中的使用格式都一样:#ifdef 宏名宏名带参数的宏中的参数不能含有,请读者上机操作。带参数的宏中的参数不能含有

25、,请读者上机操作。(2)程序中)程序中#ifdef #else #endif可以用嵌套方式。本例程序片断可以用嵌套方式。本例程序片断可为:可为:#ifdef S1#else #ifdef S2 #else #ifdef S3 #endif #endif#endifC C语言语言程序设计程序设计教程教程2.第二种形式第二种形式 #ifndef 标识符标识符 程序段程序段1 #else 程序段程序段2 #endif 与第一种形式的区别是将与第一种形式的区别是将“ifdef”改为改为“ifndef”。它的功能是,如果。它的功能是,如果标识符未被标识符未被#define命令定义过则对程序段命令定义过则

26、对程序段1进行编译,否则对程序段进行编译,否则对程序段2进行编进行编译。这与第一种形式的功能正相反。译。这与第一种形式的功能正相反。3.第三种形式第三种形式 #if 常量表达式常量表达式程序段程序段1 #else 程序段程序段2 #endif它的功能是,如常量表达式的值为真它的功能是,如常量表达式的值为真(非非0),则对程序段,则对程序段1 进行编译,否则对进行编译,否则对程序段程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。进行编译。因此可以使程序在不同条件下,完成不同的功能。C C语言语言程序设计程序设计教程教程例例 9.5 利用条件编译形式3计算(1)圆的面积;(2)矩形面

27、积;(3)三角形面积 。#include #define CHOICE1 0#define CHOICE2 1#define CHOICE3 0void main()#if CHOICE1 double r;printf(请输入圆的半径请输入圆的半径r:”);scanf(“%lf”,&r);printf(“圆的面积圆的面积=%lfn”,3.14159*r*r);#endifC C语言语言程序设计程序设计教程教程#if CHOICE2 double a,b;printf(“请输入矩形的长和宽请输入矩形的长和宽a,b:”);scanf(“%lf%lf”,&a,&b);printf(“矩形的面积矩形

28、的面积=%lfn”,a*b);#endif#if CHOICE3double x,y;printf(“请输入三角形的底和高请输入三角形的底和高x,y:”);scanf(“%lf%lf”,&x,&y);printf(“三角形的面积三角形的面积=%lfn”,x*y/2);#endifC C语言语言程序设计程序设计教程教程总结总结 (1)预处理功能是语言特有的功能,它是在对源程序正式编译前由预处)预处理功能是语言特有的功能,它是在对源程序正式编译前由预处理程序自动完成的。理程序自动完成的。(2)宏定义是用一个标识符来表示一个字符串,这个字符串可以是常量、)宏定义是用一个标识符来表示一个字符串,这个字

29、符串可以是常量、变量或表达式。在宏展开中将用该字符串代换宏名。宏定义可以带有参数,变量或表达式。在宏展开中将用该字符串代换宏名。宏定义可以带有参数,宏调用时是以实参代换形参,而不是宏调用时是以实参代换形参,而不是“值传送值传送”。为了避免宏代换时发生错。为了避免宏代换时发生错误,宏定义中的字符串应加括号,即字符串中出现的形式参数两边应加括号。误,宏定义中的字符串应加括号,即字符串中出现的形式参数两边应加括号。(3)文件包含可用来把多个源文件连接成一个源文件进行编译,结果将生)文件包含可用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。成一个目标文件。(4)条件编译允许只编译源程序中满足条件的程序段,使生成的目标程序)条件编译允许只编译源程序中满足条件的程序段,使生成的目标程序较短,从而减少了内存的开销,并提高了程序的效率。较短,从而减少了内存的开销,并提高了程序的效率。

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

最新文档


当前位置:首页 > 高等教育 > 研究生课件

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