我们在网上下载的c或 c++ 源码,当你打开其中的头文件时,如果你是一个心细的计算机爱好者你会发现他们写的头文件都包含在一个条件编译中。比如:
#ifndef CLOCK_H
#define CLOCK_H
源码部分………………….
#endif //CLOCK_H
好了,现在说一说它们的作用。
这个条件编译的作用不体现在这个文件中,而是体现在整个project中。
我们一般在linux 下做开发时,project文件和makefile文件 要用工具生成或者自己书写。
我们在建立project 里的文件时一般一个功能建立一个 *.h和*.cpp文件,而在含有main函数的文件里包含所有的头文件。
我们为了说明条件编译的意义,简单举例。
下面有五个文件:
Test1.h Test2.h 这两个头文件
Test1.cpp Test2.cpp两个cpp文件
一个main.cpp
其内容如下:
Test1.h:
#include<stdio.h>
Test2.h:
#include” Test1.h”
Test1.cpp
#include” Test1.h”
Void pf1()
{
Printf(“hello world!/n ok1”);
}
Test2.cpp:
#include” Test2.h”
Void pf2()
{
Printf(“hello world /n ok2”);
}
Main.cpp
#include” Test1.h”
#include” Test2.h”
Int main()
{
Pf1();
Pf2();
return 0;
}
这样直接生成project文件和makefile文件会出现错误。原因很简单,你重复包含了#include<stdio.h>。
解决这个问题的办法很简单,用一开始提到的条件编译。
把修改如下:
Test1.h:
#ifndef TEST
#define TEST
#include<stdio.h>
#endf
Test2.h:
#ifndef TEST2
#define TEST2
#include “Test1.h”
#endf
这样修改之后,就能保证你的头文件只能被包含一次。这样,你在建立整个project时就不用考虑该包含那个头文件,以防止重复包含。
还有,像这样用条件编译解决重复定义的用法很多。比如你要在一个文件中定义一些全局变量,而你又不想在其它包含它的所有文件都用extern声明。
你可以用这样的策略:在你定义全局变量的头文件里用条件编译方法。
#ifdef OS_GLOBALS
#define OS_EXT
#else
#define OS_EXT extern
#endif
在定义变量时在前面加上OS_EXT。
在所有引用此头文件的文件里,有一个定义OS_GLOBALS这个,其它所有引用此头文件的文件都不定义OS_GLOBALS。就实现了,声明全局变量的头文件被多次应用但只被定义一次,其它文件是对变量的声明。
其实这是ucos里用的策略。
其实,我们要想防止重复定义,最好使用条件编译。
说的可能有点乱,希望对大家有帮助。