Содержание занятия: Оформление вспомогательных алгоритмов в виде подпрограмм. Сходства и отличия процедур и функций. Параметры подпрограмм: формальные и фактические; параметры-значения и параметры- переменные. Глобальные и локальные переменные.
1. Подпрограммы (процедуры и функции) -часть программы, алгоритм, который должен выполняться несколько раз с разными параметрами (данными).
Виды
Подпрограмм в Паскале
процедурафункция
производит некоторые производит некоторые действия,
действия, имя никакого имени присваивается
значения не получает какое-то значение
Структура программы с подпрограммами (п/п):
Для того, чтобы использовать подпрограмму (процедуру или функцию), ее описывают в начале программы, а затем, по мере надобности, вызывают в исполняемой части основной программы. Описание подпрограммы состоит в записи ее заголовка с указанием списка параметров и тела подпрограммы (т.е. операторов, которые входят в подпрограмму). Причем, при описании подпрограммы, нужно учитывать описанные выше отличия процедур и функций. Структура программы, включающей и процедуру и функцию, следующая:
Program Prim;
var y: real; ... описание глобальных переменных
Procedure Pr1( список параметров); заголовок процедуры
var ... описание локальных переменных
begin
... тело процедуры
...
end;
Function Pr2( список параметров): тип; заголовок функции
var ... описание локальных переменных
begin
...
... тело функции
pr2:= ...
end;
var ... описание переменных основной
begin программы
...
Pr1( список параметров); вызов процедуры
y:= Pr2( список параметров); вызов функции
...
end;
Таким образом, вспомогательный алгоритм описывается вначале программы как процедура или функция. При этом машина ничего не выполняет, а принимает к сведению описание подпрограммы. Затем подпрограмма может быть вызвана несколько раз с разными параметрами. При каждом вызове производится выполнение операторов, составляющих тело подпрограммы.
Общий вид заголовка процедуры:
Procedure Имя (параметр1:тип1, параметр2:тип2,...);
Общий вид заголовка функции:
Function Имя (параметр1:тип1, параметр2:тип2,...): тип функции;
2. Использование подпрограмм
Пример1.
Найдем значения выражений cd, 23+32, (c+sin(c))3.
Оформим возведение в степень как вспомогательный алгоритм. Воспользуемся свойством:
ln(xa)=a*lnx, тогда (xа)=exp(ln(xа))=exp(a*ln(x))
Программа на языке Паскаль
Program Prim3;
Function Pur(x,a,:real):real; { Описание подпрограммы}
begin
if x<0 then begin
write (‘функция не определена’);
exit;
end;
if x=0 then begin
Pur:=0;
exit;
end;
Pur:=exp(a*ln(x));
end; {конец описания подпрограммы}
Var c,d,y1,y2,y3:real;
begin
write(‘Введите основание и степень ’);
read(c,d);
y1:=Pur(c,d); { вызов п/п для получения сd }
writeln(c:5:2,’в степени‘,d:3:1,’равно’,y1:5:2);
y2:=Pur(2,3)+Pur(3,2); ); { вызов п/п для получения 23+32 }
y3:=Pur(c+sin(c),3); ); { вызов п/п для получения (с+sin(c))3 }
writeln(‘y2=’,y2:5:2,’ y3=‘,y3:5:2);
end.
Пример 2
Напечатать значение функции в интервале [-5,5] с шагом 0.5
Решение: Заметим, что если выражение под корнем –меньше нуля, функция не определена. Поэтому в подпрограмме определим функцию f, равную подкоренному выражению, а в основной программе будем проверять, можно ли высчитать квадратный корень из f. Для расчета х в заданном интервале с заданным шагом организуем цикл.
Program Prnt;
Function F(x:real):real;
begin
F:=3*x*x-13*x+5;
end;
var
i:integer;
x,y: real;
begin
writeln(‘__________________________’);
writeln(‘ x f ‘);
writeln(‘__________________________’);
x:=-5;
repeat
write (x:6:3);
y:=F(x);
if y<0 then
writeln(‘функция не определена’)
else begin
y:=sqrt(y);
writeln(y:6:3);
end;
x:=x+0.5;
until x>5;
writeln(‘__________________________’);
end.
Та же программа с использованием процедуры:
Program Prnt1;
Procedure F(x:real);
var
y:real;
begin
write(x:6:3);
y=3*x*x-13*x+5;
if y<0 then
writeln(‘функция не определена’)
else begin
y:=sqrt(y);
writeln(y:6:3);
end;
var
i:integer;
x: real;
begin
writeln(‘__________________________’);
writeln(‘ x f ‘);
writeln(‘__________________________’);
x:=-5;
repeat
F(x);
x:=x+0.5;
until x>5;
writeln(‘__________________________’);
end.
В данной программе в силу особенности подпрограммы-процедуры (имени не присваивается никакого значения и в основную программу при таком описании параметров ничего не передается) в ней организован расчет и печать значения функции. Основная программа организует цикл по х и оформление таблицы.
3. Параметры подпрограмм
Параметры, стоящие в списке после имени подпрограммы при ее описании, называются формальными; параметры, стоящие в списке после имени подпрограммы при ее вызове, называются фактическими.
Параметры подпрограмм (п/п)
параметры-значения, параметры-переменные,
значения этих параметров значения параметров
п/п изменить не может изменяются п/п
Таким образом, параметры-значения используются только для передачи конкретных значений в подпрограмму. При этом основная программа защищена от опасности случайной порчи значений каких-нибудь переменных (побочных эффектов), так как из подпрограммы переданные значения не возвращаются. В случае, если нужно вернуть из подпрограммы рассчитанные в ней несколько значений, необходимо использовать параметры-переменные, значения таких параметров в подпрограмму возвращаются.
Следующий пример демонстрирует отличие параметров-значений от параметров-переменных. Напишем подпрограмму-процедуру, которая возвращает максимальное из произведения или суммы двух чисел а и b. Для возвращения выбранного значения в основную программу, параметр b описан как параметр-переменная. Для проверки параметру-значению а также присваивается новое значение, но в основную программу оно не возвращается.
Program Prim3;
procedure vib(a:real;var b:real);
begin
if a+b>a*b then b:=a+b else b:=a*b;
a:=b;
writeln('подпрограмма a=',a:4:1,' b=',b:4:1);
end;
var c,d:real;
begin
c:=2; d:=3;
vib(c,d);
writeln('программа a=',c:4:1,' b=',d:4:1);
end.
В результате работы программы на экране появится следующее:
подпрограмма а=6 b=6
программа a=2 b=6
Вывод значений на экран подтверждает, что
хотя в подпрограмме были изменены значе-
ния обеих переменных а и b, только новое
значение параметра-переменной b было
передано в основную программу.
Описанные различия в использовании параметров объясняются тем, что передаваемые в подпрограмму данные записываются в отдельную область памяти, называемую стеком. При этом области данных, соответствующие параметрам-значениям переписываются в стек целиком, а при использовании параметров-переменных, в стек записывается адрес передаваемой переменной. Поэтому любая операция, изменяющая формальный параметр-переменную в подпрограмме, изменяет и фактическую переменную. Для экономии памяти и других специальных нужд, в языке Турбо-Паскаль имеются также параметры-константы, параметры без типа, параметры-подпрограммы, с которыми можно ознакомиться в специальной литературе.
4.Глобальные и локальные переменные.
Все переменные, объявленные в разделе описаний после оператора Program доступны для использования в основной программе, во всех подпрограммах и называются глобальными. Переменные, оьъявленные в разделе описаний подпрограмм, доступны только внутри этих подпрограмм и называются локальными.
Глобальные переменные удобны (не нужно думать о передаче значений в подпрограмму), но считаются опасными, так как случайное их изменение в подпрограмме приводит к изменению работы всей программы и такие ошибки трудно обнаружить. Кроме того, использование глобальных переменных в подпрограммах приводит к большим трудностям при независимой отладке подпрограмм и переносе их в другие программы. Поэтому использование глобальных переменных в студенческих программах не рекомендуется.
5. Особенности использования массивов как параметров.
Турбо Паскаль накладывает ограничения на описание типа формального параметра. Для описания типа в заголовке процедуры допускается для каждого параметра использовать лишь один идентификатор типа. Так как для описания массива используются два идентификатора, например, array[0..n] of real, то описать массив обычным образом не удается. Для этого существует два способа: с использованием специально введенного типа и с использованием открытых массивов.
а. Использование специально введенного типа:
program pr;
const n=5;
type matr=array[0..n,0..n] of real;
Procedure Proc( v:matr);
var j,m:integer;
begin
for j:=0 to n do
for m:=0 to n do
write(v[j,m]);
end;
var
v1:matr;
i,i1:integer;
begin
for i:=0 to n do
for i1:=0 to n do
v1[i,i1]:=i+i1;
Proc(v1);
...
Для передачи в подпрограмму массива был введен тип matr.
2.Использование открытых массивов:
Эта возможность появилась лишь в Турбо Паскале-7.0 и очень удобна когда заранее не известно, каких размеров массив. Например:
program pr;
const n=5;
Procedure Proc( v:array of integer);
var j:integer;
begin
…
end;
var
v1:array[0..n] of integer;
i:integer;
begin
for i:=0 to n do
v1[i]:=i;
Proc(v1);
…
При использовании открытых массивов необходимо иметь в виду, что можно передавать лишь одномерный массив и начальное значение индекса массива равно нулю.
Требования при защите задачи.
1.Необходимо правильно выделить вспомогательный алгоритм. Для этого нужно выделить действие или группу действий, которая повторяется с разными параметрами и оформить их как подпрограмму (процедуру или функцию), а изменяющиеся параметры оформить как параметры подпрограммы.
2.Необходимо четко понимать отличия формальных и фактических параметров, параметров-значений и параметров-переменных, правила передачи параметров в подпрограмму. Не используйте глобальные переменные.
3.Будте готовы по требованию преподавателя организовать вызов подпрограммы еще раз.