条件编译与文件包含
条件编译
一般情况下,在进行编译时对源程序中的每一行都要编译,但是有时希望程序中某一部分内容只在满足一定条件时才进行编译,如果不满足这个条件,就不编译这部分内容,这就是条件编译。
条件编译主要是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到多个版本控制、防止对文件重复包含的功能。#if,#ifndef,#ifdef,#else,#elif,#endif是比较常见条件编译预处理指令,可根据表达式的值或某个特定宏是否被定义来确定编译条件。
指令意义
#if 表达式非零就对代码进行编译;
#ifdef 如果宏被定义就进行编译;
#ifndef 如果宏未被定义就进行编译;
#else 作为其它预处理的剩余选项进行编译;
#elif 这是一种#else和#if的组合选项;
#endif 结束编译块的控制。
文件包含
文件包含是指一个C语言源程序中将另一个C语言源程序包含进来,通过#include预处理指令实现。
预处理时,将指定文件包含到当前文件中,插入到文件包含指令相应位置处,再对合并后的文件进行编译。
文件包含分类
函数库包含:
#include <filename>
本地文件包含:
#include "filename"
处理本地文件的一种策略是在源文件当前目录下查找,如果该头文件并未找到,编译器就像查找函数库头文件那样在标准位置查找本地头文件。
嵌套文件包含
#include文件的一个不利之处在于一个头文件可能会被多次包含,为了说明这种错误,考虑下面的代码:
#include "x.h"
#include "x.h"
显然,这里文件x.h被包含了两次,没有人会故意编写这样的代码。但是下面的代码:
#include "a.h"
#include "b.h"
看上去没什么问题。如果a.h和b.h都包含了一个头文件x.h。那么x.h在此也同样被包含了两次,只不过它的形式不是那么明显而已。
多重包含在绝大多数情况下出现在大型程序中,它往往需要使用很多头文件,因此要发现重复包含并不容易。要解决这个问题,我们可以使用条件编译。如果所有的头文件都像下面这样编写:
#ifndef _HEADERNAME_H
#define _HEADERNAME_H
...//(头文件内容)
#endif
那么多重包含的危险就被消除了。当头文件第一次被包含时,它被正常处理,符号_HEADERNAME_H被定义为1。如果头文件被再次包含,通过条件编译,它的内容被忽略。符号_HEADERNAME_H按照被包含头文件的文件名进行取名,以避免由于其他头文件使用相同的符号而引起的冲突。
但是,你必须记住预处理器仍将整个头文件读入,即使这个头文件所有内容将被忽略。由于这种处理将托慢编译速度,所以如果可能,应该避免出现多重包含。