C语言程序设计课件 第9章_第1页
C语言程序设计课件 第9章_第2页
C语言程序设计课件 第9章_第3页
C语言程序设计课件 第9章_第4页
C语言程序设计课件 第9章_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第9章编译预处理9.1文件包含9.2宏定义9.3条件编译9.4预处理命令的综合示例本章小结

9.1文件包含

9.1.1文件包含命令的作用如果文件A中有一条文件包含预处理命令,如:#include<B>则该命令将指定文件B的内容复制到文件A中“#include<B>”命令处的位置,共同组成一个程序文件,即在文件A中产生文件B的一个副本。

例如:

图9-1所示是一个文件包含关系的示意图。文件file1.c中的包含命令“#include"file2.c"”将文件file2.c复制进文件file1.c中。图(a)和图(b)所示是预处理前的情况,图(c)是将文件file2.c复制文件file1.c之后的file1.c结构示意图。图9-1文件包含关系的示意图

9.1.2#include命令的两种格式

#include命令有两种格式:

格式一:#include<文件名>

格式二:#include"文件名"

两种格式的区别是:用尖括号时,系统到存放C语言库函数头文件所在的目录(一般是C编译系统的include子目录)中寻找要复制的文件(这称为标准方式)。用双引号时,系统先在用户当前目录中或指定目录中寻找要复制的文件,若找不到,再按标准方式查找(即按尖括号的方式查找)。

通常,如果为调用系统库函数而用“#include”命令来复制相应的头文件(如stdio.h、math.h、string.h等),宜采用尖括号,以节省查找时间。如果要复制的文件是用户自己定义的(这种文件一般都位于当前目录下),宜采用双引号。

在程序设计中,文件包含是很有用的。一个大的程序可以分为多个模块,由多个程序员分别编程。有些公用的符号常量或宏定义等可单独组成一个文件,在其他文件的开头用复制命令包含该文件即可使用。这样,可避免在每个文件开头都去书写那些公用的量,从而节省时间,并减少出错。

例9-1设计一个求n!的函数,存放于文件exam.c中,然后设计主函数文件file.c,计算p=n!/m!/(n-m)!。

9.2宏定义

宏定义有两种,即不带参数的宏和带参数的宏。宏定义的作用是用标识符来代表一字符串,一旦对字符串命名,就可在源程序中使用宏定义标识符,系统编译之前会自动查找标识符并替换成字符串。

9.2.1不带参数的宏

不带参数的宏定义的一般形式为

#define宏名宏体

其中:“#”表示这是一条预处理命令;“define”为宏定义命令;“宏名”为一个合法的标识符,一般建议用大写字母,以与变量名相区别;“宏体”可以是常数、表达式或语句,甚至可以是多条语句。define、宏名、宏体三者之间要用一个或多个空格分隔。

例如:

#definePI3.1415926

在预处理时,系统在该宏定义以后查找出现的每一个宏名都用宏体来代替,这个过程叫宏替换。

例9-2求球的表面积和体积。

在预处理时,系统会查找main()函数中的宏PI并用宏体3.141 592 6替换。预编译后文件将变为

例9-3使用无参宏定义格式控制输出。

程序运行结果为

Wangyi1308001621.00

Liwei1308002612.00

采用宏定义后,如果要修改PI值,只需在宏定义处修改PI值,而不需在计算面积和体积等多处修改,减少了代码修改量,降低了程序出错的可能性,提高了程序的健壮性。

9.2.2带参数的宏

带参数宏定义的一般形式为

#define宏名(参数)宏体

例如

#defineSQR(x)(x)*(x)

#defineMOD(x,y)(x)%(y)

预处理时,系统在用宏体代替宏名的同时,实在参数会代替宏体中形式参数,同样宏替换仍只是一种简单的查找替换,不能进行计算或实现其他的功能。

当程序出现下列语句时:

y=SQR(a+b);

程序在预处理时,将被替换成如下语句:

y=(a+b)*(a+b);

例9-4带参宏定义示例。

带参数的宏定义可以嵌套调用其他已存在的宏,即下一个宏定义的宏体可以出现上面已经定义过的宏名。

例如:

#defineSQR(x)(x)*(x)

#defineCUBE(x)SQR(x)*(x)

语句CUBE(a+b)进行宏展开后,变为

(a+b)*(a+b)*(a+b)

例9-5比较宏定义中括号的使用方法的示例。

程序运行结果为

输入一个数:3

SQ1:sq=16

SQ2:sq=7

SQ3:sq=16

SQ1:sq=160

SQ2:sq=57

SQ3:sq=10

在宏替换中,不管有无参数,宏名总是原封不动替换成定义串,当定义串中带有括号时,替换时这些括号原样出现在替换结果中,即宏定义串中的括号不是运算符,仅表示括号符号。对于SQ2、SQ3的宏来说,若替换方式为

sq=160/SQ2(a+1);sq=160/SQ3(a+1);

即将参数a+1分别传入宏SQ2和SQ3中,有无括号的替换对结果的影响很大。SQ2被替换成“160/a+1*a+1”;而SQ3替换后可表示为“160/((a+1)*(a+1))”。

9.3条件编译

C语言提供了条件编译的预处理命令,可以按不同的条件去编译不同的程序部分,进而产生不同的目标代码文件。一般情况下,源程序的所有语句都会参加编译。但有时若希望只对其中的部分满足条件的语句进行编译,则要用到“条件编译”。条件编译是在对源程序编译之前的处理中,根据给定的条件,决定只编译其中的某一部分源程序,而不编译另外一部分源程序(块删除)。条件编译有3种格式。

1.格式一

条件编译格式一的一般形式为

#ifdef标识符

程序段1

#else

程序段2

#endif

条件编译格式的功能:如果标识符已经被“#define”命令定义过,则当程序编译时只对程序段1进行编译,否则只对程序段2进行编译。其中的程序段可以是一条语句,也可以是一组语句。如果是一组语句,不必像复合语句一样加上花括号。

例9-6条件编译格式一的示例。

例9-7条件编译#if-#else-#endif的用法示例。

程序运行结果为

选用较小的值编译.

程序的编译过程取决于MAX定义的大小,当MAX>99时,使用#if部分编译,而#else部分是不进行编译的,反之亦然。

在程序的第1行宏定义中,定义MAX表示常量10,在本例中表示一个数值。若条件判断为非0的数表示真,否则为假。MAX也可以为任何字符串,可以根据需要自行定义符号常量,只要定义了,就编译满足条件的部分。

2.格式二

条件编译格式二的一般形式为

#ifndef标识符

程序段1

#else

程序段2

#endif

格式二与格式一的不同之处是将“ifdef”改成“ifndef”。其功能是:如果标识符没有被“#define”命令定义过,则当程序编译时只对程序段1进行编译,否则只对程序段2进行编译。这与格式一的功能恰好相反。

例9-8利用条件编译,计算面积。

3.格式三

条件编译格式三的一般形式为

#if常量表达式

程序段1

#else

程序段2

#endif

条件编译格式三的功能:如果常量表达式的值为真(即非0),则当程序编译时只对程序段1进行编译,否则只对程序段2进行编译。

例9-9条件编译格式三的示例。

条件编译当然也可用条件语句(if语句)来实现,但若用条件语句将会对整个源程序进行编译,造成目标程序长,可执行程序的运行时间长;而采用条件编译,可减少被编译的语句,从而减少了目标程序的长度和可执行程序的运行时间(少了关系运算并跳转的时间)。

9.4预处理命令的综合示例

例9-10用条件编译输入一行电报文字,破解电报的密码是每个字母都会被输出到字母表对应的下一个字母。

例9-11三角形面积公式为

,其中S = (a + b + c )/2,a、b、c为

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论