我们在写程序的过程中老是在头文件用这样的语句:
#ifdef 标志符
程序段1
#else
程序段2
#endif
我们知道这是为了进行条件编译。即当定义了标志符则对程序段1进行编译,而没有定义标志符时则编译程序段2。那么为什么要这要呢?
其实这跟事物具有多样性一样。我们需要对不同的状况下采取不同的操作。例如程序的运行平台具有这种多样性,我们在window平台下编写的程序,可能使用某一个库或者与硬件相关的属性、方法。现在要将我们的程序移植到别的计算机系统的时候,例如linux系统。那么程序上依赖的库或者有些和硬件相关联的属性和方法不得不更改,那么我们只能在编写程序的时候提高程序的健壮性,此时就需要条件编译语句为我们实现这样的功能。
我们还见过这样的语句段:
#ifndef 标志符
#define 标志符1
#else
#define 标志符1
#endif
或许上面的说法让你有点困惑,还是举个例子吧!
#ifndef PI
#define DOUBLEPI 3.14*2
#else
#define DOUBLEPI PI*2
#endif
问题出现了,为什么不先直接#define PI 3.14,然后在定义DOUBLEPI呢?
这就是为了防止变量的重复定义。其实#ifndef的最主要目的是防止头文件的重复包含和编译。那么头文件的重复包含和编译有什么危害吗?
有危害是明显的,要不然费这么大劲干嘛呢?其实重复包含头文件有以下问题:
-
使预处理的速度变慢了,要处理很多本来不需要处理的头文件。
-
可能预处理器就陷入死循环了(其实编译器都会规定一个包含层数的上限)。例如
h1.h
包含h2.h
,h2.h
又包含h1.h
的情况,如果不采用防止头文件的重复定义,那么预处理器就会进入死循环了。 -
头文件里有些代码不允许重复出现。而重复定义头文件会重复出现一些代码。(虽然变量和函数允许多次声明(只要不是多次定义就行),但头文件里有些代码是不允许多次出现的)。例如:使用
typedef
类型定义和结构体Tag定义等,在一个程序文件中只允许出现一次。