Published using Google Docs
Інформатика 10 (АП) Урок 95
Updated automatically every 5 minutes

Урок  95                                                                        Інформатика (АП)


Покажчики; використання динамічної пам’яті.


Мета.

Навчальна. Ознайомлення з додатковими можливостями мови Паскаль, зокрема з покажчиками та їх використання для опрацювання даних.

Розвиваюча. Розвивати логічне мислення, самостійність, вміння розуміти і бачити структуру програми, що працює з масивом.

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

Тип уроку. Засвоєння нових знань, вмінь і навичок.


План

  1. Перевірка домашнього завдання.
  2. Актуалізація опорних знань.
  3. Викладення нового матеріалу.
  4. Розв’язування вправ.
  5. Підсумки уроку.
  6. Домашнє завдання.

                                                        Пам’ятка для учня!

1          Пригадайте правила техніки безпеки при роботі з ПК.

2          Через кожні 15 хв виконуйте вправи для очей та для зняття м’язової втоми.


       

Хід уроку


1. Перевірка домашнього завдання.

        1. Наявність.

        2. Питання.


2. Актуалізація опорних знань.

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

Приклад тексту: Ви танцюєте, але ноги - це ще не крила.


3. Викладення нового матеріалу.

Нам у житті завжди чогось бракує, а програмістам завжди, в першу чергу, бракує комп'ютерної пам'яті.

Давайте нагадаємо, яким чином зберігаються дані в пам'яті комп'ютера. Значення кожної змінної записане в деякій об­ласті пам'яті. Програмі відомо, за якою адресою записана ця змінна і скільки місця в пам'яті комп'ютера вона займає, оскільки кожна змінна має свій тип і довжину.

Отже, приходимо до ідеї роботи з безіменними величинами, звертаючись до них лише за адресами, з яких вони починаються.

Тому тепер треба знати не ім'я змінної, а її адресу. Величи­ни, які містять адреси, мають тип pointer, тобто «точка входу». Це новий для нас тип. Величини цього типу займають в пам'яті 4 байти.

У чому полягає зручність використання змінних, які містять адреси замість імен змінних? Тепер можна, змінюючи значення змінної типу pointer, насправді змінювати адресу, яка там записана, і тим самим подорожувати пам'яттю, читаю­чи звідти інформацію або записуючи її туди. Звичайно, такі по­дорожі дуже ризиковані і можуть призвести до втрати доро­гоцінної інформації. Тому до набуття певного досвіду варто обережно використовувати тип pointer.

Тип pointer указує на початок пам'яті, в якій записано пев­ну інформацію, розміри якої невідомі. Ми їх можемо звідти чи­тати щонайменше байтами. Але найчастіше в програмах маємо справу з типізованими змінними. Тому нам зручно було б, крім адреси початку значення змінної, вказати також програмі, скільки місця займає ця змінна. Для цього в Pascal існують різновиди типу pointer, які носять назву посилальних типів і позначаються символом «^» перед типом змінної. Тип самої змінної, на яку вказує змінна посилального типу, називається базовим.

Перейдемо до прикладів:

type A=array [1 ..100] of real;

var P_int: ^integer;

     P_real: ^real;

     P_A: ^A;

     P: pointer;

Змінна P_int міститиме адресу, що вказуватиме на комірку пам'яті, починаючи з якої записане значення цілої величини, тобто довжиною в 2 байти. При читанні цього значення Pascal розкодовуватиме послідовність 0 та 1, яка там міститься, за пра­вилами кодування цілих чисел.

Змінна Р_геаl відповідно містити­ме адресу початку величини типу real.

Корисно розібрати змінну Р_А. Вона вказуватиме на початок області пам'яті комп'ютера, з якої починається розташування елементів масиву А, кожний з яких є дійсним числом. Реальна кількість елементів масиву, з якою працюватиме користувач, поки що невідома. Відомо лише, що вона не може перевищувати числа 100.

У багатьох типів Pascal існує можливість присвоювання «нульових» значень:

v_integer := 0; v_string := ' '; v_set := [].

Схожа операція є і для посилальних типів:

v_point := nil.

У цьому випадку змінна v_point вказуватиме «в нікуди».

Як же дістатися до значення, що записане за адресою, на яку вказує змінна типу «покажчик» або посилального типу? Для цього в Pascal існує операція розіменовування.

Якщо Р вказує на адресу, за якою записане деяке значен­ня, то Р^ — це вміст області пам'яті комп'ютера, тобто значення змінної, записаної за адресою Р.

 Наприклад, результатом виконання операції J^ := I^ буде ко­піювання значення змінної, записаної за адресою I, в область пам'яті, на яку вказує змінна J. Ця операція можлива, якщо за обома адресами записані значення змінних однакового типу (рис.1).

