Процедурные типы данных

Вопросы программирования и использования среды Lazarus.

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

Процедурные типы данных

Сообщение resident » 21.03.2013 13:08:14

Подскажите, в Лазарусе есть процедурные типы данных? У меня не получилось их использовать.
Пробую сделать как в первом параграфе в статье http://www.rsdn.ru/article/delphi/Handlers.xml
Копирую в Делфи - все работает:
Код: Выделить всё
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

type
  TCalcFunction = function(const A, B : integer) : integer;

implementation
{$R *.dfm}

function Add(const A, B : integer) : integer;
begin Result := A + B; end;
function Sub(const A, B : integer) : integer;
begin Result := A - B; end;
function Mul(const A, B : integer) : integer;
begin Result := A * B; end;

procedure Example;
  var CalcFunction : TCalcFunction;
  begin CalcFunction := Add;
    ShowMessageFmt('CalcFunction(2, 3) = %d', [CalcFunction (2, 3)]);
    CalcFunction := Sub;
    ShowMessageFmt('CalcFunction(2, 3) = %d', [CalcFunction (2, 3)]);
    CalcFunction := Mul;
    ShowMessageFmt('CalcFunction(2, 3) = %d', [CalcFunction (2, 3)]);
  end;

procedure TForm2.FormCreate(Sender: TObject);
  begin
    Example;
  end;

end.



Копирую тоже самое в Лазарус - не хочет
Код: Выделить всё
unit FormMain;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;

type
  TForm1 = class(TForm)
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

type
  TCalcFunction = function(const A, B : integer) : integer;

implementation
{$R *.lfm}

function Add(const A, B : integer) : integer;
begin Result := A + B; end;
function Sub(const A, B : integer) : integer;
begin Result := A - B; end;
function Mul(const A, B : integer) : integer;
begin Result := A * B; end;

procedure Example;
  var CalcFunction : TCalcFunction;
  begin CalcFunction := Add;
    ShowMessageFmt('CalcFunction(2, 3) = %d', [CalcFunction (2, 3)]);
    CalcFunction := Sub;
    ShowMessageFmt('CalcFunction(2, 3) = %d', [CalcFunction (2, 3)]);
    CalcFunction := Mul;
    ShowMessageFmt('CalcFunction(2, 3) = %d', [CalcFunction (2, 3)]);
  end;

end.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Процедурные типы данных

Сообщение Vadim » 21.03.2013 13:29:34

resident писал(а):Подскажите, в Лазарусе есть процедурные типы данных?

Lazarus - это не язык программирования (сообщаю Вам на всякий случай ;) ).
resident писал(а):в Делфи - все работает
...
в Лазарус - не хочет
...
CalcFunction := Add;

Потому что Дельфи - среда разработки для малохольных, которые не хотят разбираться в синтаксисе языка. :D
Смотрите, что Вы делаете: результат выполнения функции Add() Вы присваиваете переменной CalcFunction, вдобавок позабыв дать функции нужные ей параметры. :D Вы это делаете по "дельфийской" привычке, которая вытеснила способность думать и понимать, что Вы делаете. Забудьте про такой полоумный синтаксис, который порождает миллион ошибок и непониманий. Вам нужно переменной присвоить не результат функции, а её адрес:
Код: Выделить всё
CalcFunction := @Add;
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Процедурные типы данных

Сообщение SeZuka » 21.03.2013 13:38:32

Это различия между ObjectPascal и Delphi.
Вам либо надо переключить на диалект дельфей:
Код: Выделить всё
unit FormMain;
{$mode delphi}{$H+}
...
  CalcFunction := Add;
  CalcFunction := Sub;
  CalcFunction := Mul;
Либо писать писать как принято в ObjectPascal:
Код: Выделить всё
  CalcFunction := @Add;
  CalcFunction := @Sub;
  CalcFunction := @Mul;
SeZuka
постоялец
 
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Re: Процедурные типы данных

Сообщение resident » 21.03.2013 14:37:49

Vadim писал(а):Lazarus - это не язык программирования

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

Vadim писал(а):Потому что Дельфи - среда разработки для малохольных, которые не хотят разбираться в синтаксисе языка. :D

Дельфи - среда быстрой разработки, и этим все сказано :D

Vadim писал(а):Забудьте про такой полоумный синтаксис, который порождает миллион ошибок и непониманий. Вам нужно переменной присвоить не результат функции, а её адрес:
Код: Выделить всё
CalcFunction := @Add;

Вот спасибо. Логично. А то я думаю, что что-то не так, читаемости нет в Делфийском примере.
Теперь посмотришь и все понятно.

з.ы. Кстати, исправил в Делфи, там тоже заработало с адресом. Так что получается Делфи не только для нехотящих разбираться, а для всех. Хочешь @ пиши, а хочешь не пиши.

Добавлено спустя 2 минуты 42 секунды:
SeZuka писал(а):Вам либо надо переключить на диалект дельфей:

Зачем же. Или были случаи возвращения людей с Лазаруса на Делфи?

SeZuka писал(а):Либо писать писать как принято в ObjectPascal:
Код: Выделить всё
  CalcFunction := @Add;

Ок, спасиб :)
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Процедурные типы данных

Сообщение Vadim » 21.03.2013 15:37:01

resident писал(а):Кстати, исправил в Делфи, там тоже заработало с адресом.

Так и должно быть, потому что это изначально было правильно. Просто в Дельфи синтаксис некоторых вещей упростили в ущерб понятности. Например, у динамически выделенной переменной, типа record, для взятия оттуда значения, символ "^" можно не писать, что многих тоже вводит в тягостное недоумение, т.к. они свято верят, что это статическая переменная и память под неё выделять не нужно. :)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Процедурные типы данных

Сообщение resident » 21.03.2013 17:33:35

Vadim писал(а):
resident писал(а): т.к. они свято верят, что это статическая переменная и память под неё выделять не нужно. :)

Не в курсе этих подробностей :)

Я все играюсь с тем примером. Опять не получается, может подскажите, как тут быть?
Вот если мне понадобиться передать функцию в качестве параметра какой-нибудь процедуре (например добавлю procedure Calculate), то как мне это сделать?
Почитал про указатели. Понятного мало. Сама процедура компилируется, но как туда передать функции не понимаю. На выражения аля Calculate(2,3,@Add); компилятор ругается.

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

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

type
  TCalcFunction = function(const A, B : integer) : integer;
  PCalcFunction = ^TCalcFunction;

implementation
{$R *.lfm}

function Add(const A, B : integer) : integer;
begin Result := A + B; end;
function Sub(const A, B : integer) : integer;
begin Result := A - B; end;
function Mul(const A, B : integer) : integer;
begin Result := A * B; end;

procedure Calculate(A, B: integer; P: PCalcFunction);
  var CalcFunction : TCalcFunction;
  begin
    CalcFunction := P^;
    ShowMessageFmt('CalcFunction(2, 3) = %d', [CalcFunction (A, B)]);
  end;

procedure Example;
  begin
    Calculate(2,3,@Add);
    Calculate(2,3,@Sub);
    Calculate(2,3,@Mul);
  end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
  begin
    Example;
  end;



end.

resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Процедурные типы данных

Сообщение Vadim » 21.03.2013 18:13:20

Код: Выделить всё
procedure Calculate(A, B: integer; P: TCalcFunction);

Теперь на место P можно подставлять адрес функции.
P - это уже указатель, т.к. ничего другого, кроме адреса функции, процедурный тип не предусматривает, поэтому никакие другие указатели из него делать не надо. Далее, уже внутри процедуры, это самое P можно использовать как функцию, без других промежуточных переменных.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Процедурные типы данных

Сообщение alexey38 » 21.03.2013 18:54:17

resident писал(а):Или были случаи возвращения людей с Лазаруса на Делфи?

