第9章预处理定义.ppt

上传人:sccc 文档编号:6113356 上传时间:2023-09-25 格式:PPT 页数:28 大小:276.55KB
返回 下载 相关 举报
第9章预处理定义.ppt_第1页
第1页 / 共28页
第9章预处理定义.ppt_第2页
第2页 / 共28页
第9章预处理定义.ppt_第3页
第3页 / 共28页
第9章预处理定义.ppt_第4页
第4页 / 共28页
第9章预处理定义.ppt_第5页
第5页 / 共28页
点击查看更多>>
资源描述

《第9章预处理定义.ppt》由会员分享,可在线阅读,更多相关《第9章预处理定义.ppt(28页珍藏版)》请在三一办公上搜索。

1、,第九章,预处理命令,本章要点,宏定义 文件包含 条件编译,主要内容,9.1 宏定义9.2“文件包含”处理9.3 条件编译,(4)经过预处理后的程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。(5)为了与一般C语句相区别,预处理命令以符号“#”开头。,预处理命令的特点,(1)用于改进程序设计环境,提高编程效率。(2)它不是C语言本身的组成部分,不能直接对它们进行编译(因为编译不能识别它们)。(3)必须在对程序进行通常的编译(包括词法和语法分析、代码生成、优化等)之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处

2、理。,如:程序中用#define命令定义了一个符号常量A,则在预处理时将程序中所有的A都置换为指定的字符串。程序中用#include命令包含一个文件“stdio.h”,则在预处理时将stdio.h文件中的实际内容代替该命令。,9.1 宏定义(1),不带参数的宏定义用一个指定的标识符(即名字)来代表一个字符串。其一般形式为,#define 标识符 字符串,宏定义使用户能以一个简单的名字代替一个长的字符串。这个标识符成为“宏名”。在预编译时将宏名替换成字符串的过程称为“宏展开”。#define是宏定义命令,9.1 宏定义(2),#include#define PI 3.1415926void ma

