Функция в переменной

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Функция в переменной

Сообщение VirtUX »

Код: Выделить всё

TFunc = function: boolean; 

Код: Выделить всё

procedure AnyDo(b: boolean);
var
  f: TFunc;
  i: integer = 0;

  function a1: boolean;
  begin
    i := 1;
  end;

  function a2: boolean;
  begin
    i := 2;
  end;

begin

  if b then f := TFunc( @a1 )
  else f := TFunc( @a2 );
  f();
  form1.Caption:= IntToStr(i);

end;

i всегда равно нулю

Код: Выделить всё

procedure AnyDo(b: boolean);
var
  f: TFunc;
  i: integer = 0;

  function a1: boolean;
  begin
    i := 1;
  end;

  function a2: boolean;
  begin
    i := 2;
  end;

begin

  if b then f := @a1
  else f := @a2;
  f();
  form1.Caption:= IntToStr(i);

end;

Ошибка

Код: Выделить всё

procedure AnyDo(b: boolean);
var
  f: TFunc;
  i: integer = 0;

  function a1: boolean;
  begin
    i := 1;
  end;

  function a2: boolean;
  begin
    i := 2;
  end;

begin

  if b then f := a1
  else f := a2;
  f();
  form1.Caption:= IntToStr(i);

end;

Тоже ошибка.
Как правильно передать функцию в переменную?
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

Да в принципе правильно передаете, только проблема у вас в локальной переменной i, так будет работать:

Код: Выделить всё

var
  i: integer = 0;

procedure AnyDo(b: boolean);
var
  f: TFunc;

  function a1: boolean;
  begin
    i := 1;
  end;

  function a2: boolean;
  begin
    i := 2;
  end;

begin

  if b then f := TFunc( @a1 )
  else f := TFunc( @a2 );
  f();
  form1.Caption:= IntToStr(i);

end;
Аватара пользователя
dunin
энтузиаст
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и
Контактная информация:

Сообщение dunin »

VirtUX писал(а):Как правильно передать функцию в переменную?

Код: Выделить всё

var i: integer;
...
procedure DoSome;
    function SetIValue: integer;
    begin
        result:= 1;
    end;
begin
    i:= SetIValue;
end;

Код: Выделить всё

var i: integer;
...
procedure DoSome;
    function SetIValue(var InValue: integer): boolean;
    begin
        InValue:= 1;
        Result:= True;
    end;
begin
    if SetIValue(i) then showmessage('получилось')ж
end;
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

dunin ТС спрашивал как в переменную запихать функцию, а не результат выполнения этой функции.
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Сообщение VirtUX »

SeZuka писал(а):так будет работать:

Если честно, то не вижу принципиальной разницы в Вашем и моем примере....
Но в Вашем примере работает :) Объясните.... :oops:

Добавлено спустя 5 минут 6 секунд:
Дело в том, что ряд переменных (в частности "i" - это всего-лишь пример. Их около 10), используемых в подпрограммах должны быть внутри процедуры/функции. Я не могу их объявлять глобально.

Добавлено спустя 6 минут 26 секунд:
Причем одна подпрограмма может работать не только с теми переменными, что и другая. Они производят вычисления (каждая свои) и сообщают о возможности основной процедуры выполнять некоторые действия. Пример не могу кинуть. Код чужой. Я лишь взялся выяснить проблему....

Добавлено спустя 6 минут 3 секунды:
Изменил

Код: Выделить всё

procedure AnyDo(b: boolean);
var
  f: TFunc;
  i: integer = 0;

  function a1: boolean;
  begin
    i := 1;
    Result := true;
  end;

  function a2: boolean;
  begin
    i := 2;
    Result := false;
  end;

begin

  if b then f := TFunc( @a1 )
  else f := TFunc( @a2 );
  if f() then
  form1.Caption:= IntToStr(i);

end;

Результат подпрограммы верный. Т.е. действие Result := true(или false); отрабатывается, а переменная "i" новое значение не получает! Почему??? Она же объявлена относительно подпрограммы глобально...
P.S. Подозреваю нужна какая-то директива компилятору "о последовательности действий" или "о видимости переменных"....
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Тип вложенных процедур/функций надо объявлять вот так:

Код: Выделить всё

TFunc = function: boolean is nested;
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Сообщение VirtUX »

Sergei I. Gorelkin писал(а):TFunc = function: boolean is nested;

Код: Выделить всё

unit1.pas(36,29) Fatal: Syntax error, ";" expected but "is" found
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Точно, чтобы оно работало, нужно еще {$modeswitch nestedprocvars} в начале файла.
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Сообщение VirtUX »

Sergei I. Gorelkin писал(а):нужно еще {$modeswitch nestedprocvars} в начале файла.

Спасибо!!! То, что нужно! Теперь в переменную f: TFunc; можно просто передавать адрес функции f := @a1; :)
Ответить