【问题标题】:What is the point of header files in C? [duplicate]C中的头文件有什么意义? [复制]
【发布时间】:2011-01-12 04:21:42
【问题描述】:

可能的重复:
[C] Header per source file.
In C++ why have header files and cpp files?
C++ - What should go into an .h file?

头文件存在于 C 中的唯一原因是开发人员可以快速查看哪些函数可用,以及它们可以接受哪些参数?还是和编译器有关?

为什么没有其他语言使用这种方法?是我一个人,还是看起来有 2 组函数定义只会导致更多的维护和更多的错误空间?还是每个 C 开发人员都必须知道的头文件?

【问题讨论】:

标签: c header-files


【解决方案1】:

存在标头的主要原因是为了在多个源文件之间共享声明。

假设您在文件a.c 中定义了函数float *f(int a, int b),并在b.cd.c 中重复使用。为了让编译器能够正确检查参数和返回值,您可以将函数原型放在头文件中并将其包含在 .c 源文件中,或者在每个源文件中重复原型。

typedef 等也是如此。

虽然理论上您可以在每个源文件中重复相同的声明,但正确管理它将成为一场真正的噩梦。

某些语言使用相同的方法。我记得 TurboPascal 单位并没有太大的不同。您可以将use ... 放在开头,表示您将需要在其他地方定义的函数。我不记得它是否也被传递到了 Delphi。

【讨论】:

    【解决方案2】:
    1. 了解图书馆中可供您使用的内容。
    2. 为编译器将程序分割成一口大小的块。同时编译一兆字节的 C 文件将占用比大多数现代硬件所能提供的更多的资源。
    3. 减少编译器负载。为什么要在屏幕显示程序中知道深度数据库引擎?让它只学习它现在需要的功能。
    4. 分离私人和公共数据。这种用法并不常见,但您可以在 C 中实现 C++ 使用私有字段的用途:每个 .c 文件包括两个 .h 文件,一个带有私有内容的声明,另一个带有其他文件可能需要的任何内容。命名空间冲突的可能性较小,由于密封而更安全。
    5. 备用配置。 Makefile 决定使用哪个头文件,相同的代码可以服务于两个不同的平台给定两个不同的头文件。

    可能更多。

    【讨论】:

    • “为什么要在屏幕显示过程中知道深度数据库引擎”……虽然如果在实现中是这样的话,那么项目可能比构建资源有更大的问题。
    • @CarlG:你从来没有编写过嵌入式设备,是吗?
    • 没有。在这样的系统中,不可能从存储中模块化视图吗?还是只是不切实际?如果可能的话,我会认为深度数据库引擎会更好地卸载到单独的嵌入式系统甚至(联网?)服务。
    • @CarlG:取决于系统,通常只是非常不切实际。模块化,在代码级别;将两者编译成加载到一个处理器中的一个二进制文件,通常没有操作系统和/或文件系统。仅仅为了模块化而将它们卸载到两个不同的处理器会给你带来很多与控制两者之间的硬件总线有关的头痛,这真的不值得。 (理论上只有 2 个 I/O 端口与直接总线相连。实际上,调试振铃、寄生负载、寄生电感和电容、EMI、时序警告、电平、时钟同步......)
    • @CarlG: 并将它们卸载到要在同一处理器上运行的两个单独的可执行文件通常与编写某种操作系统有关,该操作系统将仲裁对共享资源的访问,同步时间并提供上下文切换;通常是比单独执行的每个子任务更复杂的任务。将这些东西保存在单个二进制文件中确实大大简化了工作。
    【解决方案3】:

    编译器需要头文件中的信息来了解哪些函数、结构等可用以及如何使用它们。

    所有语言都需要这种信息,尽管它们以不同的方式检索信息。例如,Java 编译器通过扫描类文件或 Java 源代码来检索信息。

    Java 方式的缺点是编译器可能需要在其内存中保存更多信息才能执行此操作。这在今天没什么大不了的,但是在 70 年代,当 C 语言被创建时,根本不可能在内存中保留这么多信息。

    【讨论】:

    • 似乎大多数新语言甚至编译的语言都不再需要头文件了。那么如果我们要重新创建 C,你会说现在头文件是多余的吗?
    【解决方案4】:

    需要头文件来声明可用的函数和变量。您可能根本无法访问定义(=.c 文件); C 支持在库中仅以二进制方式分发代码。

    【讨论】:

    • 为什么它不直接扫描包含的 C 文件来检查里面的内容,这是我不明白的。
    • @chris 正如我所说,没有要求您拥有要调用的函数的源代码。并且没有要求平台的二进制格式包含编译器可以读取的信息,它不是那样做的。也许“愚蠢”,但事实就是如此。
    • 当你在同一个文件中有 .c 源代码,或者你包含另一个 c 源文件时,我认为编译成功,但前提是函数在调用之前定义。当您进行循环调用时,这是一个问题(尽管理论上您应该能够编写没有循环依赖关系的代码)。我想你可以说它们就像树状结构文件系统中的符号链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 2011-11-10
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多