Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Та напрямків змінних-вказівників

Читайте также:
  1. Нижче наводяться приклади можливих заходів для різних напрямків тематики з основних розділів охорони праці.
  2. Портфельний аналіз напрямків діяльності фірми

Динамічні структури даних

Незв’язані динамічні дані

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

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

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

 

ОПИС ЗМІННИХ-ВКАЗІВНИКІВ

<Ім’я змінної-вказівника>:^тип динамічної змінної

Наприклад, a:^integer; b:^real;

Щоб змінити значення динамічній змінній, на яку вказує деяка змінна-вказівник z, необхідно виконати команду:

z^:=<значення> (z – це змінна вказівник, а z^ - динамічна змінна, на яку вказує вказівник z).

Щоб змінити значення змінної-вказівника z (направити її на іншу динамічну змінну) необхідно:

z:=<деякий вказівник на іншу динамічну змінну>

 

Вказівник – це статична змінна, значенням якої є адреса пам’яті. За допомогою вказівників можна розміщувати в динамічній пам’яті будь-які типи даних (цілі, дійсні, логічні, символьні, символьні рядки, масиви, записи та інші). Вказівники, які вказують на конкретний тип даних називаються типізованими. Для опису типізованого вказівника використовується знак ^, який записується перед відповідним типом даних. Наприклад,

 

Type Tank = record

p, i, b: string[15];

rn: word;

ps: string[20];

end;

Var v1, s1: ^integer;

v2: ^real;

v3: ^Tank;

 

Тут v1, s1 вказівники на дані цілого типу, v2 вказівник на дані дійсного типу, а v3 вказівник на дані типу запис.

Можна описати вказівник і не зв’язувати його з конкретним типом даних. Для цього є стандартний тип pointer, наприклад,

Var p1, p2: pointer;

 

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

Значеннями вказівників є адреси змінних, розміщених у динамічній пам’яті. Для них допустима операція присвоєння, якщо вони вказують на один і той же тип даних та типізованому вказівнику можна присвоювати значення не типізованого, а навпаки недопустимо. Наприклад, v1:=s1; p1:=p2; s1:=p1; – допустимі присвоєння, а v1:=v2 і p1:=v3; – недопустимі.

Для звернення до даних, на які вказує вказівник, за його іменем зразу ставиться знак ^. Наприклад,

 

v1^:=5; або s1^:=v1^.

Вказівник може бути у трьох станах:

· помічений зарезервованим словом NIL (не вказує ні на які дані).

 

 

ВИДІЛЕННЯ ПАМ’ЯТІ ПІД ДИНАМІЧНУ ЗМІННУ

Оскільки динамічна змінна не має імені (а отже не описується в блоці var), то на початку роботи програми пам’ять під дану змінну не виділяється. А відповідна змінна-вказівник ні нащо не вказує. Коли змінна-вказівник ні нащо не вказує, то говорять, що вона вказує на nil.

Щоб виділити пам’ять, необхідно виконати процедуру new(x), де х – змінна-вказівник.

Після виконання даної процедури (new(x)) вказівник x буде вказувати на комірку пам’яті відповідного типу.

 

Наприклад,

Var x:^integer;

Begin

……..

New(x);

 

…….

End.

 

ЗМІНЕННЯ ЗНАЧЕНЬ ДИНАМІЧНИХ ЗМІННИХ

ТА НАПРЯМКІВ ЗМІННИХ-ВКАЗІВНИКІВ

Змінити значення динамічної змінної (нехай на неї вказує вказівник а) можна використовуючи вказівку:

a^:=<значення>

Щоб змінити напрям вказівника а необхідно:

a:=<інша змінна-вказівник>

 

Нехай на якомусь етапі роботи програми вказівник a вказує на деяку динамічну змінну, що містить число 5, а b на іншу змінну, що містить число 10.

