Var d, e, f: real;
procedure Norma (a,b: real; var c: integer);
begin c:=sqrt(sqr(a)+sqr(b));
end;
begin
readln (d,e);
Norma (d,e,f);
writeln(f); end.
Здесь d, e, f фактические параметры, которые используются при вызове процедуры. С другой стороны это глобальные переменные. Запишем модифицированное тело вызова Norma:
a:=d; b:=e; begin f:=sqrt(sqr(a)+sqr(b)); end;
Фактический параметр, который заменяет параметр-переменную не может быть константой или выражением, в отличии от параметров-значений.
Вложенные описания процедур. Процедура имеет такую же структуру, что и основная программа, то есть в описательной части указываются константы, переменные, типы и описания подпрограмм.
То есть можно говорить о вложенном описании процедур (подпрограмм) - глубина неограничена.
var c: real; s: char;
procedure P(var c: char);
var b, d: string;
procedure R (var x: string; L: real);
var e, f: boolean;
begin... end
begin ... R(b, 2.5); end;
begin ... P(s); end;
Переменные e и f являются локальными по отношению к процедуре R. Говорят, что областью их действия является процедура R. Эти переменные нельзя использовать ни в процедуре P, ни в основной программе. Переменные c: real и s - являются глобальными и имеют область действия и в процедурах P и R и в основной программе. Для переменной C в процедуре P осуществляется перекрытие ее действий формальным параметром, которой по смыслу является локальной переменной. Другими словами говорят, что действует ближайшее описание.
Вопрос №45
Модули.
Под ресурсом будем понимать вспомогательные алгоритмы, переменные, константы, типы данных и т.д. То есть все, что можно использовать в программе в качестве составного элемента. Аппарат модулей обеспечивает возможность создания набора ресурсов, которые программист может использовать в нескольких программах.
Программа или модуль называются программными единицами. Модуль является независимо конструируемой программной единицей в отличии от подпрограмм. Рассмотрим структуру модуля.
1) unit <Имя модуля>;
2) interface
uses <Список модулей 1>;
const...;
type...;
var...;
procedure...;
function...;
3) Implementation
uses <Список модулей 2>;
const...;
type...;
var...;
procedure...;
function...;
4) begin
end.
1) - Заголовок модуля.
2) - Интерфейсный отдел.
3) - Отдел реализации.
4) - Блок инициализации модуля.
1) Заголовок модуля, в котором модуль именуется обязателен, причем имя модуля и имя файла, в котором он хранится должны совпадать.
2) В разделе интерфейса программист описывает константы, тип, переменные и подпрограммы, которые поставляются другими программным единицам. Эти ресурсы называются видимыми ресурсами модуля. В разделе Uses перечисляются имена тех модулей (Список 1), из которых используются в данном модуле для описания своих ресурсов. Говорят, что ресурс из списка модулей 1 подключены к текущему модулю.
3) Отдел реализации содержит полное описание процедур и функций, которые перечислены в разделе интерфейса. При описании подпрограмм могут понадобиться дополнительные константы, типы и переменные. Они описываются в разделе реализации. Эти ресурсы являются недоступными для других текущих модулей и для программ, использующих текущий модуль. Если при описании подпрограмм необходимы ресурсы других модулей, то их имена указываются в списке 2 в строке Usesю
4) Блок инициализации модуля может содержать любые операторы, выполняющие начальные действия. Например, присваивание переменным начальных значений. Блок инициализации модуля выполняется перед основной программой, в которой подключен текущий модуль. Блок инициализации может быть пустым, но begin end. - должны быть.
Unit A;
interface
type Ind=1..100;
implementation
begin
end.
Unit B;
interface
Uses A;
type Ar=array[Ind] of char;
procedure P(f: Ar);
implementation
procedure P;
begin... end;
begin
end.
Program Main;
Uses B;
var x: Ar;
begin
...; P(x);
end.
При подключении модуля к программе используется строка Uses. При описании подпрограмм в разделе реализации список формальных параметров можно не указывать.
Вопрос №46
Основные преимущества использования модулей.
Если некоторый ресурс используется в нескольких программных единицах, то его достаточно описать 1 раз в модуле. При этом такое однократное описание позволяет поддерживать ресурс в активном состоянии. То есть при внесении изменении достаточно лишь изменить ресурс и перекомпилировать модуль.
Вопрос №47
Особенности использования модулей.
1) Если в программе подключено несколько модулей, то их блоки инициализации выполняются последовательно, в порядке перечисления имен модулей в строке Uses.
2) Если в нескольких модулях, подключенных в программе, определяются одноименные ресурсы, то программе доступен тот ресурс, который указан в последнем подключаемом модуле. Более того, если в программе определен ресурс с таким же именем, то ресурсы модулей становятся недоступными.
Unit A;
interface
var x: real;
implementation
begin end.
Unit B;
interface
type x=1..10;
implementation
begin end.
Program M;
Uses A, B;
var x: char; y:=x;
begin x:=2,5; x:='A';
end.
При необходимости доступ к каждому из ресурсов, подключенных в программе модулей, можно получить используя так называемые, уточненные имена: <имя модуля>.<имя ресурса>.
3) Если в нескольких модулях при определении ресурсов возникла рекурсия, то если эта рекурсия в разделе реализации, то компилятор сам решает проблему. Рекурсия в интерфейсной части недопустима. Если все же сложилась такая ситуация, то необходимо удалить рекурсию, создав третий модуль.
Unit A;
Interface
Uses B;
type Ind=1..10;
var x: Ar;
...
end.
Unit B;
Interface
Uses A;
type Ar=array[1..2] of real;
Ar2=array[Ind] of char;
...
end.
Один из вариантов решения. Введем:
Unit C;
interface
type Ind-1..10;
...
end.
Вопрос №48
Комбинированные типы.
Любой комбинированный тип является структурированным. Значения типа называются записями. Запись состоит из элементов, называемых полями. При этом, в отличие от массивов, поля могут быть разных типов. Доступ к отдельному полю записи осуществляется по указанию имени этого поля, поэтому имя поля в пределах записи должно быть уникальным.
Структура:
record
<имя поля>:<тип>;
...
<имя поля>:<тип>;
end;
type Anketa=record
fio: string;
age: 0..200;
ves: real;
end;
var A=Anketa;
Переменная А - переменная запись, допуск у полям которой имеет структуру: <имя записи>.<имя поля>.
A.fio:='Кузя';
A.age:=199;
A.ves:=1,98;
Над записью в целом можно выполнять только операцию присваивания (над однотипными записями). Ввод данных осуществляется поэлементно: readln(A.fio).
Любое поле записи может иметь любой тип, в том числе структурированный, в том числе полем записи может быть запись.
Вопрос №49
Оператор присоединения.
Оператор присоединения имеет вид: with <имя записи> do <оператор>.
В операторе можно обращаться к полям записи по их именам, без префиксов в виде имени записи:
with A do
if (age<=18) then k:=k+1;
Вопрос №50
Записи с вариантами.
При определении комбинированного типа можно задать постоянную часть записи и переменную часть. Это удобно в тех случаях, когда данные имеют некоторую фиксированную часть и варьируемую часть. Комбинированный тип с вариантами имеет следующую структуру:
record
< имя поля1>:<тип >;
... постоянная часть
<имя поля>:<тип>;
c ase <дескриптор> of
<константа1>: (<список полей1>); вариантная часть
...
end;
Дескриптор имеет дискретный, скалярный, упорядоченный тип. Сам дескриптор входит в постоянную часть записи. Константы должны иметь тот же тип, что и дескриптор. Каждый из списков имеет следующую структуру:
<имя поля>:<тип>;<имя поля>:<тип>;...
В каждый момент времени существования некоторой записи состав полей вариантной записи определяется значением дескриптора, то есть если дескриптор равен константе 1, то в комбинированный тип добавляется список полей 1.
type Anketa2=record
Name: string;
Born: TDat;
Case Sempol: 0..2 of
1: (Name1: string; DataZB: TDat);
2: (DataR: TDat);
end;
var a: anketa2;
...
begin...
readln (a.Name, a.Born, a.Sempol);
case a.sempol of
1: readln (a.Name, a.DataZB);
2: readln (a.DataR);
end;
Используется тип TDat, который должен быть описан в виде:
type TDat=record
d: 1..31;
m: 1..12;
y: 1..3000;
end;
Вопрос №51
Распределение памяти под записи с вариантами.
Во время компиляции программы для каждой записи с вариантами выделяется область памяти, достаточная для постоянной записи и самой длинной вариантной.
| Name1 |
,//////////,\\\\\\\\\\,////////////, , , ,
Name Born Sempol | DataR | | DataZB |
В большинстве реализаций ВПМ контроль за корректностью обращения к полям переменной части записи не ведется. Поэтому удобно использовать оператор выбора.
Вопрос №52
Перечислимые типы.
Любой перечислимый тип является скалярным, дискретным, упорядоченным типом и состоит из конечного множества значений, каждый из которых определен своим идентификатором. Определение перечислимого типа собственно и есть список идентификаторов и имеет следующий вид: (<константа1>,...,<константаN>).
type Den=('Pon','Vtor','Sred','Chet','Pyat','Sub','Vosk');
var d: Den;
d - переменная перечислимого типа и ее значением может быть любая из указанных констант. Константы считаются упорядоченным слева направо и пронумерованными, начиная с 0. Над переменными перечислимого типа выполняются функции: ord, succ, pred.
d:='Pon'; ord(d)=0;
succ от последней - не определена.
pred от первой - не определена.
Перечислимые типы удобно задавать при использовании дискретный данных с заранее известным диапазоном. Кроме того использование идентификаторов улучшает мнемонику программы.
Вопрос №53
Множественные типы.
Любой множественный тип состоит из совокупности множеств. При этом элементы каждого такого множества принадлежат некоторому базовому типу. В качестве базового типа можно использовать любой скалярный, дискретный, упорядоченный тип. В большинстве реализаций не должен превышать 256 значений.
К таким типам относятся boolean, byte, char, shortint.
Определение множественного типа имеет вид: set of <базовый тип>.
type Tchar=set of char; TCifra=0..9; TSCifra=set of TCifra;
Константные значения множественного типа изображаются списком значений базового типа в []: ['B','+','D']. Можно использовать интервалы: ['A','B','C','D']=['A'..'D'].
Над значениями множественного типа определены операции + - объединение, * - персечение, - - разность, in - принадлежность элемента. Множества можно сравнивать, при этом сравнение на большее и меньшее это включение.
A<B - A⊂B;
A<=B - A⊆B;
Вопрос №54
Реализация множеств.
В языке Pascal множества представляются, так называемыми логическими шкалами. Каждая переменная или константа множественного типа представляет собой последовательность из 0 и 1. Длина этой последовательности равна количеству элементов в базовом типе множества, а 1 стоят на тех местах, которые соответствуют некоторому элементу базового типа множества и находятся во множестве.
type Tbaza=0..9;
TS=set of Tbaza;
var a, b: TS;
a=[1, 3, 5];
b=[0, 3, 5 ,7].
Такое представление эффективно для реализации операций над множествами. Объединения множеств - поразрядная дизъюнкция логических шкал.
0101010000
1001010100
1101010100=[0,1,3,5,7];
Пересечение - поразрядная конъюнкция.
0101010000
1001010100
0001010000=[3,5];
in - конъюнкция между множеством и логической шкалой того элемента, который следует проверить на принадлежность множеству. 3 in a.
0101010000
0001000000
0001000000 - TRUE;
Все логические шкалы, отводимые коду множества кратны 8, то есть под переменные или константы множественного типа резервируется целое количество байт.
Вопрос №55
Ввод и вывод информации. Система управления вводом-выводом.
В большинстве ЯП и ОС понятие ввода-вывода информации связано с понятием файла. Файл - поименованная совокупность данных, объединенных общим назначением и хранящихся на внешнем носителе.
При наборе данных с клавиатуры говорят о входным файле или входном потоке данных. При выводе данных на экран о выходном потоке данных. Причинами использования файлов в программе являются: 1) Файл позволяет взаимодействовать со внешней средой.
2) В файлах информацию можно хранить длительное время.
3) Энергетическая зависимость внешнего носителя гораздо дешевле основной памяти, поэтому большие объемы информации принято хранить в файлах.
Система управления вводом-выводом (СУВВ).
В большинстве задач для ввода или вывода информации необходимо выполнить последовательность действий. Такую последовательность удобно описать 1 раз на машинно-ориентированном языке. Набор таких подпрограмм называется СУВВ (BIOS (basic input-output system)). Обычно СУВВ разделяют на физическую и логическую части. Подпрограммы физической части позволяют непосредственно управлять внешними устройствами и учитывают их особенности.
Программирование с учетом подпрограмм физической части позволяет сделать программу более эффективной, но требует от программиста знание особенностей внешнего устройства и знания машинно-ориентированного языка (Assembler). Логическая часть предоставляет программисту возможность работы с файлами и их записями. СУВВ является частью операционной системы.
Вопрос №56
Методы доступа.
Существуют 2 метода доступа к записи файла: - Последовательный доступ.
- Прямой доступ.
При последовательном доступе для того, чтобы обратиться к i-той записи файла необходимо последовательно прочитать все записи файла от 1 до i-1. В момент открытия файла считается доступной 1-я запись файла.
При прямом доступе в любой момент времени доступна любая запись файла.
Как правило доступ осуществляется по ключу: в каждой записи файла выделяются дополнительное поле, которое содержит уникальное значение для файла и называется ключом. В качестве ключа часто используют порядок номера в записи.
Вопрос №57
Метки файлов.
Каждый файл снабжается специальной записью, называемой меткой файла. Метка обычно содержит следующую информацию: Имя файла, сведения о владельце, время и дата создания, номер версии файла, допустимые способы обработки(файл только для чтения, файл для чтения и записи, архивный файл, системный файл), размер файла.
[______][_______][_________________]
Имя Размер Адрес начала файла
Вопрос №58
Открытие и закрытие файла.
В ОС перед обработкой записи файла выполняются процедура открытия файла, в процесс которой определяется местоположение файла на диске, определяются права прикладной программы на доступ к этому файлу. При необходимости выделяется буферная область оперативной памяти и выполняются операции для считывания первой записи файла.
По завершению работы с файлом для корректности сохранения данных в файле необходимо выполнить процедуру закрытия файла. Эта процедура переводит файл в пассивное состояние и обеспечивает целостность сохранения данных.
Вопрос №59
Буферизация ввода-вывода.
Буферизация ввода-вывода - прием программирования, состоящий в опережающей подготовке данных для последующей обработки. Операция ввода данных из файла требует некоторых действий по поиску записи файла, подготовке устройства чтения и собственно пересылке данных из файла в основную память. При этом, последнее действие занимает значительно меньше времени, чем подготовительные действия. Поэтому целесообразно организовать чтение данных крупными блоками. С другой стороны, если программа должна обрабатывать большие блоки информации, то необходимо разработать эффективный алгоритм выделения из блока некоторой логической единицы, обрабатываемой в программе.
Так как операция чтения записи является достаточно распространенной, то в СУВВ существуют специальные функции, соответствующие этому процессу. Пусть L - длина записи последовательного файла. В основной памяти выделена область размером Lxn, где n>=2. Эту область называют буфером ввода-вывода. n - коэффициент блокирования.
При первом обращении СУВВ выделяются первые m записей файла и помещаются в буфер ввода-вывода. После этого первая запись блока становится доступной программе. Если программе потребуется другая запись файла, то она будет считываться не из файла, а из буфера ввода-вывода. После того как буфер полностью исчерпан считывается следующий набор записей, начиная с n+1 записи. Обращение к внешнему устройству происходят только в момент выполнения буфера.
Буферизация является автоматизированным процессом со стороны операционной системы и для программиста является прозрачной.
Вопрос №60
Логические и физические файлы.
Понятие логического файла в Pascalе соответствует файловой переменной, с помощью которой программа ведет все операции ввода-вывода. Обычно файловая переменная связана с реально существующем на внешнем носителе фалом. Этот файл называется физическим . При этом СУВВ обеспечивает независимость прикладной программы от местоположения физических файлов на диске и особенностей внешнего устройства.
Общая схема работы с файлами в Pascalе имеет вид связывания файловых переменных с некоторыми физическими файлами:
1) Открытие файла.
2) Обработка записей файла.
3) Закрытие файла.
Вопрос №61
Общие операции над файлами.
f - имя файловой переменной.
S - выражение строкового типа.
1) assign(f,S) - процедура связывания логического файла f с физическим файлом, имя которого находится в переменной S. Имя файла задается по правилам ОС (полное имя: диск, путь, сам файл).
2) reset(f); rewrite(f) - процедуры открытия файла, соответствующего переменной f.
reset - открывает уже существующий файл и доступной становится первая запись файла.
rewrite - создает новый файл и становится возможным записать в него первую запись.
Если к моменту вызова rewrite физический файл, связанный с переменной f существовал, то вся информация в нем стирается.
3) close(f) - операция закрытия файла при этом сохраняется целостность данных.
4) eof(f) - булевская функция, возвращает true, если в процессе обработки файла f достигнут конец файла. Так как количество записей в файле заранее неизвестно, то стандартной схемой обработки файла является следующая:
while not(eof(f)) do begin {считывание и обработка} end;
5) rename (f,S) - процедура переименования файла, связанного с переменной f. Новое имя файла указывается в переменной S. К моменту переименования файл должен быть закрыт.
6) erase(f) - процедура удаления файла, связанного с переменной f. К моменту удаления файл должен быть закрыт.
Вопрос №62
Краткая характеристика основных классов файлов языка Pascal.
Существуют 3 типа классов файлов:
1) Типизированные файлы. В файлах этого типа все элементы имеют одинаковую структуру, которая определяется в момент описания файла. Записи типизированных файлов хранятся в некотором машинном предписании, поэтому у ВПМ имеется возможность контролировать корректность обращения к записям файла. В качестве типов записи файла можно указывать предопределенные или создаваемые программистом типы.
2) Бестиповые файлы. Информация о записях файла также хранится в машинном представлении, но структура и тип записи не известны, поэтому ВПМ не может контролировать корректность обращения к данным, этим занимается программист.
3) Текстовые файлы. Информация хранится в виде последовательности символов в ASCII. При этом, в отличи от предыдущих классов, записи текстового файла могут иметь различную длину. Каждая запись завершается специальным признаком конца записи. Каждая запись текстового файла называется строкой, при выводе данных в текстовом файле автоматически проводится преобразование внутреннего представления символ в сам символ.
Вопрос №63
Типизированные файлы.
Описание: var f: file of <тип записи>.
<тип записи> - имя типа, или определение типа (кроме файлового типа).
Вопрос №64
Бестиповые файлы.
Описание: f: file;
Размер записи бестипового файла определяется в момент открытия процедурами reset или rewrite. Вызовы этих процедур для бестиповых файлов имеют следующий формат: reset(f,BLsize); rewrite(f,BLsize).
Здесь второй параметр целочисленное выражение, задающее размер записи в байтах.
Ввод и вывод с помощью процедур: blockread(f,d,c,[i]); blockwrite(f,d,c,[i]).
f - имя файла.
d - имя некоторой переменной, которая задает начало области памяти и с которой или в которую будут считываться или записываться байты данных. Тип переменой d не влияет на корректность работы с данными.
c - количество блоков длины BLsize, передаваемых между файлом и основной памятью.
i - выходной параметр, который по завершению работы процедуры содержит количество действительно перемещенных записей между файлом и основной памятью. Если параметр i не указан и количество реально перемещенных блоков не совпадает с с, то процедура завершается аварийно.
Пример: Дан файл f, получить его копию в файл g.
var f, g: file; x: byte;
begin
assign(f,'f.dat'); assign(g,'g.dat');
reset(f,1); rewrite(g,1)
repeat blockread(f,x,10,i);
blockwrite(g,x,10,i) until i=10.
Вопрос №65
Файлы прямого доступа.
Типизированные и бестиповые файлы могут использоваться как файлы прямого доступа (не используется с текстовыми). Записи файла считают пронумерованными считая с 0 и доступ к некоторой записи осуществляется по ее номеру. Под текущей записью понимается запись файла, в которую можно записать информацию, или прочитать из нее информацию в текущий момент.
Определны слдующие процедуры и функции:
Filesize(f) - функция возвращает количество записей файла.
Filepos(f) - функция возвращает номер текущей позиции файла.
Seek(f,k) - процедура делает текущей запись с номером k.
Пример: дан файл целых чисел. Найти количество элементов, значения которых больше значения последнего элемента.