我正在阅读有关这两件事并且感到困惑,这两者之间有什么不同?
答案 0 :(得分:6)
绑定是一个在多个上下文中使用的单词。它总是与一件事物与另一件事物的联系有关,但是当结合行为发生时可能会有所不同。
有一个绑定时间的概念或某个组件绑定到某个其他组件的点。绑定时间的基本列表是:(1)编译时绑定,(2)链接时绑定,(3)加载时绑定,(4)运行时绑定。
编译时绑定发生在源代码编译时。对于C / C ++,有两个主要阶段,预处理器执行源文本替换,例如定义替换或宏替换,以及源文本的编译,将源文本转换为机器代码以及链接器的必要指令。
链接时的绑定是指外部符号链接到一组特定的目标文件和库。您可能有几个不同的静态库,它们具有相同的函数名称集,但函数的实际实现是不同的。因此,您可以通过选择不同的静态库来选择要使用的库实现。
加载时绑定是指加载程序将可执行文件与任何动态或共享库一起加载到内存中。加载器将函数调用绑定到特定的动态或共享库,所选择的库可能会有所不同。
运行时绑定是程序实际运行的时间,并根据当前执行的线程进行选择。
因此,链接实际上只是绑定类型之一。看看这个stackoverflow static linking vs dynamic linking,它提供了有关链接和库的更多信息。
您可能也对C ++中的std::bind
感兴趣,所以这里有一篇stackoverflow文章std::function and std::bind what are they when they should be used。
在某些东西被绑定到其他东西之前等待的时间越长,就可以在如何使用软件方面提供所需的灵活性。然而,在延迟绑定和运行时效率以及源的复杂性之间经常存在折衷。
有关绑定时间的示例,请考虑打开文件并从文件读取然后关闭它的应用程序。当文件名绑定到文件打开时,您可以选择几个不同的时间。
您可能会在编译时硬编码文件名,绑定,这意味着它只能与该文件一起使用。要更改文件名,您必须更改源并重新编译。
您可能具有用户输入的文件名,例如使用用户提示符或命令行参数,将文件名绑定到运行时打开的文件。要更改文件名,不再需要重新编译,只需使用不同的文件名再次运行程序即可。
答案 1 :(得分:0)
假设您有一个声明为:
的函数void f(int, char);
以及:
void f(int);
你用正确的签名调用函数f(4)。这是绑定。 链接器将链接到函数体的可用定义,以便与签名void f(int);
匹配答案 2 :(得分:0)
实际上两者在c编程的上下文中具有相同的含义。有些人使用绑定,有些人则使用链接。
如果你想知道链接是什么,那么这里是一个简短的解释。
假设您已经创建了一个名为sum()的用户定义函数,其声明如下所示 int sum(int,int); 然后每当从程序调用函数时,程序应该知道在内存中跳转到哪里来执行该函数。简单来说,你的程序应该知道所谓的函数地址,以便到达它的身体,这就是所谓的绑定。
现在sum是用户定义的函数,因此它将出现在源代码本身中。如果从main()调用它,那么它将在编译时链接到main,因为那时编译器将知道您的函数将在可执行文件中出现的位置。这称为静态绑定。
现在想想printf()这是库函数,它的主体在你的程序中不存在。因此,在编译程序时,printf的主体将不会出现在已编译的可执行文件中。它将在您执行程序时加载到内存中,并且它的地址在运行时将被称为main,而不是在编译时(如sum()的情况)。这种类型的链接称为动态链接。