Після виконання вказівки a^:=10 (або a^:=b^) напрям вказівника a не змінюється, змінюється значення динамічної змінної (в нашому випадку зміниться значення змінної за адресою 1: замість 5 там буде міститися 10).

Якщо ж замість a^:=b^ записати a:=b, то напрям вказівника a змінюється. Змінна-вказівник a буде вказувати на ту ж змінну, що і вказівник b. Тепер значення динамічної змінної, що знаходиться за адресою 2 можна змінити двома способами: використовуючи вказівник a та вказівник b.

Після виконання вказівок:

a:=b;

a^:=100;

b^:=15;

edit1.text:=inttostr(a^);

на екрані буде число 15 (а не 100)

 

Приклад 1. Демонструє зміну напрямків вказівників на дві незалежні динамічні змінні.

var a,b,c:^integer;

begin

new(a);

new(b);

a^:=strtoint(edit1.Text);

b^:=strtoint(edit2.Text);

c:=a;

a:=b;

b:=c;

edit3.Text:=inttostr(a^);

edit4.Text:=inttostr(b^);

end;

Результат роботи програми:

1 2

2 1

В даній програмі використовується лише дві динамічні змінні (дві комірки пам’яті)

 

Приклад 2. Демонструє перестановку двох динамічних змінних з використанням третьої.

var a,b,c:^integer;

begin

new(a);

new(b);

new(c);

a^:=strtoint(edit1.Text);

b^:=strtoint(edit2.Text);

c^:=a^;

a^:=b^;

b^:=c^;

edit3.Text:=inttostr(a^);

edit4.Text:=inttostr(b^);

end;

Результат роботи програми:

1 2

2 1

В даній програмі використовується три динамічні змінні (три комірки пам’яті). Вона працює повністю аналогічно як у випадку із звичайними статичними змінними.

Приклад 1 ефективніший за приклад 2, бо

По-перше, використовується дві комірки пам’яті;

По-друге, вміст комірок пам’яті не змінюється.

Проаналізуйте наступну програму:

var i,p:^integer;

begin

new(p);

new(i);

p^:=5;

i^:=1;

Label1.Caption:='p->'+inttostr(p^)+' i->'+inttostr(i^);

i:=p;

Label2.Caption:='p->'+inttostr(p^)+' i->'+inttostr(i^);

p^:=10;

Label3.Caption:='p->'+inttostr(p^)+' i->'+inttostr(i^);

i^:=15;

Label4.Caption:='p->'+inttostr(p^)+' i->'+inttostr(i^);

end;

 

Результат роботи програми:

p -> 5 i -> 1

p -> 5 i -> 5

p -> 10 i -> 10

p -> 15 i -> 15

Якщо вказівку i:=p змінити на i^:=p^, то результат програми буде наступним:

p -> 5 i -> 1

p -> 5 i -> 5

p -> 10 i -> 5

p -> 10 i -> 15

 

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

· Procedure New (Var P: Pointer); – резервує фрагмент купи динамічної пам’яті для розміщення змінної і записує в типізований вказівник P адресу першого байта.

· Procedure Dispose (Var P: Pointer); – повертає в купу фрагмент динамічної пам’яті, який був зарезервований за типізованим вказівником P. Якщо вказівник P невизначений, то фіксується помилка.

· Procedure GetMem (Var P: Pointer; Size: Integer); – резервує за не типізованим вказівником P фрагмент динамічної пам’яті розміру Size (в байтах) і присвоює йому адресу цієї області.

· Procedure FreeMem (Var P: Pointer; Size: Integer); – повертає в купу фрагмент динамічної пам’яті, який був зарезервований за не типізованим вказівником P. Звільняти потрібно такий розмір пам’яті, який був виділений.

 

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


Дата добавления: 2015-10-26; просмотров: 125 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Размещение объектов (полей формы) на HTML-странице.| Зв’язані динамічні дані

mybiblioteka.su - 2015-2024 год. (0.028 сек.)