Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2009 лекции ПЯВУ часть1.doc
Скачиваний:
22
Добавлен:
27.03.2015
Размер:
823.3 Кб
Скачать

Тема 9 Компоновка программ и препроцессор

9.1. Компоновка программ

Программа– это, прежде всего, текст на языке С++ [1]. С помощью компилятора текст преобразуется в исполняемый файл – форму, позволяющую компьютеру выполнять программу.

Если рассмотрим этот процесс чуть более подробно, то выяснится, что обработка исходных файлов происходит в три этапа. Сначала файл обрабатывается препроцессором, который выполняет операторы #include,#defineи еще несколько других. После этого программа все еще представлена в виде текстового файла, хотя и измененного по сравнению с первоначальным. Затем, на втором этапе, компилятор создает так называемый объектный файл. Программа уже переведена в машинные инструкции, однако еще не полностью готова к выполнению. В объектном файле имеются ссылки на различные системные функции и на стандартные функции языка С++. Например, выполнение операцииnewзаключается в вызове определенной системной функции. Даже если в программе явно не упомянута ни одна функция, необходим, по крайней мере, один вызов системной функции – завершение программы и освобождение всех принадлежащих ей ресурсов.

На третьем этапе компиляции к объектному файлу подсоединяются все функции, на которые он ссылается. Функции тоже должны быть скомпилированы, т.е. переведены на машинный язык в форму объектных файлов. Этот процесс называется компоновкой, и как раз его результат и есть исполняемый файл.

Системные функции и стандартные функции языка С++ заранее откомпилированы и хранятся в виде библиотек. Библиотека– это некий архив объектных модулей, с которым удобно компоновать программу.

Основная цель многоэтапной компиляции программ – возможность компоновать программу из многих файлов. Каждый файл представляет собой законченный фрагмент программы, который может ссылаться на функции, переменные или классы, определенные в других файлах. Компоновка объединяет фрагменты в одну «самодостаточную» программу, которая содержит все необходимое для выполнения.

Проблема использования общих функций и имен

В языке С++ существует строгое правило, в соответствии с которым прежде чем использовать в программе имя или идентификатор, его необходимо определить. Рассмотрим на примере функций. Для того чтобы имя функции стало известно программе, его нужно либо объявить, либо определить.

Объявлениефункции состоит лишь из ее прототипа, т.е. имени, типа результата и списка аргументов. Объявление функции задает ее формат, но не определяет, как она выполняется (рис. 9.1.)

double sqrt(double x); // функция sqrt

long fact(long x); // функция fact

// функция PrintBookAnnotation

void PrintBookAnnotation(const Book& book);

Рис. 9.1. Примеры объявления функций

Определение функции– это определение того, как функция выполняется. Оно включает в себя тело функции, программу ее выполнения (рис. 9.2.).

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

long fact(long x)

{

if (x == 1)

return 1;

else

return x * fact(x - 1);

}

Рис. 9.2. Функция вычисления факториала

Удобно было бы поместить определение функции в отдельный файл, а в других файлах в начале помещать лишь объявление, прототип функции.

// начало файла main.cpp

long fact(long); // прототип функции

int main(){

int x10 = fact(10); } // вызов функции

// конец файла main.cpp

// начало файла fact.cpp

long fact(long x) // определение функции вычисления факториала

{

if (x == 1)

return 1;

else

return x * fact(x - 1);}

// конец файла fact.cpp

Рис. 9.3. Программа, состоящая более чем из одного файла

Компоновщик объединит оба файла в одну программу.

Таким образом, в начале каждого файла будут сосредоточены прототипы всех используемых функций.

Программа работать будет, однако писать ее не очень удобно.

В начале каждого файла придется повторять довольно большие одинаковые куски текста. Помимо того, что это утомительно, очень легко допустить ошибку. К тому же любые изменения в объявлении функции придется вносить во все файлы.