Подпрограммы в Паскале
Процедуры и функции
Понятие подпрограммы
При разработке программ часто приходится описывать одни и те же действия, но при различных наборах исходных данных. Эти повторяющиеся вычисления выделяют в самостоятельную часть программы, которая может быть использована многократно.
Понятие подпрограммы
Автономная часть программы, реализующая определенный алгоритм и допускающая обращение к ней из различных участков основной программы, называется подпрограммой .
Подпрограммы оформляются в виде блоков, имеющих четко обозначенный вход и выход.
Виды подпрограмм
В Паскале имеется два вида подпрограмм – процедуры и функции .
Задача
Рассмотрим использование подпрограмм на примере решения следующей задачи:
Составить программу для вычисления площади четырехугольника, заданного длинами 4-х сторон и диагонали .
Задача
Мы видим, что диагональ делит выпуклый четырехугольник на два треугольника, к которым применима формула Герона:
S= √p∙(p-a)∙(p-b)∙(p-c) , поэтому, чтобы решить эту задачу достаточно вычислить площади треугольников, а потом их сложить
Задача
Простейшее решение – дважды выписать в программе операторы, задающие вычисления по этой формуле.
Однако, можно избежать этого повторения, если воспользоваться предоставляемой Паскалем возможностью использования подпрограммы.
Понятие подпрограммы-процедуры
Подпрограмма-процедура предназначена для выполнения законченной последовательности действий. Любая процедура оформляется аналогично основной программе, т.е. содержит заголовок, разделы описаний и операторов. В отличие от основной программы заголовок в процедуре обязателен.
Формат описания процедуры
Procedure ();
Раздел описаний
Begin
Тело процедуры
End ;
подпрограмма-процедура
Раздел описаний процедуры может содержать подразделы: метки, константы, типы, переменные, процедуры и функции. Раздел описаний в процедуре может отсутствовать.
При работе в программе с процедурами происходит разделение переменных на глобальные и локальные.
Глобальные переменные - это объявленные в разделе описания основной программы переменные, для которых память отводится на весь период выполнения программы.
Локальные переменные - это объявленные в разделе описания подпрограммы переменные, для которых память отводится только на период выполнения подпрограммы. Такие переменные не доступны для операторов основной программы.
Процедура без параметров
program z1;
var x,y,z,t,d,s1,s2,s,s4,a,b,c,p:real;
procedure tr1;
begin
p:=(a+b+c)/2;
s:=sqrt(p*(p-a)*(p-b)*(p-c));
end;
begin
writeln (' введите x,y,z,t,d');readln(x,y,z,t,d);
a:=x;b:=y;c:=d;tr1;s1:=s;
a:=z;b:=t;c:=d;tr1;s2:=s;
s4:=s1+s2;
write(s4)
end.
Второй способ решения задачи
Продемонстрированный способ использования процедуры не удобен из-за большого числа операторов присваивания, которые до обращения к процедуре определяют значения переменных a,b и c. Есть другой способ – описать процедуру с параметрами (аргументами).
Процедура с параметрами
program z2;
var x,y,z,t,d,s1,s2:real;
procedure tr2(var a,b,c,s:real);
var p:real;
begin
p:=(a+b+c)/2;
s:=sqrt(p*(p-a)*(p-b)*(p-c));
end;
begin
read(x,y,z,t,d);
tr2(x,y,d,s1);
tr2(z,t,d,s2);
write(s1+s2)
end.
Формальные параметры
Формальные параметры делятся на два вида: параметры-переменные и параметры-значения .
Параметры-переменные отличаются тем, что перед ними стоит служебное слово var . Они используются тогда, когда необходимо, чтобы изменения значений формальных параметров в теле процедуры приводили к изменению соответствующих фактических параметров.
Параметры-значения отличаются тем, что перед ними слово var не ставится. Внутри процедуры можно производить любые действия с параметрами-значениями, но все изменения никак не отражаются на значениях соответствующих фактических параметров, т. е. какими они были до вызова процедуры, такими же и останутся после завершения ее работы.
Формальные параметры
Если некоторый формальный параметр изображает результат выполнения процедуры (как, например, параметр s в рассмотренных нами вариантах решения задачи), то этот формальный параметр должен быть формальным параметром-переменной. Все формальные параметры, кроме тех, которые изображают результат выполнения процедуры, желательно объявлять в программах формальными параметрами-значениями, т. е., например
procedure tr 3 (a,b,c:real ; var s:real);
Подпрограмма-функция
В Паскале, помимо процедур, разрешены похожие на них конструкции, которые называют функциями .
Подпрограмма-функция предназначена для вычисления какого-либо параметра.
У этой подпрограммы два отличия от процедуры.
Первое отличие функции в её заголовке. Второе отличие заключается в том, что в теле функции хотя бы один раз имени функции должно быть присвоено значение.
): ; Раздел описаний Begin Тело функции, в котором обязательно должно быть присваивание имя_функции:= значение End ; " width="640"
Формат подпрограммы-функции
Function (список формальных параметров ): ;
Раздел описаний
Begin
Тело функции, в котором обязательно должно быть присваивание
имя_функции:= значение
End ;
Формат подпрограммы-функции
Для вызова функции из основной программы или другой подпрограммы следует выражение, где необходимо использовать значение функции, указать её имя со списком фактических параметров, которые должны совпадать по количеству и типам с формальными параметрами функции.
Решение задачи с использованием подпрограммы-функции
Решим нашу задачу третьим способом, а именно с использованием подпрограммы-функции. В этом случае вычисляемое значение площади треугольника мы описываем как некоторую функцию tr4 .
Относительно параметров функций имеется полная аналогия с параметрами процедур.
Описания функций, как и описания процедур, располагаются в программе после совокупности описания переменных.
Подпрограмма-функция
program z3;
var x,y,z,t,d:real;
function tr 4 (a,b,c:real):real;
var p:real;
begin
p:=(a+b+c)/2;
tr 4 :=sqrt(p*(p-a)*(p-b)*(p-c));
end;
begin
read(x,y,z,t,d);
write(tr4(x,y,d)+tr4(z,t,d))
end.
Рекурсия
Подпрограммы в Паскале могут обращаться к самим себе. Такое обращение называется рекурсией. Объект, который частично определяется через самого себя, называется – рекурсивным.
1 " width="640"
Использование рекурсии при решении задач
Некоторые задачи являются рекурсивными по своему определению, поэтому рекурсивные алгоритмы –это точные копии с соответствующего определения. Такова, например, задача вычисления факториала натурального числа
Для того, чтобы вычислить N! , надо знать значение (N-1)! , т. е.
1 , при N=1
N!= N ∙(N-1)! , при N1
Использование рекурсии при решении задач
Для вычисления факториала числа k составим программу с использованием
подпрограммы-функции рекурсивного вида.
Использование рекурсии при решении задач
Var k:integer; a:longint;
Function fact (n:integer):longint;
Begin
If n=1 then fact:=1 else fact:=n*fact(n-1);
End;
Begin
Write('k=');
Readln(k);
a:=fact(k);
Writeln('a=',a)
End.
Вычисление факториала без использования рекурсии
Пусть нам дана следующая задача:
Составить программу для вычисления выражения:
Здесь вычисление факториала повторяется трижды, и поэтому,можно воспользоваться подпрограммой-функцией.
Вычисление выражения без использования рекурсии
Var a,b,c:integer; d:real;
function fact (x: integer):integer;
Var I,p:integer;
begin
p:=1;
for I:=1 to x do p:=p*I; fact:=p;
end;
begin read(a,b,c);
if (fact(c)0)and (fact(b+c)0) then
begin
d:= (fact(a)+fact(b))/fact(c) + fact(a)/fact(b+c);
writeln (d:8:2);
end else writeln('деление на ноль');
end.
Вычисление выражения с использованием рекурсии
Var a,b,c:integer; d:real;
Function fact (n:integer):longint;
Begin
If n=1 then fact:=1 else fact:=n*fact(n-1);
End;
B egin read(a,b,c);
if (fact(c)0)and (fact(b+c)0) then
begin
d:= (fact(a)+fact(b))/fact(c) + fact(a)/fact(b+c);
writeln (d:8:2);
end
else writeln('деление на ноль');
end.
Еще одна задача с использованием рекурсии
Возьмем другую задачу:
Составить программу для перевода десятичного числа в двоичную систему счисления
Решим ее с использованием рекурсивной подпрограммы-процедуры
1 then dd(ndiv2); Write(nmod2) End; Begin Writeln(‘k=‘);readln(k); dd(k);writeln End. " width="640"
Еще одна задача с использованием рекурсии
Program perevod;
Var k:longint;
Procedure dd(n:longint);
Begin
If n1 then dd(ndiv2);
Write(nmod2)
End;
Begin
Writeln(‘k=‘);readln(k);
dd(k);writeln
End.
Подведем итог сказанному:
Таким образом, мы теперь имеем возможность использовать подпрограммы при решении задач, которые не только улучшают структуру и внешний вид программы, но и уменьшают вероятность ошибок, а также облегчают отладку.