Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование.docx
Скачиваний:
6
Добавлен:
26.09.2019
Размер:
1.2 Mб
Скачать

5.Подготовка файла к чтению Паскаля

Reset(<имя_ф_переменной>);

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

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

6.Чтение из файла в Паскале

Read(<имя_ф_переменной>,<список переменных>);

Рассмотрим результат действия процедуры read(f, v):

Состояние файла f и переменной v до выполнения процедуры:

Состояние файла f и переменной v после выполнения процедуры:

Для типизированных файлов при выполнении процедуры read() последовательно считывается, начиная с текущей позиции указателя, число компонент файла, соответствующее числу переменных в списке, а указатель смещается на это число позиций.

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

7.Функция определения достижения конца файла в Паскале

Eof(<имя_ф_переменной>);

Название этой функции является сложносокращенным словом от end of file. Значение этой функции имеет значение true, если конец файла уже достигнут, т.е. указатель стоит на позиции, следующей за последней компонентой файла. В противном случае значение функции – false.

8.Изменение имени файла в Паскале

Rename(<имя_ф_переменной>, <новое_имя_файла>);

Здесь новое_ имя_ файла – строковое выражение, содержащее новое имя файла, возможно с указанием пути доступа к нему.

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

9.Уничтожение файла в Паскале

Erase(<имя_ф_переменной>);

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

10.Уничтожение части файла от текущей позиции указателя до конца в Паскале

Truncate(<имя_ф_переменной>);

11.Файл Паскаля может быть открыт для добавления записей в конец файла

Append(<имя_ф_переменной>);

Типизированные файлы Паскаля. Длина любого компонента типизированного файла строго постоянна, т.к. тип компонент определяется при описании, а, следовательно, определяется объем памяти, отводимый под каждую компоненту. Это дает возможность организовать прямой доступ к каждой компоненте (т.е. доступ по порядковому номеру).

Перед первым обращением к процедурам ввода/вывода указатель файла стоит в его начале и указывает на его первый компонент с номером 0. После каждого чтения или записи указатель сдвигается к следующему компоненту файла. Переменные и выражения в списках ввода и вывода в процедурах read() и write() должны иметь тот же тип, что и компоненты файла Паскаля. Если этих переменных или выражений в списке несколько, то указатель будет смещаться после каждой операции обмена данными на соответствующее число позиций.

Для облегчения перемещения указателя по файлу и доступа к компонентам типизированного файла существуют специальные процедуры и функции:

fileSize(<имя_ф_переменной>) – функция Паскаля, определяющая число компонентов в файле;

filePos(<имя_ф_переменной>) – функция Паскаля, значением которой является текущая позиция указателя;

seek(<имя_ф_переменной>,n) – процедура Паскаля, смещающая указатель на компоненту файла с номером n. Так, процедура seek(<имя_ф_переменной>,0) установит указатель в начало файла, а процедура seek(<имя_ф_переменной>, FileSize(<имя_ф_переменной>)) установит указатель на признак конца файла.

Текстовые файлы Паскаля. Текстовые файлы предназначены для хранения текстовой информации. Именно в таких файлах хранятся, например, исходные тексты программ. Компоненты текстовых файлов могут иметь переменную длину, что существенно влияет на характер работы с ними. Доступ к каждой строке текстового файла Паскаля возможен лишь последовательно, начиная с первой. К текстовым файлам применимы процедуры assign, reset, rewrite, read, write и функция eof. Процедуры и функции seek, filepos, filesize к ним не применяются. При создании текстового файла в конце каждой записи (строки) ставится специальный признак EOLN(end of line – конец строки). Для определения достижения конца строки существует одноименная логическая функция EOLN(<имя_ф_переменной>), которая принимает значение true, если конец строки достигнут.

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

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

  • текстовые файлы удобнее для восприятия человеком, а типизированные соответствуют машинному представлению объектов;

 

  • текстовые файлы, как правило, длиннее типизированных;

 

  • длина текстовых файлов зависит не только от количества записей, но и от величины переменных.

Так, в типизированном файле числа 6, 65 и 165 как целые будут представлены одним и тем же числом байт. А в текстовых файлах, после преобразования в строку, они будут иметь разную длину. Это вызывает проблемы при расшифровке текстовых файлов. Пусть в текстовый файл пишутся подряд целые числа (типа byte): 2, 12, 2, 128. Тогда в файле образуется запись 2122128. При попытке прочитать из такого файла переменную типа byte программа прочитает всю строку и выдаст сообщение об ошибке, связанной с переполнением диапазона.

Но, вообще-то, такой файл не понимает не только машина, а и человек.

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

