Занятие 11. Процедуры и функции

Часто одна и та же последовательность операторов может выполняться в программе несколько раз в разных местах. В этом случае эту последовательность операторов можно офор­мить как подпрограмму и вызывать с разными параметрами в нужных местах программы. Подпрограммы в Паскале реализованы в виде процедур и функций. Процедура(функция) это подпрограмма, которая описывается один раз, а вызываться может несколько раз из разных мест программы, возможно с разными параметрами. Отличие процедур от функций заключается в том, что функция возвращает значение, а проце­дура - нет.

Использование процедур(функций) позволяет:

1. избежать дублирования программного кода: описав процедуру(функцию) один раз, можно вызывать ее несколько раз из разных мест программы;

2. упаковка программного кода в процедуры(функции) позволяет структурировать программу: с использованием процедур(функций) программа приобретает четкую и понятную структуру;

3. однажды написанная процедура(функция) может многократно использоваться в других программах, таким образом, создаются библиотеки процедур(функций).

Примером применения процедуры(функции) может служить подпрограмма, которая вычисляет минимальное значение двух переменных, находит подстроку из строки, обработчики событий и методы объектов оформлены в виде процедур.

Процедуры и функции перед использованием должны быть обязательно описаны.

Описание процедуры(функции) состоит из трех частей: заголовка, раздела описа­ний и тела:

<Заголовок подпрограммы>

<Раздел описаний>

<Тело>

Описание и вызов процедуры

Синтаксис описания процедуры имеет вид:

Procedure <имя процедуры> [(список формальных параметров)];

[(раздел описаний)]

begin

<операторы>

end;

Ключевое слово procedure задает описание заголовка. В заголовке задается:

- имя процедуры, по которому она в дальнейшем может быть вызвана;

- список формальных параметров, который не является обязательным.

Формальными параметрами называются параметры, которые задаются при описании процедуры, в отличие от фактических параметров, которые задаются при вызове процедуры. Каждый параметр в списке описывается со своим типом. Раз­дели­телем списка формальных параметров является - ';' (точка с запятой). Если несколько параметров имеют одинаковый тип, то их можно перечислить через запятую. Например:

Procedure Compute(x,y : integer; str : String);

В разделе описаний описываются переменные, константы и другие подпрограммы, которые используются только внутри этой процедуры.

Тело процедуры заключается в операторные скобки begin..end.

Например: процедура считает сумму двух чисел, которые поступают на вход и выдает их сумму в свойстве caption объекта Label1.

Procedure sum(a,b:integer);

Begin

Label1.Caption:=IntToStr(a + b);

End;

Синтаксис вызова процедуры имеет следующий вид:

<имя процедуры>[(список фактических параметров)];

Фактические параметры это параметры, которые задаются при вызове процедуры(функции). Разделителем списка фактических параметров является - ',' (за­пя­тая). Порядок следования и типы фактических параметров должны четко соответствовать порядку следования и типам соответствующих формальных параметров.

Пример 1.Вызов процедуры sum:

sum(4,7);

Пример 2. Дан двумерный массив размером 10 на 10, описывающий поле для игры «Сапер». Если значение в ячейке поля равно 0, то там нет мины, если значение ячейки равно 1 – там лежит мина. Написать процедуру, которая инициализирует этот массив, т.е. пустым ячейкам поля присваивает значения 0 и раскладывает 20 мин в случайных ячейках поля.

Решение. Опишем массив на верхнем уровне секции реализации или в секции Interface:

var Pole:array[1..10,1..10] of byte;

Назовем процедуру InitPole. Входных параметров она не имеет. Поэтому вызывается она следующим образом: InitPole;

В секции implemention опишем тело процедуры:

Procedure InitPole;

Var i, j, k : Integer;

Begin

{ всем ячейкам поля присвоить значение 0 }

for i:=1 to 10 do

for j:=1 to 10 do Pole[i,j]:=0;

{ разложить мины в случайные места поля }

i:=1;

randomize;

while i<=20 do

begin

j:=random(10)+1;

k:=random(10)+1;

if Pole[j,k]=1 then continue;

Pole[j,k]:=1;

i:=i+1;

end;

End;

Пример 3. В игре, описанной в пункте «Как совместить разные виды движе­ния», все летающие тарелки движутся по одному и тому же закону. Требуется написать процедуру, назовем ее FlyNLO, которая будет управлять движением тарелки. На вход процедуре поступает указатель на летающую тарелку. Для того чтобы можно было получать доступ к объектам формы внутри процедуры, следует делать процедуру методом класса формы. Для этого нужно ее заголовок описать в классе формы, как показано:

type

TForm1 = class(TForm) { описание класса формы }

Pushka: TImage;

Fly1: TImage;

Fly2: TImage;

Snar: TImage;

Timer1: TTimer;

Timer2: TTimer;

procedure FlyNLO(Sender:TObject); { заголовок процедуры }

Как видно из заголовка процедуры ей передается параметр Sender типа TObject – это указатель на конкретную летающую тарелку. Тело процедуры описывается в разделе implementation модуля и имеет следующий вид:

procedure TForm1.FlyNLO(Sender:TObject);

begin

if not (Sender as TImage).Visible then

with (Sender as TImage) do

begin

top:=random(200)+1;

left:=0;

visible:=true;

tag:=random(10)+5;

end

else

{ полет }

if (Sender as TImage).left+(Sender as TImage).Width<Form1.Width then

(Sender as TImage).left:= (Sender as TImage).left+(Sender as TImage).tag

else

(Sender as TImage).visible:=false;

end;

Как вы видите этот программный код мало, чем отличается от того, что мы писали в пункте «Как совместить разные виды движе­ния». Для правильной работы процедуры-метода необходимо указать тип объекта Sender. Для этого используется оператор As, который позволяет рассматривать Sender как объект класса TImage.

Вызывается эта процедура в обработчике события OnTimer, столько раз, сколько у нас летающих тарелок с соответствующими параметрами:

procedure TForm1.Timer1Timer(Sender: TObject);

begin

FlyNLO(Fly1); {полет 1 летающей тарелки}

FlyNLO(Fly2); {полет 2 летающей тарелки}

End;

Описание и вызов функции

Синтаксис описания функции очень похож на описание процедуры и имеет следующий вид:

Function <имя функции>[(список формальных параметров)]:<тип ре­зультата>;

[<раздел описаний>]

begin

<операторы>

end;

Ключевое слово function – задает описание заголовка функции. Заголовок содержит:

- имя функции, которое используется при ее вызове;

- список формальных параметров, при этом каждый параметр описывается со своим типом, также как при описании процедуры;

- тип возвращаемого функцией значения.

Раздел описаний функции содержит описания переменных, констант и других подпрограмм, которые используются только внутри этой функции.

Тело функции заключается в операторные скобки begin..end.

Внутри каждой функции есть зарезервированная локальная переменная с таким же именем, что и сама функция, имеющая тот же тип, что и возв­ращаемое функцией значение. Она доступна для чтения и может быть ис­пользована в промежуточных вычислениях. Она обязательно должна полу­чить значение на выходе из функции.

Пример описания функции:

function maxim(a,b:integer):integer;

begin

if a>b then

maxim:=a

else

maxim:=b;

end;

Синтаксис вызова функции имеет следующий вид:

<Переменная>:=<Имя функции>[(Список формальных параметров)]

Так как функция возвращает результат, она может использоваться в выражениях, при этом вместо функции подставляется возвращаемое ей значение.

Например, вызов функции maxim:

k:=maxim(100,56)

Наши рекомендации