Программирование на Pascal / Delphi / Лекции по Паскалю2 / Иллюстрации к Лекции 6 по информатике
.doc
Лекция 6. Паскаль. Процедуры и функции
ПЛАН
6.1. Описание функций и процедур
6.2. Рекурсивные функции и процедуры
6.1. Описание функций и процедур
Модули System, Crt, Graph
Procedure Name_P(p1, p2,...:"тип"; Var p3, p4,...: "тип";...);
Function Name_F("список формальных параметров"):"тип результата";
где Function и Procedure - служебные слова,
Name_F, Name_P - имена функции и процедуры соответственно,
p1, p2 - имена формальных параметров-значений,
p3, p4 - имена формальных параметров-переменных,
Type M= array[1..100]of real;
Procedure Name_P(p: M);
Name_P(p11, p22,..., p33, p44,...); - вызов процедуры Name_P,
Y:= Name_F("список фактических параметров"): - вызов функции Name_F,
Здесь p11, p22, . . . - имена или значения переменных,
p33, p44, . . . - имена переменных, значения которых возвращаются в программу.
Y - переменная, которой присваивается значение возвращаемое функцией.
Пример процедуры вывода на экран визитной карточки , Фрагмент 1
Program NP_1;
Var Dat, Fam: string; { Fam: глобальная переменная }
Procedure VIZ(D_R :string); { D_R - формальный параметр }
Var S_t: string; { S_t: локальная переменная }
Begin Writeln('|-------------------------------------------------|');
Writeln('|Разработчик программы:',Fam:14,' |');
Writeln('| |');
Writeln('| г. УФА, ', D_R:14,' |');
Writeln('|Телефон:22-44-66 |');
Writeln('| ----------------------------------------------------|');
Write(' Комментарий: ');
Readln(S_t)
end;
Begin
Fam:='И.И.Иванов';
Dat:='06.12.95'; {Dat - фактический параметр }
VIZ(Dat); {вызов процедуры}
Readln END.
F_PR. pas
{$I F_PR. pas}
Пример использования стандартных процедур модуля DOS для вывода текущей даты и времени, Фрагмент 2:
uses DOS; { подключение модуля DOS }
Procedure Date_Time;
var y, m, d, d_w:word;
h, min, sec, hund: word;{локальные параметры }
begin
GetDate(y,m,d,d_w); {вызов процедуры DOS, возвращающей параметры даты }
GetTime(h,min,sec,hund); { процедура, возвращающая параметры времени }
writeln('сегодня: ' );
writeln('_':10, d, ' число');
writeln('_':10, m, ' месяц');
writeln('_':10, y, ' год' );
writeln('день недели: ', d_w ); { d_w= 0 - воскресенье, и т. д. }
writeln('Время: ' );
writeln('_':6, h, ' часов' );
writeln('_':6, min, ' минут' );
writeln('_':6, sec, ' секунд' ); readln
end;
Begin
Date_Time
end.
Пример процедуры расчета "N" значений функции Y= 4*Sin(x)+7*Cos(x); в заданном диапазоне x1<=x<=x2, при N<=100 и равномерной разбивке диапазона, Фрагмент 3.
type r_1000= array[1. . 1000] of real; {задается тип r_1000}
var Z: r_1000; x1, x2: real; n: word;
Procedure Mas_Y(var Y:r_1000; x1,x2:real; n:word); {Y - параметр-переменная}
var i: word; x, dx: real; { локальные параметры }
begin
If (n>1000) or (n<2) then begin
writeln('Длина массива >1 и не должна превышать 1000');
Readln; Halt end;
i:=0; x:=x1; dx:=(x2-x1)/(n-1); { dx - шаг изменения аргумента }
If dx<= 0 then begin
writeln('x2 должно быть больше x1'); Readln; Halt end;
While x<x2 do begin
i:=i+1; x:=x1+dx*(i-1); Y[i]:=4*Sin(x)+7*cos(x)
end
end;
begin Writeln('Введите значения х1,х2, (x2>x1)'); Readln(x1, x2);
Writeln('Введите значение 1 <n<= 1000 '); Readln(n);
Mas_Y(Z, x1, x2, n); { вызов процедуры, возвращающей массив "Z" }
end.
Пример процедуры вывода массива чисел в файл, Фрагмент 4:
Type M_30х30_r= array[1..30, 1..30] of real;
{ задается тип M_30х30_r }
var x: M_30х30_r; i, j, n, m: byte;
{---------------------------------------------------}
Procedure Wr_M(a: M_30х30_r; name_f: string; n, m: byte);
Var i, j: byte; { a - массив NxM, n<=30, m<=30 }
f: text; { name_f - имя файла }
begin assign(f, name_f); rewrite(f);
For i:= 1 to n do begin writeln(f);
For j:= 1 to m do write(f, a[i,j]:6:2) end;
close(f)
end;
{---------------------------------------------------}
Begin N:= 10; { создание симметричной матрицы }
for i:= 1 to N do for j:= i to N do
x[i, j]:= 0.5 + random(50); { заполнение верхней треугольной матрицы }
for i:= 1 to N do for j:= i to N do
x[j,i]:= x[i,j]; { заполнение нижней, симметричной части матрицы }
Wr_M(x, 'file_1.out', N, N); { вызов процедуры записи массива в файл }
end.
6.2. Рекурсивные функции и процедуры
Схема линейного взаимодействия процедур
Рис.1
Схема циклического взаимодействия процедур
Рис.2
Фрагмент 5. Пусть требуется рассчитать число осколков, полученных в результате деления тела за "N" миллисекунд, если каждый осколок делится на два за одну миллисекунду. Тогда при N=0 число осколков = 1, при N>0 число осколков = 2N = 2*2(N-1).
Функция, возвращающая число осколков, будет иметь вид:
Function K_O(N: word): Longint;
begin
if N=0 then K_O:=1 {условие окончания рекурсии}
else K_O:=2*K_O(N-1) {рекурсивный вызов}
end;
Пример функции, возвращающей число осколков, без использования рекурсии:
Function K_O(N: word): Longint;
var N_1: Longint; i: word;
begin
N_1:=1; for i:=1 to N do N_1:= 2*N_1; K_0:= N_1
end;
Пример использования косвенной рекурсии, Фрагмент 6:
Program Rek; {раздел описания основной программы}
{----------------------------------------------------}
Procedure pr_1(i:word); Forward; {предварительное описание процедуры pr_1}
{----------------------------------------------------}
Procedure pr_2; {полное описание процедуры pr_2}
var ch: char; i: word;
begin
Writeln('Купите десять билетов-выиграете миллион !');
Writeln('Нажмите "Y" или "N"');
Readln(ch); i:=10;
if(ch='Y') or (ch='y') then Pr_1(i) {вызов процедуры}
else Halt end;
{----------------------------------------------------}
Procedure pr_1; {полное описание процедуры pr_1}
var n, n1: integer;
begin
if i=10 then begin Randomize; n1:= Random(900)+100 end;
if (i = 0) then Pr_2 {условие окончания прямой рекурсии}
else begin
repeat writeln('введите трехзначный номер билета');
Readln(n) until (n<1000) and (n>99);
if (n<>n1) then begin writeln('билет без выигрыша');
writeln('осталось ', i-1, 'билетов');
Pr_1(i-1) {прямая рекурсия} end
else begin Writeln('Вы угадали, получите выигрыш в банке!');
Pr_2 {косвенная рекурсия} end end;
{----------------------------------------------------}
BEGIN PR_2 {раздел выполнения основной программы} End.
Пояснение работы процедуры
Здесь процедура Pr_1 при первом вызове инициирует случайное трехзначное число "n1" - выигрышный номер. При каждом вызове процедура Pr_1 запрашивает ввод трехзначного номера билета "n". Если номер билета не совпал (n<>n1) и остались еще билеты (i<>0), то снова вызывается процедура Pr_1, иначе вызывается процедура Pr_2 (окончание рекурсивного вызова). Если номера совпали (n1=n), то выводится сообщение: 'Вы угадали, получите выигрыш в банке!'. Процедура Pr_2 либо вызывает процедуру Pr_1, либо программа заканчивается (оператор Halt). В процедуре Pr_2 заголовок не имеет параметров, а в процедуре Pr_1 параметры указываются при первом описании. В данном случае приводится управляемая на каждом шаге рекурсия (процедура запрашивает номер билета). Включив тело процедуры Pr_2 в Pr_1 и введя операторы цикла, нетрудно избавиться от рекурсивного вызова процедур.