我不太明白有一个标题;它似乎违反了DRY原则!标题中的所有信息都(可以)包含在实现中。
答案 0 :(得分:20)
它简化了编译过程。当您想要独立编译单元时,您需要一些东西来描述将链接到的部分,而无需导入所有其他文件的全部内容。
它还允许代码隐藏。可以分发标头以允许其他人使用该功能,而无需分发实现。
最后,它可以鼓励界面与实现分离。
它们不是解决这些问题的唯一方法,但30年前它们是一个很好的问题。我们今天可能不会使用头文件作为语言,但它们不是在2009年发明的。
答案 1 :(得分:4)
Java,Eiffel和C#等许多现代语言的架构师都明确同意 - 这些语言从实现中提取有关模块的元数据。但是,本身的标题概念并不排除 - 编译器在编译.h
时提取.c
文件显然是一项简单的任务,例如,就像那些其他语言的编译器是隐含的。典型的当前C编译器不这样做的事实不是语言设计问题 - 这是一个实现问题;显然,用户对这样的功能没有要求,因此没有编译器供应商不愿意实现它。
作为一种语言设计选择,拥有单独的.h
文件(以人类可读和可编辑的文本格式)为您提供两全其美的优势:您可以根据模块实现单独编译客户端代码如果您愿意,还可以通过手工编写.h
文件来存在;或者你(通过荒谬的假设一个提供它的编译器实现;-)可以自动从实现中获取.h
文件作为编译它的副作用。
如果C,C ++和& c,保持蓬勃发展(显然他们今天仍然很好;-),并且像你那样不需要手动编写标题的需求增长,最终编译器编写者将不得不提供“标题生成”选项,“两全其美”都不会理论化! - )
答案 2 :(得分:3)
当编写c时,有必要仔细考虑一下可用的计算机的功能。主记忆以千瓦为单位进行测量,而不一定非常多。磁盘更大,但不多。 Serrious存储意味着卷轴式磁带,由手工安装,由脾气暴躁的操作员,他们真的希望你离开,这样他们就可以玩狩猎wumpus。 1 MIPS的机器快速尖叫。由于所有这些限制,您必须分享它。可能还有其他用户的分数。
任何减少空间或编译时间复杂度的事情都是一个巨大的胜利。标题同时执行。
答案 3 :(得分:2)
当C发明.h
文件时,很难理解检查语言处理器的二进制输出文件的整个想法。有一个名为JOVIAL的系统可以做类似的事情,但这种系统很奇特,并且或多或少都只限于军事项目。 (我从未见过JOVIAL计划,我只是听说过。)
因此,当C出现时,模块化的通常设计模式是“无需检查”。可能存在一个限制,即.text符号只能链接到.text和.data到.data,但就是这样。也就是说,当天的编译器通常一次处理一个源文件然后链接器将它们放在一起而没有任何级别的错误检查,除非你是幸运的,“我是一个功能符号”vs“我是数据符号“。
所以实际让编译器理解你所调用的东西的想法有点新。
即使在今天,如果你制作了一个完全虚假的标题,那么大多数AOT compilers都没有人抓住你。像CLR语言和Java这样聪明的东西实际上会对类文件中的内容进行编码。
所以是的,从长远来看,我们可能不会有头文件。
答案 4 :(得分:2)
不要忘记标题提供的文档。使用该模块时,您通常需要了解其中的任何内容。我本人不想扫描一个looong源代码来了解我需要使用的内容以及如何调用它...无论如何,你将提取这些信息,这实际上会导致 - 头文件。当然,不再是现代IDE的问题,但是使用一些旧的C代码我真的很喜欢手工制作的头文件,其中包含有关使用情况和前后条件的评论。
保持源,标题和其他文档同步仍然是另一种蠕虫......
答案 5 :(得分:1)
不,你没有Java中的标题 - 但是你确实有接口,而且每个认真的Java大师都建议你将其他项目/系统使用的任何东西定义为接口和实现。
让我们看一下java接口定义包含调用签名,类型定义和内容。
MOST C头文件包含呼叫签名,类型定义和常量。
因此,对于所有实际目的,C / C ++头文件只是接口定义,因此应被视为好东西。现在我知道可以在头文件中定义无数其他东西(MARCRO,常量等等),但这只是整个C世界的一部分: -
int function target () {
// Default for shoot
return FOOT;
}
答案 6 :(得分:1)
详情阅读this
头文件通常包含类,子例程,变量和其他标识符的前向声明。希望在多个源文件中声明标准化标识符的程序员可以将这些标识符放在单个头文件中,然后只要需要标题内容,就可以包含其他代码。
C标准库和C ++标准库传统上在头文件中声明它们的标准函数。
答案 7 :(得分:0)
如果你想给其他人声明使用你的库而不给他们实现呢?
正如另一个答案所指出的 - 标题的最初原因是使用非常简单和有限的工具在平台上使解析/编译更容易。拥有2张软盘的机器是一个很好的一步,所以你可以将编译器放在另一台上,而将代码放在另一台上 - 使事情变得更容易。
答案 8 :(得分:0)
当您在标题和源文件中划分代码时,您需要划分声明和定义。当您查看头文件时,您可以看到您拥有的内容,如果您想看到实现细节,请转到源文件。