资源预览内容
第1页 / 共17页
第2页 / 共17页
第3页 / 共17页
第4页 / 共17页
第5页 / 共17页
第6页 / 共17页
第7页 / 共17页
第8页 / 共17页
第9页 / 共17页
第10页 / 共17页
亲,该文档总共17页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
本章主要内容本章主要内容1.掌握无参宏定义和带参宏定义的方法。掌握无参宏定义和带参宏定义的方法。2.掌握文件包含命令的形式和文件包含的实现过程。掌握文件包含命令的形式和文件包含的实现过程。3.掌握条件编译命令的形式及嵌套。掌握条件编译命令的形式及嵌套。第第8章章编译预处理编译预处理 C提供的预处理功能主要有以下三种:提供的预处理功能主要有以下三种:(宏定义宏定义(文件包含文件包含(条件编译条件编译所有的预处理语句均以所有的预处理语句均以“#”开头,占用一个单独开头,占用一个单独的书写行,语句的结尾不用分号的书写行,语句的结尾不用分号“;”结束。结束。8.1宏定义宏定义8.1.1无参数宏定义无参数宏定义无参数宏定义的一般形式:无参数宏定义的一般形式:#define标识符标识符字符串字符串(常量或代码串常量或代码串)例:例:#definePI3.1415926作用:用作用:用PI来代表来代表“3.1415926”。以一个简单的名字代。以一个简单的名字代替长的符号串。称这个标识符为替长的符号串。称这个标识符为“宏名宏名”,在编译时,在编译时将宏名替换成字符串的过程称为将宏名替换成字符串的过程称为“宏展开宏展开”。#define是宏定义命令。是宏定义命令。例例:从键盘输入字符(个数不多于从键盘输入字符(个数不多于100),欲统计输入字符中英),欲统计输入字符中英文字母的个数。文字母的个数。注:输入字符注:输入字符#时,或输入字符个数多于时,或输入字符个数多于100时,输入结束。时,输入结束。#includestdio.h#defineMAX100main()intn,count=0;charch;for(n=0;n=a&ch=A&ch=Z)count+;printf(Thenumberofletters:%dn,count);无参宏定义说明:无参宏定义说明:A为了使宏名和变量名相区别。通常宏名用大写字母表示。为了使宏名和变量名相区别。通常宏名用大写字母表示。A符号常量不仅可以定义常数,也可以定义字符、字符串、说明符号。符号常量不仅可以定义常数,也可以定义字符、字符串、说明符号。如如:#defineENDSTRING0A如果程序中用双引号括住的字符串内包含与符号常量有相同的名字,预编译如果程序中用双引号括住的字符串内包含与符号常量有相同的名字,预编译时并不进行宏替换。时并不进行宏替换。如:如:#defineBOOK“TheRedandTheBlack”main()printf(%ns,BOOK);运行结果:运行结果:TheRedandTheBlack如果将程序改为如果将程序改为:#defineBOOK“TheRedandTheBlack”main()printf(%ns,“BOOK”);运行结果:运行结果:BOOK无参宏定义说明无参宏定义说明(续续):A宏定义语句的末尾不必加分号。宏定义语句的末尾不必加分号。 例如:例如:#defineMAXIMUM20;错误错误if(max=MAXIMUM)break;经过宏展开后,其中的经过宏展开后,其中的if语句变为:语句变为:if(max=20;)break;显然,上述显然,上述if语句存在语法错误。语句存在语法错误。A在字符串中若出现运算符,通常需在合适的位置加括号。在字符串中若出现运算符,通常需在合适的位置加括号。例如:例如:#defineS(3+4)A可以用可以用#undef命令取消宏定义。命令取消宏定义。一般形式:一般形式:#undef标识符标识符8.1.2带参宏定义带参宏定义带参宏定义的一般形式:带参宏定义的一般形式:#define标识符标识符(形参表形参表)字符串字符串其中,形参表是由一个或多个形参组成。其中,形参表是由一个或多个形参组成。带参宏调用的一般形式:带参宏调用的一般形式:宏名宏名(实参表实参表);例:编写一个程序,求例:编写一个程序,求3个数中的最大数,要求用带参数个数中的最大数,要求用带参数的宏实现。的宏实现。#include#defineMAX1(a,b)(a)(b)?(a):(b)#defineMAX2(a,b,c)(MAX1(a,b)(c)?MAX1(a,b):(c)main()inta=23;printf(MAX=%dn,MAX2(13+5,4,a);带参数的宏与函数有本质上的区别带参数的宏与函数有本质上的区别 :函函数数在在定定义义和和调调用用中中所所使使用用的的形形参参和和实实参参都都受受数数据据类类型型的的限限制制,而而带带参参数数宏宏的的形形参参和和实实参参可可以以是是任任意意数据类型。数据类型。函函数数有有一一定定的的数数据据类类型型,且且数数据据类类型型是是不不变变的的。而而带带参参数数的的宏宏一一般般是是一一个个运运算算表表达达式式,它它没没有有固固定定的的数据类型。数据类型。函函数数调调用用时时,先先计计算算实实参参表表达达式式的的值值,然然后后带带入入形形参。而宏定义展开时,只是替换。参。而宏定义展开时,只是替换。函函数数调调用用是是在在程程序序运运行行时时处处理理的的,将将分分配配临临时时的的存存储储单单元元。而而宏宏扩扩展展是是在在编编译译时时进进行行的的,展展开开时时即即不不分分配配内内存存单单元元,不不传传递递值值,也也没没有有“返返回回值值”的的概概念。念。使使用用宏宏次次数数多多时时,宏宏展展开开后后源源程程序序增增长长,而而函函数数调调用不使源程序变长。用不使源程序变长。使用带参数的宏,应注意:使用带参数的宏,应注意: 1.对于宏定义的形参要根据需要加上圆括号,以免发生运算错误。对于宏定义的形参要根据需要加上圆括号,以免发生运算错误。#defineMULTI(x)(x)*(x)a=15;b=3;p=MULTI(a+b)*10;经过预编译,该赋值语句变为:经过预编译,该赋值语句变为:p=(a+b)*(a+b)*10;如果定义中没有使用相应的括号,定义为:如果定义中没有使用相应的括号,定义为:#defineMULTI(x)(x*x)预编译后的赋值语句变为:预编译后的赋值语句变为:p=a+b*a+b*10;显然与原题意不符。显然与原题意不符。 2.宏名与括号之间不能有空格。宏名与括号之间不能有空格。#define S (r)PI*r*r错8.2文件包含文件包含文件包含也是一种预处理语句,它的作用是使一文件包含也是一种预处理语句,它的作用是使一个源程序文件将另一个源程序文件的全部包含进个源程序文件将另一个源程序文件的全部包含进来。一般形式为:来。一般形式为:#include或或#include“文件名文件名”“文件包含文件包含”示意图示意图 file1.c file2.c file1.c 包含#include”file2.c” B A B A (a) (b) (c)8.3条件编译条件编译8.3.1条件编译命令的形式条件编译命令的形式常用的有三种形式:常用的有三种形式:形式一:形式一:#ifdef宏名宏名程序段程序段1;#else程序段程序段2;#endif或者:或者:#ifdef宏名宏名程序段;程序段;#endif8.3.1条件编译命令的形式条件编译命令的形式(续续)形式二:形式二:#ifndef宏名宏名程序段程序段1;#else程序段程序段2;#endif其中,其中,#ifndef语句的功能与语句的功能与#ifdef相反,如果宏名相反,如果宏名未定义则编译程序段未定义则编译程序段1,否则编译程序,否则编译程序2。或者:或者:#ifndef宏名宏名程序段;程序段;#endif8.3.1条件编译命令的形式条件编译命令的形式(续续)形式三:形式三:#if常数表达式常数表达式程序段程序段1;#else程序段程序段2;#endif 功功能能:首首先先计计算算“常常数数表表达达式式”的的值值,如如果果为为真真(非非零零),就就编编译译“程程序序段段1”,否否则则编编译译“程程序序段段2”。如如果果没没有有#else部部分分,则则当当“常常数数表表达达式式”的值为的值为0时,直接跳过时,直接跳过#endif。或者:或者:#if常数表达式常数表达式程序段;程序段;#endif例:阅读程序。例:阅读程序。#includemain()#ifNULLprintf(NULLisnon-zerovalue!n);#elseprintf(NULLiszerovalue!n);#endif运行结果:运行结果:NULLiszerovalue!8.3.2条件编译命令的嵌套条件编译命令的嵌套条件编译可以嵌套使用,如:条件编译可以嵌套使用,如:#if 表达式表达式1程序段程序段1;#else#if表达式表达式2程序段程序段2;#else程序段程序段3;#endif#endif
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号