Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.10.2007, 13:17   #1
TROXEVASIN
 
Регистрация: 20.10.2007
Сообщений: 6
По умолчанию необходимо сделать стек на указателях с использованием ООП

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

Описание классов:
Код:
  Telement= class
  prev:^Telement;
  inf: string;
  end;
  Tstek = class
  conec: ^Telement;
  end;
Использованные переменные:
Код:
var
  Form1: TForm1;
  Stek: Tstek;
  Cur: ^TElement;
Сами процедуры

Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Stek:=Tstek.Create;
  Edit1.Text:='1';
  Cur:=nil;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Stek.Destroy;
end;
procedure TForm1.Button1Click(Sender: TObject);
var T:Telement;
begin
  if Stek.conec=nil then begin
                           T:=Telement.Create;
                           T.inf:=Edit1.Text;
                           T.prev:=nil;
                           Stek.conec:=Addr(T);
                         end
                    else begin
                           T:=Telement.Create;
                           T.inf:=Edit1.Text;
                           T.prev:=Addr(Stek.conec);
                           Stek.conec:=Addr(T);
                         end;
end;
 
// Косячит в этой процедуре
procedure TForm1.Button2Click(Sender: TObject);
begin
  if Cur=nil then begin
                    Cur:=Addr(Stek.conec^);
                    Label1.Caption:=Cur^.inf;
                  end
             else begin
                    Cur^:=Cur.prev^;
                    Label1.Caption:=Cur.inf;
                  end;
end;
end.
TROXEVASIN вне форума Ответить с цитированием
Старый 20.10.2007, 14:10   #2
Maslan
Форумчанин
 
Регистрация: 15.10.2007
Сообщений: 147
По умолчанию

Код:
PElement=^TElement;//Это что бы члену Tstek можно было просто
                             // присваиваивать, без колдунства @(ptr^) 
                             //указатели на TElement. 
                             //(Если оставить оформление через ^TElement, то система 
                             //будет различать типы TStek.conec и TElement.prev и не даст их 
                            //присваивать друг другу.

Telement= class
   prev: PElement;
   inf: string;
end;

Tstek = class
   conec: PElement;
end;

var
Form1: TForm1;
Stek: Tstek;
Cur: PElement;

Код:
procedure TForm1.Button1Click(Sender: TObject);
Var NewElem:PElement;
begin
 New(NewElem);
 NewElem^:=Telement.Create;
 if Stek.conec=nil
    then //Свежесозданный и будет концом
      begin
       Stek.conec:=NewElem;
       Stek.conec.prev:=nil;
       Stek.conec.inf:=Edit1.Text;
      end
   else// Кстати, какой стек-то делаем FIFO,FILO?
    begin
       Cur:=Stek.conec;
        while Cur.prev<>nil do
        Cur := Cur.prev;
        New(Cur.prev);
        Cur.prev^ := Telement.Create;
        Cur.prev^.prev:=nil;
        Cur.prev^.inf:=Edit1.Text;
       Cur:=nil;
    end;
 NewElem:=nil   
end;
Код:
procedure TForm1.Button2Click(Sender: TObject);
begin
if Cur=nil
  then
    begin
     Cur:= Stek.conec;
     Label1.Caption:=Cur.inf;
    end
  else
    if Cur.prev<>nil
     then
      begin
       Cur:=Cur.prev;
       Label1.Caption:=Cur.inf;
      end
     else
       Label1.Caption:='Top of stack reached';
end;

Последний раз редактировалось Maslan; 20.10.2007 в 14:45.
Maslan вне форума Ответить с цитированием
Старый 21.10.2007, 08:42   #3
TROXEVASIN
 
Регистрация: 20.10.2007
Сообщений: 6
По умолчанию

Спасибо, Maslan. Стек было не важно FIFO или FILO. Но у меня появился ряд вопросов:

1.Из процедуры TForm1.Button1Click(Sender: TObject):
Stek.conec:=NewElem;//Здесь указателю присвоили указатель
Stek.conec.inf:=Edit1.Text;//а здесь уже, по идее Stek.conec-адрес как такое возможно?

