Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Комплексное пособие Си.pdf
Скачиваний:
57
Добавлен:
12.03.2015
Размер:
1.57 Mб
Скачать

Модульное программирование

Технология модульного программирования предполагает разбиение программы на отдельные части – модули. Модуль может содержать одну или несколько взаимосвязанных функций и общие для функций данные. Каждый модуль помещается в отдельный файл (с расширением .c или .cpp) и компилируется автономно. Получившиеся в результате компиляции объектные модули объединяются в единый исполняемый модуль (exe-файл) с помощью компоновщика (Linker).

Разбиение программы на модули уменьшает время перекомпиляции программы и облегчает процесс отладки, позволяя отлаживать программу по частям. Чем более независимы модули, тем легче отлаживать программу.

Одна из основных задач – хорошо продумать интерфейс модулей. Интерфейсом модуля являются заголовки всех функций и описания доступных извне типов, переменных и констант.

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

расширением

.h , а в

остальные файлы (с расширением .c

или .cpp)

включать эти

описания

с помощью директивы

#include

“имя.h” .

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

При разработке многомодульных программ нужно создавать проект (файл с расширением .prj). В проекте указывают, из каких файлов состоит программа. Это могут быть исходные файлы с расширением .c или .cpp, или объектные файлы с расширением .obj (полученные в результате компиляции исходных модулей), или библиотеки объектных модулей (файлы с расширением .lib). Заголовочные файлы (с расширением .h) в проекте не указывают, они должны быть в том же каталоге, в котором содержатся модули программы.

134

Создание проекта

В Turbo C 2.0 файл проекта создается пользователем вручную. Создайте новый файл (выберите в меню File | New). Введите имена

файлов программы, включаемых в проект (каждое имя с новой строки или разделяя имена пробелами). Сохраните этот файл проекта, указав после имени расширение .prj.

В Borland C++ 3.1 файл проекта создается системой в диалоге с пользователем.

Выберите в меню Project | Open project… . Откроется окно диалога “Open Project File”. В поле списка “Files” этого окна выберите нужный каталог. Затем введите имя проекта с расширением .prj в поле “Open Project File” и нажмите клавишу [Enter] или кнопку “OK”.

Рис. Окно диалога “Open Project File”

Далее выберите в меню Project | Add item или нажмите клавишу [Insert], чтобы добавить в проект файлы. В появившемся окне диалога (рис.10.2) в поле “Name” введите имя файла или выберите его из списка “Files” и нажмите кнопку “Add”. После добавления в проект всех имен файлов нажмите кнопку “Done”.

135

Рис. Окно диалога “Add to Project List”

Открытие и работа с проектом

В Borland C++ 3.1 для открытия проекта выберите в меню Project | Open project… и в появившемся окне диалога введите или выберите имя своего файла проекта.

Нажмите клавиши Ctrl – F9 (или выберите в меню команды Run | Run), чтобы запустить компиляцию, компоновку и выполнение программы. При этом неважно, текст какого файла находится в окне редактирования (можно вообще файлы программы не открывать, если они не будут редактироваться).

Пример создания многомодульной программы

Рассмотрим пример программы из лабораторной работы № 8, которая формирует список идентификаторов.

Создадим заголовочный файл “spisok.h”, который будет содержать директивы препроцессора, описание типа элемента списка и прототипы функций (подпрограмм):

#include <stdio.h>

136

#include

<stdlib.h>

 

#include

<string.h>

 

#include

<conio.h>

 

#define

MAXDL

9

(с признаком

/* макс.

длина идентификатора

конца

'\0' )

*/

элемента списка */

struct

EL_SP

/* тип

{ char id [MAXDL];/* идентификатор */ struct EL_SP *sled;

/* ссылка на следующий элемент */

};

void Vkl ( struct EL_SP **p, char t_id[] ); void PechSp ( struct EL_SP *p );

Каждую функцию программы поместим в отдельный файл, добавив в начало директиву #include “spisok.h”.

Файл “Vkl.c”:

#include "spisok.h"

*/

/*-------------------------------------------------

/* функция включения очередного идентиф. в список */

/*-------------------------------------------------

*/

void Vkl ( struct EL_SP **p, char t_id[] )

