Wskaźniki i tworzenie zmiennych dynamicznych

Rodzaje zmiennych

W języku Pascal zmienne dzielą się na statyczne i dynamiczne.
Zmienna statyczna tworzona jest w trakcie kompilacji programu i istnieje do momentu jego zakończenia lub też do momentu zakończenia funkcji lub procedury, w której została zadeklarowana.
Program w momencie uruchamiania otrzymuje od systemu operacyjnego fragment pamięci o rozmiarze 64KB przeznaczony na dane statyczne – fragment ten nazywamy segmentem danych. W segmencie tym są umieszczane wszystkie zmienne globalne programu a także zmienne zadeklarowane lokalnie w procedurach i funkcjach. Łączny rozmiar tych zmiennych nie może przekroczyć rozmiaru segmentu danych, tj. 65536 bajtów.
Zmienną dynamiczną nazywamy zmienną utworzoną w trakcie wykonywania programu. Zmienne te tworzone są na tzw. stercie, której rozmiar jest na ogół różny i może wynosić nawet do 600KB. W odróżnieniu od segmentu danych zmienną utworzoną na stercie można w dowolnym momencie usunąć, zwalniając w ten sposób niepotrzebnie zajmowaną pamięć.

Typy wskaźnikowe. Wskaźniki

Do pracy ze zmiennymi dynamicznymi używa się typów wskaźnikowych. Elementami tych typów są zmienne wskaźnikowe, które krótko nazywamy wskaźnikami. Wskaźnik jest adresem pewnej zmiennej określonego typu. Mówiąc o wskaźniku zawsze mamy na myśli zmienną, której adres zawiera wskaźnik. Ze względu na różny typ zmiennych mówimy o wskaźniku na liczbę typu Byte, wskaźniku na liczbę rzeczywistą Real, wskaźniku na łańcuch typu String itd – zawsze ze wskaźnikiem związany jest typ zmiennej na którą wskazuje dany wskaźnik.
Używamy tu sformułowania “wskaźnik wskazuje na zmienną” gdyż w rzeczywistości zawiera on adres tej zmniennej. Adresy zmiennych mają swoją specyficzną budowę, która wynika ze sposobu adresacji pamięci w komputerach PC. Pamięć ta jest dzielona na segmenty o rozmiarze 64KB (65536). Segment taki zawiera 65536 bajtów (komórek) pamięci. Zarówno segmenty pamięci jak również wszystkie komórki pamięci w danym segmencie są numerowane od zera, co oznacza, że do zapamiętania adresu segmentu wystarcza liczba typu Word, oraz za pomocą takiej liczby można określić adres komórki pamięci w danym segmencie. Drugi z tych adresów, czyli położenie komórki w segmencie nazywamy ofsetem lub przesunięciem.
Adres komórki pamięci znajdującej się w segmencie Seg i przesuniętej względem początku tego segmentu o Ofs komórek zapisujemy najczęściej w postaci $Seg:$Ofs, przy czym obie wartości zapisane są szesnastkowo.

Budowa stosów

Przykład 1

program wsk;

var
wsk1, wsk2: ^integer;
i: integer;

begin
i := 1;
wsk1 := @i;
if @wsk1^ = wsk1 then
writeln(‘tak’);   {drukuje tak}
writeln(wsk1^);   {drukuje 1}
wsk1^ := 2;
wsk1 := nil;
if wsk1 = nil then
writeln(‘tak’);   {drukuje tak}
writeln(i);  {drukuje 2}
new(wsk2);
wsk2^ := 3;
writeln(wsk2^);   {drukuje 3}
dispose(wsk2);
new(wsk1);
wsk2 := wsk1;
wsk1^ := 4;
writeln(wsk1^);   {drukuje 4}
readln;
dispose(wsk1);
{dispose(wsk2); – to byłby błąd}
if wsk2 = nil then
writeln(‘tak’);   {nic nie drukuje}
readln;
end.

Author: ZSE

Share This Post On
Skip to content