ТЕМА №6: ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ
ПРОГРАММНО - ДИДАКТИЧЕСКОЕ ОБЕСПЕЧЕНИЕ: ЭВМ типа IBM. Turbo-Pascal 5.
ЦЕЛИ И ЗАДАЧИ: Дать основные понятия подпрограмм (процедур и функций). Познакомить с видами формальных параметров: параметры-значения, параметры-переменные. Научить различать фактические и формальные параметры. Знакомство с понятием рекурсии. Выработка навыков составления программ с использованием процедур и функций.
ТРЕБОВАНИЯ К ЗНАНИЯМ И УМЕНИЯМ:
Учащиеся должны знать:
- Что такое подпрограмма;
- Что такое процедура;
- Для чего используются процедуры;
- Что такое формальные и фактические параметры;
- Чем отличается задание параметров-значений от параметров-переменных;
- В каком месте программы ставится описание процедур;
- Как вызывается процедура;
- Структуру процедуры.
- Что такое функция;
- Чем отличаются процедуры от функций,
- Для чего используются функции;
- Чем отличается заголовочная строка функции от заголовочной строки процедуры;
- В каком месте программы ставится описание функции;
- Как вызывается функция;
- Структуру функции;
- Что такое рекурсия;
- Для чего и как используется опережающее описание подпрограммы.
Учащиеся должны уметь:
- Правильно описывать процедуры и функции;
- Правильно вызывать процедуры и функции;
- Различать формальные и фактические параметры;
- Правильно описывать параметры-значения и параметры
- Различать формальные и фактические параметры;
- Использовать простейшие рекурсии при составлении программ
ПЛАН-СОДЕРЖАНИЕ УРОКА
Подпрограммы.
Автономная часть программы, с помощью которой можно производить одни и те же вычисления, с разными исходными данными и в различных местах программы, многократно, называется подпрограммой. Виды подпрограмм: процедуры и функции.
Процедуры.
Процедура (подпрограмма)
– многократно повторяющаяся часть программы, оформленная отдельно от основной программы. Место расположения процедур в программах - Раздел описаний, за описание переменных.
Преимущества использования процедур - уменьшение объем программы, сокращение времени на отладку.
Принцип работы процедуры:
Выполнение программы начинается с выполнения основной части программы. Как только появляется необходимость в выполнении процедуры, она вызывается по имени с передачей входных данных. После выполнения процедура передает в основную часть программы выходных данных (результатов), в то место, откуда была вызвана процедура.
Затем продолжается выполнение основной части программы.
Процедура оформляется подобно основной программе:
Раздел описаний основной программы
|
Заголовок процедуры
|
Procedure имя
(список параметров);
|
Описываются формальные параметры
|
Раздел описаний
|
label …;
Var …;
|
|
Раздел операторов процедуры
|
Begin
…
end;
|
|
Описание функций
|
Раздел операторов основной программы
|
Procedure имя (формальные параметры);
Раздел описаний
Begin
Раздел операторов
End;
Все переменные, представленные в разделе описаний основной программы называются
глобальными. Они действуют как в разделе операторов основной программы, так и в любой подпрограмме.
Параметры (переменные), определяемые при описании процедуры называются
формальными.
Параметры (переменные), задаваемые при вызове процедуры называются
фактическими.
Формальные параметры (переменные, описываемые в процедуре) делятся на параметры - значения и параметры - переменные
Параметры-значения – передают информацию только в процедуру (входные), описываются как переменные с указанием типа (без зарезервированного слова Var).
Параметры-переменные – передают информацию, как в процедуру, так и обратно (выходные), их описание начинается со слова Var, затем следует список переменных с указанием типа.
Пример:
Procedure sterline (
len: integer); - параметры-значения.
Procedure stl (l: integer,
Var n integer); - параметры-значения и параметры – переменные.
Формальные параметра описываются только в заголовке процедуры. Формальные параметры никогда не описываются в разделе описаний процедуры. Если в процедуре используются переменные, отличные от формальных параметров, их необходимо обязательно описать в разделе описания процедуры.
Вызов процедуры подобно специальным операторам происходит по имени с указанием фактических параметров, например:
stl (а, n);
Имена фактических параметров могут не совпадать с именами формальных параметров, но они должны соответствовать друг другу по типу. Формальные параметры описываются в разделе описания основной программы и до вызова процедуры должны получить значения.
Пример использования процедур:
Написать программу, которая выводит на экран строку, состоящую из заданного числа звездочек. Использовать процедуру.
Uses crt;
Var n: integer;
Procedure sterline (var len: integer);
Var i:integer;
Begin
For i:=1 to len do
Write (‘*’);
End;
Begin
Write(‘Введите количество звездочек’); Readln(n);
Sterline (n);
Readln; End.
Функции.
Функция, как и процедура, может содержать несколько операторов, несколько входных (и только) параметров, но результат получается только один. Этот единственный результат обозначается именем функции и передается в основную программу.
В общем виде функция записывается в разделе описания основной программы следующим образом:
Function имя (формальные параметры):тип;
Раздел описаний
Begin
Операторы
Имя:= …
End;
Поскольку результат обозначается именем функции, то после формальных параметров указывается тип функции, который должен совпадать с типом результата вычислений. В конце описания функции имени функции обязательно присваивается какое-то значение. Вызывается функция по ее имени с указанием фактических параметров. Функция может использоваться в операторах присваивания, условных операторах и т.п. Например,
Res:=Compare(x1,x2);
Пример использования функций:
Написать программу, которая с помощью функции сравнивает два целых числа и выводит результат сравнения в виде одного из знаков: >,<,=
Uses crt;
Var x1,x2:real; res:char;
Function Compare (a,b: real):char;
Begin
If a>b then Compare:=’>’ else if a<b then Compare:=’<’ else Compare:=’=’;
End;
Begin
Writeln (‘Введите числа’);
Readln(x1,x2);
Res:=Compare(x1,x2);
Writeln(x1:6:2, res,x2:6:2);
Readln; end.
Рекурсия.
Рекурсия – это вывоз подпрограммой
(процедурой или функцией) самой себя.
Рассмотрим построение рекурсивной функции на примере вычисления N!. При правильно организованной рекурсивной подпрограммы осуществляется многократный переход от некоторого текущего уровня организации алгоритма к низшему уровню последовательно до тех пор, пока не будет получено тривиальное решение поставленной задачи.
PROGRAM DEMO1;
USES CRT;
VAR M:BYTE;
FUNCTION FAKT(N:BYTE):LONGINT;
BEGIN
IF N=1 THEN FAKT:=1
ELSE FAKT:=FAKT(N-1)*N;
END;
BEGIN
CLRSCR;
WRITE('N-');READLN(M);
WRITELN('N!=',FAKT(M));
READKEY;
END.
В нашем примере происходит так: в операторе печати вызывается функция FAKT с параметрам N, которая в свою очередь вызывает функцию FAKT с параметрам N-1, и так далее, пока не вызывается FAKT(1). Тогда это процесс останавливается, затем происходить извлечение результата в обратном порядке.
Это хорошо видно на следующем примере программы:
Текст программы:
|
Результат работы программы:
|
PROGRAM DEMO2;
USES CRT;
VAR CH: WORD;
PROCEDURE WRITEA;
BEGIN
CH:=CH+1;
WRITELN('НАЧАЛО',CH);
IF CH<4 THEN WRITEA;
WRITELN(' КОНЕЦ',CH);
CH:=CH-1;
END;
BEGIN
CLRSCR;
CH:=0;
WRITEA;
READKEY;
END.
|
НАЧАЛО 1
НАЧАЛО 2
НАЧАЛО 3
НАЧАЛО 4
КОНЕЦ 4
КОНЕЦ 3
КОНЕЦ 2
КОНЕЦ 1
|
Рекурсивная форма организации алгоритма обычно выглядит изящнее итерационной и дает более компактный текст программы, но при выполнении, как правили, медленнее и может вызвать переполнение стека.
Стек – это специальная область памяти (конечное число ячеек), где сохраняется
адреса возврата (адрес вызывающей программы, используется для передачи управления вызывающей программе). Стеки используются так же для передачи параметров в процедуры (для обычных параметров в стек заносятся их значения, для параметров-переменных – их адреса), размер стек ограничен. Стек можно представить в виде стопки книг. Если стопка достигла максимального размера, то при добавлении новой книги сверху – нижняя книга должна быть убрана.
Нужно обязательно отслеживать в программе наполнение стека, то есть не допускать зацикливания рекурсии.
Рекурсивный вызов может быть косвенным. В этом случае программа обращается к себе опосредованно, путем вызова другой программы, в которой содержится обращение к первой. При использовании такого подхода нужно использовать
опережающее описание. Опережающее описание заключается в том, что объявляется лишь заголовок процедуры, а ее тело заменяется директивой
FORWARD. После этого можно в другой процедуре использовать обращение к ней – ведь компилятор уже может правильным образом организовать ее вызов. Обратите внимание: тело второй процедуры описывается после первой и начинается заголовком, в котором уже не указываются описанные ранее формальные параметры.
Пример:
PROCEDURE B( J:BYTE);FORWARD; { тело процедуры заменено директивой FORWARD }
PROCUDURE A( I:BYTE);
BEGIN
…
B(I);
…
END;
PROCEDURE B;
BEGIN
…
A(J);
…
END;
Примеры программ с процедурами и функциями:
При составлении программ обязательно использовать процедуры или функцию.
- Найти разность двух факториалов F=m! – k!, используя функцию.
Uses crt;
Var F,m,k:integer;
Function Fact(n:integer):integer;
Var P,i:integer;
Begin
P;=1;
For i:=2 to n do
P;=P*i;
|
Fact:=P;
End;
Begin
Read (M,K);
F:=Fact(m) – Fact(K);
Writeln (‘F=’,F:5);
repeat until keypressed
End.
|
- Написать программу «Бегущие огни» с использованием процедуры рисования окружности.
uses crt,graph;
var gd,gm,x:integer;
begin
gd:=detect;
initgraph(gd,gm,'');
x:=20;
repeat
repeat
setcolor(4);
circle(x,200,15);
setfillstyle(1,3);
floodfill(x,200,4);
delay(8000);
setcolor(0);
|
circle(x,200,15);
setfillstyle(1,3);
floodfill(x,200,0);
x:=x+40;
until x>600;
repeat
setcolor(4);
circle(x,200,15);
delay(8000);
setcolor(0);
circle(x,200,15);
x:=x-40;
until x<20;
repeat until keypressed; end.
|
Примеры программ с использованием рекурсий:
Вычислить Xn:
PROGRAM DEMO3;
USES CRT;
VAR X1,X2: WORD;I,M:BYTE;S:LONGINT;
FUNCTION XN(X,N:BYTE):LONGINT;
BEGIN
IF N=0 THEN XN:=1
ELSE XN:=XN(X,N-1)*X;
END;
BEGIN
CLRSCR;
WRITE('X,N-');READLN(X1,M);
WRITELN('XN-',XN(X1,M));
READKEY;
END.
|
Подсчитать сумму N чисел Фибоначчи (1,1,2,3,5,8,13,..):
PROGRAM DEMO4;
USES CRT;
VAR X1,X2: WORD;I,M:BYTE;S:LONGINT;
FUNCTION FIB(N:BYTE):LONGINT;
BEGIN
IF N=1 THEN FIB:=1;
IF N=2 THEN FIB:=1;
IF N>=3 THEN FIB:=FIB(N-1)+FIB(N-2);
END;
BEGIN CLRSCR;
WRITE('N-');READLN(M); S:=0;
FOR I:=1 TO M DO
S:=S+FIB(I);
WRITELN('S-',S);
READKEY;
END.
|
Написать рекурсивную функцию вычисления суммы 1+2+3+4+5+…+N:
PROGRAM DEMO5;
USES CRT;
VAR M:WORD;
FUNNCTION SUM(N:WORD):LONGINT;
BEGIN
IF N=1 THEN SUM:=1 ELSE SUM:=SUM(N-1)+N;
END;
BEGIN
WRITE(‘N-‘);READLN(M);
WRITELN(‘СУММА -’,SUM(M));
READKEY;END.
Используя рекурсивную функцию получить подобную фигуру:
|
1 вариант (простая рекурсивная форма)
PROGRAM DEMO6;
USES CRT,GRAPH;
VAR X,Y: WORD;I,K,M,N:BYTE;
GD,GM:INTEGER;
PROCEDURE LINT(X,Y,N,M:WORD);
BEGIN
LINETO(X+N,Y);
LINETO(X+N,Y+N);
LINETO(X+M,Y+N);
LINETO(X+M,Y+M);
X:=X+M;Y:=Y+M;
N:=N-2*M;
K:=K+1;
IF K<5 THEN LINT(X,Y,N,M);
END;
BEGIN
GD:=DETECT;
INITGRAPH(GD,GM,'');
LINT(0,0,100,10);
READKEY;
END.
|
2 вариант (рекурсивная форма с опережающим описанием)
PROGRAM DEMO7;
USES CRT,GRAPH;
VAR X,Y: WORD;I,K,M,N:BYTE;
GD,GM:INTEGER;
PROCEDURE LNT(X,Y,N,M:WORD); forward;
PROCEDURE LINT(X,Y,N,M:WORD);
BEGIN
for k:=1 to 5 do begin
lnt(x,y,n,m);
X:=X+M;Y:=Y+M;
N:=N-2*M; end;
END;
procedure lnt;
begin
LINETO(X+N,Y);
LINETO(X+N,Y+N);
LINETO(X+M,Y+N);
LINETO(X+M,Y+M);
end;
BEGIN
GD:=DETECT;
INITGRAPH(GD,GM,'');
LINT(0,0,100,10);
READKEY;
|
|