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

Глава 59

Крупные проекты

Первичный файл

Библиотечный файл

Рис. 146 – Окна преобразованного проекта P_59_1

Компиляция проекта

Теперь всё готово для компиляции и запуска нашего проекта. Перейдите в окно первичного модуля и нажмите сочетание Ctrl+F9, — оба файла будут откомпилированы, и программа запустится как обычно. Я не зря прошу перейти в окно именно первичного модуля. Если при нажатии Ctrl+F9 активным будет другое окно, компилятор выдаст обидное сообщение: «Cannot run a unit» — нельзя запустить модуль. В самом деле, модуль — это лишь часть программы, он не может быть исполнен. Компилятор же считает, что в активном окне содержится главная программа и пытается её запустить.

Чтобы не спотыкаться здесь, настройте в IDE имя первичного файла, то есть файла с главной программой, — здесь это P_59_1. Для этого обратитесь к пункту меню Compile à Primary file… и укажите там нужный файл (рис. 147). Теперь компилятор будет знать, с какого файла начинать компиляцию. Но и библиотечный файл MyLibr он тоже будет обрабатывать всякий раз, когда вы измените в нём чтото, — это очень удобно.

А если начнёте другой проект? Тогда не забудьте сменить имя первичного файла, либо сбросьте это имя через пункт меню Compile à Clear Primary file.

486

Глава 59

Крупные проекты

Указание первичного

Сброс первичного

файла

файла

Рис. 147 – Пункты меню для настройки первичного файла

Инициализация модуля

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

Начнем с того, что переменная Stack упоминается в главной программе лишь однажды — при инициализации:

Stack:= nil; { Инициализация стека пустым значением }

Когда-нибудь — в будущих проектах — вы забудете об этой важной мелочи, и наживете несколько часов головной боли. Но, если эту инициализацию перенести в модуль MyLibr, то можно впредь не вспоминать о ней. Для этого создадим в модуле ещё одну секцию — секцию инициализации. Она располагается в модуле последней и открывается ключевым словом BEGIN, вставленным перед завершающим словом END. Между этими словами записывают операторы инициализации, — всё это похоже на главную программу в первичном модуле. В нашем случае секция будет такой:

unit MyLibr;

{ . . . }

begin

{ секция инициализации модуля }

Stack:= nil; { Инициализация стека }

end.

Когда сработает эта инициализация? Вы знаете, что стрельба начинается с операторов главной программы в первичном модуле P_59_1. Это справедливо, пока не подключены библиотечные модули. С ними порядок исполнения программы слегка изменится. Первыми будут выполнены операторы в секциях инициализации подключенных модулей, причем в том порядке, в каком эти модули перечислены в списке USES (если там указано несколько модулей). И лишь затем начнёт выполняться главная программа в первичном модуле. Этот порядок гарантирует компилятор, ваше вмешательство здесь не требуется.

487

Глава 59

Крупные проекты

Итак, переместив инициализацию переменной из главной программы в модуль, мы обеспечим её автоматическое выполнение и в будущих проектах. Разумеется, что в главной программе инициализация уже излишня. А раз так, то и переменная Stack с описанием её типа в секции интерфейса уже ни к чему, — вернем всё это в секцию реализации. После всех перемещений наш проект обретет окончательный вид.

Внешний библиотечный модуль:

unit MyLibr;

{ имя библиотечного модуля }

interface

{ --- секция интерфейса --- }

procedure Push(const arg : string);

{ заголовок процедуры }

function Pop(var arg : string): boolean; { заголовок функции }

{- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -}

implementation

{ --- секция реализации --- }

type PRec = ^TRec;

{ Тип указатель на запись }

TRec = record

{ Тип запись для хранения связанных строк }

mStr : string;

{ хранимая строка }

mNext : PRec;

{ указатель на следующую запись }

end;

 

 

var Stack : PRec;

{ Голова стека }

{ Процедура размещения строки в стеке }

procedure Push(const arg : string);

var p : PRec;

 

begin

 

New(p);

{ создаем новую переменную-запись }

p^.mStr:= arg;

{ размещаем строку }

{ размещаем в голове стека }

p^.mNext:= Stack;

{ указатель на предыдущую запись }

Stack:=p;

{ текущая запись в голове стека }

end;

 

488

Глава 59

Крупные проекты

{ Процедура извлечения строки из стека }

function Pop(var arg : string): boolean;

var p : PRec;

 

begin

 

 

Pop:= Assigned(Stack);

{ Если стек не пуст, то TRUE }

{ Если стек не пуст... }

 

if Assigned(Stack) then begin

arg:= Stack^.mStr;

{ извлекаем данные из головы стека }

p:= Stack;

{ временно копируем указатель на голову }

Stack:= Stack^.mNext;

{ переключаем голову на следующий элемент }

Dispose(p);

{ удаляем ненужный элемент }

end

 

 

end;

 

 

begin

{ --- секция инициализации модуля --- }

Stack:= nil; { Инициализация стека пустым значением } end.

Теперь в интерфейсной части модуля маячат лишь процедура Push и функция Pop. Первичный файл проекта с главной программой станет таким:

{ P_59_1 – Первичный файл проекта } uses MyLibr;

var F : text; S : string;

begin {--- Главная программа ---}

{Открываем входной файл } Assign(F, 'P_56_1.pas'); Reset(F);

{Пока не конец файла, читаем строки и помещаем в стек } while not Eof(F) do begin

Readln(F, S);

Push(S);

end;

 

Close(F);

 

{Открываем выходной файл } Assign(F, 'P_56_1.out'); Rewrite(F);

{Пока стек не пуст, извлекаем и печатаем строки } while Pop(S) do Writeln(F, S);

Close(F);

end.

Откомпилируйте проект, запустите и проверьте, жива ли распиленная «дамочка»?

489

Соседние файлы в папке delphi