Wstęp do programowania 2

Transkrypt

Wstęp do programowania 2
Wstęp do programowania 2
wykład 6
typy dostępu – c.d
Agata Półrola
Wydział Matematyki UŁ
2005/2006
http://www.math.uni.lodz.pl/~polrola
Przykład wykorzystania typów
dostępu
 zob. pakiet rodzajowy listapak (lista
sortowana)
type box;
type wsk_box is access box;
type box is record
dane: integer;
nast: wsk_box;
end record;
Deklaracja stałych
 Można deklarować stałe typu dostępu
c: constant wsk_box :=
new box'(0,null);
 przy deklaracji konieczne jest nadanie
wartości początkowej
 ‘bycie stałą’ oznacza w tym przypadku, że
wartość typu dostępu musi cały czas
odwoływać się do tego samego obiektu
 wartość ‘wskazywanego’ obiektu można
zmienić
c: constant wsk_box := new box'(0,null);
l:wsk_box:=new box'(1,null);
c.all := l.all;
--c:=l; -- niepoprawne
 sposób obsługi stałych typu dostępu wyjaśnia
również sposób przekazywania elementów
typu dostępu jako parametrów podprogramów
function suma(p: wsk_box) return integer
is
pom:wsk_box :=p;
s: integer :=0;
begin
while pom /= null loop
s := s + pom.dane;
end loop;
return s;
end suma;
Przekazywanie parametrów
 podprogram operuje na kopii zmiennej
będącej parametrem
 w przypadku parametru w trybie ‘out’
jego wartość jest kopiowana do
podprogramu, aby zapobiec losowym
odwołaniom
Pool-specific access types
 Poznane dotychczas typy dostępu są
typami „pool-specific”
 nowe
obiekty są alokowane w obszarze
pamięci (storage pool) skojarzonym z
danym typem dostępu
 obszar skojarzony z typem dostępu
przestaje istnieć gdy skończy się zasięg
widoczności tego typu
 obiekty do których odwołujemy się za
pomocą „pool – specific access types”
muszą być obiektami zaalokowanymi za
pomocą new
b:box;
w: wsk_box := b;
-- niepoprawne
Ograniczenie to nie występuje w przypadku tzw.
ogólnych typów dostępu (general access types)
 W przypadku gdy zaalokowany obiekt
przestaje być dostępny (nie odwołuje
się do niego żadna wartość typu
dostępu) zajmowana przez niego
pamięć może zostać automatycznie
zwolniona (garbage collection).

w praktyce jest to zaimplementowane w
niewielu kompilatorach
w1: wsk_int_1 := new integer'(2);
w2: wsk_int_2 := new integer'(4)
w1.all := w2.all;
-- w1 := w2; -- niedozwolone
 Nie ma możliwości konwersji jednego
„pool-specific access type” na inny (nawet
w pokazany wyżej sposób). Wartość typu
dostępu może odwoływać się tylko do
obiektów w „swoim” obszarze.
Sposoby inicjowania zmiennej
a: array(1..10) of wsk_box :=
(1..10 => new box);
-- alokacja 10 obiektów
b1,b2: wsk_box := new box;
-- alokacja 2 obiektów
nn: wsk_box := new box'(1,null);
ll: wsk_box := new box'(nn.all);
i: integer := 2;
nnn: wsk_int := new integer'(i);
Zakresy
 Typy dostępu mogą odwoływać się do:
 podtypów
type wsk_pos is access positive;
type wsk_pos1 is access
integer range 1 .. integer'last;
wp : wsk_pos := new positive'(10);
wp1 : wsk_pos := new integer'(10);
wp2 : wsk_pos := new integer'(0);
-- Constraint_Error
tablic zawężonych lub niezawężonych
type tab is array (integer range
<>,integer range <>) of float;
type wsk_tab is access tab;
wt,wt1 : wsk_tab;
-- przy alokacji trzeba podać rozmiar:
wt := new tab'(1..10 => (1..10 => 0.0));
wt1 := new tab(1..5,1..5);
-- niedozwolone:
wt1 := new tab;


wt, wt1 mogą odwoływać się do tablic różnego rozmiaru
po zaalokowaniu rozmiar tablicy nie może być zmieniany
subtype wsk_tab_3 is wsk_tab(1..3,1..3);
wt3: wsk_tab_3;
-- odpowiednik
wt33 : wsk_tab(1..3,1..3);
subtype tab3 is tab(1..3,1..3);
wt3 := new tab3;
wt33 := new tab3'(others=>(others=>0.0));
Odwołanie do elementów tablic:
wt := new tab'(1..10 => (1..10 => 0.0));
wt1 := new tab(1..5,1..5);
wt(1,1) := 0.1;
wt.all := (others=> (others=> 0.1));
 Typy dostępu mogą odwoływać się do innych
typów dostępu
type wsk_int is access integer;
wi: wsk_int := new integer'(4);
type wsk_wsk is access wsk_int;
www: wsk_wsk;
begin
www:=new wsk_int;
www.all := wi;
put(www.all.all);
www.all.all := 2;
General access types
 Dotychczas poznane typy dostępu
umożliwiały operacje na elementach
tworzonych dynamicznie (alokowanych za
pomocą new)
 Typy dostępu mogą służyć do odwoływania
się do obiektów zadeklarowanych statycznie.
Są to tzw. ogólne typy dostępu (general
access types).
type wsk_int_G is access all integer;
i: aliased integer:=0;
wii: wsk_int_G;
wii:=i'access;
można czytać i modyfikować wartość
zmiennej „i” za pomocą zmiennej typu
dostepu
 w deklaracji typu dostępu używamy
słowa „all”,
 zmienne do których odwołujemy się w
powyższy sposób deklarujemy jako
„aliased”
 ostrzeżenie
dla programisty (zmienna
może być modyfikowana niebezpośrednio)
 informacja dla kompilatora (nie należy
przydzielać miejsca na zmienną w
niestandardowy sposób uniemożliwiający
późniejsze odwołanie)
Ograniczenie dostepu
 Możemy ograniczyć dostęp do zmiennej tak,
aby zmienne (i stałe) były „tylko do odczytu”
type wsk_int_C is
access constant integer;
i: aliased integer;
ic: aliased constant integer := 1212;
wii: wsk_int_C;
wii:=i'access; -- dostep do zmiennej
wii:=ic'access; -- dostep do stalej
Dostęp do elementów tablic
 składowe tablicy również mogą być
zadeklarowane jako „aliased”
tabi : array(1..100) of aliased integer;
type wsk_int_G is access all integer;
wii:= wsk_int_G;
wii:= tabi(i)'access;
Dostęp do pól rekordu
można również deklarować jako „aliased” pola
rekordu
type komorka is record
i: aliased integer;
j: integer;
end record;
type wsk_int_G is access all integer;
wii:= wsk_int_G;
k: komorka;
wii:=k.i'access;
Konwersja typów
 konwersja dla „pool-specific access
types” nie jest dozwolona
 konwersja między „general access type”
jest możliwa:
 wskazywane
typy muszą być takie same
 zakresy podtypów muszą być zgodne
 typ dostępu „tylko do odczytu” nie może
być przekonwertowany na typ dostępu do
zmiennej
 „pool-specific type” może być
przekonwertowany do „general access
type”, ale nie odwrotnie

Podobne dokumenty