ТЕМА №6: ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ
ПРОГРАММНО - ДИДАКТИЧЕСКОЕ ОБЕСПЕЧЕНИЕ: ЭВМ типа IBM. Turbo-Pascal 5.
ЦЕЛИ И ЗАДАЧИ: Дать основные понятия подпрограмм (процедур и функций). Познакомить с видами формальных параметров: параметры-значения, параметры-переменные. Научить различать фактические и формальные параметры. Знакомство с понятием рекурсии. Выработка навыков составления программ с использованием процедур и функций.
ТРЕБОВАНИЯ К ЗНАНИЯМ И УМЕНИЯМ:
Учащиеся должны знать:
- Что такое подпрограмма;
- Что такое процедура;
- Для чего используются процедуры;
- Что такое формальные и фактические параметры;
- Чем отличается задание параметров-значений от параметров-переменных;
- В каком месте программы ставится описание процедур;
- Как вызывается процедура;
- Структуру процедуры.
- Что такое функция;
- Чем отличаются процедуры от функций,
- Для чего используются функции;
- Чем отличается заголовочная строка функции от заголовочной строки процедуры;
- В каком месте программы ставится описание функции;
- Как вызывается функция;
- Структуру функции;
- Что такое рекурсия;
- Для чего и как используется опережающее описание подпрограммы.
Учащиеся должны уметь:
- Правильно описывать процедуры и функции;
- Правильно вызывать процедуры и функции;
- Различать формальные и фактические параметры;
- Правильно описывать параметры-значения и параметры
- Различать формальные и фактические параметры;
- Использовать простейшие рекурсии при составлении программ
ПЛАН-СОДЕРЖАНИЕ УРОКА
Подпрограммы.
Автономная часть программы, с помощью которой можно производить одни и те же вычисления, с разными исходными данными и в различных местах программы, многократно, называется подпрограммой. Виды подпрограмм: процедуры и функции.
Процедуры.
Процедура (подпрограмма)
– многократно повторяющаяся часть программы, оформленная отдельно от основной программы. Место расположения процедур в программах - Раздел описаний, за описание переменных.
Преимущества использования процедур - уменьшение объем программы, сокращение времени на отладку.
Принцип работы процедуры:
Выполнение программы начинается с выполнения основной части программы. Как только появляется необходимость в выполнении процедуры, она вызывается по имени с передачей входных данных. После выполнения процедура передает в основную часть программы выходных данных (результатов), в то место, откуда была вызвана процедура.
Затем продолжается выполнение основной части программы.
Процедура оформляется подобно основной программе:
Раздел описаний основной программы |
||
Заголовок процедуры |
Procedure имя (список параметров); |
Описываются формальные параметры |
Раздел описаний |
label …; Var …; |
|
Раздел операторов процедуры |
Begin … end; |
|
Описание функций |
||
Раздел операторов основной программы |
Раздел описаний
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. |
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; |