C包括警卫究竟做了什么?

我有一个关于在C中包含警卫的问题。我已经做了一些阅读,但我会欣赏一点澄清。

假设我有一个带有函数定义的头文件“header.h”。

#ifndef HEADER_FILE #define HEADER_FILE int two(void){ return 2; } #endif 

此头文件具有包含保护。 但是,我对#define HEADER_FILE实际上在做什么感到困惑。 假设我忘了包含守卫,完全忽略添加’#define HEADER_FILE’对我来说是完全合法的。

所以我的问题是:当我们定义HEADER_FILE时,我们究竟在做什么? 我们定义了什么? 为什么忘记包含守卫是可以的,在这种情况下我们也忘了添加#define HEADER_FILE?

任何帮助表示赞赏!

它是一个预处理器宏。

所有这些都是预处理器语法,基本上说,如果尚未定义此宏,则定义它并包含#ifndef#endif之间的所有代码

它实现的目的是防止多次包含文件,这可能会导致代码出现问题。

你的问题:

为什么忘记包含守卫是可以的,在这种情况下我们也忘了添加#define HEADER_FILE?

忘记它是可以的,因为没有它它仍然是合法的C代码。 预处理器在编译之前处理您的文件,并在最终程序中包含指定的代码,如果没有逻辑指定它不应该的原因。 这只是一种常见的做法,但并不是必需的。

一个简单的例子可能有助于说明其工作原理:

您的头文件header_file.h包含:

 #ifndef HEADER_FILE #define HEADER_FILE int two(void){ return 2; } #endif 

在另一个文件( foo.c )中,您可能有:

 #include "header_file.h" void foo() { int value = two(); printf("foo value=%d\n", value); } 

一旦它被“预处理”并准备好编译,这将转化为:

 int two(void){ return 2; } void foo() { int value = two(); printf("foo value=%d\n", value); } 

所有包含守卫在这里完成的是确定是否应该粘贴#ifndef ...#endif之间的标题内容来代替原始的#include

但是,由于该函数未声明为externstatic ,并且实际上是在头文件中实现,因此如果您尝试在另一个源文件中使用它,则会出现问题,因为不会包含函数定义。

您可以在此处阻止多次包含该文件

 #ifndef HEADER_FILE 

如果HEADER_FILE则测试是否为真

 #define HEADER_FILE 

会定义它,现在如果你将文件包含在另一个文件中,第一次定义HEADER_FILE ,而第二次,它将被定义,因此文件的内容不再包括在内,因为#ifndef HEADER_FILE将是假的。

请记住,这些是在实际编译完成之前由预处理器评估的,因此它们在编译时进行评估。