6

我不太明白有标题的意义。这似乎违反了 DRY 原则!标头中的所有信息都(可以)包含在实现中。

4

9 回答 9

20

它简化了编译过程。当你想独立编译单元时,你需要一些东西来描述将链接到的部分,而不必导入所有其他文件的全部。

它还允许隐藏代码。可以分发标头以允许其他人使用该功能而无需分发实现。

最后,它可以鼓励接口与实现的分离。

它们不是解决这些问题的唯一方法,但 30 年前它们是一个很好的方法。我们今天可能不会将头文件用于一种语言,但它们并不是在 2009 年发明的。

于 2009-10-02T04:43:42.373 回答
4

许多现代语言(如 Java、Eiffel 和 C#)的架构师显然同意您的观点——这些语言从实现中提取有关模块的元数据。然而,就其本身而言,标头的概念并不排除这一点——例如,编译器在编译.h. .c当前典型的 C 编译器不这样做的事实不是语言设计问题,而是实现问题;显然用户对这样的功能没有需求,所以没有编译器供应商会费心去实现它。

作为一种语言设计选择,拥有单独.h的文件(以人类可读和可编辑的文本格式)可以让您两全其美:如果您愿意,您可以根据尚不存在的模块实现单独编译客户端代码,通过手写.h文件;或者您(荒谬地假设提供它的编译器实现;-)可以.h从实现中自动获取文件作为编译它的副作用。

如果 C、C++ 和 c 继续蓬勃发展(显然他们今天仍然做得很好;-),并且像您这样不手动编写头文件的需求增长,最终编译器编写者将不得不提供“头文件生成”选项,并且“两全其美”不会停留在理论上!-)

于 2009-10-02T04:56:58.787 回答
3

考虑一下在编写 c 时可用的计算机的功能会有所帮助。主内存以千字为单位,不一定很多。磁盘更大,但不多。严重的存储意味着卷到卷的磁带,由脾气暴躁的操作员手工安装,他们真的希望你离开,这样他们就可以打猎。一台 1 MIPS 的机器正在快速尖叫。由于所有这些限制,您必须分享它。可能与其他用户的分数。

任何降低编译空间时间复杂度的东西都是一个巨大的胜利。标题两者兼而有之。

于 2009-10-02T04:54:34.020 回答
2

当 C 发明文件时,检查语言处理器的二进制输出文件的整个想法很难理解.h。有一个名为JOVIAL的系统做了类似的事情,但它是异国情调的,或多或少地仅限于军事项目。(我从未见过 JOVIAL 节目,我只听说过。)

因此,当 C 语言出现时,通常的模块化设计模式是“没有任何检查”。可能存在 .text 符号只能链接到 .text 和 .data 到 .data 的限制,但仅此而已。也就是说,当时的编译器通常一次处理一个源文件,然后链接器将它们放在一起而没有丝毫错误检查,如果幸运的话,“我是一个函数符号”与“我是一个数据符号”。

所以让编译器真正理解你调用的东西的想法有点新。

即使在今天,如果你制作了一个完全伪造的头文件,在大多数AOT 编译器中也没有人能抓住你。像 CLR 语言和 Java 这样的聪明东西实际上确实在类文件中进行了编码。

所以是的,从长远来看,我们可能不会有头文件。

于 2009-10-02T08:25:02.147 回答
2

不要忘记标题提供的文档。使用该模块通常需要了解其中的任何内容。就我而言,我不想扫描一个 looong 源代码来了解我需要使用什么以及如何调用它......无论如何你都会提取这些信息,这实际上会导致 - 一个头文件。当然,现代 IDE 不再是问题,但是使用一些旧的 C 代码时,我真的很喜欢手工制作的头文件,其中包含有关用法和前置条件和后置条件的注释。

保持源代码、标题和其他文档同步仍然是另一种蠕虫……

于 2009-10-02T08:55:37.807 回答
1

不,您在 Java 中没有标头——但您确实有接口,我每个认真的 Java 大师都建议您将其他项目/系统使用的任何东西定义为接口和实现。

让我们看看一个 java 接口定义包含调用签名、类型定义和内容。

MOST C 头文件包含调用签名、类型定义和常量。

因此,出于所有实际目的,C/C++ 头文件只是接口定义,因此应该被认为是一件好事。现在我知道它也可以在头文件中定义无数其他东西(MARCRO,常量等),但这只是整个 C 美妙世界的一部分:-

int function target () {
    // Default for shoot
    return FOOT;
}
于 2009-10-02T06:36:03.843 回答
1

有关详细信息,请阅读

头文件通常包含类、子例程、变量和其他标识符的前向声明。希望在多个源文件中声明标准化标识符的程序员可以将此类标识符放在单个头文件中,然后在需要头文件内容时,其他代码可以包含该头文件。

C 标准库和 C++ 标准库传统上在头文件中声明它们的标准函数。

于 2009-10-02T06:39:07.897 回答
0

如果你想给其他人声明以使用你的库而不给他们实现呢?

正如另一个答案指出的那样 - 标头的最初原因是使用非常简单且有限的工具使平台上的解析/编译更容易。拥有一台带有 2 个软盘的机器是向前迈出的一大步,这样您就可以在一个上安装编译器,在另一个上安装您的代码——这让事情变得容易多了。

于 2009-10-02T04:42:44.413 回答
0

当您在头文件和源文件中划分代码时,您将声明和定义分开。当您查看头文件时,您可以看到您拥有的内容,如果您想查看实现细节,请转到源文件。

于 2009-10-02T11:39:10.990 回答