3、in()float l,s,r,v;printf(“input radius:”);scanf(“%f”,input radius:4 l=25.1327s=50.2655v=268.0826,9.1 宏定义(3),宏名一般习惯用大写字母表示,以便与变量名区别,但这并非规定,也可用小写字母。使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量,同时也避免书写字符串出错。另外,可以通过改变#define命令行来更改宏名所代表的字符串。宏定义是用宏名代替一个字符串,也就是作简单的置换,不作正确性检查,即预编译时不作任何语法检查。宏定义不是C语句,不必在行末加分号,如果加了分号则连分号一

4、起进行置换。#define命令出现在程序函数的外面,宏名的有效范围为定义命令之后到本源文件结束。,如:定义数组大小,可以用#define array_size 1000int arrayarray_size;当该程序在另外一个场合中,需要定义更长的数组,则只要更改#define命令行即可实现,即改为#define array_size 2000在该场合下array_size所代表的是2000,使用宏定义,可以提高程序的通用性。,一个宏定义如下:#define PI 3.141s9在宏替代时,不会指出该宏是错误的,只有在编译的时候,才会提示在使用宏的行存在语法错误。,9.1 宏定义(4),可以用

5、#undef命令终止宏定义的作用域。在进行宏定义时,可以引用已定义的宏名,可以层层置换。对程序中用双撇号括起来的字符串内的字符,即使与宏名相同,也不进行置换。宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只作字符替换,不分配内存空间。,9.1 宏定义(5),带参数的宏定义带参数的宏定义不是进行简单的字符串替换,还要进行参数替换。其一般形式为,#define 宏名(参数表)字符串,字符串中包含在括号中所指定的参数。,对带参数的宏定义是这样展开置换的:在程序中如果有带实参的宏,则按#define命令行中指定的字符串从左到右进行置换。如果串中包含宏中的形参,则将程序语句中相应的实

6、参(可以是常量、变量或表达式)代替形参。如果宏定义中的字符串中的字符不是参数字符,则保留。,定义一个a和b为边的矩形面积的宏:#define S(a,b)a*b area=S(3,2);展开后为:area=3*2;,9.1 宏定义(6),#include#define PI 3.1415926#define S(r)PI*r*rvoid main()float a,area;a=3.6;area=S(a);printf(“r=%fnarea=%fn”,a,area);,9.1 宏定义(7),说明:对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替#define命令行中的形参。当实参

7、是一个表达式(非单个常量或变量),则在宏定义时,最后宏所代表的字符串内把宏中的形参用括号括起来,以免在宏展开时,造成计算错误。在宏定义时,在宏名与带参数的括号之间不应加空格;否则将空格以后的字符都作为代替字符串的一部分。,如:当如下语句出现时area=S(a+b);展开为:area=3.1415926*a+b*a+b;为实现原意,宏定义应改为#define S(r)PI*(r)*(r),如下宏定义:#define S(r)PI*r*r对于语句area=S(a);将展开为:area=(r)PI*r*r(a);,9.1 宏定义(8),带参数的宏和函数之间,混淆:在调用函数时也是在函数名后的括号内写

8、实参,也要求实参和形参的数目相等。,不同之处:函数调用时,先求出实参表达式的值,然后代入形参;而使用带参数的宏只是进行简单的字符替换。函数调用是在程序运行时处理的,为形参分配临时的内存单元;而红展开则是在编译前进行的,在展开时不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。,9.1 宏定义(9),对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的形参也无类型,只是一个符号代表,展开时代入指定的字符串即可。宏定义时,字符串可以时任何类型的数据。调用函数只可得到一个返回值;而用宏可以设置得到几个结果。,#define P

9、I 3.1415926#define CIRCLE(R,L,S,V)L=2*PI*R;S=PI*R*R;V=4.0/3.0*PI*R*R*R;,9.1 宏定义(10),使用宏次数多时,宏展开后源程序变长,因为每展开一次都使程序增长;而函数调用不会使源程序变长。宏替换不占运行时间,只占编译时间;而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。,一般用宏来代表简短的表达式比较合适。有些问题,用宏和函数都可以,但用宏可以简化程序。如:宏定义#define MAX(x,y)(x)(y)?(x):(y)函数:int max(int x,int y)return(xy?x:y);,9.1 宏定

10、义(11),用宏代表输出格式#include#define PR printf#define NL“n”#define D“%d”#define D1 D NL#define D2 D D NL#define D3 D D D NL#define D4 D D D D NL#define S“%s”,void main()int a,b,c,d;char string=“CHINA”;a=1;b=2;c=3;d=4;PR(D1,a);PR(D2,a,b);PR(D3,a,b,c);PR(D4,a,b,c,d);PR(S,string);,1121231234CHINA,9.2“文件包含”处理(

11、1),所谓“文件包含”处理是指一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中。C语言提供了#include命令用来实现“文件包含”的操作。其一般形式为,#include“文件名”或#include,9.2“文件包含”处理(2),好处:“文件包含”命令可以节省程序设计人员的重复劳动。如:某单位的人员往往使用一组固定的符号常量(g=9.81,pi=3.1415926,e=2.718,c=),可以把这些宏定义命令组成一个头文件,然后各人都可以用#include命令将这些符号常量包含到自己所写的源文件中。这样每个人就可以不必重复定义这些符号常量,相当于工业上的标准零件

12、,拿来就用。,将宏代表输出格式做出头文件,并包含到用户程序中:(1)将格式宏做成头文件format.h#include#define PR printf#define NL“n”#define D“%d”#define D1 D NL#define D2 D D NL#define D3 D D D NL#define D4 D D D D NL#define S“%s”,(2)主文件file1.cvoid main()int a,b,c,d;char string=“CHINA”;a=1;b=2;c=3;d=4;PR(D1,a);PR(D2,a,b);PR(D3,a,b,c);PR(D4,a

13、,b,c,d);PR(S,string);,9.2“文件包含”处理(3),注意:“文件包含”是预处理操作,它在编译前将包含的文件包含到主文件中,得到一个新的源程序,然后对这个文件进行编译,得到一个目标文件(.obj)。常用在文件头部的被包含的文件称为“标题文件”或“头文件”,常以“.h”为后缀。当然也可不用“.h”为后缀,而用“.c”为后缀或者没有后缀也是可以的,但用“.h”作后缀更能表示此文件的性质。如需要修改程序中常用的一些参数,可以不必修改每个程序,只需把这些参数放在一个头文件中,在需要时修改头文件即可。但是应当注意,被包含文件修改后,凡包含此文件的所有文件都要全部重新编译。头文件除了可

