Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование на Pascal / Delphi / Лекции по Паскалю2 / Иллюстрации к Лекции 6 по информатике

.doc
Скачиваний:
29
Добавлен:
02.05.2014
Размер:
232.45 Кб
Скачать

Лекция 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 и введя операторы цикла, нетрудно избавиться от рекурсивного вызова процедур.