c - 为什么标准 C 库不需要分为头文件和实现文件?
问题描述
在 C++ 中创建一个类,或在 C 中使用structs创建一个等价类时,最好将其分成两个文件:一个头文件(用于声明)和一个实现文件(用于实际定义方法等)。
这样做是因为如果方法定义存在于多个文件中,它们可能会发生冲突(并且包含保护不能阻止这种情况,因为宏只存在于定义它们的文件中,并被复制到包含它们的文件中;包含保护防止在同一个文件中多次包含相同的标题)
然而,似乎许多标准 C 库实际上定义了一些东西。让我们stdlib.h
以 C 语言为例。这个库似乎定义了一个malloc
分配内存的方法。但是(当然)如果我包含stdlib.h
在多个文件中,则 malloc 的方法定义似乎没有冲突。
换句话说,如果我要使用自己的内存分配方法创建自己的库(假设它不是宏函数),我将不得不在其中声明它mylib.h
并实际定义它,mylib.c
但这似乎不适stdlib.h
用于某种原因.
这是如何运作的?为什么标准 C 库可以做到这一点,但用户定义的标头(不幸的是,在我看来)不能?
解决方案
标准 C 库已经被编译成一个库,它可能被称为类似libc.so
或MSVCRT100.DLL
. 您可以提供此文件,而不是编译*.o
器*.obj
将从您的文件生成的*.c
文件。编译器会自动将此运行时库与每个程序链接。
这也是其他库的工作方式。如果您有已编译的 OpenSSL 库,您可以链接到#include
源代码中的库和头文件以查看其接口,例如函数名称和原型。您不需要构建库的其他源文件。
您可以将源代码下载到 C 库的许多实现中,例如 GNU libc。运行时实际上是在*.c
文件中实现的,您可以读取、修改、重新编译并向维护者提交补丁,但它会提前编译到共享库,并且您的编译器会链接到该库。
推荐阅读
- java - 如何根据 2 个值从地图中过滤文档并创建另一个地图
- linux - 什么时候不使用 -r 和 cp?
- sql-server - 将一个巨大的 XML 字符串传递给一个存储过程并进一步解析它,使用解析的元素作为参数来调用另一个存储过程
- r - 将 `rlang::exec` 与使用 `rlang::ensym` 的函数一起使用
- javascript - 为什么 Chrome 控制台选项卡中未定义私有变量?
- python - 从维护其他数字的数据框中删除 .0
- json - 在 JSON 文件中获取此结构的好方法是什么
- c# - 指定的资源名称长度不在允许的限制范围内 Azure Blob 存储
- reactjs - 无法将 Office UI Fabric React 组件添加到现有项目
- sharepoint - MS Graph API 调用在本地主机上给出 403(以前工作过)