2.Почему эти записи выдают одинаковый результат?
Stek.conec.inf
Stek.conec^.inf

3.При необходимости освободить память мне пользоваться Dispose?

Последний раз редактировалось TROXEVASIN; 21.10.2007 в 08:49.
TROXEVASIN вне форума Ответить с цитированием
Старый 21.10.2007, 20:20   #4
Maslan
Форумчанин
 
Регистрация: 15.10.2007
Сообщений: 147
По умолчанию

Цитата:
1.Из процедуры TForm1.Button1Click(Sender: TObject):
Stek.conec:=NewElem;//Здесь указателю присвоили указатель
Stek.conec.inf:=Edit1.Text;//а здесь уже, по идее Stek.conec-адрес как такое возможно?
Это возможно, т.к. Delphi автоматически умеет разыменовывать указатели, если эт неообходимо по логике. А логика тут какая? (указатель_на_класс)>поле_класса, значит можно разыменовать.

Цитата:
2.Почему эти записи выдают одинаковый результат?
Stek.conec.inf
Stek.conec^.inf
По написанному выше. Запись Stek.conec^.inf более правильная, но необязательная.

Цитата:
3.При необходимости освободить память мне пользоваться Dispose?
Код:
 <variable>.Free;
Типа 
 while Stek.conec<>nil do 
  begin
   cur:=Stek.conec;
  Stek.conec:=Stek.conec^.prev;
  cur.Free 
end;
Maslan вне форума Ответить с цитированием
Старый 22.10.2007, 09:47   #5
TROXEVASIN
 
Регистрация: 20.10.2007
Сообщений: 6
По умолчанию

Можно ли вынести описание класса c использованием указателей в dll библиотеку?
Вопрос возник по тому что процедура работает корректно в теле программы, а если ее вынести в dll она выдает какую-то ошибку.

library Classy;

uses
SysUtils,
Classes;
{$R *.res}
type
PRabota=^TRabota;
PElement=^TElement;
PStek=^TStek;
TRabota = class
Imya: String;
no: integer;
PredshRab: String;
a: integer;
b: integer;
m: integer;
SredProd: real;
D: real;
SKO: real;
Color: byte;
next: PRabota;
Stek: PStek;
end;
TElement = class
AdrRab:PRabota;
next:PElement;
end;
TStek = class
Home: PElement;
Position: PElement;
end;
TList = class
Home: PRabota;
end;
procedure RabotaADD(Imyae,PredshRabe:string;n oe,ae,be,me:integer;List:TList); stdcall;
Var Rab:PRabota;
begin
if List.Home=nil
then //Свежесозданный и будет Началом
begin
New(Rab);
Rab^:=TRabota.Create;
Rab.Color:=0;
Rab.Imya:=Imyae;
Rab.no:=noe;
Rab.PredshRab:=PredshRabe;
Rab.a:=ae; Rab.b:=be; Rab.m:=me;
Rab.SredProd:=(ae+4*me+be)/6;
Rab.SKO:=(be-ae)/6;
Rab.D:=Sqr(Rab.SKO);
List.Home:=Rab;
List.Home.next:=nil;
end
else //Свежесозданный встает в конец Стека используем FIFO
begin
Rab:=List.Home;
while Rab.next<>nil do Rab := Rab.next;
New(Rab.next);
Rab.next^ := TRabota.Create;
Rab.next.next:=nil;
Rab.next.Color:=0;
Rab.next.Imya:=Imyae;
Rab.next.no:=noe;
Rab.next.PredshRab:=PredshRabe;
Rab.next.a:=ae; Rab.next.b:=be; Rab.next.m:=me;
Rab.next.SredProd:=(ae+4*me+be)/6;
Rab.next.SKO:=(be-ae)/6;
Rab.next.D:=Sqr(Rab.next.SKO);
end;
end;

