Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / Pascal и Delphi / Borland Pascal / Использование указателей /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Управление связанным списком - Программирование от RIN.RU
Управление связанным списком

Предположим, вы хотите написать программу для ведения своих личных счетов. Вы можете хранить все данные о счетах в записях, таких как запись типа TCheck. Но при написании программы трудно предположить, с каким количеством счетов вам придется иметь дело. Одно из решений здесь состоит в создании большого массива записей счетов, но это приведет к лишним затратам памяти. Более элегантное и гибкое решение состоит в расширении определения записи и включении в нее указателя на следующую запись списка, что приведет к образованию связанного списка, показанного ниже:


type
PCheck = ^TCheck;
TCheck = record
Amount: Real;
Month: 1..12;
Day: 1..31;
Year: 1990..2000;
Payee: string[39];
Next: PCheck; { указывает на следующую запись }
end.


Пример 1. Записи в связанном списке.


Теперь вы можете считать каждую запись счета из файла и выделить для нее память. Если запись находится в конце списка, поле Next следует сделать равным nil. В вашей программе требуется отслеживать только два указателя: первый счет в списке и "текущий" счет.


Построение списка


Ниже приведена процедура, которая строит связанный список записей, считывая их из файла. Здесь подразумевается, что вы открыли файл записей TCheck и именем CheckFile, который содержит по крайней мере одну запись.


var ListChecks, CurrentCheck: PCheck;


procedure ReadChecks;
begin
New(ListOfChecks); { выделить память для первой записи }
Read(CheckFile, ListOfChecks^); { считать первую запись }
CurrentCheck := ListOfChecks; { сделать первую запись
текущей }
while not Eof(CheckFile do
begin
New(CurrentCheck^.Next); { выделить память для
следующей записи }
Read(CheckFile, CurrentCheck^.Next^); { считать
следующую запись }
CurrentCheck := CurrentCheck^.Next; { сделать следующую
запись текущей }
end;
CurrentCheck^.Next := nil; { после последней считанной
записи следующей нет }
end.


Пример 2. Построение связанного списка.




Перемещение по списку


Когда у вас есть список, вы можете легко выполнять поиск в нем конкретной записи. В Примере 8.9 показана функция, которая находит первый счет с конкретной суммой и возвращает указатель на него.


function FindCheckByAmount(AnAmount: Real): PCheck;
var Check: PCheck;
begin
TempCheck := ListOfChecks; { указывает на первую запись }
while (Check^.Amount <> AnAmount) and
(Check^.Next <> nil) do
Check := Check^.Next;
if Check^.Amount = AnAmount then
FindCheckByAmount := Check { возвращает указатель на
найденную запись }
else FindCheckByAmount := nil; { или nil, если таких
записей нет }
end;


Пример 3. Поиск в связанном списке.


Освобождение выделенной для списка памяти


Как показано в процедуре DisposeChecks в Примере 4, вы можете перебрать список, дойдя до каждого элемента и освободив его.


procedure DisposeChecks;
var Temp: PCheck;
begin
CurrentCheck := ListOfChecks; { указывает на первую
запись }
while CurrentCheck <> nil do
begin
Temp := CurrentCheck^.Next { сохранить указатель Next }
Dispose(CurrentCheck); { освобождение текущей записи }
CurrentCheck := Temp; { сделать сохраненную запись
текущей }
end;
end;


Пример 4. Освобождение памяти для связанного списка.






 8  Комментарии к статье  8 8  Обсудить в чате

8  В тему

Для чего используются указатели?

Работа с большими объемами данных

Работа с данными неизвестного размера

Работа с временными буферами данных

Связанные списки

Выделение памяти для динамических переменных

Процедуры GetMem и FreeMem

Общие проблемы использования указателей

Потери динамически распределяемой памяти

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь