Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Procedural types in statements and expressions


Автор: Christoph 30.1.2009, 19:22
нашел в справке такую инфу

Код


if F = MyFunction then ...;
In this case, the occurrence of F results in a function call; the compiler calls the function pointed to by F, then calls the function MyFunction, then compares the results. The rule is that whenever a procedural variable occurs within an expression, it represents a call to the referenced procedure or function. In a case where F references a procedure (which doesn't return a value), or where F references a function that requires parameters, the previous statement causes a compilation error. To compare the procedural value of F with MyFunction, use

if @F = @MyFunction then ...;

@F converts F into an untyped pointer variable that contains an address, and @MyFunction returns the address of MyFunction.

To get the memory address of a procedural variable (rather than the address stored in it), use @@. For example, @@F returns the address of F.


так вот написано что @F хранит адресс, адресс функции, и написано чтоб получить адресс процедурной переменны, то надо писать @@F, разве @F и @@F отличаются? Вот решил написать небольшой пример, но есть своки бока


Код

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
   end;
TProc=function(k:integer):integer;
function Fun(i:integer):Integer;
var
  Form1: TForm1;
  Proc:Tproc;
implementation

{$R *.dfm}
function Fun(i:integer):integer;
begin
  Result:=i*2;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Proc:=@Fun;
ShowMessage(String(@Proc));
end;



Правильно ли я вывожу адресс? а то мне выводит пустое окно, а если пишу так:
Код

ShowMessage(String(@@Proc));


...то ошибка  вылетает, ошибка AV. Можете помочь разъяснить ситуацию? Спасибо

Автор: Bose 30.1.2009, 19:24
procedure TForm1.FormCreate(Sender: TObject);
begin
Proc:=@Fun;
ShowMessage(IntToStr(@Proc));
end;

Добавлено @ 19:25
К тому же всё это можно записать как:
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
Proc:=Fun;
ShowMessage(IntToStr(Proc));
end;


Добавлено @ 19:25
без заморочек с @

Автор: bems 30.1.2009, 19:41
тут еще нужно привести указатель к целому

Автор: Christoph 30.1.2009, 19:42
Bose, ты ошибаешся, запись

Код

Proc:=Fun;


Будет требовать параметры, и будет пытаться присвоить результат переменной Proc.Была бы процедура другое дело, А переменная Proc у меня другого типа  smile 

Мне кажется что приведения IntToStr не сработает) потом что там указатель и string, я не знаю, я чуть позже попробую

Автор: bems 30.1.2009, 19:47
Код

ShowMessage(IntToStr(cardinal(@Proc)));

Автор: Bose 30.1.2009, 21:20
Цитата(Christoph @  30.1.2009,  18:42 Найти цитируемый пост)
Bose, ты ошибаешся, запись
Код

Proc:=Fun;

Будет требовать параметры, и будет пытаться присвоить результат переменной Proc.Была бы процедура другое дело, А переменная Proc у меня другого типа  smile 

Мне кажется что приведения IntToStr не сработает) потом что там указатель и string, я не знаю, я чуть позже попробую 


Не ошибаюсь. Точнее ошибаюсь, но не в этой строке.
правильно будет вот так:
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  Proc:=Fun;
  ShowMessage(IntToStr(Proc(12)));
end;

Здесь ShowMessage показывает результат выполнения функции Fun(12).


А результат выполнения этого:
Код

ShowMessage(IntToStr(cardinal(@Proc)));

Цитата

4552572

Здесь ShowMessage показывает адрес переменной Proc.

Автор: bems 30.1.2009, 21:51
Цитата(Bose @  30.1.2009,  21:20 Найти цитируемый пост)
Здесь ShowMessage показывает адрес переменной Proc.
а разве не это надо было?

Автор: Christoph 30.1.2009, 23:39
Bose, да прости чуть не продумал, не хотел тебя обвенять smile

Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  Proc:=Fun;
  ShowMessage(IntToStr(cardinal(@@Proc)));
end;


Выводит 4545536

Код

Во такой код
procedure TForm1.FormCreate(Sender: TObject);
begin
  Proc:=Fun;
  ShowMessage(IntToStr(cardinal(@Proc)));
end;


Выводит 4530368, адресса разные, что же получается?! Пример для наглядности

Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  ShowMessage(IntToStr(cardinal(@@Proc))); //4545536
end;
// и...
procedure TForm1.FormCreate(Sender: TObject);
begin
  ShowMessage(IntToStr(cardinal(@Proc)));  //0
end;

// и..

procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage(IntToStr(cardinal(@Fun))); //4530368
end;


Значит получается так и есть что @@Proc возращает адресс переменной Proc, а @Proc указывает на адресс начало функции, и не разу не видел чтоб был оператор @@,эх ну ладно, надо учить асм)
bems, Bose, спасибо за обсуждение темы.
P.s если не будет комментариев я тему закрываю

Автор: Bose 31.1.2009, 06:36
Цитата(bems @  30.1.2009,  20:51 Найти цитируемый пост)
а разве не это надо было?

Это.  smile это я решил что важнее результат.

Автор: bems 31.1.2009, 16:21
Цитата(Christoph @  30.1.2009,  23:39 Найти цитируемый пост)
Значит получается так и есть что @@Proc возращает адресс переменной Proc, а @Proc указывает на адресс начало функции

а зачем авторам хелпа распространять ложную информацию? ну да, так и есть
Цитата(Christoph @  30.1.2009,  23:39 Найти цитируемый пост)
не разу не видел чтоб был оператор @@

значит мало кода читал. Это встречается.
Цитата(Christoph @  30.1.2009,  23:39 Найти цитируемый пост)
надо учить асм)

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)