Включите каталоги против вопроса о директории lib - PullRequest
23 голосов
/ 17 февраля 2011

В чем разница между ссылками на включаемые файлы и ссылками на файлы lib?

Я довольно новичок в C / C ++, и мне трудно понять разницу между использованием включаемых файлов и статического файла lib для вызова функций.На мой взгляд, у включаемых файлов есть функции, которые можно вызывать так же, как и .lib-файлы.

Ответы [ 3 ]

37 голосов
/ 17 февраля 2011

В C ++ (и 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

#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.

Цель этапа компиляции компоновки - взять эти предварительно скомпилированные функции и функции, которые вы только что скомпилировали, и свернуть их.вместе в один исполняемый файл.

По сути, вы можете рассматривать статическую библиотеку как предварительно скомпилированный код для ряда предопределенных функций, а соответствующий ей включаемый файл - как инструмент, позволяющий любому коду желать использоватьте функции знают, какие доступны и каково их описание.


* Это не совсем верно, но здесь достаточно для наших целей.
2 голосов
/ 17 февраля 2011

Включаемые файлы обычно содержат объявление символа (функция, переменная). Это даст компилятору знать, что имя определено (в заголовке) или где-либо еще (в случае объявления):

a.h:

void a_useful_function(); //declaration 

но вы также можете иметь определение:

a.h:

void a_useful_function()
{
    //... do something
}

Библиотеки - это набор функций, которые обычно отображаются в заголовках. Заголовок обычно является интерфейсом библиотеки, с которой вы будете ссылаться.

Существуют библиотеки только для заголовков, которые имеют код объявлений и определений в одном файле.

Вы упомянули, что в ваш вопрос включены каталоги. Каталоги include - это места, где компилятор ищет директиву препроцессора #include "a.h".

Но есть также библиотечные каталоги, где компоновщик ищет необходимые библиотеки, которые обычно предоставляют реализации (определения) для объявлений в ваших заголовках.

1 голос
/ 17 февраля 2011

, чтобы дать более простой ответ:

.lib файлы - это скомпилированные библиотеки. если вы включаете .lib, вам также необходимо включить заголовочные файлы .h / hpp, чтобы ваш компилятор знал, как получить доступ к функциям в .lib.

когда вы компилируете свою программу, все функции, используемые в lib, только связаны, они снова скомпилированы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...