第10章 编译预处理课件.ppt
第10章 编译预处理-2-宏定义宏定义文件包含文件包含条件编译条件编译 本章教学内容本章教学内容本章教学目标本章教学目标 掌握带参与不带参宏定义的使用掌握带参与不带参宏定义的使用掌握文件包含的使用掌握文件包含的使用了解条件编译了解条件编译-3-10.1宏定义宏定义 在在C语言中所有的预处理命令都以语言中所有的预处理命令都以”#”开头,宏定义是预处理指令的开头,宏定义是预处理指令的一种,以一种,以#define开头开头。在在C语言源程序中允许用一个标识符来表示一个语言源程序中允许用一个标识符来表示一个字符串,称为字符串,称为“宏宏”。被定义为。被定义为“宏宏”的标识符称为的标识符称为“宏名宏名”。在预处。在预处理过程中,宏调用会被展开为对应的字符串,这个过程称为理过程中,宏调用会被展开为对应的字符串,这个过程称为“宏代换宏代换”或或“宏展开宏展开”。 宏的使用有很多好处,不仅可以简化程序的书写,而且便于程序的宏的使用有很多好处,不仅可以简化程序的书写,而且便于程序的修改和移植,使用宏名来代替一个字符串,可以减少程序中重复书写某修改和移植,使用宏名来代替一个字符串,可以减少程序中重复书写某些字符串的工作量。些字符串的工作量。 根据宏定义中是否有参数,可以将宏分为根据宏定义中是否有参数,可以将宏分为不带参数的宏定义不带参数的宏定义与与带参带参数的宏定义数的宏定义两种,下面分别讨论这两种宏的定义与调用。两种,下面分别讨论这两种宏的定义与调用。-4-10.1.1 不带参数的宏定义不带参数的宏定义 不带参数的宏的宏名后面没有参数,不带参数的宏定义又称简单宏不带参数的宏的宏名后面没有参数,不带参数的宏定义又称简单宏定义。其定义的一般形式为:定义。其定义的一般形式为: #define 宏名宏名 字符串字符串 其中,其中,“#”表示预处理命令。表示预处理命令。define是关键字,表示该命令为宏定是关键字,表示该命令为宏定义。为了与一般的普通变量相区别,宏名一般使用大写。义。为了与一般的普通变量相区别,宏名一般使用大写。“字符串字符串”一一般为常量、表达式或字符串。般为常量、表达式或字符串。 在进行预处理时,系统会将程序中的在进行预处理时,系统会将程序中的“宏名宏名”用用“字符串字符串”来替换。来替换。-5-10.1.1 不带参数的宏定义不带参数的宏定义【例【例10-1】不带参数的宏定义的例子】不带参数的宏定义的例子。 #include #define M (a*a+4*a) int main() int a, b; scanf(%d,&a); b=M*M+3*M+5; printf(b=%dn,b); return 0;-6-带参数的宏定义带参数的宏定义 在C语言中,宏定义可以不带参数,也可以带参数。 在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。 带参数宏定义的一般形式为: #define 宏名宏名(形参表形参表) 字符串字符串 带参数宏调用的一般形式为: 宏名宏名(实参表实参表); 带参数的宏调用时,不仅简单地用字符串代替宏名,而且要用实参代换对应的形参。 例如: #define M(x) 5*x+x*x /*宏定义宏定义*/ f=M(8); /*宏调用宏调用*/ 在宏调用时,用实参8去代替形参x,经过预处理宏展开后f=5*8+8*8。-7-带参数的宏定义带参数的宏定义(续续)【例【例10-2】带参数的宏定义举例。】带参数的宏定义举例。 #include #define M(x,y,z) x*y+z int main( ) int a=1,b=2, c=3; printf(“%dn”,M(a+b,b+c,c+a); return 0; -8-带参数的宏定义带参数的宏定义(续续)【例例10-3】用宏来定义多个语句的例子。】用宏来定义多个语句的例子。 #include #define M(x,y,z) x=a*m; y=a*n; z=a*h int main() int a, m, n, h, q1, q2, q3; a=5,m=8,n=7,h=10; M(q1,q2,q3); printf(“q1=%dnq2=%dnq3=%dn”,q1,q2,q3); return 0; -9-10.2 文件包含文件包含 在在C语言中文件包含是指一个源文件可以将另一个源文件的全部内容语言中文件包含是指一个源文件可以将另一个源文件的全部内容包含进来。编译预处理程序把包含进来。编译预处理程序把#include命令行中所指定的源文件的全部内命令行中所指定的源文件的全部内容放到源程序的容放到源程序的#include命令行所在的位置命令行所在的位置。 文件包含的一般形式为:文件包含的一般形式为: #include 或或 #include“文件名文件名”-10-10.2 文件包含文件包含【例例10-5】将宏定义放在头文件head.h中,使用文件包含命令将它包含在一个程序中。/*文件head.h*/ #define MAX(a,b) (a)(b)?(a):(b)/*example10-5.c*/ #include #include “head.h” int main( ) int x,y,max; printf(“please input two numbers:”); scanf(“%d,%d”,&x,&y); max=MAX(x,y); printf(“max=%dn”,max); return 0;-11-10.3 条件编译条件编译 条件编译是C语言三种编译预处理命令之一。一般情况下,源程序中的所有行均参加编译,但有时希望部分行在满足一定条件时才进行编译,即按不同的条件去编译不同的程序部分,从而产生不同的目标代码文件,这就称为“条件编译”。 条件编译有以下几种形式: (1)#ifdef命令命令 条件编译命令#ifdef的一般形式为: #ifdef 标识符标识符 程序代码程序代码1 #else 程序代码程序代码2 #endif-12-【例题例题10-6】#ifdef形式的条件编译。形式的条件编译。 #include #define PRICE 8 int main() #ifdef PRICE printf(“PRICE is %dn”, PRICE); #else printf(“PRICE is not found!n”); #endif return 0;(2)#ifndef命令命令 条件编译命令#ifndef的一般形式为: #ifndef 标识符标识符 程序代码程序代码1 #else 程序代码程序代码2 #endif-13-10.3 条件编译条件编译(续续)【例10-7】#ifndef形式的条件编译。 #include #define PRICE 8 int main() #ifndef PRICE printf(“PRICE is %dn”, PRICE); #else printf(“PRICE is not found!n”); #endif return 0;10.3 条件编译条件编译(续续) (3) #if命令命令 条件编译命令#if的一般形式为: #if 表达式表达式 程序代码程序代码1 #else 程序代码程序代码2 #endif 功能:若表达式的值为真(非0),则对程序代码1进行编译,否则对程序代码2进行编译。-14-10.3 条件编译条件编译(续续)【例题例题10-8】#if形式的条件编译。 #include #define R 1 int main( ) floatc r, s; printf(“please enter a number:”); scanf(“%f”,&c); #if R r=3.14159*c*c; printf(“area of round is:%fn”, r); #else-15- s=c*c; printf(“area of square is:%fn”, s); #endif return 0;本章小结本章小结 编译预处理是指在对源程序进行编译之前,首先对源程序中的编译预处理命令进行处理。C语言中所有的预处理命令都以语言中所有的预处理命令都以“#”开头,末尾不能加分号开头,末尾不能加分号。所有的预处理命令都在编译前处理,因此它不具有任何计算、操作等功能。若预处理命令有变化,则必须对程序重新进行编译和链接。C语言提供的编译预处理命令主要有宏定义宏定义、文件包含文件包含和和条件编译条件编译3种。 宏定义是用一个标识符来表示一个字符串宏定义是用一个标识符来表示一个字符串,这个字符串可以是常量、变量或表达式。在宏替换时,用该字符串代换宏名。根据宏定义中是否有参数,可以将宏分为不带参数的宏定义与带参数的宏定义两种。在写带有参数的宏定义时,宏名与带括号参数间不能有空格,否则将空格以后的字符都作为了替换字符串的一部分,这样就变成不带参数的宏定义了。不要把带参数的宏定义与带参数的函数混淆,带参的宏定义在预处理时只是字符串的替换,而带参的函数却是将实参的值一一对应的传递给形参。 文件包含是指一个源文件可以将另一个源文件的全部内容包含进来文件包含是指一个源文件可以将另一个源文件的全部内容包含进来。编译预处理程序把#include命令行中所指定的源文件的全部内容放到源程序的#include命令行所在的位置。在编译时作为一个源程序编译(并不是作为两个文件连接),得到一个目标文件。 条件编译是按不同的条件去编译不同的程序部分,从而产生不同的目标代码文条件编译是按不同的条件去编译不同的程序部分,从而产生不同的目标代码文件件。条件编译只编译满足条件的程序段,使生成的目标程序较短,从而减少了内存的开销。-16- 谢 谢!