delphi передача процедуры как параметра

Параметры функций, процедур

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

Типы параметров процедуры и функции Delphi.

В процедуры можно передать следующие типы параметров:

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

Параметр – константа

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

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

Параметр – переменные

Если мы хотим изменить какую-либо переменную в ходе выполнения процедуры/функции Delphi, то нам нужно в объявлении, перед именем добавить ключевое слово var. Приведу пример:

Смотрите. Мы описали первую функцию MyF и, изменяя в её теле переменную i, мы будем изменять переменную, которую передали как параметр. Такой способ передачи параметра называется передачей параметра по ссылке. Сейчас все станет ясно. Для этого разберем процедуру pr. Мы задаем переменной x значение ноль, выводим его, чтобы убедиться в этом. Далее мы эту переменную передаем в функцию MyF, где в результате наш x увеличивается на единицу. Это произошло именно благодаря тому, что параметр функции MyF объявлен с ключевым словом var.

Выходные параметры

В Delphi есть тип параметра функции, который используется только для вывода значения. Объявляется такой тип при помощи директивы Out. Данная директива может использоваться только в функциях. Использование выходных параметров очень напоминает использование var, разница в том, что значение не может быть изменено подпрограммой. Выходное значение в Delphi используется для возврата дополнительных переменных из функции. Нужно это тогда, когда одной переменной Result не обойтись.

Источник

Delphi передача процедуры как параметра

Данная с татья посвящена передаче функции в качестве параметра в другую функцию / процедуру.

Необходимо было реализовать вычисление определенных интегралов 20 функций методами трапеций и прямоугольников. Если реализовывать поставленную задачу, то для каждой реализуемой функции необходимо было запрограммировать каждый метод отдельно. Поэтому возник закономерный вопрос: А нельзя-ли запрограммировать каждую функцию, которую надо интегрировать, отдельно, и методы интегрирования отдельно, а после этого передавать в методы интегрирования интегрируемую функцию в качестве параметра.

Изучая данный данный вопрос в Интернете на большинстве сайтов размещена статья « Передача функции как параметра« (одна из первых ссылок на сайте delphiworld). Основные недостатки статьи: это привязка к DLL и вызов функции в общем виде.

На одном из форумов нашел понятное объяснение которое в итоге и реализовал.

Прежде всего необходимо определить пользовательский тип переменной описывающий шаблон функции, которую будем передавать в качестве параметра в другую процедуру/функцию. Определяем этот тип переменной следующим образом:

type
TMyFuncType = function (xn:double) : double;

количество параметров шаблона функции должно соответствовать количеству параметров передаваемой функции.

Далее вводим переменную пользовательского типа TMyFuncType:

var
MyFunc:TMyFuncType;

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

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

function rectangle1(var a,b:double; n:integer; MyFunc1:TMyFuncType): double; //метод прямоугольников
var
xn: array of double;
sum,h :double;
i:integer;
begin
SetLength(xn, n);
xn[0] := a;
h:= (b-a)/n;
sum := MyFunc1(xn[0]); //Вызов передаваемой функции
for i:=1 to n-1 do begin
xn[i] := xn[i-1]+h;
sum := sum + MyFunc1(xn[i]);
//Вызов передаваемой функции
end;
Result := sum*h;
end;

В параметрах передаваемых функции следует обратить внимание на параметр MyFunc1:TMyFuncType, который обеспечивает передачу имени одной из выбранных функций в качестве параметра функции. При этом вызов передаваемой функции осуществляется стандартным образом

Вызов метода интегрирования прямоугольника с определенными параметрами осуществляется стандартным путем

c := rectangle1(a, b, n, MyFunc);

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

Источник

Передача процедур и функций в качестве параметров

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Задача на использование функций в качестве параметров других функций
Составить программу по заданному условию. Первая часть условия является заданием на разработку.

С++ Использование функций как параметров процедур
Процедура Р формирует массив из элементов Z, для которых одновременно выполняются условия F1( Z)>C.

Директивы и соглашения вызова процедур и передача параметров
Здравствуйте. Сразу говорю что не наглею, а прошу помощи в решении задачи: Задача: Логика работы.

Передача файлов в качестве параметров
Необходимо передать файловую переменную как параметр. При передаче выдает переполнение стека, не.

2. Чаще всего перадаются просто указатели на функцию, вроде CallBack функций.

Тоесть, если function TheFunction (progress: longint): boolean;

Пишешь указатель SomeRoutine (a,b, @TheFunction); в качестве параметра.

посмотри пример кода здесь

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

Пытался так
Дальше в процедуре SomeRoutine пытаюсь вызвать функцию TheFunction так:

Ссылка на видеоурок по этой теме:

Помощь в написании контрольных, курсовых и дипломных работ здесь.

delphi передача процедуры как параметраИспользование функций в качестве формальных параметров
Помогите вычислить f(x)/g(x), где в качестве f(x) и g(x) могут быть четыре различные функции.

delphi передача процедуры как параметраПередача чисел в качестве параметров функции
Привет, нужна ваша помощь! Вычислить произведение целых чисел, переданных в качестве параметров.

Передача массивов в качестве параметров функции
Задав динамический двумерный массив вещественных данных (матрицу А размером NxN), реализовать его.

delphi передача процедуры как параметраОбработать одномерный массив с использование процедур и функций без параметров и с параметрами
После первого элемента вставить 0 Обработать одномерный массив с использование процедур и функций.

Источник

Сейчас онлайн:
На сайте — 3
На IRC-канале — 2

Подпрограммы (часть 3)

Решение домашнего задания из урока №20

Домашнее задание, предложенное в прошлом уроке было следующим:

Введение

Третий и завершающий урок по теме «подпрограммы». В предыдущих двух мы разобрались, что такое подпрограммы, зачем они нужны, а также научились создавать свои собственные подпрограммы и пользоваться ими. В этом уроке будет скорее не новый материал, а дополнение к уже имеющемуся.

Способы передачи параметров в подпрограммы

Тип данных Word выбран специально для того, чтобы отрицательные значения не могли быть переданы процедуре.

Проверка работы подпрограммы при нажатии на кнопку:

На один параметр больше.

Параметры-константы

Есть ещё одна модификация параметров подпрограммы. Можно любой из них сделать константой. Нужно это в случае, если вы хотите контроллировать свой код на предмет отсутствия команд для изменения значения входного параметра. Делается это добавлением слова const перед переменной в заголовке.

Например, мы хотим для нашей предыдущей задачи находить x и y не для числа n, а для n+1. Для этого добавим в тело подпрограммы соответствующую строку:

Но теперь, если мы сделаем параметр n константой, компилятор выдаст ошибку на только что добавленной строке:

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

Необязательные параметры

Часто подпрограммы имеют большое количество параметров, что подчёркивает их универсальность и обширность выполняемых действий. Однако во многих случаях одни и те же параметры имеют одинаковое значение, т.е. среди вариантов значений одного параметра есть наиболее популярный. В этом случае для упрощения вызова подпрограмм часть параметров делают необязательными. Необязательный параметр может быть передан подпрограмме, а может и быть опущен. Для того случая, когда он опущен, имеется его исходное значение, которое подпрограмма и будет использовать.

delphi передача процедуры как параметра

Необязательные параметры указываются в квадратных скобках.

Удобно, согласитесь? Сейчас мы научимся делать необязательные параметры и в своих подпрограммах.

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

Посмотрите количество параметров функции CreateProcess():

delphi передача процедуры как параметра

Привязка подпрограмм к форме

Итак, чтобы «привязать» процедуру к форме, мы должны сделать следующее:

delphi передача процедуры как параметра

Между именем класса формы и именем подпрограммы должна стоять точка. В результате заголовок процедуры станет таким:

delphi передача процедуры как параметра

А если, например, есть Form2 и CheckBox2 на ней, то обработчик будет такой:

Заключение

Автор: Ерёмин А.А.

Статья добавлена: 4 июня 2008

Зарегистрируйтесь/авторизируйтесь,
чтобы оценивать статьи.

Статьи, похожие по тематике

Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:

Ссылка для форумов (BBCode):

Быстрая вставка ссылки на статью в сообщениях на сайте:
<> (буква a — латинская) — только адрес статьи (URL);
<<статья:121>> — полноценная HTML-ссылка на статью (текст ссылки — название статьи).

Поделитесь ссылкой в социальных сетях:

Комментарии читателей к данной статье

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
< Private declarations >
public

procedure TForm1.Button1Click(Sender: TObject);
procedure GetXY(n: Word; var x, y: Word);
begin
x:=Trunc(Sqrt(n));
y:=n-Sqr(x);
if y = 0 then
begin
Dec(x);
y:=n-Sqr(x);
end;
end;
var N,A,B: Word;
begin
N:=StrToInt(Edit1.Text);
GetXY(N,A,B);
Label1.Caption:=IntToStr(N)+’ = ‘+IntToStr(a)+’^2 + ‘+IntToStr(b);
end;

