Ответ 1
В С++ (и C и других подобных языках) функция называется объявлением и определением.
Объявление - это просто краткое утверждение, которое объявляет, что функция существует и как выглядит интерфейс. Рассмотрим базовую функцию 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.cpp
int main (int argc, char* argv[])
{
printf("1 + 2 = %d\n", add(1, 2));
printf("8 - 3 = %d\n", sub(8, 3));
}
Если вы попытаетесь скомпилировать main.cpp
как есть, он будет жаловаться, что он не знает, что такое add
и sub
. Это происходит из-за того, что вы пытаетесь использовать их, не объявляя, что они существуют, что и является декларацией. Таким образом, вы можете сделать следующее:
// main.cpp
int add(int, int);
int sub(int, int);
int main (int argc, char* argv[])
{
printf("1 + 2 = %d\n", add(1, 2));
printf("8 - 3 = %d\n", sub(8, 3));
}
Это будет работать, но не очень гибко. Если мы добавим новую функцию mul
, нам нужно пойти и добавить ее объявление в main.cpp
и каждый другой файл .cpp
, который его использует (это большая работа, если у вас много файлов .cpp
), Итак, что мы делаем, вместо этого мы помещаем все объявления в один файл (например, math.h
), поэтому нам нужно поддерживать список объявлений только в одном месте. Затем мы просто включаем math.h
в любой файл, который использует математические функции. Это назначение файлов заголовков (файлы include.k.a.).
Это отлично работает, но может быть даже лучше. Как бы то ни было, у нас есть файл main.cpp
и файл math.cpp
, оба из которых скомпилированы каждый раз при компиляции программы *. Если ваши математические функции не меняются вообще, лучше ли их компилировать один раз и просто вставлять предварительно скомпилированные определения в ваш исполняемый файл всякий раз, когда вы перекомпилируете main.cpp
? Это как раз цель файлов .lib
. Они содержат предварительно скомпилированный код для определения соответствующих функций. Вам все еще нужен файл include, чтобы вы знали, какие функции существуют в lib.
Цель этапа компоновки компиляции состоит в том, чтобы взять эти предварительно скомпилированные функции и функции, которые вы только что скомпилировали, и свернуть их вместе в один исполняемый файл.
По существу, вы можете посмотреть статическую библиотеку как предварительно скомпилированный код для ряда предопределенных функций, а ее сопоставление включает в себя файл как инструмент, позволяющий любому коду, желающему использовать эти функции, знать, какие из них доступны и что их описание есть.
Ничего себе, это закончилось совсем немного дольше, чем я предполагал.:) Надеюсь, это поможет прояснить ситуацию!
* Это не совсем верно, но для наших целей это достаточно.