Вопросы темы:
1. Подпрограммы.
2. Процедуры.
3. Функции.
Написание любой большой программы невозможно как без разбиения задачи на менее сложные подзадачи, которые мы можем решать независимо, так и без повторного использования ранее написанного кода. Решить эти важнейшие задачи позволяет механизм подпрограмм, имеющийся в любом языке программирования, в том числе, и в Паскале.
Подпрограммой называют независимую часть программы, предназначенную для решения некой подзадачи. Подпрограмма взаимодействует с основной программой через механизм параметров - так называют входные и выходные данные, с которыми работает подпрограмма. Однажды написанная подпрограмма, выполненная с теми или иными значениями параметров, может решать некоторый класс задач.
Использование подпрограмм в чем-то похоже на расчеты с использованием математических или физических формул. Так, имея общие формулы решения квадратного уравнения, мы можем подставить вместо коэффициентов a, b и c любые числовые значения и решить любое конкретное уравнение. Аналогично, мы могли бы написать подпрограмму с входными параметрами a, b, c и выходными параметрами x1, x2 (найденные корни уравнения), а затем, применяя нужное число раз эту подпрограмму (однократное использование подпрограммы называется ее вызовом), найти корни любого количества квадратных уравнений.
Итак, использование подпрограмм позволяет решить следующие задачи:
- уменьшение размеров кода и экономия памяти за счет возможности неоднократного вызова одной и той же подпрограммы в рамках одной программы;
- лучшее структурирование программы за счет разбиения задачи на более простые подзадачи;
- эффективное повторное использование однажды написанного кода.
В Паскале подпрограммами являются процедуры и функции.
Процедуры и функции - это законченные программные единицы, которые решают некоторую подзадачу и, возможно, выполняются многократно. Все процедуры и функции делятся на две группы: стандартные и пользовательские (создаваемые разработчиком программы).
Стандартные входят в состав языка и вызываются для выполнения по своему
имени.
Процедуры.
Процедура - это независимый программный блок (программная единица), выполняющий решение некоторой самостоятельной подзадачи.
Процедуры (и функции) размещаются в программе сразу же после описания переменных (раздел Var) и перед словом Begin, указывающим начало ее основной части, т.е. следующим образом:
Program
Const
Var
.....
Процедура _1;
.....
Процедура_n;
Begin { Начало основной программы }
......
End.
Сама процедура оформляется следующим образом:
Procedure Имя(Формальные_параметры); {заголовок процедуры}
Описание локальных переменных;
Begin
Операторы; <= Тело процедуры
End;
Можно заметить, что процедура описывается так же, как программа. Отличие заключается в том, что текст программы заканчивается служебным словом End с точкой, а процедура заканчивается служебным словом End с точкой с запятой после него. Поэтому саму Паскаль-программу можно считать главной процедурой.
Формальные параметры - это список, который содержит имена переменных, являющихся исходными данными и результатами процедуры. Он может отсутствовать. Элементы списка параметров описываются полностью, с указанием типов. В этом списке через запятую указываются входные и выходные параметры процедуры с указанием их типов данных (параметры разных типов отделяются символом;). Параметры разных типов отделяются точкой с запятой. Входные параметры служат исходными данными для процедуры, а выходные определяют результаты ее вычислений, передаваемые в главную программу или другую подпрограмму. Перед выходными параметрами, измененные значения которых должны сохраняться после завершения процедуры, следует указывать ключевое слово var.
Локальные переменные - это переменные, которые используются только внутри данной процедуры.
Пример. Процедура, выводящая горизонтальную линию из n одинаковых символов, может быть такой.
Procedure GorLine(n: Integer; Sim: char);
{Изображение горизонтальной линии символом Sim}
Var
i: Integer;
Begin
For i:=1 To n Do
Write(Sim);
End;
Здесь n и Sim - формальные параметры, являющиеся входными величинами; i - локальная переменная.
Само по себе описание процедуры еще не вызывает выполнения никаких действий. Чтобы процедура сработала, ее нужно вызвать, записав в нужном месте программы имя процедуры со списком фактических параметров, которые будут подставлены на место формальных.
Пример процедуры решения квадратного уравнения с именем Equation. Входными данными этой процедуры будут значения коэффициентов уравнения a, b и c, выходными - найденные корни x1 и x2 (если они существуют). Кроме того, понадобится "временная" (а точней, локальная) переменная d, позволяющая процедуре хранить вычисленное значение дискриминанта:
procedure Equation(a,b,c:real; var x1,x2:real);
var d:real;
begin
d:=sqr(b)-4*a*c;
if d>=0 then begin
x1:=(-b+sqrt(d))/(2*a);
x2:=(-b-sqrt(d))/(2*a);
end;
end;
В случае отрицательного значения дискриминанта, значения x1 и x2 остаются неопределенными, в противном случае они вычисляются и должны быть переданы в главную программу. Вызвать эту процедуру мы могли бы, например, так:
var a,b,c,x1,x2,x3,x4:real;
...
write('Введите значения a,b,c:');
read(a,b,c);
Equation(a,b,c,x1,x2);
Здесь решается уравнение ax2+bx+c=0, значения a, b, c, вводятся с клавиатуры пользователем, результаты, если они вычислялись, будут помещены в переменные x1 и x2.
При вызове вида:
Equation(1,4,-3.5,x3,x4);
решается уравнение x2+4x-3.5=0, а ответы помещаются в переменные x3 и x4.
При каждом вызове процедуры значения фактических параметров подставляются на место формальных и с ними производятся вычисления, предусмотренные операторами подпрограммы. Указанные требования называют согласованием параметров и описывают следующим образом: формальные и фактические параметры должны быть согласованы между собой по количеству, типу и порядку следования. Это означает, что количество формальных и фактических параметров должно быть одинаковым, при этом, при вызове процедуры каждый фактический параметр должен иметь тот же тип и занимать в списке то же место, что и соответствующий ему формальный параметр. Из сказанного следует, что процедуру Equation можно вызвать только с пятью параметрами, причем все эти параметры должны быть вещественными. Если формальный параметр является выходным (перед ним в заголовке процедуры указано ключевое слово var), то соответствующий фактический параметр не может быть константой (ведь значение константы нельзя изменить).
Функции.
Функция - это независимый программный блок (программная единица), который позволяет получить результат, передаваемый через имя функции. Примером являются стандартные функции Паскаля. Имеется возможность писать свои функции. Располагаются они в программе так же, как процедуры: после описания данных и перед операторами.
Пример.
Program...;
Const
...
Var
...
Функция_1;
.....
Функция_n;
Begin { основная программа }
.....
End.
Функция оформляется так же, как процедура. Отличие имеется в заголовке и способе передачи результата. В общем виде, функция оформляется так:
Function Имя(формальные_параметры): Тип_Результата;
Описание локальных переменных;
Begin
....
Имя:=Выражение;
....
End;
Формальные параметры - это аргументы функции. Результат передается через имя функции, поэтому в заголовке указывается тип результата. По этой же причине среди операторов в теле функции должен быть хотя бы один, в котором имени функции присваивается значение. Именно это значение и будет возвращено функцией в качестве результата.
Для вычисления значения функции с конкретным параметром ее, как и процедуру, вызывают из основной программы с указанием фактических параметров-аргументов. В отличие от процедуры имя функции встречается в выражениях в качестве операнда. Когда выражение вычисляется, функция выполняется и значением операнда становится величина, возвращаемая функцией. При обращении к функции (вызове ее) на место формальных параметров подставляются фактические, как в процедуре. Типы, количество и порядок следования фактических и формальных параметров должны совпадать. Все, сказанное выше о согласовании формальных и фактических параметров, в полной мере относится и к функциям.
Пример описания и вызова функции в программе.
{Вычислить факториалы первых 10 натуральных чисел}
var i: byte;
f: integer;
function factorial (n: byte): integer;
var i: byte;
f: integer;
begin
f:=1;
for i:=1 to n do
f:=f * i;
factorial:=f;
end;
begin
for i:=1 to 10 do
begin
f:=factorial(i);
writeln(f);
end;
end.
Часто на структурных схемах алгоритмов процедуры и функции обозначаются как предопределенный процесс (см. рисунок).
Рис. Вычисления по стандартной или пользовательской подпрограмме.
Фактически, стандартные подпрограммы Паскаля также делятся на функции и процедуры, в зависимости от способа их вызова. Так, writeln относится к стандартным процедурам, а sin - к функциям. Некоторые стандартные процедуры и функции были рассмотрены ранее. Полный их список приводится в описании на конкретную версию реализации языка, а также в help-файлах (файлах помощи).
Тема 7. Файлы
Вопросы темы:
1. Текстовые файлы.
2. Типизированные файлы.
Для работы некоторых программ часто требуется обмен данными с файлами. Для ЭВМ любая информация: программа, исходные данные и результаты является набором данных.
Набор данных (физический файл) – это совокупность данных, имеющих общее имя и назначение, и существующая на некотором носителе.
В программе на Паскале наборам данных соответствуют файлы.
Файл - это логическое понятие, связанное с физически существующим набором данных. Связь обеспечивается операционной системой при выполнении программы пользователя.
В Pascal ABC различают текстовые и типизированные файлы.
Текстовые файлы.
При открытии текстового файла внешний файл интерпретируется особым образом: считается, что он представляет собой последовательность символов, сгруппированных в строки, где каждая строка заканчивается признаком конца строки (end of line).
Для работы с каждым файлом описывается переменная типа text:
var f: text;
Ее называют файловой переменной. Если программа обрабатывает несколько файлов одновременно, для каждого из них описывается такая переменная. Вся работа с файлом происходит через файловую переменную, имя файла указывается только один раз следующим оператором:
assign (f,'имя_файла');
где f - ранее описанная файловая переменная.
Этот оператор предшествует открытию файла и связывает переменную с файлом на внешнем носителе. В качестве имени файла указывается путь к файлу на жестком или сменном диске:
assign (f,'data.txt');
будет открываться файл с именем data.txt из текущей папки.
После связывания следует открыть файл. Каждый файл может быть открыт только в одном из трех режимов - для чтения данных, для записи новых данных (при этом, если файл уже существовал, его прежнее содержимое будет стерто) или для добавления данных в конец файла. Открытие файла выполняется одним из трех операторов:
reset (f); - открыть для чтения;
rewrite (f); - открыть для записи;
append (f); - открыть для добавления.
Чтение или запись данных осуществляется операторами read, readln, write и writeln, но первым параметром этих стандартных процедур указывается имя файловой переменной:
var a,b,c:real; f1,f2:text;
begin
assign (f1,'read.txt');
assign (f2,'write.txt');
reset (f1);
{открыли файл read.txt для чтения,}
rewrite (f2);
{а файл write.txt для записи}
read (f1,a,b);
{Прочитали 2 числа из файла read.txt}
c:=(a+b)/2;
writeln (f2,c:6:2); {записали значение c
и перевод строки в файл write.txt}
После того, как все операции с файлом выполнены, его следует закрыть:
close(f); - закрытие файла, связанного с файловой переменной f.
При чтении из файлов часто объем читаемых данных неизвестен заранее. Поэтому необходимы функции, определяющие, прочитаны ли уже все данные:
Eof(f) - возвращает true, если при чтении достигнут конец файла;
Eoln(f) - возвращает true, если при чтении достигнут конец строки.
Пример программы, использующей текстовые файлы.
var f,w:text;
a: array[1..5] of integer;
i: integer;
begin
assign(f,'data.txt');
reset(f);
for i:=1 to 5 do read (f,a[i]);
close(f);
assign(w,'result.dat');
rewrite(w);
writeln(w,'Результаты:');
for i:=1 to 5 do
writeln (w,a[i]:5,sqr(a[i]):5);
close(w);
end.
Файл с именем data.txt может быть, например, таким:
1 2 3
4 5
Файл результатов result.dat будет таким:
Результаты:
1 1
2 4
3 9
4 16
5 25
Типизированные файлы.
Типизированные файлы отличаются от текстовых тем, что для них тип компонент указывается непосредственно в описании файловой переменной.
В разделе Var файл описывается так:
Var
Имя: File Of Тип _ компонент;
Пример.
var f2: file of real;
Здесь объявлен файл, содержащий вещественные числа во внутреннем представлении.
Использование стандартных процедур Read и Write для типизированных файлов отличается от их использования для текстовых файлов тем, что переменные, в которые читается или из которых записывается информация, должны иметь тот же тип данных, что и компоненты типизированного файла. Таким образом, при чтении или записи типизированных файлов всегда происходит перемещение данных одинаковой
длины.
Функция FileSize для типизированных файлов возвращает количество компонентов, записанных в файл, а функция FilePos позволяет определить номер текущей компоненты файла.
Пример программы с использованием типизированного файла. Программа объявляет типизированный файл, состоящий из вещественных чисел, и записывает в него числа от 1 до 10 включительно:
var f:file of real;
r:real;
begin
assign(f,'real.dat');
rewrite(f);
r:=1;
while r<11 do
begin
write(f,r);
r:=r+1;
end;
close(f);
end.
Литература
1. http://infobz.narod.ru
2. Программирование на языках высокого уровня: учебное пособие
/ О. JI. Голицына, И. И. Попов. — М.: ФОРУМ, 2010. - 496 с.
3. Марченко А. Программирование в среде Turbo Pascal 7.0. Базовый курс. / А. И. Марченко, Л. А. Марченко. М.: Век+, 2003. – 464 с.