第三版C语言课件讲解第09章+预处理命令.ppt

上传人(卖家):晟晟文业 文档编号:4063759 上传时间:2022-11-07 格式:PPT 页数:20 大小:190.04KB
下载 相关 举报
第三版C语言课件讲解第09章+预处理命令.ppt_第1页
第1页 / 共20页
第三版C语言课件讲解第09章+预处理命令.ppt_第2页
第2页 / 共20页
第三版C语言课件讲解第09章+预处理命令.ppt_第3页
第3页 / 共20页
第三版C语言课件讲解第09章+预处理命令.ppt_第4页
第4页 / 共20页
第三版C语言课件讲解第09章+预处理命令.ppt_第5页
第5页 / 共20页
点击查看更多>>
资源描述

1、第九章第九章 预处理命令预处理命令编译预处理:编译预处理:在源程序文件中,加入在源程序文件中,加入“编译预处理命编译预处理命令令”,使编译程序在对源程序进行,使编译程序在对源程序进行通常的编译通常的编译(包括(包括词词法分析、语法分析、代码生成、代码优化法分析、语法分析、代码生成、代码优化)之前)之前,先对,先对这些命令进行预处理,然后将预处理的结果和源程序一这些命令进行预处理,然后将预处理的结果和源程序一起再进行通常的编译处理,以得到目标代码(起再进行通常的编译处理,以得到目标代码(OBJ文文件)。件)。C提供的编译预处理命令提供的编译预处理命令宏命令(宏命令(Macro)文件包含命令(文件

2、包含命令(include)条件编译命令条件编译命令这些命令均以这些命令均以#开头,以区别于语句。开头,以区别于语句。9.1 宏定义宏定义9.1.1不带参数的宏定义不带参数的宏定义一般形式一般形式:#define 标识符标识符 字符串字符串例例:#define PI 3.1415926作用作用:用标识符(称为用标识符(称为“宏名宏名”)PI来代替来代替3.1415926这个字这个字符串,在编译预处理时,将程序中在该命令以后出现的所符串,在编译预处理时,将程序中在该命令以后出现的所有的有的PI都用都用3.1415926代替(这一过程又称为代替(这一过程又称为“宏展开宏展开”)。)。例例9.1#de

3、fine PI 3.1415926main()float l,s,r,v;printf(input radius:);scanf(%f,&r);l=2.0*PI*r;s=PI*r*r;v=4.0/3*PI*r*r*r;printf(l=%10.4fns=%10.4fnv=%10.4fn,l,s,v);说明:说明:1 1)宏名一般习惯宏名一般习惯用大写字母表示用大写字母表示。非强制规定,。非强制规定,也可用小写字母;也可用小写字母;2 2)使用宏定义,可以提高程序的通用性,能作使用宏定义,可以提高程序的通用性,能作到到“一改俱改一改俱改”;3 3)宏定义只作宏定义只作简单的替换简单的替换,不作正

4、确性检查。,不作正确性检查。如果词义或语义错误,只有在编译已被宏展开后如果词义或语义错误,只有在编译已被宏展开后的源程序时才会发现错误井报错。例如:的源程序时才会发现错误井报错。例如:#define PI 3.14l59 把第二个把第二个“1”1”写成写成“l”l”。这样的错误只有。这样的错误只有在编译已被宏展开后的源程序时才会发现错误井在编译已被宏展开后的源程序时才会发现错误井报错;报错;4 4)宏定义不是宏定义不是C C语句,语句,不必在行末加分号不必在行末加分号,如果加了分,如果加了分号,则会连同分号以其进行替换;号,则会连同分号以其进行替换;如:如:#define PI 3.14159