/* Вх. данные: *p

- указатель списка

идентификаторов в

лексикографическом порядке,

t_id - включаемый

в список (текущий) ид-р */

/* Вых. данные: *p

*/

{struct EL_SP *pt,/* указатель включаемого эл-та */

*k,*j;

/* указатели

очередного и предыдущего

 

элементов

списка

*/

/* выделение памяти для нового эл-та списка */

pt = (struct EL_SP *) malloc(sizeof(struct EL_SP)); strcpy(pt->id, t_id);

if (*p==NULL || strcmp(pt->id,(*p)->id) < 0) { /* включение ид-ра в начало списка */

pt->sled=*p; *p=pt;

}

else

{ /* поиск элемента списка, после которого нужно включить идентификатор */

k=*p;

while (k!=NULL && strcmp(pt->id,k->id)>=0) { j=k; k=k->sled;

}

/* включение эл-та *pt после элемента *j */ j->sled=pt; pt->sled=k;

}

137

}

Файл “PechSp.c”:

#include "spisok.h"

 

*/

/*--------------------------------------------------

функция печати

списка

/*

*/

/*--------------------------------------------------

 

 

*/

void PechSp (

struct EL_SP *p

)

*/

/* Вх. данные:

p - указатель

начала списка

{struct EL_SP *i;

/* указатель текущего элемента списка */ printf ("\nРезультат:\n");

for ( i=p; i!=NULL; i=i->sled ) puts (i->id);

}

Файл “main.c”:

#include "spisok.h"

*/

/*

---------------------------------------------О С Н О В Н А Я П Р О Г Р А М М А

/*

*/

/*---------------------------------------------

 

*/

main()

{struct EL_SP *p; unsigned n ; unsigned i ; char t_id[MAXDL];

/* указатель начала списка

*/

/* количество идентификаторов

*/

/*

параметр цикла

*/

/*

текущий идентификатор

*/

printf ("\nВведите число идентификаторов\n n=");

scanf ("%u",&n);

пропуск символа "перевод строки" */

getchar();

/*

p=NULL;

/*

список пока пуст */

printf("Введите

идентификаторы ");

printf("после каждого нажимайте клавишу <Enter>\n"); for ( i=1; i<=n; i++ )

{gets (t_id);

Vkl (&p,t_id); /* включение ид-ра в список */

}

PechSp (p); /* печать списка */

printf ("\nДля завершения нажмите любую клавишу\n"); getch();

}

Создадим файл проекта с именем “spisok.prj”, содержащий имена файлов программы:

Vkl.c

138

PechSp.c

main.c

Откроем проект “spisok.prj” и запустим программу на выполнение. В результате компиляции программы для каждого исходного модуля будет получен объектный модуль (файлы “Vkl.obj”, “PechSp.obj”, “main.obj”), а

затем редактор связей создаст из них выполнимый модуль “spisok.exe”. При повторном запуске программы, если исходные файлы не

изменялись, перекомпиляция программы не происходит. Если вы измените текст какого-либо исходного файла, выполните команду меню Compile | Make, чтобы перекомпилировать только этот файл программы (а не все) и получить новый exe-файл.

Если какие-то модули программы изменяться уже не будут, можно в проект включить не исходные модули, а объектные. Изменим файл проекта, заменив файлы с подпрограммами на их объектные модули:

Vkl.obj

PechSp.obj

main.c

Снова выполним программу.

Можно объектные файлы программы, которые не будут больше изменяться, поместить в отдельную библиотеку (файл с расширением .lib). Для создания библиотеки служит программа-библиотекарь tlib из системы

Turbo C или Borland C++.

Создадим библиотечный файл “spisok.lib”, содержащий файлы “Vkl.obj” и “PechSp.obj”. Для этого вызовем программу-библиотекарь, введя в

командной строке MS DOS следующую команду:

tlib spisok.lib + Vkl + PechSp

Заменим в файле “spisok.prj” объектные модули на библиотечный модуль:

Spisok.lib

main.c

и снова выполним программу.

139

Контрольные вопросы

Что такое модуль?

Что такое проект? Какие файлы можно включать в проект? Для чего нужны заголовочные файлы?

Как создать библиотеку объектных модулей?

140