C语言编译预处理程序设计教程
编译预处理 在C语言中包含一类特殊的命令(或称指令),这类特殊命令的作用不是直接实现程序的功能,而是为C语言编译系统提供信息,这些信息将通知C语言编译器在对源程序进行正式编译之前应该做什么,这一类特殊的命令被称为“编译预处理命令”。 C语言的预处理程序是C语言编译系统的组成部分,它负责分析和处理程序中使用的几种预处理命令,由于预处理程序对这些预处理命令的处理是在编译程序的其它部分处理之前进行的,因此,把这些命令称为预处理命令。 C语言提供的预处理命令有如下几种: (1)宏定义 (2)文件包括 (3)条件编译 注 意: 为了与一般的C语言语句相区别,所有的预处理命令都是以符号“#”开始的。 10.1 宏定义 一种是符号常量定义,另一种是带参数的宏定义。 1 .符号常量定义 一般来讲,程序中所使用的常量(或称常数)都具有一定的意义,但如果在程序中直接使用常量本身,却很难看出它的意义。为了提高程序的可读性,C语言提供了用于定义符号常量(即用一个符号来代替一个常量)的预处理语句。 符号常量的定义 #define 符号常量名 字符串 在程序中,凡是出现符号常量名的地方,经过编译预处理程序的加工后,都被替换成它所对应的字符串。这一替换过程被称为宏展开。 例 如 #define ESC 0x1B 显然,当ESC的编码值有变化时,只要修改宏定义语句即可,而程序的其余部分则不需要做任何修改,这样,利用宏定义编写的程序,将有助于程序的调试和移植。 【例7.1】从键盘输入不超过100个字符,并统计其中英文字母(不区分大小写)的个数,直到输入的字符为'*'或输入的字符个数超过100为止。 #include "stdio.h" #define MAXnum 100 void main( ) { int i,count=0; char c; for(i=0; i= 'a' && c <= 'z' || c>='A' && c<='Z') ++count; } printf("Count=%d",count); } 说 明 程序中把要统计的英文字母的个数定义为符号常量MAXnum,这样,在以后要修改需要统计的字母个数时,只要修改MAXnum的值即可。 在使用宏定义时,需要注意如下几个问题: (1)预处理程序对符号常量的处理只是进行简单的替换工作,不作语法检查,如果程序中使用的预处理命令有错,只能在真正的编译阶段检查出来。 (2)如果不是特殊需要,预处理命令的结尾不应有分号,如果加了分号,则将连同分号一起替换。 (3)程序中出现的由双引号括起来的字符串,即使和符号常量名相同,也不进行宏替换。 2 .带参数的宏定义 使用#define命令来定义符号常量时,编译预处理程序只是简单地进行字符串替换工作,如果用#define命令定义一个带参数的宏,则编译预处理程序对源程序中出现的宏,不仅进行字符串替换,而且还进行参数替换。 带参数的宏定义 #define 宏名(参数表) 字符串 计算圆的面积的宏定义可如下所示: 【例7.2】从键盘输入两个整数,并把其中的较大值显示出来。要求利用宏定义来编程序。 在使用带参数的宏定义时,需要注意如下几个问题: (1)一般来讲,对宏定义字符串中的参数都要用括号括起来,整个字符串部分也应该用括号括起来,这样,才能够保证在任何替代情况下,总是把宏定义作为一个整体来看待,并能获得一个合理的计算顺序,否则,经过宏展开后,有可能出现意想不到的错误。 例如,下面的宏定义是用于求平方值的: (2)不难看出,带参数的宏定义也可以由函数来实现,由于程序中每使用一次宏都要进行一次替代操作,所以,如果在程序中多次使用宏,程序的目标代码可能比使用函数要长一些。一般用宏来表示一些简单的表达式。 10.2 文件包括 文件包括(又称文件包含)是指一个源文件可以将另外一个指定的源文件包括进来。 文件包括的一般形式 #include 例 如 int i1,i2,i3; float f1,f2,f3; char c1,c2,c3; 在C语言编译系统中有许多以.h为扩展名的文件,这些文件一般被称为“头文件”,在使用C语