5、26;area=P*r*r;在宏扩展后成为:在宏扩展后成为:area=3.1415926;*r*r;结果,在编译时出现语法错误。结果,在编译时出现语法错误。5)宏名的有效范围为宏名的有效范围为定义命令之后到本定义命令之后到本 源文件结束源文件结束。通。通常,常,#define命令写在文件开头,函数之前,作为文件一命令写在文件开头,函数之前,作为文件一部分,在此文件范围内有效。部分,在此文件范围内有效。6)可以用可以用#undef命令终止宏定义的作用域命令终止宏定义的作用域。这样可以。这样可以灵活控制宏定义的作用范围。灵活控制宏定义的作用范围。7)在进行宏定义时,可以引用已定义的宏名,可以层层置

6、在进行宏定义时,可以引用已定义的宏名,可以层层置换。换。例例9.2#define R 3.0#define PI 3.1415926#define L 2*PI*R#define S PI*R*R main()printf(“L=%fnS=%fn”,L,S);8)对程序中用双括号括起来的字符串内的字符,即使与宏对程序中用双括号括起来的字符串内的字符,即使与宏名相同,也不进行置换;名相同,也不进行置换;9)宏定义是专门用于预处理命令的一个专用名词,它与定宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只作字符替换,义变量的含义不同,只作字符替换,不分配内存空间不分配内存空间;9

7、.1.2带参数的宏定义一般形式一般形式#define 宏名宏名(参数表参数表)字符串字符串 字符串中包含在括弧中所指定的参数。字符串中包含在括弧中所指定的参数。例如例如#define S(a,b)a*b arear=S(2,3);其中其中S(2,3)相当与相当与2*3.置换方式置换方式 从左到右进行置换。从左到右进行置换。形参用相应的实参(可以是形参用相应的实参(可以是常量常量、变量变量或或表达式表达式)代替,不是参数字符,则保留。代替,不是参数字符,则保留。例例9.3#define PI 3.1415926#define S(r)PI*r*rmain()float a,area;a=3.6;

8、area=S(a);printf(“r=%fnarea=%fn”,a,area);说明:说明:(1)用宏名后面括号内的用宏名后面括号内的实参字符串原样代替实参字符串原样代替define命令行中的形参命令行中的形参。如果有以下语句:如果有以下语句:area=S(a+b)应当在定义时形式参数外面加一个括弧。应当在定义时形式参数外面加一个括弧。#define S(r)PI*(r)*(r)(2)在宏定义时,在宏名与带参数的括弧之间不应加空在宏定义时,在宏名与带参数的括弧之间不应加空格,否则将空格以后的字符都作为替代字符串的一部分,格,否则将空格以后的字符都作为替代字符串的一部分,S(r)PI*r*ra

9、rea=PI*a+b*a+b注意计算次序注意计算次序参数的宏参数的宏和和函数函数的比较:的比较:类似之处:在引用函数时也是在函数名后的括弧内写类似之处:在引用函数时也是在函数名后的括弧内写实参,也要求实参与形参的数目相等,实参,也要求实参与形参的数目相等,带参的宏定义与函数的区别:带参的宏定义与函数的区别:(1)函数调用时,先求出实参表达式的值,然后代入函数调用时,先求出实参表达式的值,然后代入形参。而使用带参的宏只是进行形参。而使用带参的宏只是进行i简单的字符替换;简单的字符替换;(2)函数调用是在程序运行时处理的,分配内存单元。函数调用是在程序运行时处理的,分配内存单元。而宏展开是在编译时

10、进行的,在展开时并不分配内存而宏展开是在编译时进行的,在展开时并不分配内存车元,不进行值的传递处理,也没有车元,不进行值的传递处理,也没有“返回值返回值”的概的概念;念;(3)对函数中的实参和形参都要定义类型,二者的类对函数中的实参和形参都要定义类型,二者的类型要求一致。不一致,应进行类型转换。而宏不存在型要求一致。不一致,应进行类型转换。而宏不存在类型问题,宏名无类型,它的参数也元类型,只是一类型问题,宏名无类型,它的参数也元类型,只是一个符号代表。个符号代表。调用函数只可得到一个返回值,而用宏可以设法得到调用函数只可得到一个返回值,而用宏可以设法得到几个结果。几个结果。使用宏次数多时,宏展

11、开后源程序长,因为每展开一使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长,而函数调次都使程序增长,而函数调 用不使源程序变长。用不使源程序变长。宏替换不占运行时间识占编译时间。而函数调用则占宏替换不占运行时间识占编译时间。而函数调用则占运行时间(分配单元、保现场、值传递、返回)。运行时间(分配单元、保现场、值传递、返回)。#include9.2“文件包含文件包含”处理处理 所谓所谓“文件包含文件包含”处理是指一个源文件可以将另外处理是指一个源文件可以将另外一个源文件的全部内容包含进来,一个源文件的全部内容包含进来,即将另外的文件包含即将另外的文件包含到本文件之中。到本文件之中。C

12、语言提供了语言提供了#inc1ude命令用来实现命令用来实现“文文件包含件包含”的的 操作。其一般形式为操作。其一般形式为#inc1ude“文件名文件名”或或#includefile1.cABBfile2.c这种常用在文件头部的被包含的文件称为这种常用在文件头部的被包含的文件称为“标题文件标题文件”或或“头部文件头部文件”,常以,常以“h”为后缀(为后缀(h为为head(头)的缩(头)的缩写),如写),如“stdio.h”文件。当然不用文件。当然不用“h”为后缀,而用为后缀,而用“c”为后缀或者没有后缀也是可以的,但用为后缀或者没有后缀也是可以的,但用”h”作后缀作后缀更能表示此文件的性质。更

13、能表示此文件的性质。说明:说明:(1)一个)一个include命令只能指定一个被包含文件,如果要命令只能指定一个被包含文件,如果要包含包含n个文件,要用个文件,要用n个个include命令;命令;(2)如果)如果file1.c文件包含文件包含file2.h文件,而文件文件,而文件file2.h要用要用到到file3.h的内容,则可在的内容,则可在file1.c用两个用两个include命令分别包命令分别包含文件含文件file2.h和和file3.h,而且,而且file3.h应出现在应出现在file2.h之前。之前。即:即:#include“file3.h”#include“file2.h”这样

14、这样file1.c和和file2.h都可以用到都可以用到file3.h的内容,并且的内容,并且file2中中不用声明不用声明#include“file3.h”。(3)文件包含可以嵌套;)文件包含可以嵌套;(4)在)在#include命令中,文件名可以使用双引号或尖括命令中,文件名可以使用双引号或尖括号括起来;如果要包含的是用户自己编写的文件,建号括起来;如果要包含的是用户自己编写的文件,建议使用双引号;议使用双引号;(5)被包含文件)被包含文件(file2.h)与其所在的文件与其所在的文件(file.c)在预编译在预编译之后已成为同一个文件。因此在之后已成为同一个文件。因此在 file2.h中

15、有全局静态中有全局静态变量,它在变量,它在file1.c中有效,不必用中有效,不必用extern声明。声明。9.3条件编译 一般情况下,源程序中所有的行都参加编译。但是一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件下才进行有时希望对其中一部分内容只在满足一定条件下才进行编译,这就是编译,这就是“条件编译条件编译”。条件编译的形式有:条件编译的形式有:(1)#ifdef 标识符标识符 程序段程序段1#else 程序段程序段2#endif 它的作用是当所指定的标识符已经被它的作用是当所指定的标识符已经被#define命令定命令定义过,则在程序编译阶段只编译程序