Безусловно, что многие используют Лазарь и ФПС как вспомогательное средство, особенно когда нужно под линухом написать некоторую прогу. Писать большие виндовые проекты под дельфей было всегда удобнее, как на уровне самой ИДЕ, так и на уровне многих элементов, типа уникода, ОЛЕ и т.п.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Процедурные типы данных

Сообщение stanilar » 22.03.2013 12:09:47

resident писал(а):Вот спасибо. Логично. А то я думаю, что что-то не так, читаемости нет в Делфийском примере.
Теперь посмотришь и все понятно.


При работе а собакой отсутствует проверка на типы со всеми вытекающими. Лучше пользоваться {$mode delphi}, оставьте себе возможность избавиться от дурацких ошибок на этапе компиляции :) .
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: Процедурные типы данных

Сообщение VirtUX » 22.03.2013 12:30:00

stanilar писал(а):При работе а собакой отсутствует проверка на типы со всеми вытекающими. Лучше пользоваться {$mode delphi}, оставьте себе возможность избавиться от дурацких ошибок на этапе компиляции :) .

Зачем Вы человека учите невежеству? Пусть "дурацкие ошибки" (хотя я бы сказал: "ошибки, приводящие к пониманию") заставляют становиться мудрее ;) С замылинным взглядом на жизнь мы все уже и так живем :( Так пусть хоть в творчестве люди будут чисты и трезвы :)
P.S. ИМХО...
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Процедурные типы данных

Сообщение stanilar » 22.03.2013 12:42:05

VirtUX писал(а):ИМХО...


Использование возможностей языка не есть невежество а знание и понимание отличительных особенносте одного языка от другого.

ИМНО: Давайте пойдем еще дальше: пусть человек отбросит паскаль и учит сразу правильный си, а еще лучше прочищающий мозги с++.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: Процедурные типы данных

Сообщение resident » 22.03.2013 16:29:14

Vadim писал(а):Теперь на место P можно подставлять адрес функции.
P - это уже указатель, т.к. ничего другого, кроме адреса функции, процедурный тип не предусматривает, поэтому никакие другие указатели из него делать не надо.

Не получилось подставить. Ну да мне не особо нужно, только любопытно было сработает или нет. Спасиб.

Добавлено спустя 2 минуты 1 секунду:
alexey38 писал(а):Безусловно, что многие используют Лазарь и ФПС как вспомогательное средство, особенно когда нужно под линухом написать некоторую прогу


Ах вот в чем тут дело. Я то думал, что он нужен, чтобы лицензия была. Вроде все бесплатно.

Добавлено спустя 6 минут 19 секунд:
stanilar писал(а):При работе а собакой отсутствует проверка на типы со всеми вытекающими. Лучше пользоваться {$mode delphi}, оставьте себе возможность избавиться от дурацких ошибок на этапе компиляции


Я почитал в инете, так в Делфи действительно не все так просто упростили. Даже не знаю, что лучше.
Особенно посмешил пост:
http://www.gamedev.ru/flame/forum/?id=154986&page=2#m26
"И ваша пгограмма выдаст ой вей вместо того, чтобы габотать. " :lol:
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Процедурные типы данных

Сообщение Alex2013 » 04.04.2013 13:29:02

То есть так ?
Код: Выделить всё
procedure Calculate(A, B: integer; P: PCalcFunction);
  begin 
    ShowMessageFmt( '  CalcFunction (2, 3) = %d', [P (A, B)]);
  end;


Столкнулся при присваивании обработчика событий что то типа T.OnTimer:=@ MyTmer ;
В дельфях работает без собаки
Alex2013
долгожитель
 
Сообщения: 3148
Зарегистрирован: 03.04.2013 11:59:44

Re: Процедурные типы данных

Сообщение Vadim » 04.04.2013 13:42:31

Alex2013 писал(а):В дельфях работает без собаки

Delphi, в этом случае, не пример для подражания. Из-за Delphi Вы забыли (или изначально не знали) правильный синтаксис.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 234

Рейтинг@Mail.ru
cron