русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


ТИП POINTER.


Дата додавання: 2013-12-23; переглядів: 1393.


Зсилочнии тип.

Зсилочний тип призначений для забезпечення зсилок на інші дані і називається вказівником. Вказівники використовуються для динамічної побудови складних структур даних.

Адресований простір пам'яті в ОС MS-DOS організовано сегментами: послідовними блоками пам'яті по 64 К кожен. Якщо відомий сегмент, то подальше уточнення місця об'єкту в пам'яті проходить по його зміщенню, тобто номеру байту від початку сегменту. Довільна комірка адресованого простіру MS-DOS визначається парою чисел-сегмент: зміщення (при цьому сегмент може починатися з любої фізичної адреси). Сукупну адресу комірки можна одержати наступним чином:

Сукупна адреса = сегмент* 16+зміщення;

Якщо обчислена сукупна адреса комірки пам'яті, то її можна перевести в нормалізований формат:

Сегмент = сукупна адреса div 16;

Зміщення = сукупна адреса mod 16;

Для збереження сукупних адрес рекомендується використовувати тип Longint.

В ТР можна також використовувати не типізовані вказівними, які на відміну від типових, не зв’язані з конкретним типом, вживаючи слово Pointer.

Наприклад:

Var p:pointer; (змінна — вказівник);

Значення цього типу займає 4 байти пам'яті і містить адресу якої-небудь комірки пам’яті. Адреса зберігається як два слова: одне з них визначає сегмент, інше - зміщення.

Значення вказівника не може бути в явному вигляді виведене на екран чи друк, його потрібно попередньо розшифрувати. Для роботи з вказівниками вводиться спеціальний набір функцій. Крім того, вказівники повністю сумісні з зсилочним типом і можуть використовуватись як зсилки (з уточненням). Вказівники можуть обмінюватися значеннями за допомогою операторів присвоювання та порівнюватися (= або <>).

Два вказівника вважаються однаковими, якщо в них записані одинакові значення сегменту та зміщення, в інших випадках вони вважаються нерівними. Якщо ми хочемо вказати в програмі на значення по вказаному в змінній типу pointer адресі, то необхідно використовувати символ ^ після імені вказівника: р^ - ця операція називається операцією розіменування.

Розглянемо операції, які з успіхом застосовуються при роботі і з зсилками і динамічними змінними:

1. Addr(x):pointer; - функція вказівника на початок об'єкту х в пам яті.

2.Seg(x):word; - функція, яка повертає сегмент для об'єкта х.

3.Ofs(x):word; - функція, що повертає зміщення для об'єкту х.

4.@x:pointer; - повертає вказівник на початок об'єкту х в пам'яті (аналог першої функції).

Всі вони повертають адресу об'єкту х або компоненти адреси. Під х можна розуміти любий об'єкт: змінні довільних типів, процедури і функції, але не константи. Перша функція і четверта операція виконують однакові дії. Вони потрібні для прив'язки вказівників, тобто динамічних змінних до статичних даних, а також для роботи з масивами даних в вигляді .obj -файлів, зв'язаних з файлом, який виконується на етапі компіляції. Значення типу pointer не може бути виведено на екран, але так як цей тип складається з двох слів, що зберігають сегмент та зміщення, то їх можна вивести на екран окремо, використовуючи функції Seg і Ofs.

Writeln('сегмент', Seg(P), 'зміщення', Ofs(P));

Якщо р - зсилка, тo Addr(p), @(р), Seg(p), Ofs(p) повернуть адресу або сегмент та зміщення самої змінної - зсилки р в області статичних даних; функції з вказівником (Addr{p^),@ (р^) , Seg(p^)} Ofs(p^)) повернуть зміст зсилки р:

p=Addr(p^);

Розглянемо дії оператора @ з різними типами змінних. При використанні @ з глобальними змінними, або типізованими константами оператор поверне адресу цих змінних, як правило в сегментах даних. При використанні його в середені процедури чи функції з параметрами -змінними, оператор @ поверне адреси фактичних змінних, що підставляються при виклиці процедур чи функцій. Застосування @ до параметру - значення як і до довільної локальної змінної дасть адресу в стеку, де тимчасово знаходяться значення. Можна застосовувати його і

до ідентифікаторів процедур і функцій. Це дасть точку входу в процедуру чи функцію.

5.Ptr(s,o:word):pointer;