14、以包含函数原型和宏定义外,还可以包括结构体类型定义和全局变量定义等。,9.2“文件包含”处理(4),说明:,一个#include命令只能指定一个被包含文件,如果要包含n个文件,要用n个#include命令。如果文件1包含文件2,而在文件2中要用到文件3的内容,则会在文件1中用两个#include命令分别包含文件2和文件3,而且文件3应出现在文件2之前。在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套。在#include命令中,文件名可以用双撇号或尖括号括起来。,二者区别:用尖括号时,系统到存放C库函数头文件的目录中寻找要包含的文件,这称为标准方式。用双撇号时,系统先在用户当前

15、目录中寻找要包含的文件,若找不到,再按标准方式查找。一般来说,如果为调用库函数则用#include命令来包含相关的头文件,则用尖括号,以节省查找时间;如果要包含的是用户自己编写的文件,一般用双撇号。若文件不在当前目录中,在双撇号内应给出文件路径。,9.2“文件包含”处理(5),被包含文件与其所在的文件,在预编译后已成为同一个文件,因此如果被包含文件中有全局静态变量,它在包含该文件的文件中也是有效的,不必用extern声明。,9.3 条件编译(1),一般情况下,源程序中所有行都参加编译。但是有时希望程序中一部分内容只在满足一定条件时才进行编译,也就是对这一部分内容指定编译的条件,称为“条件编译”

16、。有时,希望在满足某条件时对某一组语句进行编译,而当条件不满足时则编译另一组语句。条件编译命令可以处于程序的任何地方。,9.3 条件编译(2),条件编译命令有以下几种形式:,#ifdef 标识符 程序段1#else 程序段2#endif,说明:它的作用是若指定的标识符已经被#define命令定义过,则在程序编译阶段编译程序段1;否则编译程序段2。其中#else部分可以没有,即#ifdef 标识符 程序段#endif,程序段可以是语句组,也可以是命令行,9.3 条件编译(3),好处:条件编译对于提高C源程序的通用性是很有好处的,若一个C源程序在不同计算机系统上运行,而不同的计算机又有一定的差异,

17、往往需要对源程序作必要的修改,这就降低了程序的通用性。通过条件编译命令可以提高程序的通用性。,#ifdef COMPUTER_A#define INTEGER_SIZE 16#else#define INTEGER_SIZE 32#endif,说明:如果COMPUTER_A已定义,则假定目前程序在整数为16位的计算机上运行,若未定义,则认为不在整数为16位的计算机上运行,而是32位的计算机上运行。,此前,可以用命令行#define来定义COMPUTER_A,其后可有任意字符串,也可无字符串,如#define COMPUTER_A 0#define COMPUTER_A,9.3 条件编译(4),

18、在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:#ifdef DEBUG printf(“x=%d,y=%d,z=%dn”,x,y,z);#endif如果在它的前面有以下命令行:#define DEBUG,9.3 条件编译(5),#ifndef 标识符 程序段1#else 程序段2#endif,与相反。,9.3 条件编译(6),#if 表达式 程序段1#else 程序段2#endif,它的作用是当指定的表达式值为真时就编译程序段1;否则编译程序段2。可以事先给定条件,使程序在不同的条件下执行不同的功能。,9.3 条件编译(7),输入

19、一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。,#include#define LETTER 1void main()char str20=“C Language”,c;int i;while(c=stri)!=0),i+;#if LETTER if(c=a,运行结果:C LANGUAGE若#define LETTER 0则运行结果:c language,9.3 条件编译(8),#if这个条件编译命令直接用if语句也能达到要求,由于条件编译命令不生成目标代码,因此不用条件编译命令,目标程序长,运行时间也长。采用条件编译,可以减少被编译的语句,从而减少目标程度的长度,减少运行时间。当条件编译段比较多时,目标程序长度可以大大减少。由于课程给出的例子比较简单,当程序比较复杂时使用条件编译,其优越性就比较明显了。C语言利用预编译命令,有利于程序的移植性,并增强了程序的灵活性。,

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

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号