在C语言中使用include的最佳实践

3

我正在学习 C 语言,但不确定在哪里包含文件。基本上我可以在以下两种文件中完成:

选项1

test.h

int my_func(char **var);

test.c

#include <stdio.h>
#include "test.h"
int my_func(char **var) {printf("%s\n", "foo");}
int main() {...}

选项 2

test.h

#include <stdio.h>
int my_func(char **var);

test.c

#include "test.h"
int my_func(char **var) {printf("%s\n", "foo");}
int main() {...}

使用选项2,我只需要在需要该库的任何.c文件中包含test.h。我看到的大部分示例使用选项1

是否有一些普遍规则来确定何时采取何种方法,还是这是个人偏好的问题?


请注意,这通常取决于您的 test.h 文件是否实际声明了依赖于 stdio.h 的内容,而在您的情况下并没有。但是,如果 .h 文件包含引用,例如来自 stdio.h 的 EOFFILE*,许多人会对使用选项1或2有不同的偏好。 - nos
我想在我的函数中使用stdio功能。我已经通过在函数中添加printf来修改了示例。感谢您指出这一点。 - Spliffster
1
这不是我想表达的意思。你的.h文件仍然不依赖于stdio.h中的任何内容。你的.c文件可能会,但是.h文件才是重要的。除了test.c之外,包含你的test.h文件的人不需要知道在你的情况下这些函数使用了stdio.h。如果test.h有一个函数int my_func(FILE *output),那就是另一回事了。 - nos
7个回答

5
不要使用include,您不需要它们。
我会选择类似“选项1”的东西。为什么是“类似”?因为我会为main创建一个单独的文件,并将所有声明放在.h中,将所有定义放在相应的.c中。
当然,两个选项都是有效的。
如果您只想在main中包含一个头文件,您可以创建一个只包含include的头文件 - 这是一种常见的做法。这样,您就可以只包含一个头文件,而不是多个。

3

我倾向于选择选项1,因为在选项2中,循环依赖关系会很快出现问题,而减少输入大小是保证更快编译时间的最佳方法。选项2往往倾向于将所有内容都包含在内,无论你是否真正需要。

尽管如此,最好还是尝试一下什么样的项目结构适合你。对这些问题而言,硬性规则往往不适用于所有情况。


2

两种选项都是正确的。C标准允许这两种解决方案。

所有C标准头文件必须被设计为可以被多次包含且顺序任意:

标准头文件可以按任意顺序包含;在给定范围内可以多次包含每个标准头文件,其效果与仅包含一次相同。

(来自预处理器#ifndef)


0

我认为没有普适的规则(从“语法”角度来看,你的两个选项都是正确的并且可行的)。通常做法是在.h文件中包含库所需的头文件(就像你的选项1一样),要么是因为在使用库时需要它们(这样可以避免在.c文件中始终包含相同的头文件集合,这更容易出错),要么是因为它们在.h文件本身中被提到(例如,如果您在.h文件的函数原型中使用int32_t作为类型,则当然需要在.h文件中包含<stdint.h>)。


0

我更喜欢在C文件中使用包含(includes)。 如果您的程序变得越来越大,您可能会忘记在一个头文件中包含某些内容,但它已经被包含在您使用的另一个头文件中。 通过将它们包含在C文件中,您不会失去这些包含,同时编辑其他文件。


0

我更喜欢选项1。我想知道我在项目中使用了什么,而且在时间和效率方面,选项1比选项2更有效。


0

没有规定你必须遵循特定的方式。即使你在 test.c 文件中包含/不包含,只要你在 test.h 文件中包含它并将该 test.h 文件包含在 test.c 中,就不会有太多问题。希望你清楚了。

这是因为你有预处理器指令如 #ifndef,#define,#endif。它们被称为 包含保护 。它们用于内置头文件。但是,当你包含一个自己编写的文件时,要么选择选项2,要么使用包含保护以确保安全。

包含保护的工作原理如下。 #ifndef ANYTHING #define ANYTHING ... ... ... #endif

因此,在首次包含时,ANYTHING 尚未定义。所以 ifndef 返回 true,然后 ANYTHING 被定义,这样依次进行。但是,如果下一次你错误地包含同一文件,由于 ANYTHING 已经被定义,所以 ifndef 将返回 false,因此文件根本不会被包含。这种保护是必要的,以避免头文件中变量的重复声明。否则会产生编译错误。

希望能帮到你 干杯


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接