白 雪 飞
baixf@ustc.edu.cn
中国科学技术大学电子科学与技术系
Dept,of Elec,Sci,& Tech.,USTC
Fall,2003
第 6章 预 处 理
C语言程序设计 - 第 6章 预处理 2
目 录
? 预处理
? 宏定义
? 文件包含
? 条件编译
C语言程序设计 - 第 6章 预处理 3
预处理 (Preprocessor)
? 预处理
?在编译之前对源程序进行,预处理”
?预处理命令不是 C语句,末尾没有分号
?预处理命令不在可执行文件中执行
?预处理命令都以 #开始
?包括宏定义、文件包含、条件编译等
? 举例
?#define MAX 1000
?#include <stdio.h>
C语言程序设计 - 第 6章 预处理 4
宏 (Macro)定义
? 无参数的宏定义
? 带参数的宏定义
C语言程序设计 - 第 6章 预处理 5
无参数的宏定义
? 一般形式
?#define 标识符 字符串
? 说明
?把源程序中相应 标识符 予以替换
?仅是简单的字符串替换,没有任何语法正确
性检查
?有效范围从定义处开始,到文件结束,或者
由 #undef命令终止作用域
?行末没有分号,如有分号将会被一起替换
C语言程序设计 - 第 6章 预处理 6
无参宏定义举例
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
#define begin {
#define end }
#define forever for(;;)
void main()
begin /* { */
printf("L=%f",L);
#undef PI /* 取消对 PI的宏定义 */
forever; /* for(;;); 无限循环 */
end /* } */
C语言程序设计 - 第 6章 预处理 7
带参数的宏定义
? 一般形式
?#define 宏名 (参数表 ) 字符串
? 说明
?宏定义仅是把参数作为字符串做简单替换,
而不做任何运算求值和语法检查
?宏名与参数表的括号之间不应有空格
?应注意参数替换后可能出现的语法错误和意
料之外的运算
?应在宏定义内容及其中参数两边加上括号
C语言程序设计 - 第 6章 预处理 8
带参宏定义举例
#define S1(a,b) a*b
#define S2(a,b) ((a)*(b))
#define max(a,b) ((a)>(b)?(a):(b))
void main()
{
int x=3,y=4,i=5,j=6,s,z;
s=S1(x+y,x-y); /* s=x+y*x-y; s==11 */
s=S2(x+y,x-y); /* s=((x+y)*(x-y)); s==-7 */
z=max(i++,j++);
/* z=((i++)>(j++)?(i++):(j++)); */
/* z==7,i==6,j==8 */
}
C语言程序设计 - 第 6章 预处理 9
文件包含
? 一般形式
?#include "filename"
?#include <filename>
? 说明
?把另一个 源文件 的全部内容包含进来
?预编译后,它们已成为一个文件
?头文件的扩展名一般用,h,但并非规定
?调用库函数一般使用 <>,也可以使用 ""
?调用用户编写的头文件应使用 ""
C语言程序设计 - 第 6章 预处理 10
条件编译
? 条件编译
?对某些部分的源程序指定编译的条件
?可以减少被编译的语句,减少目标程序的长
度,减少运行时间
?有利于移植程序,增加程序的灵活性
? 命令形式
?#ifdef...#else...#endif
?#ifndef...#else...#endif
?#if...#else...#endif
C语言程序设计 - 第 6章 预处理 11
结束
The End
baixf@ustc.edu.cn
中国科学技术大学电子科学与技术系
Dept,of Elec,Sci,& Tech.,USTC
Fall,2003
第 6章 预 处 理
C语言程序设计 - 第 6章 预处理 2
目 录
? 预处理
? 宏定义
? 文件包含
? 条件编译
C语言程序设计 - 第 6章 预处理 3
预处理 (Preprocessor)
? 预处理
?在编译之前对源程序进行,预处理”
?预处理命令不是 C语句,末尾没有分号
?预处理命令不在可执行文件中执行
?预处理命令都以 #开始
?包括宏定义、文件包含、条件编译等
? 举例
?#define MAX 1000
?#include <stdio.h>
C语言程序设计 - 第 6章 预处理 4
宏 (Macro)定义
? 无参数的宏定义
? 带参数的宏定义
C语言程序设计 - 第 6章 预处理 5
无参数的宏定义
? 一般形式
?#define 标识符 字符串
? 说明
?把源程序中相应 标识符 予以替换
?仅是简单的字符串替换,没有任何语法正确
性检查
?有效范围从定义处开始,到文件结束,或者
由 #undef命令终止作用域
?行末没有分号,如有分号将会被一起替换
C语言程序设计 - 第 6章 预处理 6
无参宏定义举例
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
#define begin {
#define end }
#define forever for(;;)
void main()
begin /* { */
printf("L=%f",L);
#undef PI /* 取消对 PI的宏定义 */
forever; /* for(;;); 无限循环 */
end /* } */
C语言程序设计 - 第 6章 预处理 7
带参数的宏定义
? 一般形式
?#define 宏名 (参数表 ) 字符串
? 说明
?宏定义仅是把参数作为字符串做简单替换,
而不做任何运算求值和语法检查
?宏名与参数表的括号之间不应有空格
?应注意参数替换后可能出现的语法错误和意
料之外的运算
?应在宏定义内容及其中参数两边加上括号
C语言程序设计 - 第 6章 预处理 8
带参宏定义举例
#define S1(a,b) a*b
#define S2(a,b) ((a)*(b))
#define max(a,b) ((a)>(b)?(a):(b))
void main()
{
int x=3,y=4,i=5,j=6,s,z;
s=S1(x+y,x-y); /* s=x+y*x-y; s==11 */
s=S2(x+y,x-y); /* s=((x+y)*(x-y)); s==-7 */
z=max(i++,j++);
/* z=((i++)>(j++)?(i++):(j++)); */
/* z==7,i==6,j==8 */
}
C语言程序设计 - 第 6章 预处理 9
文件包含
? 一般形式
?#include "filename"
?#include <filename>
? 说明
?把另一个 源文件 的全部内容包含进来
?预编译后,它们已成为一个文件
?头文件的扩展名一般用,h,但并非规定
?调用库函数一般使用 <>,也可以使用 ""
?调用用户编写的头文件应使用 ""
C语言程序设计 - 第 6章 预处理 10
条件编译
? 条件编译
?对某些部分的源程序指定编译的条件
?可以减少被编译的语句,减少目标程序的长
度,减少运行时间
?有利于移植程序,增加程序的灵活性
? 命令形式
?#ifdef...#else...#endif
?#ifndef...#else...#endif
?#if...#else...#endif
C语言程序设计 - 第 6章 预处理 11
结束
The End