exports
RabotaADD;
begin
end.

Последний раз редактировалось TROXEVASIN; 22.10.2007 в 09:52.
TROXEVASIN вне форума Ответить с цитированием
Старый 22.10.2007, 09:53   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Какую ошибку и на какой строке?

И еще переназови свой TList по другому, ибо такой клас уже определен в Classes и могут быть баги

И еще нескромный вопрос зачем тебе использовать именно указатели на класс? почему переменную Next не сделать типа Trabota ведь это все равно станет указателем.
I'm learning to live...

Последний раз редактировалось Stilet; 22.10.2007 в 09:59.
Stilet вне форума Ответить с цитированием
Старый 22.10.2007, 11:05   #7
Maslan
Форумчанин
 
Регистрация: 15.10.2007
Сообщений: 147
По умолчанию

Пока не понятно, что за ошибка....
Может ругается на то, что передаваемый ей TList в основной проге не определён?

Код:
program Main;

{$APPTYPE CONSOLE}

uses
  SysUtils;
 type
 PRabota=^TRabota;
PElement=^TElement;
PStek=^TStek;
TRabota = class
Imya: String;
no: integer;
PredshRab: String;
a: integer;
b: integer;
m: integer;
SredProd: real;
D: real;
SKO: real;
Color: byte;
next: PRabota;
Stek: PStek;
end;
TElement = class
AdrRab:PRabota;
next:PElement;
end;
TStek = class
Home: PElement;
Position: PElement;
end;
TList = class
Home: PRabota;
end;
procedure RabotaADD(Imyae,PredshRabe:string;noe,ae,be,me:integer;List:TList); stdcall;external 'Classy.dll';

Var L:TList;
begin
 L:=TList.Create;
 RabotaADD('workname','none',1,2,3,4,L);
 WriteLn(L.Home.Imya);
 ReadLn;

end.
Только что отработала....

Последний раз редактировалось Maslan; 22.10.2007 в 11:09.
Maslan вне форума Ответить с цитированием
Старый 22.10.2007, 11:16   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Маслан, ты не верно тестишь.
А автора этот код в ДЛЛ прописан. и ошибка возникает из-за того скорее всего что в ДЛЛ тип TList определен так а в прокте, в котором автор вызывает свою процедуду TList определен по другому.

Еще раз попрошу автора перечитать мой предидуший пост внимательно.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.10.2007, 11:23   #9
Maslan
Форумчанин
 
Регистрация: 15.10.2007
Сообщений: 147
По умолчанию

Цитата:
Маслан, ты не верно тестишь.
Эм.... в чём не прав?
Я же
Цитата:
procedure RabotaADD(Imyae,PredshRabe:string;n oe,ae,be,me:integer;List:TList); stdcall;external 'Classy.dll';
Я согласен, что проблема скорее всего в TList, но считаю, что он не
Цитата:
в котором автор вызывает свою процедуду TList определен по другому
а вообще не определён.
Maslan вне форума Ответить с цитированием
Старый 22.10.2007, 11:43   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Эм.... в чём не прав?
Нет ты прав, ты описал эти типы не в ДЛЛ а в проге тут другое - автор не сказал как и где вызывает эту процу (может он ее в ДЛЛи и будет вызывать)

Цитата:
а вообще не определён.
Определен в юните Classes, который скорее всего стоит у автора там где он эту свою процу вызывает. Потому и говорю что неверно ты тестишь - у тя с твоим подходом все путем ессно.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
необходимо сделать несколько документов: акт, счет и т.п. Kisunya2104 Microsoft Office Excel 5 17.05.2009 18:35
про СТЕК anco Паскаль, Turbo Pascal, PascalABC.NET 5 06.07.2008 22:29
Стек Еленка Помощь студентам 2 06.06.2008 18:58
Стек Foky Паскаль, Turbo Pascal, PascalABC.NET 8 13.05.2008 18:39
Стек Dr.zlo Работа с сетью в Delphi 6 09.07.2007 07:59