为什么头文件确保C程序的模块化?

时间:2015-12-30 12:57:46

标签: c compiler-construction header-files modularity

当C书和论文谈论暴露界面(.h文件)和隐藏实现时,我感到困惑。当C主程序想要访问像队列这样的数据结构时,它会包含queue.h到源。然后他们会谈到queue.c隐藏在主程序之外,即main无法访问具体的队列类型。

现在的问题是:实现的含义是隐藏在主程序中,只能通过头文件通过定义的接口访问它

main program
------------
//call a function from .h file
Afunction();

function.h
----------
// prototypes
void Afunction(void) 

 function.c
 ---------
 // concrete implementation 
void Afunction(void) {
   // your statements here..
    {

我正在寻找答案,甚至跨越编译器设计,如果这对我来说很清楚。谢谢

2 个答案:

答案 0 :(得分:2)

我们在编程和一般工程学中,也许在任何人类努力中学到的重要事情之一是,如果你先把它分成更小的问题,然后解决每一个问题就更容易解决问题。那些问题分开了。毕竟,这比一次跳高10英尺更容易跳得高一倍。

但是对于这种类型的模块化工作,希望如此,那些较小的问题需要彼此独立,所以你真的可以解决它们中的每一个,而不必同时考虑所有其他问题。如果您想设计一款汽车,并将其分为发动机,变速箱和转向系统,您希望能够在不考虑转向和转向的情况下尽可能地设计变速箱,而无需考虑变速箱。否则,它仍然是一个大问题,而不是几个小问题。实际上,如何实现变速器的细节必须从转向中隐藏,可以这么说。

作为C的一个例子,想想printf函数,你可能已经多次从程序中调用过它。您#include的头文件stdio.h包含printf声明,如下所示:

extern int printf (const char *format, ...);

但在printf文件中还有.c定义,它是C标准库的一部分。该定义包含解释格式说明符(如%10.4f)的实际代码,并将内容打印到标准输出。它可能会或可能不会以源代码形式出现在您的计算机上,但只要您的程序调用{​​{1}},就会使用已编译的表单。

现在,你有没有必要担心printf的内部细节?可能不是,这是一件好事。它是隐藏的,不是因为它是秘密的或受版权保护的,所以你不必担心它。

答案 1 :(得分:1)

C在隐藏实现细节方面做得不好。除非您准备仅将它们作为指针导出,否则无法隐藏数据类型的结构。不过,这还有很长的路要走。

考虑标准FILE数据类型。 FILE的实现需要有很多细节,包括操作系统将对象与实际数据流关联所需的任何内容,当前缓冲区和缓冲区位置,EOF和错误标记以及一堆我现在想不起的其他事情,因为我不需要知道。

虽然我每天都使用FILE,但我不需要考虑任何这些事情。我只是以I / O库提供的方式使用FILE*,而不用担心细节是如何实现的。即使我想,我也不能拿出我的扳手并修改内部数据成员。这很好,因为如果我尝试的话,我几乎肯定会弄错。

将程序划分为单独的编译单元也意味着我不需要了解I / O库用于实现其外部API的内部函数。毫无疑问,它使用了许多内部函数,每个函数都有一个名称。如果我的代码可以看到这些名称,我必须确保我不会出于自己的目的而意外使用它们。幸运的是,我(大多数时候)不必担心,因为这些名称(大部分)是隐藏的。