Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4 основи програмування книга.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.77 Mб
Скачать

13.2. Посилальний тип даних. Посилання

Значеннями посилального типу даних є посилання (покажчики) на інші дані. Посилальні типи описуються у розділі типів наступним чином:

Type <ім’я посилального типу > = ^ <ім’я базового типу >

Ім’я змінної може бути зв’язано з описанням її типу безпосередньо в розділі змінних, або з іменем типу, вже описаного в розділі типів. Стиль мови віддає перевагу явному використанню імен типів.

Приклади описань:

1. Type

Vector = Array[1..100] of Integer;

Place = ^ Vector;

Var

a, b: Place;

або

Var

a, b: ^ Array[1..100] of Integer;

2. Type

Item = Record

Name: String[20];

Age: Integer

end;

Point = ^ Item;

Var

x, y: Point;

Якщо p – покажчик на змінну типу Т, то p^ – позначення самої цієї змінної. Ця система позначень може бути продемонстрована так:

з мінна типу ^T змінна типу T

Рис. 13.9. Покажчики на змінні та змінні.

Ще раз укажемо на те, що при описанні посилальної змінної p пам’ять резервується тільки для неї. Значенням p по суті є початкова адреса розміщення p^ у пам’яті.

Для резервування пам’яті під дане типу Т^ у мові використовується процедура New.

New (< змінна посилального типу >)

Виконання процедури New(p) полягає у заповненні комірки пам’яті, відведеної під змінну p початковою адресою ділянки пам’яті, в якій буде розміщено значення p^. Розмір цієї ділянки визначається типом змінної p.

Для звільнення пам’яті, відведеної раніш під T^, використовується процедура Dispose.

Dispose(<змінна посилального типу>)

Приклад 13.3.

Program ExamNewDis;

Type

Vector = Array[1..100] of Integer;

Place = ^Vector;

Item = Record

Name: String[20];

Age: Integer

end;

Point = ^Item;

Var

a, b: Place;

x, y: Point;

i: Integer;

Begin

New(x);

New(y);

Read(x^.Name);

Read(x^.Age);

y^ := x^;

Dispose(x);

New(a);

For I:= 1 to 100 do a^[i] := Sqr(i)+1;

b := a;

Dispose(a);

End.

Тут при зверненні до процедури New(x) буде відведено 22 байта під x^, при виконанні New(y) - 22 байта під y^, а при виконанні New(a) - 200 байт під a^. (Ми вважаємо, що під ціле число відводиться 2 байта). Оператор y^ := x^ пересилає дані з запису x^ у запис y^. Пам’ять, яку займає x^, звільняється оператором Dispose(x). Для переводу покажчика з одного даного на інше використовується оператор присвоювання. Нехай, наприклад, p і q - змінні одного посилального типу і має місце ситуація

P

Q

Тоді після виконання оператора p := q схема зміниться:

P

Q

Рис. 13.10. Виконання оператора присвоювання з покажчиками.

Зверніть увагу на те, що дані, на які до присвоювання посилалась p, стають недоступними! У прикладі, що розглядається, посилання b встановлено оператором b := a на масив a^. Тому оператор Dispose(a), звільняючи пам’ять, позбавить захисту не тільки масив a^, але й масив b^! Тому наступний оператор New може розмістити дані на місці масиву b.

На прикладах з інформаційними динамічними структурами ми бачили, що деякі поля посилальних типів можуть бути не заповнені посиланнями на інші записи, причому програміст повинен явним чином це вказувати. Для цього використовується стандартне ім’я Nil. (Після виконання операторів p := Nil; q := Nil покажчики p і q вказують на одне й те ж дане – у нікуди!)