Дана функція виконує протилежну роботу Addr, а саме організує вказівник на місце в пам'яті, що визначене заданими сегментом та зміщенням. Необхідність в ній виникає всякий раз, коли необхідно накласти динамічну структуру на системну область пам'яті.

Приклад:відомо, що образ текстового екрану починається з адреси $В000 і займає 4000 байт. Необхідно накласти на нього структуру — масив, використовуючи зсилку на такий масив і функцію Ptr.

Type VideoArray = array[0..3999] of byte;

Var V:^Ptr($B0000);

Begin

V:=^ptr($B000,0);

{дані V^ [і] звертається безпосередньо до комірок відеопам'яті в текстовому режимі}

………………..

end.

В цьому фрагменті немає виклику New і Dispose. Вони тут не потрібні, так як масив буквально накладається, а не створюється заново. Так як значення типу pointer, що повертається функцією Ptr сумісне з усіма вказівниковими типами, то можна накласти любу структуру на яку-завгодно ділянку пам'яті. Крім того його, дозволяється розіменовувати, тобто записувати:

 

Ptr($40,$40)^;

Але в чистому вигляді така конструкція має мало змісту, тому що не визначена структура на перший байт, що вказує це розіменування. Визначити цю структуру можна операцією приведення типів:

В: =Byte(Ptr($40, $40)^); {В - значення байту}

W: = Word(Ptr($40, $40)^); {W- значення слова)

X: =VideoArray(Ptr($40,$40)^);

х - це статичний масив типу VideoArray, що містить в собі образ відеопам'яті (текстове зображення). Не варто зводити лише до типу String, так як ніколи не відомо, що виявиться в нульовому елементі рядка, де повинен зберігатись її реальний розмір.

6. SizeOf(x):WORD;

Ця функція повертає об'єм в байтах, що займає х. Причому х може бути не просто змінною, але також і ідентифікатором типу.

Значення SizeOf(рядок) завжди дасть максимальне значення довжини рядка, а реальне дасть функція Length.

7. CSEC: word;

Повертає значення, що зберігається в регістрі CS мікропроцесора (на початку роботи програми в регістрі міститься сегмент початку коду програми:

8. DSEC: word;

Повертає значення, яке зберігається в регістрі DS міститься сегмент початку даних програми:

9. MemaVall: LongInt;

Повертає розмір в байтах загального вільного простору кучі.

10. MaxaVall: LongInt;

Повертає розмір в байтах найбільшого безперервного участка в кучі.

Необхідність в динамічних структурах виникає:

а) При використанні змінних, які мають доволі великий розмір, при цьому необхідні в одних частинах програми і зовсім не потрібні в інших;

б) В процесі роботи програми потрібен масив або інша структура, розмір якої змінюється в широких межах, що важко передбачити;

в) Коли розмір змінної (масиву чи запису) перевищує 64 К. Основним механізмом для організації динамічних даних являється виділення в спеціальній області пам’яті, що називається кучою, суцільної ділянки потрібного розміру і збереження адреси початку цієї ділянки в спеціальній змінній. Такі змінні називаються вказівниковими..

В ТР для визначення вказівникової змінної потрібно описати її як змінну, що має вказівниковий тип. В якості вказівникового можна використовувати вбудований тип pointer, або інший довільний тип, що визначається користувачем наступним чином:

Туре ім'я_вказівпикового_типу = ^iм'я_базового_типу;

де ім'я_базового_типу - це любий ідентифікатор типу. В результаті цього визначення, створені потім вказівникові змінні будуть вказувати на об'єкти базового типу, визначаючи тим самим динамічні змінні базового типу.

Наприклад:

Туре

DimType =array[1..1000] of real;

RecType=record

………………..

end;

IntPtr=^integer; {вказівник на цілі числа}

DimPtr=^ DimType; (на масив}

RecPtr=^RecType; {на запис}

XXXPtr=Pointer; {зсилка-вказівник}

Домовимось називати надалі вказівником, ті змінні, які мають узагальнений тип Pointer.

Цей тип сумісний з усіма зсилочними типами. Всі зсилочні змінні мають одинаковий розмір, що дорівнює 4 байти і містить адресу початку ділянки оперативної пам'яті, в якому міститься динамічна структура даних. Щоб зсилка ні на що не вказувала їй присвоюється значення Nil. Це визначена константа типу Pointer, що відповідає адресі 0000:0000.


<== попередня лекція | наступна лекція ==>
ВКАЗІВНИКИ. | ОПЕРАЦІЇ РОЗІМЕНУВАННЯ.


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн