У нас: 141825 рефератів
Щойно додані Реферати Тор 100
Скористайтеся пошуком, наприклад Реферат        Грубий пошук Точний пошук
Вхід в абонемент


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

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

Щоб розв'язати цю задачу, треба, по-перше, знайти перше слово максимальної довжини і, по-друге, обчислити, скільки разів трапляється задана буква, яка вводиться з файлу input, у цьому слові. Використаємо з цією метою динамічні дані. Опишемо в розділі опису типів вказівний тип s так, що значення змінних цього типу вказуватимуть на масив 1..100 символів. Далі введемо змінні r, rez, biz типу s, тобто змінні вказівного типу, які використаємо для визначення слова максимальної довжини.

Після опису змінних виконаємо початкову ініціалізацію. У результаті виконання new(biz); new(rez) одержимо динамічні об'єкти (рис. 10).

Рис. . Створення динамічних об'єктів

У циклі repeat організуємо формування слова і порівняння його з попереднім. Якщо новосформоване слово довше, ніж те, що було результатом, то їх треба поміняти місцями. Якби це були статичні дані, то довелось би пересилати вміст поточного слова і слова-результату через проміжний масив. Використання динамічних змінних дає змогу звести цю операцію до пересилання – переприсвоєння значень змінних вказівного типу. Новосформованому слову ставлять у відповідність змінну rez, а слову, що було найдовше до цього – змінну biz. У результаті одержують ситуацію, показану на рис. 11.

Рис. . Результат динамічного переставляння об'єктів

Програмна реалізація алгоритму матиме вигляд

program chyslovhodz(input,output);

type

mas=array [1..100] of char;

s=^mas;

var

r,rez,biz: s;

max,i,k: integer; c: char;

begin

max:=-1; i:==0;

new(biz); new(rez);

{читання тексту}

repeat

read (с);

if(c<>',')and(c<>.)

then

begin i:=i+1; biz^[i]:^ end

else {порівняння слів}

if i>max then

begin {поточне слово -> місце результату}

max:=i;

r:=rez;

rez:=biz;

biz:=r;

i:=0;

end

until c='.';

{читання заданої букви}

read(c);

{обчислення кількості заданої літери у слові}

k:=0;

for i:=1 to max do

if c=rez[i] then k:=k+l;

writeln('cлoвo');

for i:=1 to max do write(rez[i]);

writeln;

writeln('містить букву',с,к:1,'разів')

end.

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

З операцій порівняння над вказівниками (тобто значеннями вказівних змінних) визначені тільки операції відношення "=" (дорівнює) і "<>" (не дорівнює). Два значення вказівного типу дорівнюють одне одному, якщо вони обидва вказують на один і той же динамічний об'єкт, або якщо вони обидва є nil. В інших випадках вони не дорівнюють.

1.4. Контроль динамічної пам'яті

У випадку використання процедури new можливе переповнення динамічної області пам'яті. У цьому разі значення вказівної змінної, яке є параметром процедури new, не зміниться, якщо для розміщення відповідного динамічного об'єкта не вистачає місця, однак виконання програми не припиниться і це може призвести до непередбачених наслідків. Щоб уникнути таких ситуацій, у Турбо Паскалі передбачена стандартна функція MaxAvail без параметрів, яка повертає в програму максимальний розмір у байтах неперервного відрізка вільної пам'яті, придатної для розміщення динамічної змінної. Наприклад:

var Ig: ^ongint;

begin

if MaxArail>=4

then new(lg)

else writeln('He вистачає динамічної пам'яті);

Доцільно використовувати також функцію SizeOf, параметром якої є змінна або тип. Вона повертає кількість байтів, потрібних для розміщення змінної заданого типу:

type ANKETA=record

nom: integer;

FIO:record;

.......

end;

var

AN:ANKETA;

.......

begin

.......

if MaxAvail>=SizeOf(ANKETA)

then AN:=new(ANKETA) {Тут new у функціональній формі}

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

1.5. Знищення динамічних об'єктів

Розглянемо ще раз приклад, коли задано дві вказівні змінні k та j, що вказують на відповідні динамічні об'єкти (див. рис. 3). Після операції k:=j одержимо ситуацію, відображену на рис. 4.

Динамічний об'єкт "*" став недоступним, оскільки на нього не вказує жодний вказівник. Проте сам цей об'єкт є в пам'яті. Тому, перш ніж виконати присвоєння, непотрібний надалі динамічний об'єкт треба знищити.

Динамічний об'єкт, створений за допомогою процедури new, можна знищити процедурою Dispose.

Тому в нашому випадку замість присвоєння виконаємо дві операції:

Dispose(k); k:=j;

У результаті одержимо ситуацію, показану на рис. 12.

Рис. . Знищення непотрібного динамічного об'єкта

Як бачимо з рис. 10.12, пам'ять, яку займав знищений об'єкт, вивільниться, а вказівник к вказуватиме на об'єкт "**". Якщо тепер виконати

j:=nil

то одержимо ситуацію, зображену на рис. 13.

Рис. . Занулення вивільненого вказівника

Якщо на один динамічний об'єкт вказують два або більше вказівників (наприклад, k та j вказують на "**"), то знищення за допомогою Dispose об'єкта, на який вказує один з вказівників, призведе до ситуації, коли користуватися значенням об'єкта, на який вказує інший, не можна. Бувають значно складніші зв'язки вказівників і динамічних об'єктів, тому процедурою Dispose треба користуватися дуже обережно.

Розглянемо ще один приклад, що характеризує роботу з динамічними даними. Задано файли Ifile і Rfile – відповідно цілих у діапазоні 1.. 100 чисел, кількість яких непарна, і дійсних чисел, яких є не менше 100 елементів. Треба вивести елементи другого файлу, починаючи з кінця, і до елемента з порядковим номером, що має значення серединного елемента першого файлу. Кількість елементів у файлах не перевищує 10 000. Для розв'язування цієї задачі зручно ввести проміжні масиви як динамічні структури, бо інформацію в файлах опрацьовувати складно.

Алгоритм, який розв'язує цю задачу складається з таких кроків:

1) перепис елементів з файлу цілих


Сторінки: 1 2 3 4 5 6 7 8 9