《《预处理命令 》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《预处理命令 》PPT课件.ppt(21页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第第第6.56.56.56.5章章章章 预处理命令预处理命令预处理命令预处理命令第第6.56.5章:预处理命令章:预处理命令 u学习的意义学习的意义 C C C C语言的一个重要特征是它的语言的一个重要特征是它的语言的一个重要特征是它的语言的一个重要特征是它的预处理功能预处理功能预处理功能预处理功能。我们知道,一。我们知道,一。我们知道,一。我们知道,一个高级语言源程序在计算机上运行,必须先用编译程序将其个高级语言源程序在计算机上运行,必须先用编译程序将其个高级语言源程序在计算机上运行,必须先用编译程序将其个高级语言源程序在计算机上运行,必须先用编译程序将其翻译为机器语言。编译包括词法分析、
2、语法分析、代码生成、翻译为机器语言。编译包括词法分析、语法分析、代码生成、翻译为机器语言。编译包括词法分析、语法分析、代码生成、翻译为机器语言。编译包括词法分析、语法分析、代码生成、代码优化等步骤,有时在编译之前还要做某些预处理工作,代码优化等步骤,有时在编译之前还要做某些预处理工作,代码优化等步骤,有时在编译之前还要做某些预处理工作,代码优化等步骤,有时在编译之前还要做某些预处理工作,如去掉注释,变换格式等。如去掉注释,变换格式等。如去掉注释,变换格式等。如去掉注释,变换格式等。C C C C语言允许在源程序中包含预处理语言允许在源程序中包含预处理语言允许在源程序中包含预处理语言允许在源程序
3、中包含预处理命令,在正式编译之前(词法分析之前)系统先对这些命令命令,在正式编译之前(词法分析之前)系统先对这些命令命令,在正式编译之前(词法分析之前)系统先对这些命令命令,在正式编译之前(词法分析之前)系统先对这些命令进行进行进行进行“预处理预处理预处理预处理”,然后整个源程序再进行通常的编译处理。,然后整个源程序再进行通常的编译处理。,然后整个源程序再进行通常的编译处理。,然后整个源程序再进行通常的编译处理。从语法上讲,这些预处理命令不是从语法上讲,这些预处理命令不是从语法上讲,这些预处理命令不是从语法上讲,这些预处理命令不是C C C C语言的一部分,但使用它语言的一部分,但使用它语言的
4、一部分,但使用它语言的一部分,但使用它们却扩展了们却扩展了们却扩展了们却扩展了C C C C语言程序设计的环境,可以简化程序开发过程,语言程序设计的环境,可以简化程序开发过程,语言程序设计的环境,可以简化程序开发过程,语言程序设计的环境,可以简化程序开发过程,提高程序的可读性,也更有利于移植和调试提高程序的可读性,也更有利于移植和调试提高程序的可读性,也更有利于移植和调试提高程序的可读性,也更有利于移植和调试C C C C语言程序。本章语言程序。本章语言程序。本章语言程序。本章主要介绍主要介绍主要介绍主要介绍宏定义宏定义宏定义宏定义、文件包括文件包括文件包括文件包括和和和和条件编译条件编译条件
5、编译条件编译等预处理命令。等预处理命令。等预处理命令。等预处理命令。u学习的意义学习的意义 源程序生成执行文件的过程:源程序生成执行文件的过程:源程序生成执行文件的过程:源程序生成执行文件的过程:.c.c或或或或.cpp.cpp编译编译编译编译.obj.obj链接链接链接链接.exe.exe#include#include#define PI 3.14159#define PI 3.14159void main()void main()float r=4;float r=4;printf(“s=%fn”,PI*r*r);printf(“s=%fn”,PI*r*r);预处理命令预处理命令预处理命
6、令预处理命令预处理预处理预处理预处理本章讨论之本章讨论之本章讨论之本章讨论之重点!重点!重点!重点!u学习目标学习目标 u学习内容学习内容 预处理命令简介预处理命令简介预处理命令简介预处理命令简介宏定义宏定义宏定义宏定义l l 不带参数的宏定义不带参数的宏定义不带参数的宏定义不带参数的宏定义l l 带参数的宏定义带参数的宏定义带参数的宏定义带参数的宏定义文件包括文件包括文件包括文件包括条件编译条件编译条件编译条件编译本章小结本章小结本章小结本章小结掌握掌握掌握掌握#include#include、#define#define、#if#if、#ifdef#ifdef、#else#else、#if
7、ndef#ifndef和和和和#endif#endif等命令的用法;等命令的用法;等命令的用法;等命令的用法;掌握宏定义和宏替换的一般方法;掌握宏定义和宏替换的一般方法;掌握宏定义和宏替换的一般方法;掌握宏定义和宏替换的一般方法;掌握包含文件的处理方法;掌握包含文件的处理方法;掌握包含文件的处理方法;掌握包含文件的处理方法;了解条件编译的作用和实现方法。了解条件编译的作用和实现方法。了解条件编译的作用和实现方法。了解条件编译的作用和实现方法。6.5.1 6.5.1 预处理命令简介预处理命令简介 预处理命令:预处理命令:预处理命令:预处理命令:C C C C源程序中以源程序中以源程序中以源程序中
8、以#开头、以换行符结尾的行开头、以换行符结尾的行开头、以换行符结尾的行开头、以换行符结尾的行 种类:种类:种类:种类:l l 宏定义宏定义宏定义宏定义#define#define、#undef#undefl l 文件包含文件包含文件包含文件包含#include#includel l 条件编译条件编译条件编译条件编译#if#if、#ifdef#ifdef、#else#else、#elif#elif、#endif#endif等等等等l l 其他其他其他其他#line#line、#error#error、#program#program等等等等本章主要讨论的本章主要讨论的本章主要讨论的本章主要讨论的
9、内容!内容!内容!内容!格式:格式:格式:格式:l l“#”“#”开头开头开头开头l l 占单独书写行占单独书写行占单独书写行占单独书写行l l 语句尾不加分号语句尾不加分号语句尾不加分号语句尾不加分号6.5.2 6.5.2 宏定义宏定义 宏定义分为两种:宏定义分为两种:宏定义分为两种:宏定义分为两种:不带参数的宏定义不带参数的宏定义不带参数的宏定义不带参数的宏定义和和和和带参数的宏定义带参数的宏定义带参数的宏定义带参数的宏定义。1 1 1 1、不带参数的宏定义、不带参数的宏定义、不带参数的宏定义、不带参数的宏定义 一般形式一般形式一般形式一般形式#define#define 标识符标识符标识
10、符标识符 单词串单词串单词串单词串指令名称指令名称指令名称指令名称宏名,被定义代表宏名,被定义代表宏名,被定义代表宏名,被定义代表后面的单词串后面的单词串后面的单词串后面的单词串 宏体,是宏的内宏体,是宏的内宏体,是宏的内宏体,是宏的内容文本容文本容文本容文本 可缺省,表示宏名可缺省,表示宏名可缺省,表示宏名可缺省,表示宏名定义过或取消宏体定义过或取消宏体定义过或取消宏体定义过或取消宏体 功能功能功能功能 用指定标识符用指定标识符用指定标识符用指定标识符(宏名宏名宏名宏名)代替字符序列代替字符序列代替字符序列代替字符序列(宏体宏体宏体宏体)如如如如#define YES 1#define YE
11、S 1#define NO 0#define NO 0#define PI 3.1415926#define PI 3.1415926#define OUT printf(“Hello,World”);#define OUT printf(“Hello,World”);#define#define SIZE SIZE 10 10#define#define INT_STRINT_STR%d%d void main()void main()int a int aSIZESIZE,i;,i;for(i=0;i for(i=0;i=0;i-)-1;i=0;i-)printf(printf(INT_S
12、TRINT_STR,ai);,ai);宏定义宏定义宏定义宏定义void main()void main()int a int a1010,i;,i;for(i=0;i for(i=0;i=0;i-)-1;i=0;i-)printf(printf(%d%d,ai);,ai);预编译预编译预编译预编译处理后处理后处理后处理后 注意:注意:宏替换时仅仅是将源程序中与宏名相同的宏替换时仅仅是将源程序中与宏名相同的标识符替换成宏的内容文本,并不对宏的内容文本做标识符替换成宏的内容文本,并不对宏的内容文本做任何处理。任何处理。宏定义注意事项宏定义注意事项宏定义注意事项宏定义注意事项 l l C C C C
13、程序员通常用程序员通常用程序员通常用程序员通常用大写字母大写字母大写字母大写字母来定义宏名,以便与变量名区别。来定义宏名,以便与变量名区别。来定义宏名,以便与变量名区别。来定义宏名,以便与变量名区别。如:如:如:如:#define#define PIPI 3.14159 3.14159l l 宏定义的宏定义的宏定义的宏定义的位置任意位置任意位置任意位置任意,但,但,但,但一般放在函数外面一般放在函数外面一般放在函数外面一般放在函数外面。l l 宏定义时,如果单词串太长,需要写多行,可以在行尾宏定义时,如果单词串太长,需要写多行,可以在行尾宏定义时,如果单词串太长,需要写多行,可以在行尾宏定义时
14、,如果单词串太长,需要写多行,可以在行尾使用反斜线使用反斜线使用反斜线使用反斜线“”续行符续行符续行符续行符 例如:例如:例如:例如:#define LONG_STRING this is a very long string that is#define LONG_STRING this is a very long string that is used as an exampleused as an examplel l 宏名的宏名的宏名的宏名的作用域作用域作用域作用域是从是从是从是从#define#define定义之后直到该宏定义所在文定义之后直到该宏定义所在文定义之后直到该宏定义所在
15、文定义之后直到该宏定义所在文件结束件结束件结束件结束 l l#undef#undef#undef#undef可可可可终止宏名作用域终止宏名作用域终止宏名作用域终止宏名作用域#undef#undef 标识符标识符标识符标识符#define YES 1#define YES 1void main()void main().#undef YES#undef YES#define YES 0#define YES 0void max()void max().YESYES原作用域原作用域原作用域原作用域YESYES新新新新作用域作用域作用域作用域l l 宏定义可以宏定义可以宏定义可以宏定义可以嵌套定义嵌
16、套定义嵌套定义嵌套定义,但不能递归定义,但不能递归定义,但不能递归定义,但不能递归定义#define R 2.0#define R 2.0#define PI 3.14159#define PI 3.14159#define L 2*PI*R (#define L 2*PI*R ()#define S PI*R*R (#define S PI*R*R ()#define M M+10 (#define M M+10 ()l l 程序中字符串常量即双引号中的字符,不作为宏进行宏程序中字符串常量即双引号中的字符,不作为宏进行宏程序中字符串常量即双引号中的字符,不作为宏进行宏程序中字符串常量即双引号
17、中的字符,不作为宏进行宏替换操作替换操作替换操作替换操作#define XYZ this is a test#define XYZ this is a test printf(XYZ);printf(XYZ);输出:输出:输出:输出:XYZXYZ,而不是:,而不是:,而不是:,而不是:this is a testthis is a test。宏定义注意事项宏定义注意事项宏定义注意事项宏定义注意事项 l l 宏定义一般以宏定义一般以宏定义一般以宏定义一般以换行结束换行结束换行结束换行结束,不要用分号结束,以免引起不,不要用分号结束,以免引起不,不要用分号结束,以免引起不,不要用分号结束,以免引起
18、不必要的错误必要的错误必要的错误必要的错误#define PI#define PI 3.14;3.14;a=PI*2*2;a=PI*2*2;预编译预编译预编译预编译处理后处理后处理后处理后a=a=3.14;3.14;*2*2;*2*2;错误!错误!错误!错误!l l 宏可以被宏可以被宏可以被宏可以被重复定义重复定义重复定义重复定义。#define N 10#define N 10 /第一次宏定义第一次宏定义第一次宏定义第一次宏定义int f()int f()N N的内容是的内容是的内容是的内容是1010 return(N*N);return(N*N);#define N 20#define N
19、 20 /第二次宏定义第二次宏定义第二次宏定义第二次宏定义void main()void main()N N的内容是的内容是的内容是的内容是2020 printf(%dn,N+f();printf(%dn,N+f();l l 在定义宏时,如果宏是一个表达式,那么一定要将这个在定义宏时,如果宏是一个表达式,那么一定要将这个在定义宏时,如果宏是一个表达式,那么一定要将这个在定义宏时,如果宏是一个表达式,那么一定要将这个表达式用()括起来,否则可能会引起非预期的结果。表达式用()括起来,否则可能会引起非预期的结果。表达式用()括起来,否则可能会引起非预期的结果。表达式用()括起来,否则可能会引起非预
20、期的结果。#define NUM1 10#define NUM1 10#define NUM2 20#define NUM2 20#define NUM NUM1+NUM2#define NUM NUM1+NUM2 void main()void main()int a=2,b=3;int a=2,b=3;a*=a*=NUMNUM;b=b*b=b*NUMNUM;printf(a=%d,b=%dn,a,b);printf(a=%d,b=%dn,a,b);void main()void main()int a=2,b=3;int a=2,b=3;a*=a*=10+20 10+20 ;b=b*b=b
21、*10+20 10+20 ;printf(a=%d,b=%dn,a,b);printf(a=%d,b=%dn,a,b);预编译预编译预编译预编译处理后处理后处理后处理后输出结果:输出结果:输出结果:输出结果:a=60,b=50a=60,b=50()()()输出结果:输出结果:输出结果:输出结果:a=60,b=90a=60,b=90 2 2 2 2、带参数的宏定义、带参数的宏定义、带参数的宏定义、带参数的宏定义 一般形式一般形式一般形式一般形式#define#define 标识符标识符标识符标识符(参数列表参数列表参数列表参数列表)单词串单词串单词串单词串参数表由一个或多个参数构成,参数只有参参
22、数表由一个或多个参数构成,参数只有参参数表由一个或多个参数构成,参数只有参参数表由一个或多个参数构成,参数只有参数名,没有数据类型符,参数之间用逗数名,没有数据类型符,参数之间用逗数名,没有数据类型符,参数之间用逗数名,没有数据类型符,参数之间用逗号隔号隔号隔号隔开,参数名必须是合法的标识符开,参数名必须是合法的标识符开,参数名必须是合法的标识符开,参数名必须是合法的标识符 通常会引用通常会引用通常会引用通常会引用宏的参数宏的参数宏的参数宏的参数 例:例:例:例:#define S(a,b)a*b#define S(a,b)a*b .area=S(3,2);area=S(3,2);宏展开:宏展
23、开:宏展开:宏展开:area=3*2;area=3*2;宏展开:宏展开:宏展开:宏展开:形参用实参换,其它字符保留形参用实参换,其它字符保留形参用实参换,其它字符保留形参用实参换,其它字符保留宏体及各形参外一般应加括号宏体及各形参外一般应加括号宏体及各形参外一般应加括号宏体及各形参外一般应加括号()()()()不能加空格不能加空格不能加空格不能加空格例例例例#define S#define S (r)PI*r*r(r)PI*r*r相当于定义了不带参宏相当于定义了不带参宏相当于定义了不带参宏相当于定义了不带参宏S S,代表字符串代表字符串代表字符串代表字符串“(“(r)PI*r*r”r)PI*r
24、*r”例例例例#define POWER(x)x*x#define POWER(x)x*x x=4;y=6;x=4;y=6;z=POWER(x+y);z=POWER(x+y);宏展开:宏展开:宏展开:宏展开:z=x+y*x+y;z=x+y*x+y;一般写成:一般写成:一般写成:一般写成:#define POWER(x)define POWER(x)(x x)*(x x)宏展开:宏展开:宏展开:宏展开:z=(x+y)*(x+y);z=(x+y)*(x+y);#define MAX(x,y)(x)(y)?(x):(y)#define MAX(x,y)(x)(y)?(x):(y).void main
25、()void main()int a,b,c,d,t;int a,b,c,d,t;.t=MAX(a+b,c+d);t=MAX(a+b,c+d);宏展开:宏展开:宏展开:宏展开:t=(a+b)(c+d)?(a+b):(c+d);t=(a+b)(c+d)?(a+b):(c+d);int max(int x,int y)int max(int x,int y)return(x y?x:y);return(x y?x:y);void main()void main()int a,b,c,d,t;int a,b,c,d,t;.t=max(a+b,c+d);t=max(a+b,c+d);【例例例例】用宏定
26、义和函数实现同样的功能用宏定义和函数实现同样的功能用宏定义和函数实现同样的功能用宏定义和函数实现同样的功能带参的宏与函数区别带参的宏与函数区别带参的宏与函数区别带参的宏与函数区别带参宏带参宏带参宏带参宏函数函数函数函数处理时间处理时间处理时间处理时间编译时编译时编译时编译时程序运行时程序运行时程序运行时程序运行时参数类型参数类型参数类型参数类型无类型问题无类型问题无类型问题无类型问题定义实参、形参类型定义实参、形参类型定义实参、形参类型定义实参、形参类型处理过程处理过程处理过程处理过程不分配内存,简单的不分配内存,简单的不分配内存,简单的不分配内存,简单的字符置换字符置换字符置换字符置换分配内
27、存,先求实参值,分配内存,先求实参值,分配内存,先求实参值,分配内存,先求实参值,再代入形参再代入形参再代入形参再代入形参程序长度程序长度程序长度程序长度变长变长变长变长不变不变不变不变运行速度运行速度运行速度运行速度不占运行时间不占运行时间不占运行时间不占运行时间调用和返回占时间调用和返回占时间调用和返回占时间调用和返回占时间6.5.3 6.5.3 文件包含文件包含处理过程处理过程处理过程处理过程 功能功能功能功能 一个源文件可将另一个源文件的内容全部包含进来一个源文件可将另一个源文件的内容全部包含进来一个源文件可将另一个源文件的内容全部包含进来一个源文件可将另一个源文件的内容全部包含进来
28、一般形式一般形式一般形式一般形式#define#define 或或或或#define “#define “包含文件名包含文件名包含文件名包含文件名”预编译时预编译时预编译时预编译时,用被包含文件的内容取代该预处理命令,再用被包含文件的内容取代该预处理命令,再用被包含文件的内容取代该预处理命令,再用被包含文件的内容取代该预处理命令,再对对对对“包含包含包含包含”后的文件作一个源文件编译后的文件作一个源文件编译后的文件作一个源文件编译后的文件作一个源文件编译:直直直直接到系统指定的接到系统指定的接到系统指定的接到系统指定的“文件包含目录文件包含目录文件包含目录文件包含目录”去查去查去查去查找被包含
29、的文件找被包含的文件找被包含的文件找被包含的文件 “”:系统首先到当前目录下系统首先到当前目录下系统首先到当前目录下系统首先到当前目录下查找被包含文件,如果没查找被包含文件,如果没查找被包含文件,如果没查找被包含文件,如果没找到,再到系统找到,再到系统找到,再到系统找到,再到系统指定的指定的指定的指定的“文件包含目录文件包含目录文件包含目录文件包含目录”去查找。去查找。去查找。去查找。预编译预编译预编译预编译处理后处理后处理后处理后A A源文件源文件源文件源文件prg1.cppprg1.cpp#include prg1.cpp#include prg1.cpp B B源文件源文件源文件源文件p
30、rg2.cppprg2.cppB BA A新源文件新源文件新源文件新源文件prg2.cppprg2.cpp文件包含举例文件包含举例文件包含举例文件包含举例:#include head.h#include head.h#include func.cpp#include func.cpp void main()void main()int a,b,c;int a,b,c;a=getnum();a=getnum();b=getnum();b=getnum();c=max(max(a,b),NUM);c=max(max(a,b),NUM);printf(MAX=%dn,c);printf(MAX=%d
31、n,c);(stdio.hstdio.h文件中的内容)文件中的内容)文件中的内容)文件中的内容)#define NUM 10#define NUM 10 int max(int x,int y)int max(int x,int y)return(x y?x:y);return(x y?x:y);int getnum()int getnum()int a;int a;scanf(%d,&a)scanf(%d,&a)return(a);return(a);void main()void main()int a,b,c;int a,b,c;a=getnum();a=getnum();b=getnu
32、m();b=getnum();c=max(max(a,b),NUM);c=max(max(a,b),NUM);printf(MAX=%dn,c);printf(MAX=%dn,c);#include#include#define NUM 10#define NUM 10int max(int x,int y)int max(int x,int y)return(x y?x:y);return(x y?x:y);int getnum()int getnum()int a;int a;scanf(%d,&a)scanf(%d,&a)return(a);return(a);预编译预编译预编译预编译处
33、理后处理后处理后处理后文件包含的优点文件包含的优点文件包含的优点文件包含的优点:一个大程序,通常分为多个模块,并由多个程序员分别一个大程序,通常分为多个模块,并由多个程序员分别一个大程序,通常分为多个模块,并由多个程序员分别一个大程序,通常分为多个模块,并由多个程序员分别编程。有了文件包含处理功能,就可以将多个模块共用的数编程。有了文件包含处理功能,就可以将多个模块共用的数编程。有了文件包含处理功能,就可以将多个模块共用的数编程。有了文件包含处理功能,就可以将多个模块共用的数据(如符号常量和数据结构)或函数,集中到一个单独的文据(如符号常量和数据结构)或函数,集中到一个单独的文据(如符号常量和
34、数据结构)或函数,集中到一个单独的文据(如符号常量和数据结构)或函数,集中到一个单独的文件中(如上例中的文件件中(如上例中的文件件中(如上例中的文件件中(如上例中的文件head.hhead.hhead.hhead.h和和和和func.cppfunc.cppfunc.cppfunc.cpp)。这样,凡是要)。这样,凡是要)。这样,凡是要)。这样,凡是要使用其中数据或调用其中函数的程序员,只要使用文件包含使用其中数据或调用其中函数的程序员,只要使用文件包含使用其中数据或调用其中函数的程序员,只要使用文件包含使用其中数据或调用其中函数的程序员,只要使用文件包含处理功能,将所需文件包含进来即可,不必再
35、重复定义它们,处理功能,将所需文件包含进来即可,不必再重复定义它们,处理功能,将所需文件包含进来即可,不必再重复定义它们,处理功能,将所需文件包含进来即可,不必再重复定义它们,从而减少重复劳动。从而减少重复劳动。从而减少重复劳动。从而减少重复劳动。文件包含的几点说明文件包含的几点说明文件包含的几点说明文件包含的几点说明 常用在文件头部的被包含文件,称为常用在文件头部的被包含文件,称为常用在文件头部的被包含文件,称为常用在文件头部的被包含文件,称为“标题文件标题文件标题文件标题文件”或或或或“头头头头部文件部文件部文件部文件”,常以常以常以常以.h.h.h.h(headheadheadhead)
36、作为后缀,简称头文件)作为后缀,简称头文件)作为后缀,简称头文件)作为后缀,简称头文件。在头文。在头文。在头文。在头文件中,除可包含宏定义外,还可包含外部变量定义、结构类件中,除可包含宏定义外,还可包含外部变量定义、结构类件中,除可包含宏定义外,还可包含外部变量定义、结构类件中,除可包含宏定义外,还可包含外部变量定义、结构类型定义等。型定义等。型定义等。型定义等。一条包含命令,只能指定一个被包含文件一条包含命令,只能指定一个被包含文件一条包含命令,只能指定一个被包含文件一条包含命令,只能指定一个被包含文件。如果要包含。如果要包含。如果要包含。如果要包含n n n n个文件,则要用个文件,则要用
37、个文件,则要用个文件,则要用n n n n条包含命令。条包含命令。条包含命令。条包含命令。文件包含可以嵌套文件包含可以嵌套文件包含可以嵌套文件包含可以嵌套,即被包含文件中又包含另一个文件。,即被包含文件中又包含另一个文件。,即被包含文件中又包含另一个文件。,即被包含文件中又包含另一个文件。6.5.4 6.5.4 条件编译条件编译根据一定的条件去编译源文件的不同部分,这就是根据一定的条件去编译源文件的不同部分,这就是根据一定的条件去编译源文件的不同部分,这就是根据一定的条件去编译源文件的不同部分,这就是条件编译条件编译条件编译条件编译。1 1、#if#if#endif#endif形式形式形式形式
38、 格式:格式:格式:格式:#if#if 条件条件条件条件1 1 程序段程序段程序段程序段1 1#elif#elif 条件条件条件条件2 2 程序段程序段程序段程序段2 2#else#else 程序段程序段程序段程序段n n#endif#endif常量表达式。通常会用到宏名,常量表达式。通常会用到宏名,常量表达式。通常会用到宏名,常量表达式。通常会用到宏名,条件可以不加括号条件可以不加括号条件可以不加括号条件可以不加括号“()()()()”#elif#elif和和和和#else#else可以可以可以可以没有没有没有没有#endif#endif必须存在,它必须存在,它必须存在,它必须存在,它是是是
39、是#if#if命令的结尾命令的结尾命令的结尾命令的结尾 如果条件如果条件如果条件如果条件1 1 1 1为真就编译程序段为真就编译程序段为真就编译程序段为真就编译程序段1 1 1 1,否,否,否,否则如果条件则如果条件则如果条件则如果条件2 2 2 2为真就编译程序段为真就编译程序段为真就编译程序段为真就编译程序段2 2 2 2,如果各条件都不为真就编译程,如果各条件都不为真就编译程,如果各条件都不为真就编译程,如果各条件都不为真就编译程序段序段序段序段n n n n。作用:作用:作用:作用:#if#if和和和和#elif#elif常常与常常与常常与常常与defineddefined命令配合命令
40、配合命令配合命令配合使用,使用,使用,使用,defineddefined命令的格式为命令的格式为命令的格式为命令的格式为:defineddefined(宏名)(宏名)(宏名)(宏名)或或或或 defined defined 宏名宏名宏名宏名功能:功能:功能:功能:判断某个宏是否已经定义,如果已经定义,判断某个宏是否已经定义,如果已经定义,判断某个宏是否已经定义,如果已经定义,判断某个宏是否已经定义,如果已经定义,defineddefined命令返回命令返回命令返回命令返回1 1,否则返回,否则返回,否则返回,否则返回0 0。DefinedDefined命令只能与命令只能与命令只能与命令只能与#
41、if#if或或或或#elif#elif配合配合配合配合使用,不能单独使用。使用,不能单独使用。使用,不能单独使用。使用,不能单独使用。例如:例如:例如:例如:#if defined#if defined(USAUSA)的含义是)的含义是)的含义是)的含义是“如果定义了宏如果定义了宏如果定义了宏如果定义了宏USA”USA”。例:下面的程序利用例:下面的程序利用例:下面的程序利用例:下面的程序利用ACTIVE_COUNTRYACTIVE_COUNTRY定义货币的名称定义货币的名称定义货币的名称定义货币的名称#define USA 0#define USA 0#define ENGLAND 1#de
42、fine ENGLAND 1#define FRANCE 2#define FRANCE 2#define ACTIVE_COUNTRY USA#define ACTIVE_COUNTRY USA#if ACTIVE_COUNTRY=USA#if ACTIVE_COUNTRY=USA char*currency=“dollar”;char*currency=“dollar”;/有效有效有效有效#elif ACTIVE_COUNTRY=ENGLAND#elif ACTIVE_COUNTRY=ENGLAND char*currency=pound char*currency=pound;#else
43、#else char*currency=france char*currency=france;#endif#endif void main()void main()float price1,price2,sumprice;float price1,price2,sumprice;scanf(%f%f,&price1,&price2);scanf(%f%f,&price1,&price2);sumprice=price1+price2;sumprice=price1+price2;printf(sum=%.2f%s,sumprice,currency);printf(sum=%.2f%s,su
44、mprice,currency);char*currency=“dollar”;char*currency=“dollar”;void main()void main()float price1,price2,sumprice;float price1,price2,sumprice;scanf(%f%f,&price1,&price2);scanf(%f%f,&price1,&price2);sumprice=price1+price2;sumprice=price1+price2;printf(sum=%.2f%s,sumprice,currency);printf(sum=%.2f%s,
45、sumprice,currency);预编译预编译预编译预编译处理后处理后处理后处理后2 2、#ifdef#ifdef#endif#endif形式形式形式形式 格式:格式:格式:格式:#ifdef#ifdef 宏名宏名宏名宏名 程序段程序段程序段程序段1 1#else#else 程序段程序段程序段程序段2 2#endif#endif等价于等价于等价于等价于“#if defined#if defined(宏名)(宏名)(宏名)(宏名)”在在在在#ifdef#ifdef和和和和#else#else之间可以加多个之间可以加多个之间可以加多个之间可以加多个#elif#elif命令命令命令命令 如果宏名
46、已被如果宏名已被如果宏名已被如果宏名已被#define#define行定义,则编译程序段行定义,则编译程序段行定义,则编译程序段行定义,则编译程序段1 1,否则编译,否则编译,否则编译,否则编译程序段程序段程序段程序段2 2 作用:作用:作用:作用:#define INTEGER#define INTEGER#ifdef INTEGER#ifdef INTEGER int add(int x,int y)int add(int x,int y)/有效有效有效有效 return(x+y);return(x+y);#else#else float add(float x,float y)float
47、 add(float x,float y)return(x+y);return(x+y);#endif#endif void main()void main()#ifdef INTEGER#ifdef INTEGER int a,b,c;int a,b,c;/有效有效有效有效 scanf(%d%d,a,b);scanf(%d%d,a,b);printf(a+b=%dn printf(a+b=%dn,add(a,b);add(a,b);#else#else float a,b,c;float a,b,c;scanf(%f%f,a,b);scanf(%f%f,a,b);printf(a+b=%fn
48、 printf(a+b=%fn,add(a,b);add(a,b);#endif#endif int add(int x,int y)int add(int x,int y)/有效有效有效有效 return(x+y);return(x+y);void main()void main()int a,b,c;int a,b,c;/有效有效有效有效 scanf(%d%d,a,b);scanf(%d%d,a,b);printf(a+b=%dn printf(a+b=%dn,add(a,b);add(a,b);预编译预编译预编译预编译处理后处理后处理后处理后3 3、#ifndef#ifndef#endi
49、f#endif形式形式形式形式 格式:格式:格式:格式:#ifndef#ifndef 宏名宏名宏名宏名 程序段程序段程序段程序段1 1#else#else 程序段程序段程序段程序段2 2#endif#endif如果宏名没被如果宏名没被如果宏名没被如果宏名没被#define#define行定义,则编译程序段行定义,则编译程序段行定义,则编译程序段行定义,则编译程序段1 1,否则编译,否则编译,否则编译,否则编译程序段程序段程序段程序段2 2 作用:作用:作用:作用:条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差
50、别:条件编译是在预编译时处理;而条件语句则是在程序运行条件编译是在预编译时处理;而条件语句则是在程序运行条件编译是在预编译时处理;而条件语句则是在程序运行条件编译是在预编译时处理;而条件语句则是在程序运行时处理。时处理。时处理。时处理。条件编译中的条件不可以包含变量名,只能是常量表达式条件编译中的条件不可以包含变量名,只能是常量表达式条件编译中的条件不可以包含变量名,只能是常量表达式条件编译中的条件不可以包含变量名,只能是常量表达式(通常包含宏名),可以不加括号;而条件语句中的条件是条(通常包含宏名),可以不加括号;而条件语句中的条件是条(通常包含宏名),可以不加括号;而条件语句中的条件是条(