第 六 章 预处理
★ 内容提要:
宏定义概念与定义形式
宏定义与函数调用的区别
文件包含
条件编译
? 宏定义
? 宏与函数的区别
? 文件包含
? 条件编译
编译时预处理是 C 语言区别于其它高级语言
的特征之一,即在通常的编译( 包括词法、
语法、代码生成、优化等 )之前,先对程序
中的特殊命令进行, 预处理,,然后再进行编
译。
⑴宏定义;
预处理功能主要有三种:
⑶条件编译。⑵文件包含;
第 六 章 预处理
9.1 宏定义
# define 宏名 替换字符串
宏定义的一般格式:
宏定义就是用一个宏名代替一个字符
串,以简化编程,提高程序的可读性;
注意,宏名必须定义在前引用在后,
其后不要加, ;, 号。
宏定义指令的最终作用是要求预编译器
在源程序中寻找宏 名,并将所有的这些
,宏名, 用, 替换字符串, 替换。
# define 宏名 替换字符串
宏定义的一般格式:
运行结果,
area=28.274333
9.2 带参的宏定义
说明,相应实参可以是较复杂的表达式,此时为得到
正确的结果,应当在 替换字符串的形式参数外面加上
一个括号。宏名与带 参数的括号之间不应加空格,非
则将出错。
不仅可以进行简单的字符替换,还可以进行
参数替换,改参数可以是表达式。
# define 宏名 ( 参数 ) 替换字符串
带参 宏定义的一般格式:
运行结果,
area=40.715040
运行结果,
area=66.476099
3.1415926*(a+1)*(a+1)
9.3 正确区分在 形式上 相似的宏与函数的概念
设有以下,
带参的宏,S(a+1) 函数调用,sqrt(a+1.5)
宏定义与函数调用的区 别有,
先求表达式的值,然后
进行形实结合的数据传
递,返回一个值,有类
型的概念。
只作简单的字符替
换,不进行值的传
递,也没有返回值
和类型的概念
操作内容
在程序运行时处理在预编译时处理处理时间
函数调用带参宏定义
#define FUDGE(K) K+3.14159
#define PR(a) printf( "%3d",(int)( a))
#define PRINT(a) P R(a) ; p ri nt f( "%4d \ n",++ a)
void main( ){
int i,x=2;
PR( x*FUDGE(2) );
for(i=0; i<5; i+ +)
PRINT(i);
}
[ 例 9 - 4],课堂实践,阅读程序给出结果。
运行结果,
7 0 1 2 3 4 6
9.4 文件包含
说明,filename 可以是:
?, *,h, 标题文件(头文件)。其中包含
一些库函数的原型说明、公用性的符号常数、
带参的宏定义、类型的定义、全局变量等。
文件包含是指将另外的文件包含到本文件之中
# include <filename> 或
# include, filename,
文件包含 一般格式:
或
,”
9.4 文件包含
说明,filename 可以是:
?, *,c, 源程序等文件,即另一个指定文
件的全部内容。
文件包含是指将另外的文件包含到本文件之中
# include <filename> 或
# include, filename,
文件包含 一般格式:
或
,”
执行结果
模块 A
# inc lude <ma th.h>
模块 B
math.h
fil e1.c
预编译预编译
模块 A
模块 B编译编译
目标
模块
可执行
程序
库函数
或其它目
标程序
链接链接
运行运行
C 程序的编
译运行过程
9.5 条件编译
通过条件编译指令,可以控制编译器有选择
地进行编译,满足条件时编译某一组语句,否
则编译另一组语句。
利用条件编译指令,可以控制产生不同的版
本,对于程序调试、移植都是非常有用的。
结构一,# ifdef 标识符
程序段 1
[# else
程序段 2]
# endif
几种常用的条件编译结构:
? 编译条件的真假由标 识符是否在此之前用 # define
指令定义过来决定。其中 # else 部分是可选的。
结构二,# ifndef 标识符
程序段 1
[# else
程序段 2]
# endif
? 结构二的作用与
结构一阵好相反,如
果标识符未被定义过
,编译程序段 1,否
则编译程序段 2 。
结构三,# if 表达式 e
程序段 1
[# else
程序段 2]
# endif
? 结构三中,当表
达式 e 的值为非 0 时,
条件成立,编译程序
段 1,否则编译程序
段 2 。
结构四:
# if 常量 表达式 e 1
程序段 1
# elif 常量 表达式 e 2
程序段 2
??
# elif 常量 表达式 e n
程序段 n
[#else
程序段 n+1]
# endif
? 结构四中,预编译
程序将依顺序计算表
达式 e i 的值,当计算到
某表达式 e k 的值为非 0
时,则程序段 k 被编译
,其后的表达式将不
再计算,其他的程序
段也将不被编译。若
所有表达式的都为 0,
则程序段 n+1 被编译。
# include <stdio.h>
#include <math.h>
#define EPS 1e - 7
void main(){
double udf_sin(double x); // 用户自定义函数原型说明
double a; scanf("%lf",&a);
printf("%f %f \ n",udf_sin(a),sin(a));
}
double udf_sin( double x ){ // 用户自定义函数
double sum,term,n=1; sum=term=x;
while( fabs(term) > EPS ){
n=n+1;
term=term*( - x*x)/((2*n - 2)*(2*n - 1));Th e end
培 育 英 才 钻 研 科 学
书山有径勤为路
学海无边苦作舟
书山有径勤为路书山有径勤为路
学海无边苦作舟学海无边苦作舟