C语言第9章预处理实用教案

上传人:re****.1 文档编号:569858103 上传时间:2024-07-31 格式:PPT 页数:25 大小:455.50KB
返回 下载 相关 举报
C语言第9章预处理实用教案_第1页
第1页 / 共25页
C语言第9章预处理实用教案_第2页
第2页 / 共25页
C语言第9章预处理实用教案_第3页
第3页 / 共25页
C语言第9章预处理实用教案_第4页
第4页 / 共25页
C语言第9章预处理实用教案_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《C语言第9章预处理实用教案》由会员分享,可在线阅读,更多相关《C语言第9章预处理实用教案(25页珍藏版)》请在金锄头文库上搜索。

1、 宏定义是由源程序中的宏定义命令完成宏定义是由源程序中的宏定义命令完成的。宏代换的。宏代换(di hun)(di hun)(宏展开宏展开) )字符串的工作字符串的工作量量1.1.不带参数的宏定义不带参数的宏定义 (1 1)无参宏定义的一般格式)无参宏定义的一般格式 #define #define 标识符标识符 语言符号语言符号字符串字符串 9.1 9.1 宏宏 处处 理理第1页/共24页第一页,共25页。define: 为宏定义(dngy)关键字;标识符: 定义(dngy)的宏名,通常用大写字母取名,以便于与变量区别;语言符号字符串: 即宏体,可以是常数、表达式、格式串等。例如: #defin

2、e PI 3.1415926定义(dngy)了一个符号常量PI,表示用标识符PI替换3.1415926。在编译预处理时,会将程序代码中所有的PI都用3.1415926替换。第2页/共24页第二页,共25页。 2. 关于不带参数的宏定义的几点说明: (1)宏名一般用大写字母表示,便于(biny)与变量名区别;一般将字符个数较多的字符串用一个宏名替换,减少程序中多处引用字符串书写错误。 (2)宏定义是用宏名来表示一个字符串,在宏展开时以该字符串取代宏名,这只是一种简单的代换, 预处理程序对它不作任何检查。如有错误,只能在编译源程序时才能发现。 (3)宏定义不是语句,在行末不加分号,如加上分号则连分

3、号也一起置换。 第3页/共24页第三页,共25页。(4 4)宏定义)宏定义(dngy)(dngy)必须写在函数之外,其作用必须写在函数之外,其作用域为宏定义域为宏定义(dngy)(dngy)命令起到源程序结束。如要终止其命令起到源程序结束。如要终止其作用域可使用作用域可使用#undef#undef命令。例如:命令。例如:# define PI 3.14159# define PI 3.14159main()main()# undef PI /*# undef PI /*终止宏定义终止宏定义(dngy)PI*/(dngy)PI*/min().min().表示表示PIPI只在只在mainmain函

4、数中有效,在函数中有效,在minmin中无效。中无效。(5 5) 在源程序中用双引号括起来宏名,预处理程在源程序中用双引号括起来宏名,预处理程序不对其作宏代换。序不对其作宏代换。 第4页/共24页第四页,共25页。 (6 6) 宏定义可以嵌套,但嵌套的宏定义名要是已经定义的宏定义可以嵌套,但嵌套的宏定义名要是已经定义的宏名。在宏展开时由预处理程序宏名。在宏展开时由预处理程序(chngx)(chngx)层层替换。例如:层层替换。例如:#define R 14.256#define R 14.256#define PI 3.1415926#define PI 3.1415926#define S

5、PI*R*R /* PI#define S PI*R*R /* PI、R R是已定义的宏名是已定义的宏名*/*/ 则语句则语句printf(%f,s); printf(%f,s); 在宏代换后变为:在宏代换后变为: printf(%f,3.1415926*14.256*14.256); printf(%f,3.1415926*14.256*14.256); 第5页/共24页第五页,共25页。 例 9.1 不带参数(cnsh)的宏的程序 #include #define PI 3.115926 #define STRING This is a test main() float r, s; pr

6、intf(STRINGn); scanf(%f,&r); while( r0 ) s=PI*r*r; printf(s=%10.3fn,s); scanf(%f,&r); 宏宏定定义义不不是是语语句句,所所以以不不能能在在行行 尾尾 加加 分分 号号(fnho)(fnho)。否否则则,宏宏展展开开时时,会会将将分分号号(fnho)(fnho)作作为为宏宏体中的体中的1 1个字符。个字符。 在宏展开时,预在宏展开时,预处理程序仅以宏体替处理程序仅以宏体替换宏名,而不作换宏名,而不作(b (b zu)zu)任何检查任何检查第6页/共24页第六页,共25页。 例9.2 #define N 2 #de

