|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
Функция из переменной
Подскажите пожалуйста, как вызвать функцию из переменной?
Задача такая: Имеется пять функций (одностроковых например: f4:=500*1.2*1000/(Rvar/100*x+R880)) и процедура (многострочная), строящая график на канве. Можно конечно и пять процедур накопипастить, под каждую функцию... Но.. Не могу понять, как в процедуру ввести переменную (например F) и согласно условию подставлять в неё какую-либо из фцнкций (тиапа F:=f1, F:=f2, и т.д.). |
#2
|
||||
|
||||
Указатель на функцию. Как это делается при динамическом вызове dll.
Пишу программы за еду. __________________ |
Этот пользователь сказал Спасибо NumLock за это полезное сообщение: | ||
shonty (23.08.2017)
|
#3
|
|||
|
|||
Дополню немного.
Есть 2 типа функций. Просто функции и методы класса. Для первого варианта можно так: Код:
type TFunc = function (x : double) : double; function f1(x : double) : double; begin result := x+1; // просто для примера end; function f2(x : double) : double; begin result := x-1; end; function CalcFunc(x1, x2, dx : double; func : TFunc) : double; var i : double; begin // просто бред для примера result := 0; i := x1; while i <= x2 do begin result := result + func(i); i := i + dx; end; end; // где-то вызов begin writeln('f1 ->', CalcFunc(1,5,0.2,f1); writeln('f2 ->', CalcFunc(1,5,0.2,f2); end; Для второго случая есть 2 подварианта. а. Тоже самое, только тип описан как Код:
type TFunc = function (x : double) : double of object; б. Передавать объект класса. тогда их можно "нанаследовать" от одного родителя. Там есть еще вариант с мета классом. Код:
unit Unit2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TFuncClass = class class function Name : String; virtual; class function f(x : double) : double; virtual; end; TMetaClass = class of TFuncClass; TF1 = class(TFuncClass) class function Name : String; override; class function f(x : double) : double; override; end; TF2 = class(TFuncClass) class function Name : String; override; class function f(x : double) : double; override; end; TForm2 = class(TForm) Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } function Calc(x1, x2, dx : double; cls : TMetaClass) : double; public { Public declarations } end; var Form2: TForm2; implementation {$R *.dfm} class function TFuncClass.Name : String; begin result := 'TFuncClass'; end; class function TFuncClass.f(x : double) : double; begin Raise Exception.Create('Should not be called.'); end; class function TF1.Name : String; begin result := 'f1'; end; class function TF1.f(x : double) : double; begin result := x + 1; end; class function TF2.Name : String; begin result := 'f2'; end; class function TF2.f(x : double) : double; begin result := x - 1; end; function TForm2.Calc(x1, x2, dx : double; cls : TMetaClass) : double; var i : double; begin result := 0; i := x1; while i <= x2 do begin result := result + cls.f(i); i := i + dx; end; end; procedure TForm2.Button1Click(Sender: TObject); begin Memo1.Lines.Add(Format('class %s, name %s -> %.4f',[TF1.ClassName,TF1.Name,Calc(1,5,0.2,TF1)])); Memo1.Lines.Add(Format('class %s, name %s -> %.4f',[TF2.ClassName,TF2.Name,Calc(1,5,0.2,TF2)])); end; end. Код:
class TF1, name f1 -> 78,0000 class TF2, name f2 -> 38,0000 ЗЫ. Я там совместил вызов собственно функции, форматирование строки и ее добавление в Memo. Думаю, разберешся. ЗЗЫ. Для особо умных. Мне просто было интересно - помню ли я как работать с метаклассами, последний раз делал такое лет 8 назад. Что-то еще помню, написал с первого раза без ошибок. Последний раз редактировалось lmikle, 23.08.2017 в 06:17. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
shonty (23.08.2017)
|
#4
|
|||
|
|||
Цитата:
Цитата:
PS Мне, как простому советскому радиолюбителю, для подбора резисторов в регуляторе тока (а зависимости сильно нелинейны) нужна программа для отображения графиков. А хотел выкрутится так: var a, b, c, d, e; F:=a*(fnc1)+b*(fnc2)+c*(fnc3)+d*(fnc4)+e*(fnc5) и подстановкой переменных a,b,c,d,e в "0" и "1" выбирать нужный участок выражения Теперь сделаю как положено |
#5
|
|||
|
|||
Если пишешь для себя, то сойдет. Если собираешься делиться, то еще приделай возможность грузиить эти функции из dll, тогда можно будет расширять набор функций не меняя основную программу. Код не намного сложнее получится. Только надо будет сделать получение адресов таких же функций из dll'ей и сохранение их в спике для дальнейшего вызова.
Ну и , насколько я помню, там еще куча интересных зависимостей есть, фильтров от емкостей и индуктивностей, например). |
#6
|
||||
|
||||
Эх, эмбаркадера им лямбды с дженериками дала — используй лямбды с дженериками, используй — не хочу.
Код:
function demo(f1, f2: TFunc<integer, Integer>): integer; begin result := f1(f2(1)); // compose functions end; ... foo := demo( function (a: integer): integer begin result := a+1; end, function (a: integer): integer begin result := a-1; end) ... использование лямбд из переменных f1 = function (a: integer): integer begin result := a+1; end; f2 = function (a: integer): integer begin result := a-1; end; bar = demo(f1, f2) — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 25.08.2017 в 08:49. |
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение: | ||
shonty (25.08.2017)
|