Кроме процедур read и write при работе с текстовыми файлами используются их разновидности readln и writeln. Отличие заключается в том, что процедура writeln после записи заданного списка записывает в файл специальный маркер конца строки. Этот признак воспринимается как переход к новой строке. Процедура readln после считывания заданного списка ищет в файле следующий признак конца строки и подготавливается к чтению с начала следующей строки.

Пример решения задачи с файлами Паскаля

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

Пояснения: нам понадобятся две файловые переменные f1 и f2, поскольку оба файла текстовые, то тип переменных будет text. Задача разбивается на два этапа: первый – формирование первого файла; второй – чтение первого файла и формирование второго.

Для завершенности решения задачи есть смысл добавить еще одну часть, которая в задаче явно не указана – вывод на экран содержимого второго файла.

Пример процедуры Assign Паскаля

Program primer; Var f1,f2:text;     I,n: integer;     S: string; Begin {формируем первый файл}     Assign(f1, ‘file1.txt’); {устанавливаем связь файловой переменной с физическим файлом на диске}     Rewrite(f1);  {открываем файл для записи}     Readln(n) {определим количество вводимых строк}     for i:=1 to n do     begin         readln(s); {вводим с клавиатуры строки}         writeln(f1,s); {записываем последовательно строки в файл}     end;     close(f1); {заканчиваем работу с первым файлом, теперь на диске существует файл с именем file1.txt, содержащий введенные нами строки. На этом программу можно закончить, работу с файлом можно продолжить в другой программе, в другое время, но мы продолжим}   {часть вторая: чтение из первого файла и формирование второго}     Reset(f1); {открываем первый файл для чтения}     Assign(f2, ‘file2.txt’); {устанавливаем связь второй файловой переменной с физическим файлом}     Rewrite(f2); {открываем второй файл для записи}   {Дальше необходимо последовательно считывать строки из первого файла, проверять выполнение условия и записывать нужные строки во второй файл. Для чтения из текстового файла рекомендуется использовать цикл по условию «пока не конец файла»}     While not eof(f1) do     Begin         Readln(f1,s);{считываем очередную строку из первого файла}         If (s[1]=’A’) or (s[1]=’a’) then         Writeln(f2,s); {записываем во второй файл строки, удовлетворяющие условию}     End;     Close(f1,f2); {заканчиваем работу с файлами}   {часть третья: выводим на экран второй файл}     Writeln;     Writeln(‘Второй файл содержит строки:’);     Reset(f2); {открываем второй файл для чтения}     While not eof(f2) do {пока не конец второго файла}     Begin         Readln(f2,s);{считываем очередную строку из второго файла}         Writeln(s); {выводим строку на экран}     End; End.

ПОДПРОГРАММЫ В ЯЗЫКЕ ПАСКАЛЬ.ПРОЦЕДУРЫ И ФУНКЦИИ.ОТЛИЧИЯ.ОСОБЕННОСТИ ПРИМЕНЕНИЯ.

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

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

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

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

Формат описания процедуры: Procedure <Имя процедуры> (<Имя форм. параметра 1>:<Тип>; < Имя форм. параметра 2>:<Тип>?); <Раздел описаний> Begin <Тело процедуры> End;

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

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

Формат описания функции: Function <Имя функции> (<Имя форм. параметра 1>:<Тип>; < Имя форм. параметра 2>:<Тип>?) : <Тип результата>; <Раздел описаний> Begin <Тело функции> End;

В теле функции обязательно должна быть хотя бы команда присвоения такого вида: <Имя функции>:=<Выражение>;

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

Вызов процедуры представляет в программе самостоятельную инструкцию: <Имя процедуры>(<Фактический параметр 1>, < Фактический параметр 2>?);

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

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

Приведем простейший пример использования подпрограммы.

Задача: "Найти максимальное из трех введенных чисел". Для решения воспользуемся описанием функции, принимающей значение максимального из двух чисел, которые передаются в нее в виде параметров.

Program Fn; Var A,B,C :Real; Function Max(A,B:Real):Real; {Описываем функцию Max с формальными} Begin {параметрами A и B, которая принимает }

If A>B Then Max:=A {значение максимального из них } Else Max:=B {Здесь A и B - локальные переменные }

End; Begin

Writeln('Введите три числа'); Readln(A,B,C); Writeln('Максимальным из всех является ', Max(Max(A,B),C))

End.

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

Существует два способа передачи фактических параметров в подпрограмму: по значению и по ссылке. В первом случае значение переменной-фактического параметра при вызове подпрограммы присваивается локальной переменной, являющейся формальным параметром подпрограммы. Что бы потом ни происходило с локальной переменной, это никак не отразится на соответствующей глобальной. Для одних задач это благо, но иногда требуется произвести в подпрограмме действия над самими переменными, указанными в качестве фактических параметров. На помощь приходит второй способ. Происходит следующее: при обращении к подпрограмме не происходит формирования локальной переменной-формального параметра. Просто на время выполнения подпрограммы имя этой локальной переменной будет указывать на ту же область памяти, что и имя соответствующей глобальной переменной. Если в этом случае изменить локальную переменную, изменятся данные и в глобальной.

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

Еще один классический пример. Задача: "Расположить в порядке неубывания три целых числа".

Program Pr; Var S1,S2,S3 :Integer; Procedure Swap(Var A,B: Integer);{Процедура Swap с параметрами-переменными} Var C : Integer; {C - независимая локальная переменная} Begin  C:=A; A:=B; B:=C {Меняем местами содержимое A и B} End; Begin

Writeln('Введите три числа'); Readln(S1,S2,S3); If S1>S2 Then Swap(S1,S2); If S2>S3 Then Swap(S2,S3); If S1>S2 Then Swap(S1,S2); Writeln('Числа в порядке неубывания:V',S1,S2,S3)

End.

ФОРМАЛЬНЫЕ И ФАКТИЧЕСКИЕ ПАРАМЕТРЫ ПОДПРОГРАММ.РАЗНОВИДНОСТИ ФОРМАЛЬНЫХ ПАРАМЕТРОВ.

Формальные параметры подпрограммы указывают, с какими аргументами следует обращаться к этой подпрограмме (количество аргументов, их последовательность, типы). Они задаются в заголовке подпрограммы в виде списка, разбитого на группы. Разделителем групп является знак точка с запятой (;). В каждую группу  включаются  параметры одного типа, принадлежащие к одной  категории.

Все формальные параметры можно разбить на четыре категории:

  • параметры-значения;

  • параметры-переменные;

  • параметры-константы (используются только в версии 7.0);

  • параметры-процедуры и параметры-функции.

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

function Max( A: array[ 1..100 ] of real ): real;

Чтобы правильно записать этот заголовок, следует в основной программе ввести тип-массив, а затем использовать его в заголовке:

type tArr =array [ 1..100 ] of real; function Max ( A: tArr ) : real;

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

Вызов по ссылке и по значению

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

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

Приведем примеры:

Передачу данных по значению использует процедура установки даты в операционной системе, заголовок которой выглядит так:

Procedure SetDate (Year, Month, Day : Word);

В подпрограмму передается три величины. Ее вызов в основной программе может иметь различные формы:

  • SetDate (MyYear, MyMonth, MyDay); где MyYear, MyMonth, MyDay - переменные типа Word, которые описаны в основной программе и должны иметь при обращении к процедуре определенные значения. При вызове процедуры эти значения присваиваются внутренним переменным процедуры Year, Month, Day.

  • SetDate (MyYear+1, MyMonth div 2, MyDay); при вызове процедуры используются арифметические выражения, которые вычисляются при вызове. В подпрограмму поступает результат вычислений.

  • SetDate (1999, 1, 31); где в подпрограмму передаются значения констант.

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

Приведем пример.

Для получения от операционной системы даты используется процедура, имеющая заголовок

Procedure GetDate (Var Year, Month, Day : Word);

Она имеет три переменные, передаваемые по ссылке. Если мы аналогично предыдущему случаю, вызовем эту процедуру из основной программы командой

GetDate (MyYear, MyMonth, MyDay);

процедура разместит свои переменные Year, Month, Day в тех же ячейках памяти, что и переменные основной программы MyYear, MyMonth, MyDay. После завершения подпрограммы эти переменные сохраняют полученные в процедуре значения.

В 7 версии Borland Pascal предусмотрен новый механизм передачи в подпрограмму параметров по значению. Этот механизм используется, если значение параметра не должно изменяться - этопараметры-константы.

Объявление параметра-константы в заголовке подпрограмм имеет вид

  const <имя константы>:<тип константы>

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

  • константа может быть задана в явном виде;

  • может быть указана переменная или выражение совместимого с константой типа.

Например, Procedure Primer (Const x : byte).

Внимание! При вызове процедур необходимо следить за соответствием типов данных в вызывающей программе и подпрограмме.

Параметрызначения

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

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

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

Пример.

procedure Inp ( Max, Min: real ; N: Word ); function Mult (X, Y: integer): real;

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

Inp(Abs (Z), - Abs (T), 2 * K); M:=Mult(X + Y, X - Y); MA:=MAX( B, 5 );

Локальные и глобальные переменные и подпрограммы

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

Рассмотрим две почти одинаковые программы.

Program Variant1;      Var   X : real; Procedure writeX; Var   X : real; Begin   write(X) End; Begin   X := Pi;;   writeX End.