7、fine M N+1 #define NUM 2M+1 main( ) int i; for (i=1; i=NUM; i+) printf(“%dn”, i ); 宏展开后的等价程序(chngx)如下: main( ) int i; /* NUM展开后2*2+1+1*/ for (i=1; i=6; i+) printf(“%dn”, i ); NUM宏展开(zhn ki): 2*N+1+1 再宏展开(zhn ki): 2*2+1+1第7页/共24页第七页,共25页。3带参宏定义(1)带参宏定义格式:#define 宏名(形参表) 宏体(2)带参宏调用格式:宏名(实参表)(3)宏展开:用宏调

8、用提供的实参字符串,直接置换宏定义命令行中相应形参字符串,非形参字符保持不变带参宏定义说明(1)定义有参宏时,宏名与左圆括号之间不能留有空格。否则,编译系统将空格以后的所有(suyu)字符均作为替代字符串,而将该宏视为无参宏。(2)有参宏的展开,只是将实参作为字符串,简单地置换形参字符串,而不做任何语法检查。第8页/共24页第八页,共25页。 例例9.3 带参数带参数(cnsh)的宏的宏 #include #define F(a) a*a /*宏名宏名F ,形参形参a*/ main() int x=3,y=4, b, z;b=x+y;z=F(x+y); /* 展展开开为为:z=x+y*x+y

9、;*/printf(b=%dnz=%dn,b,z); 第9页/共24页第九页,共25页。4.4.带参的宏和带参函数区别带参的宏和带参函数区别(qbi)(qbi) (1 1)在在函函数数调调用用时时,是是先先求求出出实实参参表表达达式式的的值值,再再传传递递给形参,而宏定义只是简单的字符替换;给形参,而宏定义只是简单的字符替换; (2 2)函函数数调调用用是是在在程程序序运运行行时时处处理理的的,分分配配存存储储单单元元,而而宏宏展展开开(调调用用)是是在在编编译译预预处处理理时时进进行行的的,展展开开时时不不分分配配内内存单元,不进行值传递,没有返回值的概念;存单元,不进行值传递,没有返回值的

10、概念; (3 3)对对函函数数实实参参和和形形参参都都要要定定义义类类型型,而而宏宏不不存存在在类类型型,宏宏定定义义时时字字符符串串可可以以是是任任何何类类型型数数据据,一一律律看看成成字字符符串串,宏宏名名也没类型,只是一个符号表示,展开时代入指定的符号即可。也没类型,只是一个符号表示,展开时代入指定的符号即可。第10页/共24页第十页,共25页。 (4)定定义义带带参参数数的的宏宏,可可以以实实现现(shxin)一一些些简简单单的的函函数数功功能能。 #define MAX(x,y) (x)(y)?(x) : (y) main( )int a, b, c, t ; t = MAX(a+b

11、, c+d); /* 展开后为展开后为 t = (a+b)(c+d)?(a+b):(c+d)* / 如如果果第第一一行行写写成成:#define MAX(x,y) xy ? x : y 则则展展开开后后为为 t = a+bc+d?a+b:c+d;因因为为置置换换展展开开是是用用“表表达达式式”对对等等的的置置换换“形形参参表表”中中的的参数。参数。第11页/共24页第十一页,共25页。 例9.4 带参数的宏的宏体中有()#define SA(i) i*i #define SB(j) (j)*(j) main() int a,b,x,y; a=3; b=7; x=SA(a+b)/SA(a+b);

12、 /* x=a+b*a+b/a+b*a+b */ y=SB(a+5)/SB(b+2); /* y=(a+5)*(a+5)/(b+2)*(b+2) */ printf(“x=%d,y=%dn”,x,y); 运行(ynxng)结果: x=54,y=63 第12页/共24页第十二页,共25页。9.2 9.2 文文 件件 包包 含含1文件包含的概念文件包含是指,一个源文件可以将另一个源文件的全部内容包含进当前文件中来。2文件包含处理命令的格式 include “包含文件名” 或 include 两种格式的区别仅在于:(1)使用双引号:系统首先到当前目录下查找被包含文件,如果(rgu)没找到,再到系统指

13、定的“包含文件目录”(由用户在配置环境时设置)去查找。(2)使用尖括号:直接到系统指定的“包含文件目录”去查找。一般地说,使用双引号比较保险。 第13页/共24页第十三页,共25页。 3文件包含的优点文件包含的优点 一一个个大大程程序序,通通常常分分为为多多个个模模块块,并并由由多多个个程程序序员员分分别编程。别编程。 有有了了文文件件包包含含处处理理功功能能,就就可可以以将将多多个个模模块块共共用用的的数数据据(如如符符号号常常量量和和数数据据结结构构)或或函函数数,集集中中到到一一个个单单独独的的文文件件中中。这这样样,凡凡是是要要使使用用其其中中数数据据或或调调用用其其中中函函数数的的程

