当前位置:文档之家› C语言程序设计第9章(预处理命令)

C语言程序设计第9章(预处理命令)

说明:
(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之前。 即:
例9.1
#define PI 3.1415926 main( ) {
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.4f\ns=%10.4f\nv=%10.4f\n",l,s,v); }
• 宏替换不占运行时间只占编译时间。而函数调用则占 运行时间(分配单元、保现场、值传递、返回)。
9.2 “文件包含”处理
所谓“文件包含”处理是指一个源文件可以将另外 一个源文件的全部内容包含进来, 即将另外的文件包含 到本文件之中。C语言提供了#inc1ude命令用来实现“文 件包含”的 操作。其一般形式为
4)宏定义不是C语句,不必在行末加分号,如果
加了分号,则会连同分号以其进行替换; 如: #define PI 3.1415926; area = P*r*r; 在宏扩展后成为: area = 3.1415926;*r*r; 结果,在编译时出现语法错误。
5)宏名的有效范围为定义命令之后到本 源文件 结束。通常,#define命令写在文件开头,函数之前,作
第九章 预处理命令
编译预处理:在源程序文件中,加入“编译预处理命 令”,使编译程序在对源程序进行通常的编译(包括词 法分析、语法分析、代码生成、代码优化)之前,先对 这些命令进行预处理,然后将预处理的结果和源程序一 起再进行通常的编译处理,以得到目标代码(OBJ文件)。
C提供的编译预处理命令
宏命令(Macro)
为文件一部分,在此文件范围内有效。
6)可以用#undef命令终止宏定义的作用域。这样可以
灵活控制宏定义的作用范围。
7)在进行宏定义时,可以引用已定义的宏名,可以层层置 换。
例9.2 #define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R main( ) {
说明:
1)宏名一般习惯用大写字母表示。非强制
规定,也可用小写字母;
2)使用宏定义,可以提高程序的通用性,能作 到“一改俱改”;
3)宏定义只作简单的替换,不作正确性检查。 如果词义或语义错误,只有在编译已被宏展开后 的源程序时才会发现错误井报错。例如:
#define PI 3.14l59 把第二个“1”写成“l”。这样的错误只有在 编译已被宏展开后的源程序时才会发现错误井报 错;
(3)对函数中的实参和形参都要定义类型,二者的类 型要求一致。不一致,应进行类型转换。而宏不存在 类型问题,宏名无类型,它的参数也无类型,只是一 个符号代表。
• 调用函数只可得到一个返回值,而用宏 可以设法得到几个结果。
• 使用宏次数多时,宏展开后源程序长,因为每展开一 次都使程序增长,而函数调 用不使源程序变长。
#inc1ude“文件名”

#include<文件名>
file1.c
file2.c
#includeB<file2.c>
B
A
这种常用在文件头部的被包含的文件称为“标题文件” 或“头部文件”,常以“h”为后缀(h为head(头)的 缩写),如“stdio.h”文件。当然不用“h”为后缀,而用 “c”为后缀或者没有后缀也是可以的,但用”h”作后缀 更能表示此文件的性质。
说明: (1)用宏名后面括号内的实参字符串原样代替#define 命令行中的形参。
如果有以下语句: area=S( a+b )
S( r )
PI *r * r
注意计算次序
area=PI*a+b*a+b
应当在定义时形式参数外面加一个括弧。
#define S(r) PI*(r)*(r)
(2)在宏定义时,在宏名与带参数的括弧之 间不应加空格,否则将空格以后的字符都作
例如
#define S(a,b) a*b
arear=S(2,3);
其中S(2,3)相当与2*3. 置换方式
从左到右进行置换。 形参用相应的实参(可以是常量、变量或表达式) 代替,不是参数字符,则保留。
Hale Waihona Puke 例9.3 #define PI 3.1415926 #define S(r) PI*r*r main( ) { float a,area; a=3.6; area=S(a); printf(“r=%f\narea=%f\n”,a,area); }
printf(“L=%f\nS=%f\n”,L,S); }
8)对程序中用双括号括起来的字符串内的字符,即使
与宏名相同,也不进行置换;
9)宏定义是专门用于预处理命令的一个专用名词,它与定
字符 义变量的含义不同,只作
替换,不分配内存空间;
9.1.2带参数的宏定义
一般形式 #define 宏名(参数表) 字符串 字符串中包含在括弧中所指定的参数。
为替代字符串的一部分,
参数的宏和函数的比较:
• 类似之处:在引用函数时也是在函数名后的括弧内写 实参,也要求实参与形参的数目相等,
• 带参的宏定义与函数的区别:
(1)函数调用时,先求出实参表达式的值,然后代入 形参。而使用带参的宏只是进行i简单的字符替换;
(2)函数调用是在程序运行时处理的,分配内存单元。 而宏展开是在编译时进行的,在展开时并不分配内存 单元,不进行值的传递处理,也没有“返回值”的概 念;
文件包含命令(include)
条件编译命令
这些命令均以#开头,以区别于语句。
9.1 宏定义
9.1.1不带参数的宏定义 一般形式:
#define 标识符 字符串 例:
#define PI 3.1415926 作用:
用标识符(称为“宏名” )PI来代替3.1415926这个字 符串,在编译预处理时,将程序中在该命令以后出现的所 有的PI都用3.1415926代替(这一过程又称为“宏展开”)。
相关主题