- •Лабораторна робота №17
- •Теоретичні відомості.
- •Об'являються вказівники так:
- •Операції з вказівниками
- •Процедури для роботи з вказівниками
- •Функції для роботи з вказівниками і адресами
- •1. Приклад програми створення і видалення черги з десяти елементів.
- •2. Приклад програми створення і видалення стека з десяти елементів.
- •Виключення даних із списку
- •Практична частина
Функції для роботи з вказівниками і адресами
Addr(x):Pointer - повертає адрессу зазначеного об'єкта;
Ofs(X):Word - повертає значення зміщення об'єкта Х;
Seg(X):Word - повертає значення сегмента об'єкта Х;
Ptr(Segment,Offset:Word):Pointer - перетворить окремо задане значення сегмента і зміщення до типу "вказівник";
MaxAvail:Longint - повертає розмір найбільшої безперервної (постійної) ділянки пам'яті в хіпі;
MamAvail:Longint - повертає cуму всіх вільних ділянок пам'яті в хіпі;
CSeg:Word - повертає поточне значення регістра Cs;
DSeg:Word - повертає поточне значення регістра Ds;
SSeg:Word - повертає поточне значення регістра Ss;
SPtr:Word - повертає поточне значення регістра Sp.
Приклади.
1. Приклад програми створення і видалення черги з десяти елементів.
У ній для роботи з чергою використовуються дві процедури:
1) procedure AddEl, що у залежності від стану черги створює перший чи додає черговий елемент у кінець черги;
2) procedure GetDelEl, що витягає інформацію з початкового елемента черги з наступним звільненням його пам'яті.
program Queue;
uses Crt;
type
TPtr = ^TElem;
TElem = record
Inf : Real;
Link : TPtr
end;
var
BegQ, EndQ : TPtr;
Value : Real;
i : Byte;
procedure AddEl (Val : Real);
var
P : TPtr;
begin
New (P);
P^.Inf := Val;
P^.Link := nil;
if EndQ = nil { якщо створюється перший елемент черги }
then BegQ := P
{ якщо створюється черговий елемент черги }
else EndQ ^.link := P;
EndQ := P
end;
procedure GetDelEl( var Val : Real);
var
P : TPtr;
begin
Val := BegQ^.Inf;
P := BegQ;
BegQ := P^.Link;
if BegQ = nil { если удаляется последний элемент очереди }
then EndQ := nil;
Dispose (P)
end;
Begin
ClrScr;
{ Початкові установки вказівників }
BegQ := nil;
EndQ := nil;
{ Створення черги из 10-ти елементів }
for i := I to 10 do AddEl (i) ;
{ Видалення черги з роздруківкою значень її елементів}
while BegQ <> nil do
begin
GetDelEl (Value);
Writeln ( 'Value = ', Value :5 :2 )
end
End.
2. Приклад програми створення і видалення стека з десяти елементів.
У ній для роботи зі стеком використовуються дві процедури:
Процедура, що, у залежності від стану стека, створює перший чи додає наступний елемент у стек (procedure Push).
Процедура, що витягає з вершини стека інформацію і потім звільняє пам'ять (procedure Рор)..
Помітимо, що на відміну від процедур AddEl і GetDelEl для черги, у процедурах Push і Pop не треба було особливо виділяти випадки створення першого і видалення останнього елементів стека, тому що при вихідному значенні Тор = nil цим випадкам відповідають такі ж самі послідовності операторів, як і для додавання і видалення чергового елемента стека.
program Stack;
uses Crt;
type
TPtr = ^TElem;
TElem = record
Inf : Real;
Link : TPtr
end;
var
Top : TPtr;
Value : Real;
I : Byte;
procedure Push (Val : Real);
var
P : TPtr;
begin
New (P);
P^.Inf := Val;
P^.Link := Top;
Top := P
end;
procedure Pop (var Val : Real);
var
P : TPtr;
begin
Val := Top^.Inf;
P := Top;
Top := P^.Link;
Dispose (P)
end;
Begin
ClrSor;
{ Початкові установки вказівників }
Top := nil;
{ Створення стека із 10-ти елементів }
for i := 1 to 10 do Push (i);
{ Видалення стека з роздруківкою значень його елементів }
while Top <> nil do
begin
Pop (Value);
Writeln ( 'Value = ', Value :5 :2 )
end;
End.
3. Приклад побудови пов'язаного списку.
Такі списки широко застосовуються на практиці :
у багатовіконних системах кожному вікну відповідає запис
записи пов'язані в список;
в екранних редакторах рядки пов'язані в двонаправлений список.
У даній програмі елементами списку є записи з полями:
Name (прізвище співробітника), Year (рік народження), Salary (його річний прибуток). Next-- вказівник на наступний елемент списку.
Програма вводить дані з клавіатури (ознака кінця списка- порожній рядок замість прізвища чергового співробітника), роздруковує їх і звільняє, пам'ять, видаляючи список із пам'яті.
Program dinmam_pointer;
Uses crt;
Type
ListPtr=^List;
Str40=String[40];
List = Record
Name : Str40;
Year : Word;
Salary : real;
Next : ListPtr;
End;
Var
Start : Pointer; { Вказівник на початок списку }
CurPtr, LastPtr : ListPtr;
CurName : Str40;
NameLen : Byte Absolute CurName;
Begin
ClrScr;
Start:=Nil; {Поки список пустий}
Write(‘Прізвище: ');
Readln(CurName);
While NameLen>0 do
begin
New(CurPtr); { розподіл пам'яті під елемент }
If Start=Nil
Then Start:=CurPtr
{ при першому виконанні циклу встановили адресу початку списку}
Else LastPtr^.Next:=CurPtr;
{при другому і наступних виконаннях циклу в попередньому елементі (LastPtr^) у поле Next поставили адресу такого (CurPtr) елемента списку}
CurPtr^.Name:=CurName;
Write('Рік народження :');
Readln(CurPtr^.Year);
Write('Годовой доход :');
Readln(CurPtr^.Salary);
LastPtr:=CurPtr;
Write('Прізвище: ');
Readln(CurName);
end;
If Start<>Nil
Then CurPtr^.Next:=Nil;
{якщо було введено хоча б один елемент списку, то в останньому елементі в поле Next ставимо значення Nil - ознака кінця списку }
{ Друкування елементів списку }
Writeln;
CurPtr:=Start;
While CurPtr<>Nil Do
With CurPtr^ Do
begin
Writeln(Name:40,Year:6,Salary:12:2);
CurPtr:=Next; { перехід до наступного елемента списку }
end;
{ Видалення з пам'яті елементів списку }
CurPtr:=Start;
While CurPtr<> Nil Do
begin
LastPtr:=CurPtr^.Next; { наступний елемент }
DisPose(CurPtr);
CurPtr:=LastPtr; {перехід до наступного елемента списку}
end;
Readln;
End.
4. Приклад програми, що вводить із термінала назву підручників (кінець списку характеризує введення символу "прогалина"), динамічно відводить місце в пам'яті під кожну назву і будує з них пов'язаний список, упорядкований за алфавітом. По закінченні формування каталог книг виводиться на екран. Використання спискових структур дозволяє:
виключити попереднє резервування пам'яті;
дає можливість сортувати список одночасно з введенням;
дозволяє спрощувати подальшу роботу з даними (достатньо просто дозволяє виключати не потрібні і добавляти нові елементи).
program Sort_spis;
uses crt;
сonst k=3;
type
nazv=string[25];
ssylka=^element;
element=record
ss:ssylka;
dan:nazv;
end;
var
kniga:nazv;
nach,tek,ob,obpr:ssylka;
i:integer;
Begin
clrscr;
{Формування 1-го елемента списку}
New(nach);
readln;
writeln('Введіть перше найменування. ');
readln(kniga);
nach^. ss:= nil;
nach^. dan:=kniga;
{Формування списку}
while kniga<>' 'do
begin
tek:=nach;
new(ob);
writeln('Введіть чергову назву ');
readln(kniga);
{Пошук підхожого місця}
while (tek<>nil) and (tek^. dan<kniga) do
begin
obpr:=tek; {Посилання на попередній елемент}
tek:=tek^. ss {Перехід до наступного елемента}
end;
{Вставка нового елемента}
ob^. ss:=tek;
ob^. dan:=kniga;
if tek=nach
then nach:=ob
else obpr^. ss:=ob
end; {Кінець формування списку}
{Виведення на екран упорядкованого списку книг}
writeln('Каталог підручників ');
tek:=nach;
while tek^. ss<>nil do
begin
writeln(tek^. dan);
tek:=tek^. ss
end;
readln;
end.