16、段义过,则在程序编译阶段只编译程序段1,否则编译程序,否则编译程序段段2。其中其中#else部分可以没有,即部分可以没有,即#ifdef 标识符标识符 程序段程序段1#endif 这里的这里的“程序段程序段”可以是语句组,也可以是命令行。可以是语句组,也可以是命令行。这种条件编译对于提高这种条件编译对于提高C源程序的通用性是很有好处源程序的通用性是很有好处的。如果一个的。如果一个C源程序在不同计算机系统上运行,而不同源程序在不同计算机系统上运行,而不同的计算机又有一定的差异(例如,有的机器以的计算机又有一定的差异(例如,有的机器以16位来存放位来存放一个整数,而有的则以一个整数,而有的则以32

17、位存放一个整数),这样往往需位存放一个整数),这样往往需要对源程序作必要的修改,这就降低了程序的通用性,可要对源程序作必要的修改,这就降低了程序的通用性,可以用以下的条件编译来处理。以用以下的条件编译来处理。#ifdef COMPUTER_A#define INTEGER_SIZE 16#else#define INTEGER_SIZE 32#endif 如果如果COMPUTER_A在前面已被定义过,则编译下在前面已被定义过,则编译下面的命令行:面的命令行:#define INTEGER_SIZE 16否则,编译下面的命令行否则,编译下面的命令行:#define INTEGER_SIZE 32

18、如果在这组条件编译命令之前曾出现以下命令行:如果在这组条件编译命令之前曾出现以下命令行:#define COMPUTER_A 0或将或将COMPUTER_A定义为任何字符串,甚至是定义为任何字符串,甚至是:#define COMPUTER_A则预编译后程序中的则预编译后程序中的INTEGER_SIZE都用都用16代替,否则代替,否则都用都用32代替。代替。这样,源程序可以不必作任何修改就可以用于不同类这样,源程序可以不必作任何修改就可以用于不同类型的计算机系统。型的计算机系统。例如,在调试程序时,常常希望输出一些所需的信息,例如,在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出

19、这些信息。可以在源程序中插而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段。入以下的条件编译段。#indef DEBUG printf(“x=%d,y=%d,z=%dn”,x,y,z);#endif如果在它的前面有以下命令了行:如果在它的前面有以下命令了行:#define DEBUG 则在程序运行时输出则在程序运行时输出x,y,z的值,以便调试时分析。调的值,以便调试时分析。调试完成后只需将这个试完成后只需将这个define命令行删去即可。当然也可用命令行删去即可。当然也可用printf语句实现这样的功能,但却麻烦的多。语句实现这样的功能,但却麻烦的多。(2)#ifndef

20、标识符标识符 程序段程序段1#else 程序段程序段2#endif 它的作用是当所指定的标识符它的作用是当所指定的标识符未未被被#define命令定义命令定义过,则在程序编译阶段只编译程序段过,则在程序编译阶段只编译程序段1,否则编译程序段,否则编译程序段2。它只是第一行与第一种形式不同。这种形式与第一种。它只是第一行与第一种形式不同。这种形式与第一种形式的作用相反。形式的作用相反。以上两种形式用法差不多,根据需要任选一种,视以上两种形式用法差不多,根据需要任选一种,视方便而定。方便而定。(3)#if 表达式表达式 程序段程序段1#else 程序段程序段2#endif它的作用是当指定的表达式值为真(非零)时就编译程它的作用是当指定的表达式值为真(非零)时就编译程序段序段1,否则编译程序段,否则编译程序段2。可以事先给定一定条件,使。可以事先给定一定条件,使程序在不同的条件下执行不同的功能。程序在不同的条件下执行不同的功能。不用条件编译命令而直接用不用条件编译命令而直接用if语句也能达到要求,用语句也能达到要求,用条件编译命令的好处在于:可以减少被编译的语句,从条件编译命令的好处在于:可以减少被编译的语句,从而减少目标程序的长度,减少运行时间。当条件编译段而减少目标程序的长度,减少运行时间。当条件编译段比较多时,目标程序长度可以大大减少。比较多时,目标程序长度可以大大减少。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(第三版C语言课件讲解第09章+预处理命令.ppt)为本站会员(晟晟文业)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|