预处理:预处理命令是由ANSI C统一规定的,但是它们不是C语言本身的组成部分,不能直接对它们进行编译(因为编译程序不能识别它们)。必须在对程序进行通常的编译(包括词法和语法分析、代码生成、优化等)之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处理(例如,若程序中用#define命令定义了一个符号常量A,则在预处理时将程序中所有的A都置换为指定的字符串。若程序中用#include命令包含一个文件“stdio.h”,则在预处理时将stdio.h文件中的实际内容代替该命令)。经过预处理后的程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。C提供的预处理功能主要有:宏定义、文件包含、条件编译,为了与一般C语句相区别,这些命令以符号“#”开头。
1.宏定义:
1.1不带参数的宏定义:用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为:
#define 标识符 字符串
比如:#define PI 3.1415,它的作用是在本程序文件中用指定的标识符PI来代替3.1415这个字符串,在编译预处理时,将程序中在该命令以后出现的所有的PI都用3.1415代替,这个过程称为“宏展开”。#define是宏定义命令。
宏名一般用大写字母表示,以便于变量名相区别
1.2带参数的宏定义
带参数的宏定义不是进行简单的字符串替换,还要进行参数替换,其定义形式一般为:
#define 宏名(参数表) 字符串。比如:#define S(a,b) a*b …… area=S(3,2)
2.“文件包含”:指一个源文件可以将另外一个源文件的全部内容包含进,即将另外的文件包含到本文件之中。C语言提供了#include命令用来实现“文件包含”的操作。其一般形式为:
#include“文件名”或#include<文件名>
在编译时并不是对两个文件分别进行编译,然后再将它们的目标程序连接的,而是在经过编译预处理后将头文件包含到主文件中,得到一个新的源程序,然后对这个文件进行编译,得到一个目标文件,被包含的文件成为新的源文件的一部分,而单独生成目标文件。
“头文件”常以“.h”为后缀(head的缩写)。当然不用“.h”为后缀,而用“.c”为后缀或者没有后缀也是可以的,但用“.h”作后缀更能表示此文件的性质。
如果需要修改程序中常用的一些参数,可以不必修改每个程序,只需把这些参数放在一个头文件中,在需要时修改头文件即可。但是应当注意,被包含文件修改后,凡包含此文件的所有文件都要全部重新编译。
3.条件编译:一般情况下,源程序中所有行都参加编译。但是有时希望程序中一部分内容只在满足一定条件时才进行编译,也就是对这一部分内容指定编译的条件,这就是“条件编译”。有时,希望在满足某条件时对某一组语句进行编译,而当条件不满足时则编译另一组语句。条件编译命令有以下几种形式:
(1)#ifdef标识符
程序段1
#else
程序段2
#endif
它的作用是若指定的标识符已经被#define命令定义过,则在程序编译阶段编译程序1;否则编译程序2.其中else部分可以没有。
(2)#ifndef 标识符
程序段1
#else
程序段2
#endif
它的作用是若标识符未被定义过则编译程序段1;否则编译程序段2
(3)#if 表达式
程序段1
#else
程序段2
#endif
它的作用是当指定的表达式值为真时就编译程序段1;否则编译程序段2