2009-10-31 78 views
321

我已经看到这样的代码通常在头文件开始:为什么在C++头文件中使用#ifndef和#define?

#ifndef HEADERFILE_H 
#define HEADERFILE_H 

,并在文件的结尾是

#endif 

这样做有什么目的?

+22

+1 - 我也有同样的疑问,并在这里得到更多的好答案,可能对未来的访问者有用:http://stackoverflow.com/q/3246803/1134940 – 2012-12-11 05:27:31

+5

我想补充说,你可以也可以使用** #pragma once **,这就是你所要做的,它和ifndef具有相同的用途。有关这两者的比较,请参阅:http://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards – Dimension 2013-06-01 16:12:33

+2

最好提一下'#pragma':它激活编译器特定的功能。尽管'#pragma once'被广泛支持,但它并不标准。 – Potatoswatter 2013-06-01 16:41:10

回答

369

这些被称为#include guards

包含标题后,它会检查是否定义了唯一值(在此例中为HEADERFILE_H)。然后,如果没有定义,它定义它并继续到页面的其余部分。

当代码再次被包含时,第一个ifndef失败,导致一个空白文件。

可以防止任何标识符(如类型,枚举和静态变量)的双重声明。

+3

嗯interresting。我曾经退出VC++因为它给了我关于双重定义的错误。没关系,我现在是一个Objective-C编码器=) – 2009-10-31 10:19:15

+0

Koning Baard XIV:VC甚至有一个'#pragma once'这样做:-) – Joey 2009-10-31 10:23:03

+63

另外它可以防止递归包含...想象一下,“alice.h”包括“ bob.h“和”bob.h“包含”alice.h“,他们没有包含警卫...... – 2009-10-31 10:39:56

21
#ifndef <token> 
/* code */ 
#else 
/* code to include if the token is defined */ 
#endif 

#ifndef检查给定令牌是否已经#defined先前在文件中或在包含文件;如果没有,则包括它与结尾#else之间的代码,或者如果不存在#else,则说明#endif声明。 #ifndef通常用于通过在包含文件后定义标记并检查未在该文件的顶部设置标记来使标头文件具有幂等性。

#ifndef _INCL_GUARD 
#define _INCL_GUARD 
#endif 
+3

以下划线开头的标识符被保留;你不应该自己定义它们。使用类似'#ifndef H_HEADER_NAME'的东西。 – 2013-08-24 19:46:31

+5

我知道这是一个旧评论,但实际上,下划线限制仅适用于“外部标识符” - 可能以编译对象的符号表结束的标识符,即全局变量和函数名称。它不适用于宏名称。 – Stu 2014-05-15 13:05:19

+1

斯图的评论是真的吗?我刚刚阅读https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier,现在我不太确定。 – Will 2017-06-28 08:23:50

2

这样可以防止多次包含同一头文件。

#ifndef __COMMON_H__ 
#define __COMMON_H__ 
//header file content 
#endif 

假设您已将此头文件包含在多个文件中。所以第一次 __COMMON_H__没有被定义,它会被定义并包含头文件。

下一次__COMMON_H__被定义,所以它不会再包含。

相关问题