14、程序序员员,只只要要使使用用文文件件包包含含处处理理功功能能,将将所所需需文文件件包包含含进进来来即即可可,不不必再重复定义必再重复定义(dngy)它们,从而减少重复劳动。它们,从而减少重复劳动。第14页/共24页第十四页,共25页。4说明说明(1)编编译译预预处处理理时时,预预处处理理程程序序将将查查找找指指定定的的被被包包含含文文件,并将其复制到件,并将其复制到#include命令出现的位置上。命令出现的位置上。 (2)常常用用在在文文件件头头部部的的被被包包含含文文件件,称称为为“标标题题文文件件”或或“头头部部文文件件”,常常以以“h”(head)作作为为后后缀缀,简简称称头头文文件件

15、。在在头头文文件件中中,除除可可包包含含宏宏定定义义外外,还还可可包包含含外外部部变变量量(binling)定定义义、结构类型定义等。结构类型定义等。(3)一一条条包包含含命命令令,只只能能指指定定一一个个被被包包含含文文件件。如如果果要要包含包含n个文件,则要用个文件,则要用n条包含命令。条包含命令。(4)文文件件包包含含可可以以嵌嵌套套,即即被被包包含含文文件件中中又又包包含含另另一一个个文件。文件。 第15页/共24页第十五页,共25页。Atype file2.c /*显示file2.c内容*/fun2() printf(“file2 includen”); Atype file1.c#

16、 include “file2.c” /*包含(bohn)file2.c文件*/fun1() printf(“file1 includen”); fun2(); Atype expfile.c# include “file1.c” /*包含(bohn)file1.c文件*/main() printf(“expfile includen”); fun1(); printf(“endn”) ;第16页/共24页第十六页,共25页。9.3 9.3 条条 件件 编编 译译 条件编译允许只编译源程序中满足条件的程序段,使生成的目标程序较短,从而减少(jinsho)了内存的开销并提高了程序的效率。 条件编

17、译可有效地提高程序的可移植性,并广泛地应用在商业软件中,为一个程序提供各种不同的版本。 (1)在不同的系统中,一个int 型数据占用的内存字节数可能是不同的。 (2)利用条件编译,还可使同一源程序即适合于调试(进行程序跟踪、打印较多的状态或错误信息),又适合高效执行要求。 第17页/共24页第十七页,共25页。 1. 1. 第一种形式第一种形式 # ifdef # ifdef 标识符标识符 程序段程序段1 1 #else #else 程序段程序段2 2 #endif #endif 如如果果标标识识符符(宏宏定定义义的的标标识识符符)已已被被 #define#define命命令令定定义义过过则则

18、对对程序段程序段1 1进行编译;否则进行编译;否则(fuz)(fuz)对程序段对程序段2 2进行编译。进行编译。 如果没有程序段如果没有程序段2 2,本格式中的,本格式中的#else#else可以没有,可以没有, 即可以写为:即可以写为: # ifdef # ifdef 标识符标识符 程序段程序段 #endif #endif第18页/共24页第十八页,共25页。例例9.5 条件条件(tiojin)编译实例编译实例1#include #define TED 10main() #ifdef TED printf(Hi,Tedn);#else printf(Hi,Anyonen); #endif #

19、ifndef RALPH printf(RAPLH not definedn); #endif 第19页/共24页第十九页,共25页。 2. 第二种形式 # ifndef 标识符 程序段1 #else 程序段2 #endif 与第一种形式的区别是将“ifdef”改为“ifndef”。 它的功能是,如果标识符未被#define命令定义过则对程序段1进行(jnxng)编译, 否则对程序段2进行(jnxng)编译。这与第一种形式的功能正相反。第20页/共24页第二十页,共25页。 3. 第三种形式 # if 常量表达式 程序段1 #else 程序段2 #endif 它的功能是,如常量表达式的值为真(

20、非0),则对程序段1 进行编译,否则对程序段 2进 行 编 译 。 可 以 使 程 序 在 不 同 条 件(tiojin)下,完成不同的功能。第21页/共24页第二十一页,共25页。例例 9.6 条件编译条件编译(biny)实例实例3#define LETTER 1main( ) char str20 = “C labguage”, c ; int i = 0; while ( ( c = stri != 0 ) i + + ; # if LETTER if ( c = a & c = A & c = Z ) c = c + 32 ; #endif printf ( “%c”, c) ; 运行

21、运行(ynxng)结果:结果: C LANGUAGE第22页/共24页第二十二页,共25页。 同同 学学 们们 再再 见见第23页/共24页第二十三页,共25页。感谢您的欣赏(xnshng)!第24页/共24页第二十四页,共25页。内容(nirng)总结宏定义是由源程序中的宏定义命令完成的。定义了一个(y )符号常量PI,表示用标识符PI替换3.1415926。一般将字符个数较多的字符串用一个(y )宏名替换,减少程序中多处引用字符串书写错误。则语句printf(%f,s)。printf(STRINGn)。scanf(%f,&r)。printf(s=%10.3fn,s)。printf(Hi,Tedn)。可以使程序在不同条件下,完成不同的功能。感谢您的欣赏第二十五页,共25页。

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

最新文档


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

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