Страница 1 из 2

Динамическая память. Помогите

Добавлено: 06 июн 2008, 10:11
Oleg_Rus
Надо написать лабораторку со списками. Я написал такой код:

uses Crt;

type TBook= ^TPBook;
TPBook= record
Title: String[40];
Author: String[40];
Year: String[4];
NBook: TBook;
end;
var First, Book: TBook;

Procedure InputBook(First: TBook);
var str: String;
Number: Integer;
begin
New(First);
Write('‚Введите название книги: ');
Readln(Str);
First^.Title:=Str;
Write('‚Введите автора книги: ');
Readln(Str);
First^.Author:=Str;
Write('‚Введите год издания: ');
Readln(Str);
First^.Year:=Str;
New(Book);
First^.NBook:=Book;
end;

Procedure OutputBook(First: TBook);
begin
Writeln('Название: ', First^.Title);
Writeln('Автор: ', First^.Author);
Writeln('Год издания: ', First^.Year);
end;

begin
InputBook(First);
InputBook(Book);
OutputBook(First);
OutputBook(Book);
end.

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 10:37
Игорь Акопян
и чё? запутались с объявлениями и типами? я тоже :)

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 11:25
MOTOCoder
Вообще, структура элемента списка должна быть такой:
[syntax='Delphi']
Type
PBook=^TBook;

Type
TBook=Record;
Year:Integer;
Title:string[40];
Author:String[40];
{прочие данные}
Link:PBook;{Ссылка на следующий элемент, обратите внимание, PBook, а не TBook}
end;



[/syntax]

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 16:45
Oleg_Rus
да ващще надо организовать двунаправленный список, а я даже однонаправленный построить не могу...

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 16:46
Oleg_Rus
если сможете, мужики, помогите с объяснениями. мне еще перед преподом откусаться надо....

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 17:17
MOTOCoder
Вот откопал у себя пример работы со списком:
[syntax='Delphi']
program Lists;

type
PListItem=^TListItem;
TListItem=record
rData:real;
sData:string[20];
Link:PListItem;
end;

var
P:PListItem;
I:integer;
S:integer;

function ListSum(Root:PListItem):Real;
var
Item:PListItem;
sum:Real;
begin
Item:=Root;
Sum:=0;
while Item<>nil do
begin
Sum:=Sum+Item^.rData;
Item:=Item^.Link;
end;
ListSum:=Sum;
end;

function StoreData:PListItem;
var
X,Y,R:PListItem;
i:integer;
begin
New(X);
X^.rData:=1;
New(Y);
Y^.rData:=2;
X^.Link:=Y;
R:=X;
for I:=3 to 10 do
begin
New(X);
X^.rData:=I;
Y^.Link:=X;
Y:=X;
end;
StoreData:=R;
end;

begin
for i:=1 to 10 do
Inc(S,I);
writeln(S);
P:=StoreData;
writeln(ListSum(P):0:0);
readln;
end.

[/syntax]

Двунаправленый список, как я понимаю, должен содержать еще и ссылку на предыдущий элемент.

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 17:22
Serge_Bliznykov
MOTOCoder, ну, Ваш вариант наименований получше, но это же НЕ ПРИНЦИПИАЛЬНО (я про организацию динамического списка).
у Вас:

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

PBook=^TBook;
TBook=Record; 
  Link:PBook
у автора вопроса:

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

TBook= ^TPBook;
TPBook= record
  NBook: TBook;
помоему - одно и то же... ;-)


Oleg_Rus, а ошибка (точнее ошибки) в другом:
1) путаемся что такое передаваемые параметры и глобальные переменные
в процедуру передаётся First и там же работа с глобальной Book (которая, кстати, передатся в процедуру в качестве параметра?!!!!

2) главное, непонимание зачем же в динамическом списке ссылка на следующую книгу (NBOOK)...

смотрите, логика работа со список такая - храним ссылку на головной элемент (на первую книгу), для удобства добавления можно хранить ссылку на последнюю добавленную книгу (но можно и не хранить, тогда ссылку на последнюю книгу всегда можно получить перебрав все записи, начиная с головы!)
Ну что, теперь сами исправите программу или помочь?...

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 17:24
Serge_Bliznykov
Да... пока писал ответ, тут уже почти всё решили и без меня...

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 17:25
MOTOCoder
Да, действительно никакой разницы, сам запутался. Просто привык, что в Delphi обычно P используется при описании указателей.

Re: Динамическая память. Помогите

Добавлено: 06 июн 2008, 17:33
Serge_Bliznykov
не знаю, насколько это Вам будет полезно, но вот, кстати, из чужой лабы кусочек..

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

Const  
   n_items=7; 
   l_name=30; 
   Type 
   tname=string[l_name]; 
   pMan=^Man; 
   Man=record 
      name:tname;  
      birth:integer;  
      pay:real;  
      next :p Man;  
      prev :p Man;  
   end;  
Var  
   DefaultMode,ActiveColor,InactiveColor:word;  
   key:char; 
   item:word; 
   prev:word; 
   beg :p Man; 
   fin :p Man; 
   p :p Man; 
   name:tname; 
   person:Man; 
  
 
procedure Add(var beg,fin :p Man; const person:Man);  
   var p :p Man; 
   begin  
      new(p); 
      p^:=person; 
      p^.next:=nil; 
      p^.prev:=fin;  
      if beg=nil  
         then beg:=p 
         else fin^.next:=p; 
 
      fin:=p; 
   end;  

........

procedure Del(var beg,fin,p :p Man); 
   begin  
      if (p=beg) and (p=fin) then 
         begin  
            beg:=nil;  
            fin:=nil;  
         end  
         else  
            if p=beg then 
               begin  
                  beg:=beg^.next;  
                  beg^.prev:=nil;  
               end  
               else 
                  if p=fin then  
                     begin  
                        fin:=fin^.prev;  
                        fin^.next:=nil;  
                     end  
                     else 
                        begin  
                           p^.prev^.next:=p^.next;   
                            p^.next^.prev:=p^.prev; 
 
                        end;  
      dispose(p); 
   end;  

procedure ReadFile(var beg,fin :p Man); 
   var  
      f:text;  
      person:Man;  
   begin  
      {$I-} 
      assign(f,'dbase.txt');
      reset(f);  
      if(IOResult<>0) then Error('Oaee dbase.txt ia iaeaai!');  
      {$I+}  
      while not eof(f) do  
         begin  
            with person do readln(f,name,birth,pay);  
            Add(beg,fin,person);      {aiaaaeaiea yeaiaioa a nienie}  
         end;  
      close(f);  
   end;  
  

Begin  
   beg:=nil;  
   fin:=nil;  
   ReadFile(beg,fin); 
....
end.