在标头和源中都包含 <stdbool.h> 吗?

Posted

技术标签:

【中文标题】在标头和源中都包含 <stdbool.h> 吗?【英文标题】:include <stdbool.h> in both the header and the source? 【发布时间】:2014-02-03 04:57:11 【问题描述】:

我还是 C 的新手。我对源文件和头文件有疑问。我有一个这样的头文件:

#ifndef MISC_H_
#define MISC_H_
#define BYTE 8

#include <stdbool.h>
#include <stdio.h>
#include "DataStruct.h"

bool S_areEqual(char *firstString, char *secondString); /* (1) */
bool S_randomDataStructureCheck(char *string, DataStruct *data); /* (2) */

#endif

    bool 用于函数参数,因此,我在源代码中也有它。我是否必须在头文件和源文件中都使用#include &lt;stdbool.h&gt;?在哪些情况下我会和我不会?

    如果我在另一个头文件中有一个 typedef,在头文件中用作函数参数怎么办?我必须在头文件和源文件中都#include "DataStruct.h" 吗?

标准是什么?

【问题讨论】:

在您的示例中,标头包含&lt;stdio.h&gt; 的原因并不明显。没有对它指定的类型的引用。你确实需要&lt;stdbool.h&gt;"DataStruct.h"。另见What is a good reference documenting patterns of use of header files in C? 和Should I use #include in headers? 是的,它在这里并不明显,但 在源代码中的函数本身的错误检查期间使用。 感谢@JonathanLeffler 您需要区分代码用户所需的标头和实现代码所需的标头。代码客户端使用的标头应仅包含代码用户所需的标头。实现该功能的代码很可能需要&lt;stdio.h&gt;,但这应该隐藏在源文件中,而不是包含在头文件中。标头定义接口。它应该是独立的(所以它需要包含&lt;stdbool.h&gt;"DataStruct.h");它应该是最小的并且不包含无关的标题(所以没有&lt;stdio.h&gt;)! 【参考方案1】:

不,您不必同时包含在头文件和源 (.c) 文件中。如果您已包含在源包含的标头中,那么源也可以使用它。当某些标头依赖于其他标头时,标头包含的顺序可能很重要。详情请参阅this answer。

顺便说一句,你会注意到这些线条

#ifndef MISC_H_
#define MISC_H_

这样可以确保标题只包含一次。

更新

来自cmets:

所以在源代码中,您只包含其各自的标题?

如果您的意思是,如果源文件包含其各自的标题,那么这取决于。通常,文件应该包含他们需要的文件。

如果一个源文件需要一个头文件,但它自己的头文件不需要这个头文件,那么包含应该进入源文件而不是它的头文件。一个原因是,每个文件只包含它需要的文件,这在概念上更简洁,因此很容易分辨出依赖关系是什么。另一个原因是它减少了变化的影响。

让我们看一个例子。假设你有 foo.c 和 foo.h 并且 foo.c 需要 foodep.h 来编译,但 foo.h 不需要:

选项 1:foo.h

#include "foodep.h"

现在假设有许多其他文件 foo1.h、foo2.h、foo3.h 等包含 foo.h。然后,对 foodep.h 的任何更改都会影响所有其他文件及其相关的头文件和源文件。

选项 2:foo.c

#include "foodep.h"

现在,没有其他文件可以看到 foodep.h。对 foodep.h 的更改只会影响 foo.c。

通常,尝试应用与面向对象编程相同的做法 - 封装并最小化更改范围。

【讨论】:

所以在源代码中,您只需包含其各自的标题? 是的;定义函数的源代码必须包含声明函数的标头,就像使用函数的源代码必须包含标头一样。标头确保函数的定义和使用正确一致。【参考方案2】:

查看这一点的简单方法是,您应该始终包含提供您在程序中使用的函数/别名/宏的标头,是否真正需要包含它们应该留给编译器。

这是因为每个标头都是在#ifdef - #endif 子句下定义的,条件是某些标头特定的 MACRO(如果您定义自己的标头,则必须这样做,以避免多次包含,从而避免痛苦的编译器错误)。

因此,我的建议是,如果您在程序中使用bool,则应包含stdbool.h。如果编译器已经将它包含在其他一些头文件的定义中,它将不会再次包含stdbool

【讨论】:

以上是关于在标头和源中都包含 <stdbool.h> 吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Xcode 4 在每个标头中都包含 iostream?

预处理器#ifndef

Chapter 9 (排序)

Fastlane Beta:Bundler::GemNotFound:在任何源中都找不到 CFPropertyList-3.0.0

数组的增,删

Rails bundle install 在任何源中都找不到 turbo-rails-7.1.1