可能重复:
头文件和库文件的区别是什么?
有人能告诉我头文件和库文件的实际含义及其区别吗?
例如,我们在程序中包含扩展名为.h的头文件,它只是定义,而实际实现是在库文件中定义的,这是在链接阶段完成的。这就是人们所说的,但有时我们也会将库文件目录包含在程序中,以生成可执行文件。例如,在posix线程中,人们说要在命令行中包括-lpthread,但是为什么当我们包含头文件#include<>时,仍然需要包含库文件呢?请问原因是什么?
可能重复:
头文件和库文件的区别是什么?
有人能告诉我头文件和库文件的实际含义及其区别吗?
例如,我们在程序中包含扩展名为.h的头文件,它只是定义,而实际实现是在库文件中定义的,这是在链接阶段完成的。这就是人们所说的,但有时我们也会将库文件目录包含在程序中,以生成可执行文件。例如,在posix线程中,人们说要在命令行中包括-lpthread,但是为什么当我们包含头文件#include<>时,仍然需要包含库文件呢?请问原因是什么?
一般来说,头文件会告知编译器某些事情(主要是它们的存在或声明),以便于编译器能够正确地构建单个转换单元(例如单个 C 文件)。
库文件是实际的可执行代码,其中包含在头文件中指定的功能。这通过链接器链接提供实际的功能(即定义而不仅仅是声明)。
因此,在你的示例中,你可能会有以下一行代码:
#include <pthread.h>
这告诉编译器关于 pthread_mutex_this
、pthread_condvar_that
和 pthread_thread_the_other
等内容的存在,但并没有提供它们的实现。
-lpthread
选项告诉链接器应该基于 pthread
名称来查找库,并从中获取实现,以便形成最终可执行文件。
同样地,虽然 stdio.h
包含有关 I/O 相关内容的信息,但实际的代码将在运行时库中(尽管您很少需要特别链接该库,因为编译器会尝试自动处理)。因为通常是通过编译器进行链接(即编译器会为您调用链接器),所以它知道您可能需要 C 运行时库。如果您直接使用链接器(例如使用 ld
命令),那么这种情况可能不会发生,您需要显式指定。
-lmath
(对于那些将其与C RTL分开的环境)。但是为什么通常不需要这样做的原因在我的答案的最后一段中有解释 - 我会稍微详细说明一下。 - paxdiablo库文件: 这些文件是编译器用来定义已在程序中使用并在头文件中声明的函数的文件。例如,printf()在I/O库中具有完整的定义,如它将如何工作等等。因此,编译器使用该库来获取printf的机器代码。
区别:
i. 函数的实现包含在头文件中。
ii. 函数的实现在你可以获取源代码的c文件中。
iii. 所需的库由编译器默认包含, 例如标准c库。
注意: 这里有一个参考标准C库包含了什么内容,它被许多编译器默认包含。