首先,混淆是因为预处理器已经将头文件包含在包含函数的代码中,哪些库函数链接到汇编器/编译器生成的对象文件?部分混乱主要是由于我对头文件和库之间的差异的无知.经过一番谷歌搜索和堆栈溢出(这是术语?:p),我收集到头文件大多包含函数声明,而实际的实现是在另一个二进制文件中被称为库(我还不是100%肯定这个).
所以,假设在以下程序中:
#include<stdio.h> int main() { printf("whatever"); return 0; }
预处理器包括代码中头文件的内容.编译器/编译器汇编程序完成其工作,然后最终链接器将此目标文件与实际存储的printf工作方式的另一个目标文件相结合.
我的理解正确吗?我可能会离开…你可以帮我吗?
谢谢.
编辑: – 我有alwayss想知道C STL ..它总是困惑我,它究竟是什么?收集所有这些标题或什么?现在看完回应后,我可以说STL是一个对象文件/类似于目标文件的东西?
而且,我想我可以读取功能定义的功能,如pow(),sqrt()等等.我打开ehader文件,找不到任何东西.那么,库中的函数定义是以二进制不可读的形式呢?
解决方法
预处理器是执行文本操作的实用程序.它将输入包含预处理指令的文本(通常为C源代码)的文件,并通过将指令应用于文本来输出文件的修改版本.该文件不必是C源代码,因为预处理器正在进行文本处理.我已经看到C Preprocssor用于扩展make实用程序,允许将preprossor指令包含在make文件中,然后将输出输入make.
库是一个包含各种功能的对象代码的文件.它是一种将多个源文件的输出编译成单个文件的方法.很多时候提供了一个库文件以及包含函数声明以及预处理器指令的头文件.h文件.所以要使用库,你包括使用#include指令提供的头文件,并链接到库文件.
链接器是一个实用程序,它接收各种对象文件和库文件来创建可执行文件.当使用外部或全局函数或变量时,C源文件使用一种标记来告诉链接器,需要在该点插入函数或变量的地址. C编译器只知道它编译的源代码,而不知道其他文件(如目标文件或库)中的内容.因此,链接器的工作是使用各种对象文件和库,并使用全局函数或对象文件和库中的变量以及为该全局函数或变量生成的实际对象代码之间的最终连接.在某些情况下,相同的全局函数名称可能会用在几个不同的对象文件或库中,因此链接器通常只会使用第一个对象文件或库,并发出关于其他人发现的警告.
因此,C程序的编译和链接的基本过程是:
– 预处理器实用程序生成要编译的C源
– 编译器将C源编译成生成一组的对象代码
对象文件
– 链接器将各种对象文件与任何库连接
可执行文件