
- •Методичні вказівки для допомоги студентам у вивченні самостійних тем з предмету
- •Урок № 6
- •Особливості інтегрованого середовища програмування Turbo Pascal. Основні пункти меню
- •Урок № 13
- •Поняття рекурсії. Зовнішні оголошення та оголошення процедур та функцій з випередженням
- •Урок № 14
- •Особливості роботи в текстовому режимі
- •Урок № 20
- •Сортування масиву. Методи сортування масиву
- •Урок № 21
- •Рекурсивне сортування масиву методом вибору
- •Урок № 21
- •Алгоритми роботи з двомірними таблицями на мові програмування Pascal
- •Урок № 25
- •Приклади опису багатомірних масивів засобами мови програмування Pascal
- •Урок № 26
- •Робота з елементами двомірного масиву
- •Урок № 27
- •Записи. Види записів. Робота з записами
- •Урок № 30
- •Множини. Дії над множинами
- •Урок № 32
- •Запис/читання файлу. Маніпуляції вмістом файлу
- •Урок № 33
- •Типізовані файли. Текстові файли. Нетипізовані файли
- •Урок № 37
- •Динамічні данні без внутрішніх посилань
- •Урок № 42
- •Робота з кольорами
- •Урок № 43
- •Робота з координатами
- •Урок № 44
- •Принцип виведення точки та лінії на екран
- •Урок № 45
- •Принцип побудови не заповнених геометричних фігур
- •Урок № 46
- •Принцип побудови заповнених геометричних фігур
- •Урок № 47
- •Виведення тексту в графічному режимі
- •Урок № 50
- •Використання модуля mouse Питання для вивчення:
- •Урок № 51
- •Принципи побудови графічного зображення, що рухається
- •Урок № 52
- •Модуль Graphs3d
Урок № 37
(згідно робочої навчальної програми)
Динамічні данні без внутрішніх посилань
Питання для вивчення:
Динамічні структури даних.
Статичні і динамічні змінні.
Адреси.
Покажчики та їх оголошення.
Динамічні структури даних. У будь-якій обчислювальній системі пам'ять відноситься до таких ресурсів, яких завжди не вистачає. Управління пам'яттю - одна з головних турбот програміста, так як для нього дуже важливо створювати програми, ефективно використовують пам'ять, адже під час виконання програми пам'ять необхідна для наступних елементів програм і даних:
сама програма користувача;
системні програми часу виконання, які здійснюють допоміжні дії при роботі програми користувача;
визначені користувачем структури даних і константи;
точки повернення для програм;
тимчасова пам'ять для зберігання проміжних результатів при обчисленні виразів;
тимчасова пам'ять при передачі параметрів;
буфери вводу-виводу, використовувані як тимчасові області пам'яті, в яких зберігаються дані між моментом їх реальної фізичної передачі з зовнішнього пристрою або на нього і моментом ініціалізації в програмі операції введення або виведення;
різні системні дані (інформація про статус пристроїв введення-виведення та ін.).
З цього переліку видно, що управління пам'яттю стосується широкого класу об'єктів.
Якщо в програмі на потрібний програмний об'єкт ми посилаємося на ім'я А [3], то машинний код містить посилання на номер комірки пам'яті (адреса байта), починаючи з якої розміщується цей об'єкт. Адреси задаються двома 16-тіразряднимі словами (тип word) - сегментом і зміщенням. Кожне з них здатне адресувати 216 = 65536 байт (64 Кбайт). Для адресації простору розміром в 1 Мбайт потрібно 20 розрядів. Сегменти адресують пам'ять з точністю до параграфа - фрагмента пам'яті в 16 байт. Зсув адресує пам'ять з точністю до байта, але впределах сегмента. Реальний (абсолютний) адреса складається із значення сегмента, зрушеного на 4 розряди вліво (помноженого на 16), і зміщення. Фрагмент програми обчислення абсолютної адреси в реальному режимі:
Var
Segment, Offset: word;
Address: LongInt;
. . .
Address: = Segment * 16 + Offset;
Програма на Паскалі отримує один сегмент даних, тому область пам'яті, в якій можуть бути розміщені статичні змінні Вашої програми, обмежена 64 Кбайтами. При спробі виконати програму, що вимагає більшого розміру пам'яті, буде видана помилка:
Error 49: Data Segment too large {Занадто великий сегмент даних}
При динамічному розподілі пам'яті Ви можете запросити блоки розміром до одного сегмента (64 Кбайт) кожен, причому їх можна вимагати в межах основної пам'яті (640 Кбайт) в реальному режимі і без програмних обмежень в захищеному.
Бувають такі дані, розмір яких з'ясовується тільки при виконанні програм. Крім того, іноді ми не знаємо, буде існувати певний об'єкт чи ні.
Наприклад, у програмі для обробки текстів (такі програми називаються "текстовими процесорами") потрібно організувати пошук слів, визначених користувачем. Природно, що визначити заздалегідь довжину слова, яке буде задано, неможливо. Часто програмний об'єкт, причому значного розміру, буває потрібен на нетривалий час. Використання статичних програмних об'єктів в таких випадках дуже неефективно, оскільки програма має бути розрахована на максимальні розміри об'єктів. Область пам'яті, в якій можуть бути розміщені статичні змінні, обмежена, і, розраховуючи на максимальний розмір змінних, ми обмежуємо їх кількість. У Паскалі, крім статичних, передбачені динамічні об'єкти. Пам'ять під них відводиться під час виконання програми, а коли програмний об'єкт можна видалити, пам'ять звільняється.
І статичні, і динамічні змінні викликаються по їх адресами. Без адреси не отримати доступ до потрібної комірки пам'яті, але, використовуючи статичні змінні, безпосередньо адресу Ви не вказуєте, а звертаєтеся до змінної по імені. Компілятор розміщує змінні в пам'яті і підставляє потрібні адреси в коди команд.
Адресація динамічних змінних відбувається через покажчики. У Паскалі можна визначити змінні, які мають тип покажчик, їх значення визначають адресу об'єкта. Для роботи з динамічними змінними в програмі повинні бути передбачені:
виділення пам'яті під динамічну змінну;
привласнення вказівником на динамічну змінну адреси виділеної пам'яті (ініціалізація покажчика);
звільнення пам'яті після використання динамічної змінної.
Програміст сам повинен резервувати місце під змінну, визначати значення покажчиків, звільняти пам'ять - видаляти динамічні змінні. Для використання динамічної змінної десь у статиці повинен бути вказівник на неї. Компілятор передбачає місце під покажчик, про ініціалізації покажчика має дбати програміст.
Замість будь-якої статичної змінної можна використовувати динамічну, але без реальної необхідності цього робити не варто. Змінні простих типів немає сенсу розміщувати в динамічній області, оскільки вони займають менше місця, ніж покажчик на них. Наприклад, покажчик на ціле займає 4 байти, саме ціле - 2 байти. Крім того, при динамічному розподілі пам'яті подовжується текст програми, знижуються наочність і швидкодію. Це пояснюється тим, що, по-перше, потрібно під час виконання програми визначати значення покажчиків, а по-друге, ускладнюється доступ до значення змінної.
Покажчики та їх оголошення. Для роботи з динамічними програмними об'єктами в Паскалі передбачений контрольний тип або тип покажчиків. В змінної посилального типу зберігається посилання на програмний об'єкт (адреса об'єкта). Покажчик складається з сегменту і зсуву. За правилами Паскаля покажчики на різні типи даних мають різні типи, причому ці типи несумісні, тобто покажчики на різні типи даних не можуть посилатися на один об'єкт.
Щоб зв'язати контрольний тип з певним типом даних, використовується символ ^, що поміщається перед ім'ям типу. Наприклад, є тип масив:
Type
A = Array [1 .. 100] of integer;
Тип покажчика на такий об'єкт:
Type
tA = ^ A;
Змінні посилального типу можуть визначатися як статичні, при цьому за загальними правилами оголошення змінних можливий запис з явним і неявним визначенням посилального типу.
Type
A = Array [1 .. 100] of integer; {Тип масив з 100 цілих чисел}
tA = ^ A; {Тип покажчик на тип А}
Var
B: tA; {Покажчик на тип А}
C: ^ A; {Покажчик на тип А}
Для отримання даних, відповідних покажчику, символ "^" наводиться після імені покажчика. Дії з елементами масиву типу А можуть бути описані через дії над покажчиками В і С.
B ^ [i]: = i; {i-му елементу масиву, на який вказує В, присвоїти значення i}
C ^ [i]: = B ^ [i]; {i-му елементу масиву, на який вказує С, присвоїти значення i-го елемента масиву, на який вказує В}
Після виконання цього коду i-е елементи масивів, на які вказують В і С, будуть рівні. Покажчики можуть посилатися на будь-який тип даних, крім файлового. Розберемо простий приклад, звернувши ще раз увагу на синтаксис:
Var
P: ^ integer; {Покажчик на ціле}
P ^ - мінлива цілого типу, на яку посилається Р, вона може стояти як в лівій, так і в правій частині виразів:
P ^: = 16;
x: = x + P ^;
Перший оператор присвоює цілочисельний змінної, на яку посилається Р, значення 16, другий додає до значення змінної х значення 16, другий додає до значення змінної х значення 16. Аналогічно визначаються і використовуються покажчики на змінні будь-якого типу, в тому числі і визначеного користувачем.
Питання для контролю вивченого матеріалу:
Що являють собою динамічні дані?
Опрацюйте матеріал, розробіть власну програму.
Література:
Меженний О.А.Turbo Pascal: М: Издательский дом «Вильямс», 2006. – 336 с., стор. 153-157