Задача №3 заработала:
unit Unit1;

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
Button1: TButton;
CheckBox3: TCheckBox;
procedure Button1Click(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
procedure CheckBox2Click(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;
var
Form1: TForm1;
A: Boolean; //»Пойдем на концерт! Я билет достал! (билет есть или врет)
B: Boolean; //»Ура! Я с тобой пойду! (пойдет на концерт или врет)
implementation
<$R *.dfm>
procedure TForm1.CheckBox1Click(Sender: TObject);

begin
A:= CheckBox1.Checked
end;

procedure TForm1.CheckBox2Click(Sender: TObject);

begin
B:= CheckBox2.Checked
end;

Задача №2 заработала при:
unit Unit1;

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;

procedure TForm1.Button1Click(Sender: TObject);
function RusToUpper(Str: String): String;
const
LetL = ‘абвгдеёжзийклмнопрстуфхцчшщъыьэюя’;
LetU = ‘АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ’;
var i: Integer;
begin
Result:=Str;
for i:=1 to Length(Str) do
if Pos(Str[i],LetL) > 0 then
Result[i]:=LetU[Pos(Str[i],LetL)];
end;
var
N1: string;
begin
N1:=Edit1.Text;
Label1.Caption:=’заглавные и прописные кирилические символы написаны только как заглавные = ‘+RusToUpper(N1);
end;

Первое задание заработало при:
unit Unit1;

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;

procedure TForm1.Button1Click(Sender: TObject);
function Factorial(n: Integer): Int64;
var i: Integer;
begin
Result:=1;
for i:=2 to n do
Result:=Result*i;
end;
var n: Integer;
begin
n:=StrToInt(Edit1.Text);
Label1.Caption:=’Факториал обозначается как «n!» = 1*2*3*. *n = ‘+IntToStr(Factorial(n));
end;

Оставлять комментарии к статьям могут только зарегистрированные пользователи.

Источник

Использование процедур и функций в Delphi

Скобки

Добавление скобок при вызове процедур и функций без параметров уже давно не является новинкой в Delphi, тем не менее, эта возможность мало известна. Эту возможность оценят по достоинству те программисты, которым приходится работать на двух языках (C++ и Delphi), так как им не нужно будет постоянно помнить о разнице в синтаксисе при вызове процедур и функций в разных языках. В Delphi оба варианта, приведенные ниже, считаются корректными.

Возможность перегрузки

Впервые концепция перегрузки процедур и функций была реализована в Delphi 4. Она позволяет иметь несколько различных процедур и функций с одинаковыми именами, но с разными списками параметров. Такие процедуры и функции должны быть описаны с применением директивы overload.

procedure Test (I: integer); overload;
procedure Test (S: string); overload;
procedure Test (D: double); overload;

При вызове процедуры Test, Delphi сама решит, какую из трех процедур необходимо выполнить, в зависимости от передаваемого ей параметра. Но нужно отметить, что это не самая безопасная возможность языка. Применение перегружаемых процедур и функций может стать неиссякаемым источником трудноуловимых ошибок в программе. Поэтому пользуйтесь этой возможностью осторожно.

Передача параметров

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

Передача параметров по значению

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

procedure Test(s: string);

При вызове указанной процедуры будет создана копия передаваемой ей в качестве параметра строки s, с которой и будет работать процедура Test. При этом все внесенные в строку изменения никак не отразятся на исходной переменной s.

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

Передача параметров по ссылке

Pascal позволяет также передавать параметры в функции или процедуры по ссылке — такие параметры называются параметрами-переменными. Передача параметра по ссылке означает, что функция или процедура сможет изменить полученные значения параметров. Для передачи параметров по ссылке используется ключевое слово var, помещаемое в список параметров вызываемой процедуры или функции.

procedure ChangeMe(var x: longint);
begin
x := 2; // Параметр х изменен вызванной процедурой
end;

Вместо создания копии переменной x, ключевое слово var требует передачи адреса самой переменной x, что позволяет процедуре непосредственно изменять ее значение.

Передача параметров констант

Если нет необходимости изменять передаваемые функции или процедуре данные, можно описать параметр как константу. Ключевое слово const не только защищает параметр от изменения, но и позволяет компилятору сгенерировать более оптимальный код передачи строк и записей. Вот пример объявления параметра-константы:

procedure Test(const s: string );

Передача открытых массивов

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

function AddEmUp(A: array of integer): integer;

В открытом массиве можно передавать переменные, константы или выражения из констант.

Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf.

Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий:

procedure WhatHaveIGot( A: array of const );

Вызвать объявленную выше функцию можно, например, с помощью такого оператора:

procedure WhatHaveIGot( [‘Text’, 10, 5.5, @WhatHaveIGot, 3.14, true, ‘c’] );

При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом:

PVarRec = ^TVarRec;
TVarRec = record
case Byte of
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
vtExtended: (VExtended: PExtended);
vtString: (VString: PShortString);
vtPointer: (VPointer: Pointer);
vtPChar: (VPChar: PChar);
vtObject: (VObject: TObject);
vtClass: (VClass: TClass);
vtWideChar: (VWideChar: WideChar);
vtPWideChar: (VPWideChar: PWideChar);
vtAnsiString: (VAnsiString: Pointer);
vtCurrency: (VCurrency: PCurrency);
vtVariant: (VVariant: PVariant);
vtInterface: (VInterface: Pointer);
vtWideString: (VWideString: Pointer);
vtInt64: (VInt64: PInt64);
end;

Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно приведенных значений.

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

procedure WhatHaveIGot( A: array of const );
var
i: integer;
TypeStr: string;
begin
for i := Low(A) to High(A) do
begin
case A[i].VType of
vtInteger : TypeStr := ‘Integer’;
vtBoolean : TypeStr := ‘Boolean’;
vtChar : TypeStr := ‘Char’;
vtExtended : TypeStr := ‘Extended’;
vtString : TypeStr := ‘String’;
vtPointer : TypeStr := ‘Pointer’;
vtPChar : TypeStr := ‘PChar’;
vtObject : TypeStr := ‘Object’;
vtClass : TypeStr := ‘Class’;
vtWideChar : TypeStr := ‘WideChar’;
vtPWideChar : TypeStr := ‘PWideChar’;
vtAnsiString : TypeStr := ‘AnsiString’;
vtCurrency : TypeStr := ‘Currency’;
vtVariant : TypeStr := ‘Variant’;
vtInterface : TypeStr := ‘Interface’;
vtWideString : TypeStr := ‘WideString’;
vtInt64 : TypeStr := ‘Int64’;
end;
ShowMessage( Format( ‘Array item %d is a %s’, [i, TypeStr] ) );
end;
end;

Значения параметров по умолчанию

В Delphi есть одна очень полезная возможность — использование значений параметров по умолчанию. Она позволяет установить принимаемое по умолчанию значение параметра процедуры или функции. Это значение будет использоваться в тех случаях, когда вызов процедуры или функции производится без указания значения данного параметра. В объявлении процедуры или функции принимаемое по умолчанию значение параметра указывается после знака равенства, следующего после его имени. Поясним это на следующем примере:

procedure HasDefVal( s: string; i: integer = 0 );

Подобное объявление означает, что процедура HasDefVal может быть вызвана двумя путями. В первом случае — как обычно, с указанием обоих параметров:

procedure HasDefVal( ‘Hello’, 26 );

Во втором случае можно задать только значение параметра s, а для параметра i использовать значение, установленное по умолчанию:

procedure HasDefVal( ‘Hello’ );

function Add( I1, I2: integer ): integer;
begin
Result := I1 + I2;
end;

Предположим также, что исследования показали целесообразность добавления в программу возможности сложения трех чисел. Однако замена имеющейся функции функцией сложения трех чисел приведет к тому, что вам придется переправлять немало текста, который перестанет компилироваться из-за внесения в функцию еще одного параметра. Однако при использовании значений параметров по умолчанию проблема решается легко и просто. Достаточно изменить объявление функции так, как показано ниже.

function Add( I1, I2: integer; I3: integer = 0 ): integer;
begin
Result := I1 + I2 + I3;
end;

Директива

Директива <$X->запрещает вызов функций как процедур (с игнорированием возвращаемого результата). По умолчанию этот режим включен (<$X+>). Так вот, запомните, использование переменной Result недопустимо при сброшенном флажке опции Extended Syntax, расположенном во вкладке Compiler диалогового окна Project Options, или при указании директивы компилятора <$X->.

В каждой функции языка Objecl Pascal существует локальная переменная с именем Result, предназначенная для размещения возвращаемого значения. Кроме того, вернуть значение из функции можно также путем присвоения значения переменной, имеющей то же имя, что и данная функция. Это стандартный синтаксис языка Pascal, сохранившийся от его предыдущих версий. При использовании в теле функции переменной с ее именем не забывайте, что существуют большие отличия в обработке этого имени — все зависит от того, где она расположена — в левой части оператора присвоения или же в любом другом месте текста функции. Если имя функции указано в левой части оператора присвоения, то предполагается, что назначается возвращаемое функцией значение. Во всех других случаях предполагается, что осуществляется рекурсивный вызов этой функции.

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

Источник

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

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