Delphi forward Описание «вперёд»

Delphi 7. Занятие 2_6. Часть 5.

Задачи, рассматриваемые в статье.

  1. процедура: описание вперёд Delphi forward;
  2. Delphi процедура в процедуре;
  3. передача в процедуру переменной процедурного тип;
  4. параметры по умолчанию.

Рассмотрим такую ситуацию. Имеются две процедуры.

procedure pr1();

begin

pr2(); //вызов процедуры.

end;

и

procedure pr2();

begin

end;

Из процедуры pr1() осуществляется попытка вызова процендуры pr2().

Однако компилятор не пропустит такой вызов и сообщит об ошибке. Дело в том, что по правилам языка все переменные, процедуры и функции доолжны быть описаны (определены) до момента обращения к ним.

Вызов процедуры pr2() находится в процедуре pr1(). Так как описание поцедуры procedure pr2(); находится ниже по тексту программы, то компилятор не пропустит такую ситуацию.

Это часто бывает не очень удобно при написании текста программы. Однако имеется возможность разрешить эту коллизию. Достаточно применить delphi forward declaration в секции interface или implementation.

forward Делается это следующим образом: в описание процедуры добавляется ключевое слово Delphi FORWARD:

implementation

procedure pr2();FORWARD;

Таким образом с помощью так называемого «опережающего описания» можно располагать процедуры и функции в любом месте модуля.

Delphi процедура в процедуре

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

Делается это следующим образом.

procedure ppr1();

var … ;

function ff1():тип;

var … ;

begin

end;

begin

ff1(); //вызов функции

end;

Кроме ff1() внутри процедуры ppr1() может быть описана ещё одна (или несколько) других процедур и функций.

Аналогично, внутри функции ff1() может быть описана ещё одна (или несколько) других процедур и функций.

Приведём пример:

function pr1():integer;

var y,z:integer;

function pr2(xx:integer):integer;

var x:integer;

begin

x:=3;

result:=x+xx+y;

end;

begin

y:=5;

z:=y+pr2(4);

result:=z;

end;

procedure TForm1.Button6Click(Sender: TObject);

var x1:integer;

begin

x1:=pr1();

edit16.Text:=inttostr(x1);

end;

В результате имеем:

Delphi forward

Как образовался данный результат?

Функция pr1() вызывается из обработчика клика
procedure TForm1.Button6Click(Sender: Tobject);

Функция возвращает значение переменной z.

Оно формируется из значения переменной y и значения, возвращаемого функцией pr2(4).

Значение, формируемое в pr2():

result:=x+xx+y;

В нём x=3, xx=4 (передаётся через параметр-значение). Интереснее со занчением y. Вложенная процедура «видит» все переменные внешней процедуры (или функции). Поэтому, так как значение y напрямую не определено в pr2(), оно будет взято из внешней процедуры pr1().

Таким образом, вложенные процедуры образуют как бы матрёшку. Самая маленькая матрёшка видит все переменные, определённые во внешних матрёшках. И если эти переменные не переопределены в самой внутренней процедуре, то она может пользоваться этими значениями.

Вышележащие матрёшки видят переменные тех матрёшек, которые являются внешними по отношению к ней, но не видят переменных, содержащихся во внутренних матрёшках.

Delphi передача процедуры в процедуру

В Delphi кроме рассмотренных типов параметров у процедур и функций есть ещё один очень интересный тип параметра — процедурный.

Выглядит это так.

Объявляется тип данных:

type

tpr=procedure(список_параметров); или

tfn=function(список_параметров):тип;

Далее при описании процедуры или функции указывается параметр процедурного типа:

procedure рrос(pr:tpr);

begin

pr(фактические_параметры); //количество и типы фактических параметров должны строго соответствовать списку в tpr=procedure(список_параметров);

В нашем примере при вызове pr(фактические_параметры); будет организовано обращение к MyProc().

end.

И, наконец, реальная процедура, ссылка на которую будет передаваться в procedure рrос(pr:tpr);

В реальной процедуре список параметров также должен строго соответствовать описанию в tpr=procedure(список_параметров);

procedure MyProc(список_параметров);

begin

end;

Пусть у нас имеется обработчик клика по кнопке:

procedure TForm1.Button1Click(Sender: Tobject);

begin

proc(MyProc); //вызывается процедура proc. В качестве параметра ей передаётся ссылка на процедуру MyProc();

end;

Покажем это на примере.

implementation

{$R *.dfm}

function fun1(i:integer):integer;FORWARD;

function fun2(i:integer):integer;FORWARD;

type

fun=function(i:integer):integer;//при создании процедурного типа имя функции (процедуры) не указывается.

function ff(fn:fun):string; //в описании функции указан параметр процедурного типа. Через него передаётся ссылка на конкретную функцию. Эта функция обязательно должна иметь один параметр целого типа.

var j:integer;

begin

j:=5+fn(3); //вызов функции, имеющей один параметр целого типа.

//в процедуре pr функция ff будет вызвана дважды.

//при первом вызове в функцию ff будет передана ссылка на функцию fun1.

//при втором вызове в функцию ff будет передана ссылка на функцию fun2.

result:=intToStr(j);

end;

procedure pr(var ss:string);

begin

ss:=’вызов ff(fun1)даёт результат=’+ff(fun1)+’ вызов ff(fun2) даёт результат=’+ff(fun2);

//вызов ff(fun1) передаёт в функцию ff ссылку на функцию fun1

//вызов ff(fun2) передаёт в функцию ff ссылку на функцию fun2

//результат возвращается из процедуры pr через var-параметр ss.

end;

function fun1(i:integer):integer;

begin

result:=i*2;

end;

function fun2(k:integer):integer;

begin

result:=k*3;

end;

procedure TForm1.Button7Click(Sender: TObject);

var s:string;

begin

pr(s); //результат возвращается из процедуры pr через переменнуюs. В процедуре pr объявлен соответствующий var-параметр.

form1.Edit17.Text:=s;

end;

Результат работы программы:

delphi процедура в процедуре

Параметры по умолчанию

Ещё одна очень полезная вещь — задание параметров по умолчанию. В шапке процедуры они долны стоять обязательно последними.

Поясним использование параметров по умолчанию на примере.

function pprr(x:integer;s:string=’параметр по умолчанию’):string;

begin

result:=s;

end;

procedure TForm1.Button8Click(Sender: TObject);

begin

form1.Edit18.Text:=pprr(1);

form1.Edit19.Text:=pprr(1,’заданная строка’);

end;

Первый вызов процедуры производится без передачи значения последнему параметру. При этом функция вернёт значение параметра, заданное по умолчанию.

Во втором случае функция вернёт передаваемое значение.

Преимущество такого параметра сразу не очевидно, однако во многих ситуациях значительно упрощает пользование программой.

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

Есть одно существенное ограничение. Предположим, что имеются три параметра по умолчанию. Если передать значение второму параметру по умолчанию, то можно не указывать третий параметр, но первый надо задать обязательно.

То есть правильно, например, вызвать MyPr(s,1,4,9), MyPr(s,1,4). Но не верно пытаться сделать вызов MyPr(s,,4).

Обновлено: 09.01.2021 — 14:35

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *