为什么标准 C 库不需要分成 header 和实现文件?
Why don't Standard C Libraries need to be divided into a header and implementation file?
在 C++ 中创建一个 class,或者在 C 中使用 结构 创建一个 等价物 时,这总是一个好主意将其分为两个文件:一个 header 文件(用于声明)和一个实现文件(用于实际定义方法等)。
这样做是因为 method-definitions 如果它们存在于多个文件中可能会发生冲突(并且包含守卫无法阻止这种情况,因为宏仅存在于定义它们的文件中,并被复制到包含它们的文件;包含守卫防止在 同一文件 )
中多次包含相同的 header
但是,似乎很多标准 C 库实际上都定义了一些东西。让我们以 C 中的 stdlib.h
为例。这个库似乎定义了一个名为 malloc
的方法来分配内存。但是(当然)如果我在多个文件中包含 stdlib.h
,malloc 的 method-definitions 似乎没有冲突。
换句话说,如果我要用自己的内存分配方法创建自己的库(假设它不是宏函数),我将不得不在 mylib.h
中声明它并在 mylib.c
但由于某种原因这似乎不适用于 stdlib.h
。
这是如何运作的?为什么标准 C 库可以做到这一点,但 user-defined headers(不幸的是,在我看来)不能?
标准C库已经被编译成一个库,可能被称为libc.so
或MSVCRT100.DLL
。您可以提供此文件,而不是编译器将从您的 *.c
文件生成的 *.o
或 *.obj
文件。编译器 link 将此运行时库与每个程序一起静默自动地添加。
其他图书馆也是这样工作的。如果您有已编译的 OpenSSL 库,您可以 link 到库和 #include
源代码中的头文件以查看其接口,例如函数名称和原型。您不需要构建库的其他源文件。
您可以下载源代码到许多C库的实现,例如GNU libc。实际上,运行时是在 *.c
文件中实现的,您可以读取、修改、重新编译并将补丁提交给维护者,但它会提前编译到共享库中,您的编译器 link到那个。
老问题了,以后应该会有人遇到这个问题吧
我的回答是:
stdlib.h
不是 图书馆。相反,它是一个大型库的头文件,它定义了一个名为 malloc
的方法来分配内存。
即:
stdlib.h
仅包含其成员的声明(原型)。
库本身(<em>.a
或 </em>.so
in linux-OS ) 包含 malloc
方法(和其他方法)的实际定义(实现)。
but this does not appear to apply to stdlib.h for some reason.
确实如此,但唯一的区别是,在您的示例中,您依赖源文件(即 mylib.c
)来构建库。而在您在问题中使用的标准 C 案例中,如果您包含其头文件(即 stdlib.h
),它已经是一个应该链接到您的程序的库。
在 C++ 中创建一个 class,或者在 C 中使用 结构 创建一个 等价物 时,这总是一个好主意将其分为两个文件:一个 header 文件(用于声明)和一个实现文件(用于实际定义方法等)。
这样做是因为 method-definitions 如果它们存在于多个文件中可能会发生冲突(并且包含守卫无法阻止这种情况,因为宏仅存在于定义它们的文件中,并被复制到包含它们的文件;包含守卫防止在 同一文件 )
中多次包含相同的 header但是,似乎很多标准 C 库实际上都定义了一些东西。让我们以 C 中的 stdlib.h
为例。这个库似乎定义了一个名为 malloc
的方法来分配内存。但是(当然)如果我在多个文件中包含 stdlib.h
,malloc 的 method-definitions 似乎没有冲突。
换句话说,如果我要用自己的内存分配方法创建自己的库(假设它不是宏函数),我将不得不在 mylib.h
中声明它并在 mylib.c
但由于某种原因这似乎不适用于 stdlib.h
。
这是如何运作的?为什么标准 C 库可以做到这一点,但 user-defined headers(不幸的是,在我看来)不能?
标准C库已经被编译成一个库,可能被称为libc.so
或MSVCRT100.DLL
。您可以提供此文件,而不是编译器将从您的 *.c
文件生成的 *.o
或 *.obj
文件。编译器 link 将此运行时库与每个程序一起静默自动地添加。
其他图书馆也是这样工作的。如果您有已编译的 OpenSSL 库,您可以 link 到库和 #include
源代码中的头文件以查看其接口,例如函数名称和原型。您不需要构建库的其他源文件。
您可以下载源代码到许多C库的实现,例如GNU libc。实际上,运行时是在 *.c
文件中实现的,您可以读取、修改、重新编译并将补丁提交给维护者,但它会提前编译到共享库中,您的编译器 link到那个。
老问题了,以后应该会有人遇到这个问题吧
我的回答是:
stdlib.h
不是 图书馆。相反,它是一个大型库的头文件,它定义了一个名为 malloc
的方法来分配内存。
即:
stdlib.h
仅包含其成员的声明(原型)。
库本身(<em>.a
或 </em>.so
in linux-OS ) 包含 malloc
方法(和其他方法)的实际定义(实现)。
but this does not appear to apply to stdlib.h for some reason.
确实如此,但唯一的区别是,在您的示例中,您依赖源文件(即 mylib.c
)来构建库。而在您在问题中使用的标准 C 案例中,如果您包含其头文件(即 stdlib.h
),它已经是一个应该链接到您的程序的库。