Создать список целочисленных элементов. Составить процедуру записи отрицательных нечетных элементов исходного списка в один список, положительных четных – в другой и продемонстрировать ее работу.
// Лабораторная работа 1.
// Реализация списков с помощью динамических переменных.
// Выполнил Сергеев Андрей, группа 999.
// Формирование двух списков из исходного списка.
// Исходные данные – элементы основного списка – в файле LW1Dat.txt
// Результаты работы помещаются в файл LW1Res.txt
program LW1;
{$APPTYPE CONSOLE}
uses SysUtils;
type
tValue=Integer; // тип содержательной части элемента списка – целый
pItem=^tItem; // тип указателя на элемент списка
tItem=record // тип элемента списка
Value: tValue; // содержательная часть элемента списка
Next: pItem; // указатель на следующий элемент списка
end; // record tItem
procedure Create(var List: pItem); // Создание пустого списка List
begin
List:=nil;
end; //procedure Create
procedure InsertFirst(var List: pItem; v: tValue);
// Включение элемента со значением v в начало списка List
var NewItem: pItem; // указатель на новый элемент списка
begin
New(NewItem); // выделение памяти под новый элемент списка
NewItem^.Value:=v; // запись v в поле Value нового элемента
NewItem^.Next:=List; // новый элемент ссылается на первый
List:=NewItem; // новый элемент становится первым
end; // procedure InsertFirst
procedure InsertLast(var List: pItem; v: tValue);
// Включение элемента со значением v в конец списка List
var NewItem, LastItem:pItem; // указатели на новый и последний элементы
begin
New(NewItem); // выделение памяти под новый элемент списка
NewItem^.Value:=v; // запись значения v в поле Value нового элемента
NewItem^.Next:=nil; // новый элемент становится последним в списке
if List=nil // если список пуст,
then List:=NewItem // то новый элемент становится первым в списке
else begin // список не пуст – поиск последнего элемента:
LastItem:=List; // устанавливаем LastItem на начало списка,
|
while LastItem^.Next<>nil do begin // пока не достигнут конец списка,
LastItem:=LastItem^.Next; // сдвигаем LastItem на следующий элемент
end;
LastItem^.Next:=NewItem; // новый элемент следует за последним
end;
end; // procedure InsertLast
procedure WriteList(var f: Text; List: pItem); // Вывод в файл f элементов списка List
var Item:pItem; // указатель на элемент списка
begin
Item:=List; // устанавливаем Item на начало списка
while Item<>nil do begin // пока не достигнут конец списка:
Write(f, Item^.Value:5); Item:=Item^.Next; // вывод элемента и сдвиг Item
end;
Writeln(f);
end; // procedure WriteList
function Size(List: pItem): Word;
// Возвращение числа элементов списка
var Item:pItem; // указатель на элемент списка
Begin
Item:=List; // устанавливаем Item на начало списка
Result:=0; // обнуляем счетчик числа элементов
while Item<> nil do begin // пока не достигнут конец списка:
Item:=Item^.Next; Inc(Result); // сдвигаем Item и увеличиваем счетчик
end; // while
end;
procedure Clear(var List: pItem);
// Удаление элементов списка
var Item: pItem; // указатель на удаляемый элемент списка
begin
while List<>nil do begin // пока список не пуст:
Item:=List; // устанавливаем Item на начало списка,
List:=List^.Next; // передвигаем начало списка на следующий элемент
Dispose(Item); // и удаляем элемент
end; // while
end; //procedure Clear
procedure FormLists(L: pItem; var L1, L2: pItem);
// Формирование списков L1 и L2 из списка L по правилу:
// отрицательные нечетные – в L1, положительные четные – в L2
var Item: pItem; // указатель на текущий элемент списка
begin
Item:=L; // устанавливаем Item на начало списка
while Item<>nil do begin // пока не достигнут конец списка L
if (Item^.Value<0) and odd(Item^.Value) // нечетные отрицательные
then InsertLast(L1, Item^.Value); // включаем в список L1
if (Item^.Value>0) and not odd(Item^.Value) // положительные четные
|
then InsertLast(L2, Item^.Value); // включаем в список L2
Item:=Item^.Next; // сдвигаем Item на следующий элемент
end; // while
end; // procedure FormLists
var
fDat, fRes:Text; // файлы с исходными данными и результатами работы
L, L1, L2:pItem; // указатели на исходный и результирующие списки
v: tValue; // значение элемента списка
begin
Assign(fDat,'LW3Dat.txt'); Reset(fDat); // открытие файла для чтения
Assign(fRes,'LW3Res.txt'); Rewrite(fRes); // открытие файла для записи
Create(L); Create(L1); Create(L2); // создание пустых списков
while not eof(fDat) do begin // пока не достигнут конец файла fDat:
Read(fDat, v); // чтение из файла очередного значения в v,
InsertFirst(L, v); // вставка элемента со значением v в начало списка L
end; // while
Writeln(fRes, 'Исходный список:'); WriteList(fRes, L); // вывод списка L
Writeln(fRes, 'Число элементов списка: ', Size(L)); // вывод размера L
FormLists(L, L1, L2); // формирование списков L1 и L2
Writeln(fRes, 'Список отрицательных нечетных элементов:');
WriteList(fRes, L1); // вывод списка L1
Writeln(fRes, 'Число элементов списка: ', Size(L1)); // вывод размера L1
Writeln(fRes, 'Список положительных четных элементов:');
WriteList(fRes, L2); // вывод списка L2
Writeln(fRes, 'Число элементов списка: ', Size(L2)); // вывод размера L2
Clear(L);Clear(L1);Clear(L2); // удаление списков
Close(fDat);Close(fRes); // закрытие файлов
end.
Тема 2. МОДУЛИ
1. Назначение модулей
Наличие модулей в Delphi позволяет:
1) создавать библиотеки программных элементов – подпрограмм, констант, типов и переменных;
2) практически неограниченно увеличивать кодовую часть программы;
3) использовать подпрограммы, константы, типы и переменные, содержащиеся в стандартных модулях (поставляемых в составе системы программирования Delphi) и в модулях других программистов;
4) программировать и отлаживать программу по частям.
|
Модуль состоит из следующих частей:
· заголовок модуля;
· секция интерфейса;
· секция реализации;
· секция инициализации;
· секция деинициализации.
Первые три части являются обязательными. Обязательна также указанная последовательность разделов.
2. Заголовок модуля
Заголовок модуля состоит из зарезервированного слова unit и идентификатора. Идентификатор модуля должен быть уникальным. Пример заголовка:
unit MyModule;
Модуль должен быть помещен в файл, имя которого совпадает с именем модуля, а его расширение должно быть.pas. После компиляции файл с модулем получает расширение.dcu.
3. Секция интерфейса
Секции интерфейса выполняет представительскую функцию, – в ней указываются константы, типы, переменные, процедуры и функции, которые могут быть использованы в основной программе или в другом модуле при подключении данного модуля.
Секция начинается зарезервированным словом interface. Далее могут размещаться: 1) предложение uses, в котором перечисляются имена модулей, используемых данным модулем; 2) раздел описания констант; 3) раздел описания типов; 4) раздел описания переменных; 5) раздел описания процедур и функций. Порядок следования разделов описаний так же, как и в главной программе, может быть произвольным. Возможно повторение разделов. Требуется только одно: используемое сейчас должно быть описано выше. Любой из подразделов может отсутствовать. Допустима даже пустая секция интерфейса, но модуль с такой секцией никому не нужен.
В разделе объявления процедур и функций указываются лишь заголовки подпрограмм. Сами подпрограммы (их блоки) размещаются в секции реализации.
В секциях интерфейса различных модулей недопустимо циклическое обращение друг к другу, так как компилятор в этом случае не может установить связей.
4. Секция реализации модуля
Назначение секции реализации – реализация подпрограмм, заявленных в секции интерфейса.
Секция начинается зарезервированным словом implementation. Далее могут размещаться: 1) предложение uses, в котором перечисляются имена модулей, используемых данным модулем, но не упомянутые в предложении секции uses интерфейса; 2) раздел описания меток; 3) раздел описания констант; 4) раздел описания типов; 5) раздел описания переменных; 6) раздел описания процедур и функций.
Структурно секция реализации отличается от секции интерфейса только тем, что разрешено наличие раздела описаний меток.
Как и в секции интерфейса: 1) порядок следования разделов описаний может быть произвольным; 2) возможны повторения разделов; 3) действует правило: используемое сейчас должно быть описано выше; 4) любой из подразделов может отсутствовать; 5) допустима пустая секция реализации.
Модули с пустой секцией реализации не так уж и бесполезны, более того, они часто используются. Естественно, что при этом в секции интерфейса не должно содержаться описаний подпрограмм, допустимы только константы, типы и переменные.
Раздел описания подпрограмм обязательно должен содержать описания подпрограмм, заявленных (описанных) в секции интерфейса. В описаниях этих подпрограмм допустимо использовать сокращенные заголовки без списков формальных параметров. Описания каждой подпрограмм обязательно содержит её блок (тело), состоящее из раздела описаний и раздела операторов.
В отличие от интерфейсов модулей в секциях реализации модулей допустимо циклическое обращение друг к другу, т. к. взаимодействие модулей осуществляется через интерфейсы, и здесь не возникает проблемы с установлением необходимых связей.
Важно понимать, что все метки, константы, типы, переменные и подпрограммы, описанные в секции реализации, кроме подпрограмм из секции интерфейса, являются локальными элементами данного модуля, они не видны из других программ и модулей, они создаются только с одной целью – реализовать подпрограммы секции интерфейса!
5. Секция инициализации
Секция инициализации – факультативная часть модуля. В ней размещаются операторы, которые выполняются в начале работы той программы, которая использует данный модуль. Если программа использует несколько модулей, то содержимое их секций инициализации выполняется в порядке перечисления имён модулей в предложении uses. Эта секция начинается зарезервированным словом initialization, например:
Initialization
Assign(f1, 'File1.dat');
6. Секция деинициализации
Раздел деинициализации начинается словом finalization и является необязательным. В этом разделе размещаются операторы, выполняемые при завершении работы программы, использующей данный модуль. Если программа использует несколько модулей, то содержимое их секций деинициализации выполняется в порядке, обратном порядку их перечисления в предложении uses.
В конце модуля размещается слово end. (с точкой).
7. Использование модуля в основной программе
Чтобы использовать подпрограммы, константы, типы, переменные, описанные в интерфейсной секции модуля, в основной программе следует записать слово uses, после которого указать имя (имена) модуля (модулей). После этого в основной программе можно использовать идентификаторы, указанные в интерфейсных секциях перечисленных модулей.
Если в программе используется объявление uses, оно должно открывать раздел описаний программы.
8. Использование идентификаторов элементов модуля
Как правило, идентификаторы объектов модуля (имена констант, типов, переменных, процедур и функций) используются в основной программе (или другом модуле) обычным образом. Однако может оказаться, что используемый идентификатор элемента модуля совпадает с идентификатором использующей его программы. Чтобы различить их, при обращении к элементу модуля указывается имя модуля, а затем через точку – идентификатор объекта (аналогично использованию полей записи).
Пример.
program Example;
uses Unit1;
var x: Real; // переменная x программы
Begin
Read(x); // чтение значения переменной x программы
Read(Unit1.x); // чтение значения переменной x модуля
Writeln(x, Unit1.x); // использование одноименных переменных программы и модуля
end.
unit Unit1;
Interface
var x: Real; // переменная x модуля
Implementation
end.
9. Добавление модуля к проекту
Для добавления модуля к проекту необходимо в меню File выполнить команду New и в появившемся списке вновь создаваемых элементов проекта выбрать Unit (модуль). В окне кода проекта появится новая страница с заготовкой модуля, а в файл проекта автоматически будут вставлена ссылка на этот модуль. Новый модуль необходимо сохранить в нужной папке под нужным именем. Обычно модуль хранится в той же папке, что и проект.
10. Компиляция проекта, использующего модули
Программу, использующую модули, можно компилировать либо с помощью команды меню Project | Compile <имя проекта> (клавиши Ctrl+F9) либо Project | Build <имя проекта>.
При использовании команды Project | Compile наряду с компиляцией главной программы компилируются и те используемые программой модули, у которых к моменту компиляции был изменен текст.
При использовании команды Project | Build все используемые программой модули перекомпилируются безусловно.
Контрольные вопросы
1. Что такое модуль?
2. Для чего используются модули?
3. Какое имя должен иметь файл, содержащий модуль?
4. В файл с каким расширением имени компилируется файл исходного кода модуля?
5. Как получить доступ к программным элементам, определенным в модуле?
6. Какова структура модуля?
7. Из каких секций состоит модуль?
8. Каково назначение и структура секции интерфейса?
9. Каково назначение и структура секции реализации?
10. Каково назначение и структура секции инициализации?
11. Каково назначение и структура секции деинициализации?
12. Что означает перекрытие имен при использовании модулей?
13. Как получить доступ к перекрытому имени?
14. Как добавить модуль к проекту?
15. Каким образом компилируется проект, использующий модули?
Лабораторная работа 2.
Создание модуля для работы
с динамическим списком
Задание
Измените программу выполнения лабораторной работы 1 «Организация списков с помощью динамических переменных», расположив все необходимые типы, процедуры и функции обработки списков в модуле.