链接到包含文件与链接到lib文件有什么区别?
我是C/C++的新手,我很难搞清楚使用包含文件和静态lib文件来调用函数之间的区别.在我看来,包含文件具有可以像.lib文件一样调用的函数.
Mac*_*Mac 37
在C++(和C和其他类似语言)中,一个函数被认为既有声明又有定义.
声明只是一个简短的声明,声明函数存在,以及它的界面是什么样的.考虑一个add将两个整数相加的基本函数.其声明可能如下所示:
int add(int, int);
Run Code Online (Sandbox Code Playgroud)
这意味着"存在一个add带两个整数并返回整数的函数".尽管我们可以根据其名称做出一个很好的猜测,但它没有具体说明函数的实际功能.
函数的定义是我们确切定义函数的作用的地方.这可能是您认为的实际功能代码.使用add功能作为一个例子:
int add (int a, int b)
{
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
那么这与你的问题有什么关系呢?好吧,假设我们有许多数学函数math.cpp:
// math.cpp
int add (int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
Run Code Online (Sandbox Code Playgroud)
并且假设我们决定在我们的主要功能中使用其中的一些main.cpp:
// main.cpp
#include <iostream>
int main (int argc, char* argv[])
{
std::cout << "1 + 2 = " << add(1, 2) << std::endl;
std::cout << "8 - 3 = " << sub(8, 3) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
如果你尝试编译main.cpp,因为它是,它会抱怨它不知道什么是add和sub是.这是因为你试图使用它们而不声明它们存在 - 这正是声明的用途.所以你可能会做以下事情:
// main.cpp
#include <iostream>
int add(int, int);
int sub(int, int);
int main (int argc, char* argv[])
{
std::cout << "1 + 2 = " << add(1, 2) << std::endl;
std::cout << "8 - 3 = " << sub(8, 3) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这可行,但不是很灵活.如果我们添加一个新函数mul,我们需要将其声明添加到使用它的main.cpp每个其他.cpp文件中(如果你有很多文件,这是很多工作.cpp).所以我们所做的是将所有声明放在一个文件中(比如说math.h),所以我们只需要在一个地方维护声明列表.然后,我们只需包含math.h在使用数学函数的任何文件中.这是头文件(又名包含文件)的目的.
这很好用,但可能会更好.实际上,我们有一个main.cpp文件和一个math.cpp文件,每次编译程序时都会编译它们.如果您的数学函数根本没有改变,那么最好将它们编译一次,然后只要重新编译就将预编译的定义插入到可执行文件中main.cpp?这正是.lib文件的目的.它们包含用于相关功能定义的预编译代码.您仍然需要包含文件来让您知道lib中存在哪些函数.
编译链接阶段的目的是获取这些预编译函数和刚刚编译的函数,并将它们一起滚动到一个可执行文件中.
本质上,您可以将静态库看作许多预定义函数的预编译代码,并将其匹配包含文件作为工具,让任何想要使用这些函数的代码知道哪些是可用的以及它们的描述是什么.
提供一个更简单的答案:
.lib 文件是预编译库。如果包含 .lib,还需要包含 .h/hpp 头文件,以便编译器知道如何访问 .lib 中的函数。
当您编译程序时,仅链接库中使用的所有函数,而不会再次编译它们。