在标头和源中都包含 <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 <stdbool.h>
?在哪些情况下我会和我不会?
如果我在另一个头文件中有一个 typedef,在头文件中用作函数参数怎么办?我必须在头文件和源文件中都#include "DataStruct.h"
吗?
标准是什么?
【问题讨论】:
在您的示例中,标头包含<stdio.h>
的原因并不明显。没有对它指定的类型的引用。你确实需要<stdbool.h>
和"DataStruct.h"
。另见What is a good reference documenting patterns of use of header files in C? 和Should I use #include
in headers?
是的,它在这里并不明显,但 <stdio.h>
,但这应该隐藏在源文件中,而不是包含在头文件中。标头定义接口。它应该是独立的(所以它需要包含<stdbool.h>
和"DataStruct.h"
);它应该是最小的并且不包含无关的标题(所以没有<stdio.h>
)!
【参考方案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?
Fastlane Beta:Bundler::GemNotFound:在任何源中都找不到 CFPropertyList-3.0.0