Рис.1

Якщо виконати операцію J:=І, то змінна J матиме таку са­му адресу, як і змінна I (рис.2).

Рис.2

У результаті виконання цієї операції посилання на значен­ня 4 втрачене. У пам'яті комп'ютера в цьому місці фактично лишилося «сміття», бо цим значенням уже ніхто не зможе ско­ристатися. Саме подібних ситуацій треба уникати.

Структури змінних, на які вказують величини посилальних типів, називають ще динамічними, оскільки ми самі роз­поділяємо їх у пам'яті та звільняємо від них пам'ять, коли не­обхідність у їх значеннях відпадає. Це класичний спосіб роботи з масивами невідомої наперед довжини. Бувають також задачі, коли кількість і розмірність масивів не дозволяє одночасно роз­ташувати їх у пам'яті. Проте з алгоритму видно, що робота з усіма масивами одночасно не ведеться. Отже, резервувати для них заздалегідь пам'ять, як ми робили це досі, нераціонально.

Для розміщення динамічних змінних Pascal відводить спеціальну область пам'яті розміром в 64 Кбайти. Ця область носить назву «купи».

Розглянемо процедурні та функціональні можливості Pascal, які допоможуть вам при використанні посилальних типів.

Нагадаємо, що в процедурах і функціях після їх назв по­дається список формальних параметрів із зазначенням їх типів. Параметри, перед якими є службове слово var, є резуль­татами, а перед якими немає - аргументами.

  1. Процедура New(var Р: pointer) відводить місце для збері­гання динамічної змінної Р^ і присвоює її адресу покажчику Р.
  2. Процедура GetMem(var Р: pointer; Size: integer) відводить місце в Size байт у «купі» і присвоює адресу його початку по­кажчику Р. При цьому відводиться нерозривний блок пам'яті.
  3. Процедура Dispose(var Р: pointer) вивільняє пам'ять від динамічної змінної, на яку вказував покажчик Р.
  4. Процедура FreeMem(var Р: pointer; Size: integer) звільняє Size байт у «купі», починаючи з адреси, що записана у змінній Р.
  5. Функція MaxAvail повертає довжину в байтах найбільшо­го суцільного вільного блоку динамічної пам'яті.
  6. Функція MemAvail повертає суму в байтах усіх довжин вільних блоків у «купі».

А тепер розглянемо програму, що демонструє роботу з ди­намічною пам'яттю. Для цього використаємо задачу, подібну до тих, які розв'язували, вивчаючи масиви.

Нехай нам треба розташувати в динамічній пам'яті елемен­ти цілочислового масиву, кількість яких наперед невідома, та порахувати кількість значень, з яких утворено цей масив, як­що відомо, що їх кількість не перевищує 256.

program dimension;

type Dim = array [1 ..5000] of integer;

var P: ^Dim;

      i, n, L, m: integer;

      SL: integer;

      PSize:  longint;

      S:  set of byte;

begin

write ('Задайте кількість елементів масиву: ');

readln (n);

SL:=StzeOf (integer);

PSize := SL*(MaxAVail div SL);

L := n*SL;

if (L > PSize) or (SizeOf(Dim) > PSize)

then

   writeln ('Такий масив не може бути розміщений у пам’яті')

else

begin

   GetMem(P, L);

   S:=[];

   m:=0;

      for і:= 1 to n do

      begin

       readln (Р^[і]);

           if not(P"[i] in S) then

             begin

                 S:=S + P^[i];

                 m := m+1;

             end;

      writeln (Р^[і]);

    end;

      for і := 1 to n do

      writeln (Р^[і]);

      writeln ('Кількість значень, з яких складається масив:т);

      FreeMem(P, L);

end;

end.

У цій програмі використано функцію SizeOf, яка визначає розмір у байтах одного елемента вказаного типу.

Використання динамічної пам'яті для розміщення даних різної структури - дуже потужна можливість.

За допомогою динамічних змінних організовуються і розміщуються в пам'я­ті такі дані, як стеки, списки, черги, дерева.


4. Підсумки уроку.

  1. Що таке показник?
  2. Як реалізовується показник в мові Паскаль?
  3. Як називиється спеціальне місце пам’яті для показників в мові Паскаль?
  4. Які бувають процедури та функції, які використовують показники?

5. Домашнє завдання.

  1. Опрацювати конспект.
  2. Підготуватися до практичної роботи.