链接到包含文件和链接到 lib 文件有什么区别?
我是 C/C++ 的新手,我很难弄清楚使用包含文件和静态 lib 文件调用函数之间的区别。在我看来,包含文件具有可以像 .lib 文件一样调用的函数。
最佳答案
在 C++(以及 C 和其他类似语言)中,函数被称为同时具有声明和定义。
声明只是一个简短的声明,声明函数存在,以及它的接口(interface)是什么样的。考虑一个将两个整数相加的基本函数 add
。它的声明可能如下所示:
int add(int, int);
这意味着“存在一个函数add
,它接受两个整数并返回一个整数”。尽管我们可以根据它的名称做出很好的猜测,但它并没有具体说明函数的实际作用。
函数的定义是我们准确定义函数做什么的地方。这可能是您认为的实际功能代码。以add
函数为例:
int add (int a, int b)
{
return a + b;
}
那么这与您的问题有什么关系?好吧,假设我们在 math.cpp
中有许多数学函数:
// math.cpp
int add (int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
还假设我们决定在 main.cpp
的 main 函数中使用其中的一些:
// 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;
}
如果您尝试按原样编译 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;
}
这可行,但不是很灵活。如果我们添加一个新函数 mul
,我们需要将它的声明添加到 main.cpp
和所有其他使用它的 .cpp
文件中(如果您有很多 .cpp
文件,这将是一项繁重的工作)。因此,我们所做的是将所有声明放入一个文件(例如,math.h
),因此我们只需在一个位置维护声明列表。然后,我们只需将 math.h
包含到任何使用数学函数的文件中。这就是头文件(也就是包含文件)的用途。
这很好用,但可能会更好。实际上,我们有一个 main.cpp
文件和一个 math.cpp
文件,每次编译程序时都会编译这两个文件*。如果您的数学函数根本没有改变,那么肯定最好编译一次,然后在重新编译 main.cpp
时将预编译的定义插入到您的可执行文件中?这正是 .lib
文件的目的。它们包含相关函数的定义的预编译代码。您仍然需要包含文件来让您知道 lib 中存在哪些函数。
编译链接阶段的目的是把这些预编译的函数和你刚刚编译的函数,一起滚动到一个单独的可执行文件中。
本质上,您可以将静态库视为许多预定义函数的预编译代码,并将其匹配的包含文件视为一种工具,让任何想要使用这些函数的代码知道哪些可用以及它们的描述是。
* 这并不完全正确,但对于我们这里的目的来说已经足够了。
关于c++ - 包含目录与 lib 目录概念问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5022374/