Program Variant2; Var   X : real; Procedure writeX; Begin   write(X) End; Begin   X := Pi;   writeX End.

Нетрудно догадаться о содержании решаемой задачи: присвоить глобальной переменной X некоторое значение, а затем напечатать это число через специальную процедуру.

Во втором варианте программы переменная с именем Х описана только в основной программе, поэтому она, как глобальная переменная, доступна в подпрограмме. В результате будет напечатано значение числа Пи.

В первом варианте переменная X переопределена в подпрограмме, таким образом, в подпрограмме имеется локальная переменная X, ничем не связанная с переменной Х основной программы. Поскольку этой локальной переменной не присвоено значение, будет напечатано случайное число, содержащееся в соответствующей ячейке памяти.

Возникает вопрос, какова роль локальных переменных, нельзя ли все переменные описать как глобальные?

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

Кроме локальных переменных, в подпрограммах могут быть и локальные подпрограммы. Это подпрограммы, текст которых размещен внутри текста подпрограммы более высокого уровня. Использование таких подпрограмм, как и локальных переменных, ограничивается подпрограммой, к которой они принадлежат.

Локальность или глобальность являются понятиями относительными. Программа с вложенными в нее подпрограммами представляет собой иерархическое дерево. Объект, локальный по отношению к более высокому уровню иерархии, ведет себя как глобальный по отношению к подпрограммам более низкого уровня.

МОДУЛЬНОЕ ПРОГРАММИРОВАНИЕ.ОПРЕДЕЛЕНИЕ МОДУЛЯ.СТРУКТУРА МОДУЛЯ В ЯЗЫКЕ ПАСКАЛЬ.

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

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

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

Использование модульного программирования позволяет упростить тестирование программы и обнаружение ошибок. Аппаратно-зависимые подзадачи могут быть строго отделены от других подзадач, что улучшает мобильность создаваемых программ.

Термин «модуль» в программировании начал использоваться в связи с внедрением модульных принципов при создании программ. В 70-х годах под модулем понимали какую-либо процедуру или функцию, написанную в соответствии с определенными правилами. Например: «Модуль должен быть простым, замкнутым (независимым), обозримым (от 50 до 100 строк), реализующим только одну функцию задачи, имеющим одну входную и одну выходную точку».

Первым основные свойства программного модуля более-менее четко сформулировал Парнас (Parnas): «Для написания одного модуля должно быть достаточно минимальныхзнаний о тексте другого». Таким образом, в соответствии с определением, модулем могла быть любая отдельная процедура (функция) как самого нижнего уровня иерархии (уровня реализации), так и самого верхнего уровня, на котором происходят только вызовы других процедур-модулей.

Таким образом, Парнас первым выдвинул концепцию скрытия информации (information hiding) в программировании. Однако существовавшие в языках 70-х годов только такие синтаксические конструкции, как процедура и функция, не могли обеспечить надежного скрытия информации, поскольку подвержены влиянию глобальных переменных, поведение которых в сложных программах бывает трудно предсказуемым.

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

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

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

Впервые специализированная синтаксическая конструкция модуля была предложена Н. Виртом в 1975 г. и включена в его новый язык Modula . Насколько сильно изменяются свойства языка, при введении механизма модулей, свидетельствует следующее замечание Н.Вирта, сделанное им по поводу более позднего языка Модула-2: «Модули – самая важная черта, отличающая язык Модула-2 от его предшественника Паскаля».

По своей организации и характеру использования в программе модули Паскаля близки к модулям-пакетам (PACKAGE) языка программирования Ада. В них так же, как и в пакетах Ады, явным образом выделяется некоторая «видимая» интерфейсная часть, в которой сконцентрированы описания глобальных типов, констант, переменных, а также приводятся заголовки процедур и функций. Появление объектов в интерфейсной части делает их доступными для других модулей и основной программы. Тела процедур и функций располагаются в исполняемой части модуля, которая может быть скрыта от пользователя.

Значение модулей для технологии разработки программного проекта может быть продемонстрировано диаграммой на рис. 2.

Модули представляют собой прекрасный инструмент для разработки библиотек прикладных программ и мощное средство модульного программирования. Важная особенность модулей заключается в том, что компилятор размещает их программный код в отдельном сегменте памяти. Длина сегмента не может превышать 64 Кбайт, однако количество одновременно используемых модулей ограничивается лишь доступной памятью, что позволяет создавать большие программы.

Структура модулей Паскаля

Всякий модуль Паскаля имеет следующую структуру:

Unit <имя_модуля>; interface <интерфейсная часть>; implementation < исполняемая часть >; begin  <инициирующая часть>;  end .

Здесь UNIT – зарезервированное слово (единица); начинает заголовок модуля;