o l d a l 1 11) Statikus és dinamikus hatóköri szabályok. Statikus és dinamikus hatókör procedure A is procedure B is end B; procedure C is B; end C; procedure D is procedure B is end B; C; end D; D; end A; értelmezzük Változók élettartama (Kapcsolódó fogalmak Hatókör,Memóriára való leképzés) Hatókör és élettartam Globális változó: az egész program végrehajtása alatt létezik Lokális változó: csak a definiáló blokk végrehajtása alatt létezik Dinamikusan lefoglalt változók C/C++ static változók, Java zárványok (inner) Dinamikusan lefoglalt változók tatók, referenciák (egy későbbi előadás) Ha a hatókör kisebb az élettartamnál int sum ( int p ) { static int s = 0; s += p; return s; } void f ( void ) { cout << sum(10) << endl; cout << sum(3) << endl; } Deklaráció kiértékelése Rugalmatlan C, C++ int t[10]; pl. Ada A blokk utasítás szerepe
o l d a l 2 12) Változók ábrázolása a memóriában. Élettartam. Egy program a memóriában Futtatás közben a program által használt tár felépítése: kód (statikus) adatok végrehajtási verem dinamikus tárterület (heap) Statikus változók A hatókörhöz igazodó élettartam t Dinamikus változók Ahonnan a programozó allokátorral tud memóriát foglalni Explicit felszabadítás vagy szemétgyűjtés fel) a változó Statikus és automatikus: deklaráció hatására Objektum élettartama Élettartam (extent, lifetime): az objektum lefoglalása és felszabadítása közötti időtartam statikus objektumok élettartamuk a program teljes futása fajtái globális változó névtérbe tartozó változó lokális statikus változó (static kulcsszó) ha nincsen kezdőérték-adás, a típusnak megfelelő 0 értékkel inicializálódnak Élettartam lokális változók (automatikus objektumok): a deklaráció helyétől a hatókör végéig tart dinamikusan lefoglalt objektumok: a lefoglalástól a felszabadításig mindkét fentire vonatkozó tulajdonságok nem inicializálódnak, ha nincsen kezdőérték-adás használat előtt inicializálni kell őket, különben definiálatlan a program működése tömbök elemei, osztályok adattagjai élettartamuk a tömb/osztály élettartamával azonos Változók leképzése a memóriára A fordító a tárgykódban lefoglal neki helyet Futás közben a végrehajtási vermen jön létre és szűnik meg Allokátorral foglaljuk le, és pl. deallokátorral szabadítjuk fel (vagy a szemétgyűjtés)
o l d a l 3 13) Deklarációk statikus és dinamikus kiértékelése. Blokk utasítás szerepe. A statikus és a dinamikus szerkesztés előnyei/hátrányai csak egyszer kell megcsinálni, nem minden futtatáskor megoszthatók nagy könyvtárak a programok között, kisebb méretű futtatott programok csak az szerkesztődik be, amire szükség van ez esetleg még csökkenti is a végrehajtási időt verziókhoz könnyebben alkalmazkodó program gyakori futási hiba (könyvtár hiánya vagy rossz verziója miatt) Típusmeghatározás fordítási időben hasznos: hibák korai felfedezése, hatékonyság növelése Ada, C++, Java futási időben haszna: nagyobb rugalmasság, nagyobb kifejezőerő Java, Smalltalk, LISP Biztonságosság vs. rugalmasság csak dinamikus típusellenőrzés n, de meglehetősen biztonságos statikus típusrendszer: C++, Pascal típuskényszerítés, variáns rekord helyenként dinamikus típusellenőrzéssel kombinálva Blokk: Blokkszerkezetes nyelvek Ilyen: Algol 60, Pascal, Ada, Haskell Nem ilyen: C, C++, Java(!) fontos kérdés -részébe procedure A is procedure B is end; declare procedure C is end; declare end; end; end; Lokális és nonlokális deklaráció ális (local) a blokkra nézve A blokkon kívülről nem hivatkozható lokkban elhelyezett deklaráció nonlokális (non-local) a befoglalt blokkok számára Alternatív elnevezés: globális a befoglalt blokkra nézve declare X: Float; declare end; end; Globális deklaráció is / nonlokális (globális) egy deklaráció egy blokkra nézve relatív deklaráció: az egész programra vonatkozik A hatóköre az egész program abszolút int glo; void f ( int par ) { int loc = par; glo = loc; }
o l d a l 4 Dinamikusan lefoglalt változók sd még: memóriára való leképzés Deklaráció kiértékelése Rugalmatlan C, C++ int t[10]; pl. Ada A blokk utasítás szerepe Ha egy blokkban kivétel keletkezik A blokkban lekezelhetjük egy kivételkezelő részben (a blokkban lép fel ) klarációk kiértékelése, vagy a kivételkezelő rész végrehajtása közben: Csak a hívóban/tartalmazóban kezelhető le(ott lép fel ) A blokk utasítás egyik haszna procedure A is N: Integer; Put("Hány adat lesz?"); Get(N); declare T: array (1..N) of Integer; -- beolvasás és feldolgozás end; end; Egy másik haszon tárigényű változót csak rövid ideig akarok használni Ada: kivételkezelés
o l d a l 5 14) Dinamikus memória. Allokáció, felszabadítás. Szemétgyűjtés. Aliasing. memóriaszivárgás: felszabadítatlan lefoglalt memória dinamikus tárterület (heap) Változók leképzése a memóriára Statikus A fordító a tárgykódban lefoglal neki helyet Automatikus Futás közben a végrehajtási vermen jön létre és szűnik meg Dinamikus változók dinamikus tárterületen jönnek létre Ahonnan a programozó allokátorral tud memóriát foglalni Explicit felszabadítás vagy szemétgyűjtés Utasítás hatására jön létre (és esetleg szabadul fel) a változó Statikus és automatikus: deklaráció hatására Mutató típusok A dinamikus változók használatához Ada: access típusok type P is access Integer; X: P; --Dinamikus változó létrehozása X := new Integer; --Dinamikus változó elérése a mutatón keresztül X.all := 3; Memóriaszivárgás A dinamikus memóriakezelés baja Mikor szabadítsunk fel egy változót? Dinamikus változó élettartama Az alias-ok miatt bonyolult Ha felszabadítom: nem hivatkozik még rá valaki egy másik néven? Ha nem szabadítom fel: felszabadítja más? Mutató típusok definiálása type P is access Integer; type Q is access Character; type R is access Integer; Meg kell adni, hogy mire mutató mutatók vannak a típusban: gyűjtőtípus P, Q és R különböző típusok Mutatók a C++ nyelvben Nincsen önálló mutató típus fogalom Mutató típusú változók int *x; Nem lehet két különböző int-re mutató mutató típust definiálni A Javában csak implicit módon jelennek meg a mutatók Mutató, ami sehova sem mutat : Nullpointer Az Adában: a null érték Minden mutató típusnak típusértéke type P is access Integer; X: P := null; Y: P; -- implicit módon null-ra inicializálódik Ha felszabadítom int *x = new int; int *y = identitás(x); delete x; *y = 1; // illegális memóriahivatkozás int *identitás( int *p ) { return p; } Ha nem szabadítom fel int *x = new int; x = másolat(x); // memory leak int *másolat( int *p ) { int *q = new int; *q = *p; return q; // return new int(*p); }
o l d a l 6 Megoldások Legyen ügyes a programozó Legyen szemétgyűjtés Használjunk automatikus változókat Ott a hatókörhöz kapcsolódik az élettartam C++: automatikus objektum destruktora Szemétgyűjtés Garbage collection Ne a programozónak kelljen megszüntetnie a nem használt dinamikus változókat A futtató rendszer megteszi helyette Nő a nyelv biztonságossága A hatékonyság picit csökken (a memóriaigény és a futásiidő-igény is nő) Megéri (kiforrott szemétgyűjtési algoritmusok) LISP (1959), Ada, Java, modern nyelvek Felszabadítás az Adában Szemétgyűjtéssel (alapértelmezett) A típusrendszer az alapja Explicit felszabadítással Ada.Unchecked_Deallocation A hatékonyság növelése érdekében Van, amikor csak így lehet A dinamikus változó felszabadul, amikor a létrehozásához használt mutató típus megszűnik Ekkor már nem férek hozzá a változóhoz alias segítségével sem, csak ha nagyon trükközök >Tehát biztonságos a felszabadítás A programozó szabadít fel Ha a mutató típus a program végéig létezik, nincs szemétgyűjtés A programozó kézbe veheti a felszabadítást Nem csak ilyenkor veheti kézbe Ada.Unchecked_Deallocation sablon ez felel meg a C++ delete-jének Ada.Unchecked_Deallocation with Ada.Unchecked_Deallocation; procedure A is type P is access Integer; procedure Free is new Ada.Unchecked_Deallocation(Integer,P); X: P := new Integer; Y: P := X; Free(X); Y.all := 1; -- definiálatlan viselkedés end A; Memóriaszivárgás: Sorok egy láncolt szerkezet. with Sorok; procedure A is package Int_Sorok is new Sorok(Integer); procedure B is S: Int_Sorok.Sor; Int_Sorok.Betesz(S,1); end B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; end A; Mi történik? A sor objektumok a stack-en jönnek létre A sor elemei a heap-en allokáltak Amikor a sor objektum megszűnik (automatikusan), az elemek nem szabadulnak fel
o l d a l 7 Megoldás o Felszámoló eljárást írni, és azt ilyenkor meghívni o C++: a sor destruktorában felszabadítani o Ada 95: Controlled típust használni (Destruktor az Adában) with Ada.Finalization; use Ada.Finalization; type Sor is new Limited_Controlled with private; procedure Finalize ( S: in out Sor ); procedure Betesz ( S: in out Sor; E: in Elem ); procedure Kivesz ( S: in out Sor; E: out Elem ); private type Csúcs; type Mutató is access Csúcs; type Csúcs is record Adat: Elem; Következő: Mutató; end record; type Sor is new Limited_Controlled with record Eleje, Vége: Mutató := null; end record; end Sorok; Aliasing. Aljas mutatók ra mutat, amelyet nem a heap-en hoztunk létre (Ada 95) bútum cím lekérdezésére való, minden típushoz használható -hez Borzasztó veszélyes int *f ( int p ) { int n = p; return &n; } int main() { int i = *f(3); // illegális memóriahivatkozás } Implementáció (Finalize) procedure Finalize ( S: in out Sor ) is P: Mutató; while S.Eleje /= null loop P := S.Eleje; S.Eleje := S.Eleje.Következő; Felszabadít(P); end loop; end Finalize; Memóriaszivárgás: felszabadítás kell! with Ada.Unchecked_Deallocation; package body Sorok is procedure Felszabadít is new Ada.Unchecked_Deallocation(Csúcs, Mutató); procedure Kivesz ( S: in out Sor; E: out Elem ) is end Sorok; type P is access all Integer; N: aliased Integer := 1; X: P := N ' Access; void f() { int n = 1; int& r = n; int* p = &n; // ez hasonlít a leginkább } Az Ada szigorúbb, biztonságosabb procedure A is type P is access all Integer; procedure B ( X: out P ) is N: aliased Integer := 1; X := N Access; end B; X: P; B(X); end; Élettartam ellenőrzése yes, ha az N objektum legalább ugyanannyi ideig fennmarad, mint az X típusa. X := N Access; égi ellenőrzést is végez, hogy a mutatott objektum élettartama legalább akkora-e, mint a mutató típusának hatásköre.
o l d a l 8 15) Típusosztályok. Típusosztályok az Adában elemi típusok skalár típusok diszkrét típusok felsorolási egész (előjeles, ill. moduló) valós típusok (fix- és lebegőpontos) mutató típusok összetett típusok tömb, rekord stb. Mutató típusok type P is access Integer; X: P; X := new Integer; X.all := 3; Valós típusok, elemi, skalár egy rögzített hosszúságú mantissza és egy előjeles egész exponens type Real is digits 8; R: Real := 2.12345678 a mantissza ábrázolásához szükséges decimális jegyek száma predefinit típus: Float - implementációfüggő a többi ebből, származtatással type Real is new Float digits 8; Egész típusok type Mod10 is mod 10; type Bájt is mod 256; A típusértékek a 0..9, illetve a 0..255 A számokon értelmezett szokásos műveletek (például a + ) a maradékosztályok szerint, azaz modulo számolnak. A felsorolási típusok osztálya sorrendje adja követi - nullától egyesével Az egész típusok osztálya felsorolási +A -A A+B A-B A*B A/B A rem B A mod B abs A A**B Az egész osztás csonkít (nulla felé...) Hatványozásnál B nemnegatív S Modulus a típus modulusa A valós típusok osztálya +X -X X+Y X-Y X*Y X/Y X**Y hatványozás: Y egész Lebegőpontos: Digits Fixpontos: Small, Delta, Fore, Aft, Scale, Round A diszkrét típusosztály pozíciószámmal azonosíthatók S Pos(A) function S Pos(A: S Base) return Integer egy egész szám, a pozíció S Val(n) az adott pozíciónak megfelelő típusérték Tömbaggregátum type T is array (1..6) of Float; ális megadás X: T := (1.0, 3.0, 1.0, 2.0, 2.0, 2.0); X: T := (2 => 3.0, 1 3 => 1.0, 4..6 => 2.0); X: T := (2 => 3.0, 1 3 =>1.0, others => 2.0); X: T := (1.0, 3.0, 1.0, others => 2.0);
o l d a l 9 16) Típusszármaztatás. Primitív műveletek, öröklődésük. Típusekvivalencia. Típuskonverzió. Alprogram, mint típusművelet Felüldefiniálás ípusok Tipikusan: átlátszatlan típus Absztrakt értékhalmaz és műveletek és a megörökölt műveleteket (Előre definiált) operátorok Primitív alprogramok Primitív műveletek típus megadása után felsorolt alprogramok Vagy valamelyik paraméter, vagy a visszatérési érték olyan típusú : egy csomagban definiálok egy (általában átlátszatlan) típust a műveleteivel aztatott típusok: megöröklik a primitív műveleteket Explicit típuskonverzió -vissza konvertálhatunk típusnévvel A szokásosnál szigorúbbak a játékszabályok type Int is new Integer; I: Integer := 3; J: Int := Int(I); K: Integer := Integer(J+1) + I + 1; Példa primitív műveletre package Queues is type Queue( Capacity: Positive ) is limited private; procedure Hiext ( Q: in out Queue; E: in Element ); procedure Lopop ( Q: in out Queue; E: out Element ); private end Queues; Példa öröklésre with Queues; use Queues; package Dequeues is type Dequeue is new Queue; procedure Loext ( Q: in out Dequeue; E: in Element ); procedure Hipop ( Q: in out Dequeue; E: out Element ); end Dequeues; Típusekvivalencia szerkezeti típus ekvivalencia: ha ugyanolyanok név szerinti típus ekvivalencia: ha kijelentjük, hogy ekvivalensek Típus ekvivalencia a C++ nyelvben class A { int x; }; class B { int x; }; // nem ekvivalensek! typedef typedef int LENGTH; csak nevet deklarál, nem definiál új típust szinoníma bevezetése Típusekvivalencia az Ada nyelvben Név szerinti ekvivalencia Van lehetőség szinoníma definiálására Típusekvivalencia tömb típusokra egy valódi típuskonstrukciós eszköz (szemben pl. a C++ tömbjeivel int t[10];) -definíció új típust hoz létre (név szerinti ekvivalencia) type T1 is array ('a'.. 'z') of Natural; type T2 is array ('a'.. 'z') of Natural; -T1 és T2 nem ekvivalensek!
o l d a l 10 17) Altípusképzés. Statikus és dinamikus típusellenőrzés. Altípusok ezetünk be új típust, csak egy altípust a meglévő típushoz subtype Napok is Integer range 1..31; Elseje: Napok := 1; Egy: Integer := 1; lseje és az Egy változó típusa megegyezik Az altípusok tulajdonságai használható, mint az eredeti (változódeklaráció, formális paraméter dekl., újabb típusok stb.) tozó entitás és a bázistípusba tartozó entitás kompatíbilisek egymással Altípusok és kompatibilitás Elseje := Egy; Egy := Elseje; dító elfogadja az értékadásokat azonos típusú értékek Azt is ellenőrizni kell, hogy az értékadás nem sérti meg a típus invariánst Elseje := 42; Típusmeghatározás fordítási időben hasznos: hibák korai felfedezése, hatékonyság növelése Ada, C++, Java típusellenőrzés futási időben haszna: nagyobb rugalmasság, nagyobb kifejezőerő Java, Smalltalk, LISP Dinamikus típusellenőrzés ni kell, hogy az értékadás nem sérti meg a típusinvariánst Elseje := 42; ító ezt elfogadja, esetleg egy figyelmeztetést (warning) küld: warning: "Constraint_Error" will be raised at run time zer ellenőrzi, hogy a baloldal altípusának (a korlátozásnak) megfelel-e a jobboldali típusérték Biztonságosság vs. rugalmasság csak dinamikus típusellenőrzés n, de meglehetősen biztonságos statikus típusrendszer: C++, Pascal típuskényszerítés, variáns rekord helyenként dinamikus típusellenőrzéssel kombinálva Ada: típusok és altípusok a fordítónak információ az entitásokról (melyik entitást mire lehet használni) kiegészítő információk a futtató rendszer számára
Nevezetes (beépített) altípusok subtype Natural is Integer range 0..Integer Last; subtype Positive is Integer range 1..Integer Last; lehetne: subtype Positive is Natural range 1..Natural Last; o l d a l 11 Altípusképzés altípus-deklaráció nélkül subtype Napok is Integer range 1..31; Nap: Napok := 7; Februári_Nap: Napok range 1..29 := 3; Szám: Integer range 1..31 := 7; Típusszinonímák subtype Elem is Integer; vezet be megszorítást, csak egy új nevet Példák altípusokra subtype Napok is Integer range 1..31; subtype Valószínűség is Float range -1.0.. 1.0; subtype Nagybetűk is Character range A.. Z ; type Hét is (Hétfő, Kedd, Szerda, Csütörtök, Péntek, Szombat, Vasárnap); subtype Munkahét is Hét range Hétfő.. Péntek; Ma: Hét := Szombat; if Ma in Munkahét then Elmegyek_Dolgozni; end if; Származtatás + altípusképzés type Napok is new Integer range 1..31; type Napok is range 1..31; type Hónap_Napok is new Integer; subtype Napok is Hónap_Napok range 1..31; Altípus létrehozása type Beosztás is array (Napok range <>) of Boolean; subtype Munkanap is Beosztás(Hétfô.. Péntek); Kati_Beosztása : Beosztás(Kedd.. Szombat); Jancsi_Beosztása : Munkanap; Peti_Beosztása : Beosztás := (True,True,False); -2147483648 Alprogramok gyűjteménye package Trigonometrikus is function Sin ( X: Float ) return Float; function Cos ( X: Float ) return Float; function Tan ( X: Float ) return Float; end Trigonometrikus;
o l d a l 12 18) Átlátszatlan típus. Adatabsztrakció. Egységbezárás. Abstract State Machine. Abstract Data Type. Egységbe zárás és absztrakció ami egybe tartozik, az legyen egyben rejtsük el a részleteket a többi komponens elől Modula-2, CLU, Haskell -elvű nyelvek: osztály Csomag - programegység külvilág számára nyújtott felület látható rész: kívülről használható komponensek specifikációja átlátszatlan rész (opcionálisan megadható) reprezentációs információ a fordító számára (logikailag a törzshöz tartozik) megvalósítás, implementációs részletek package Stacks is subtype Item is Integer; type Item_Array is array( Integer range <> ) of Item; type Stack(Capacity: Positive ) is record Data: Item_Array(1..Capacity); Stack_Pointer: Natural := 0; end record; procedure Push( V: in out Stack; X: in Item ); end Stacks; Absztrakt adattípus tatunk a reprezentációnak és a műveletek implementációjának részleteitől s type Verem is private; ó Az absztrakció fontossága reprezentációját a külvilág elől! egységbe zárás: olvashatóság (átláthatóbb kód) információ elrejtés: módosíthatóság karbantarthatóság modularizáció: könnyebb/gyorsabb elkészíteni Átlátszatlan típus reprezentációt elrejtem a csomag specifikációjának átlátszatlan részében csak a műveleteken keresztül használják a típust es nézet az átlátszatlan (privát) részben van
o l d a l 13 package Stacks is subtype Item is Integer; -- ebből lesz majd paraméter type Stack is private; procedure Push( V: in out Stack; X: in Item ); private Capacity: constant Positive := 100; type Item_Array is array( 1..Capacity ) of Item; type Stack is record Data: Item_Array; Stack_Pointer: Natural := 0; end record; end Stacks; package Stacks is subtype Item is Integer; -- ebből lesz majd paraméter type Stack (Capacity: Positive) is private; procedure Push( V: in out Stack; X: in Item ); private type Item_Array is array( Integer range <> ) of Item; type Stack( Capacity: Positive ) is record Data: Item_Array(1..Capacity); Stack_Pointer: Natural := 0; end record; end Stacks; Az átlátszatlan típus műveletei reprezentációról az utóbbiban a Capacity:Positive mező := = /= melyek valamelyik paramétere vagy visszatérési értéke olyan típusú Abstract State Machine - egységbe zárva - részletek elrejtve Típusmegvalósítás pl. absztrakt adattípus (Abstract Data Type)
o l d a l 14 19) Definit és indefinit típusok. http://adaconcept.com/syntaxer.php?file=programs/osszetett_tipusok.adb Nem teljesen meghatározott típus indefinite type Például: a diszkriminánsos rekord típus a megszorítás nélküli indexhatárú tömb típus: o nem ismerjük a méretét o de például helyes ez: X: T := (1,5,3); Ha az aktuális lehet indefinit generic type T(<>) is private; procedure Swap( A, B: in out T ); procedure Swap( A, B: in out T ) is C: T := A; A := B; B := C; end Swap; Nem teljesen meghatározott típus indefinite type predefinit típus: Float - implementációfüggő a többi ebből, származtatással type Real is new Float digits 8; Korlátozott indefinit típust is megengedünk generic type T(<>) is limited private; with function "<" (A, B: T) return Boolean is <>; function Maximum ( A, B: T ) return T; function Maximum ( A, B: T ) return T is if A < B then return B; else return A; end if; end Maximum;
o l d a l 15 20) Tömbök ábrázolása. Indexelés. Többdimenziós tömbök. Tömbszeletek. A tömbök attribútumai Adában. Összetett típusok: tömbök Elemek típusa + indexek típusa type Tömb is array (1..10) of Integer; Tömbök Tömb típusok az Adában ) típusok megvalósításának egy eszköze pus tetszőleges diszkrét típus (felsorolási vagy egész) s tetszőleges (teljesen meghatározott) típus általában speciális szintaxist biztosítanak a tömbökhöz k elérése, de a tömb méretének módosítása nem type T is array ( 1..10 ) of Integer; X: T := (1,3,5,7,9,2,4,6,8,0); I: Integer := X(5); Típusekvivalencia tömb típusokra egy valódi típuskonstrukciós eszköz szemben pl. a C++ tömbjeivel int t[10]; -definíció új típust hoz létre (név szerinti ekvivalencia) type T1 is array ('a'.. 'z') of Natural; type T2 is array ('a'.. 'z') of Natural; T1 és T2 nem ekvivalensek! Példák type T1 is array ('a'.. 'z') of Natural; type T2 is array (Character range 'a'.. 'z') of Natural; type T3 is array (Character) of Natural; type T4 is array (Character'First.. Character'Last) of Natural; type T5 is array (1..10) of T2; type T6 is array (Integer) of T3; -- Storage_Error veszélye! -- X: T6; Névtelen tömb típus type Napok is (Hétfô, Kedd, Szerda, Csütörtök, Péntek, Szombat, Vasárnap); Házimunka: array (Napok) of Natural; gyes komponensek: Házimunka(Hétfô) a tömb első eleme, Házimunka(Kedd) a második stb. típusból csak egy objektum jön létre Többdimenziós tömb type T is array (Boolean, Boolean) of Boolean; És: T := ( (False, False), (False,True) ); És(False,True) --Nem olyan, mint a tömbök tömbje type T1 is array (Boolean) of Boolean; type T2 is array (Boolean) of T1; Vagy: T2 := ( (False,True), (True,True) ); Vagy(False)(True) -- Sorfolytonos ábrázolás
o l d a l 16 Tömbműveletek X(1..1) és X(1) más típusú! := = /= = (lexikografikusan értelmezett) relációk s hosszúságú logikai értékeket tartalmazó vektorokra az and, or, xor, és a not műveletek Tömbök attribútumai type T is array ( 1..10 ) of Integer; X: T := (0,2,4,6,8,1,3,5,7,9); X ' First --az első index, azaz 1 X ' Last --az utolsó index, azaz 10 X ' Range --X ' First.. X ' Last X ' Length --az X hossza, azaz 10 bjektum szerepel az attribútum neve előtt (v.ö. Integer ' First) Iterálás tömbön for I in X ' Range loop Put_Line( Integer ' Image( X(I) ) ); end loop; Többdimenziós tömbök attribútumai type T is array (Boolean, Boolean) of Boolean; És: T := ( (False, False), (False,True) ); És ' First(1) az első index az első dimenzióban, azaz False És ' Last(2) az utolsó index a második dimenzióban, azaz True Megszorítás nélküli index type Vektor is array (Integer range <> ) of Integer; type Mátrix is array (Integer range <>, Integer range <>) of Float; deklarálásakor kell eldönteni a konkrét indexhatárokat: V1: Vektor (1.. 3); V2: Vektor (2.. 4); V3: Vektor (1.. 8); A: Mátrix(1.. 2, 1.. 5); M: Mátrix; -- hibás változódefiníció (fordítási hiba) Megszorítás nélküli indexű tömb típus rogram formális paraméterének vagy visszatérési értékének típusa lehet ilyen lletve a kiszámolt érték határozza meg az aktuális indexhatárokat étrehozásához meg kell adni az indexhatárokat (méretet), altípusképzéssel indexelésű tömbök egy típusba tartozhatnak
o l d a l 17 Megszorítás nélküli indexű tömbök jellemzői type Vektor is array (Index range <>) of Elem; V: Vector(1..0); Értékadás szeletre: a szelet is balérték W(1..3) := (3,5,1); tömböt tömbbel, elemet tömbbel, tömböt elemmel, elemet elemmel Példák konkatenációra type Vektor is array (Integer range <>) of Float; K1: Vektor(0..2); K2: Vektor(1..3); -- ok: K2 := K1; K3: Vektor := K1&K2; -- K3'First = 0 K4: Vektor :=K1&1.0; -- ok: K4(0..2) := K2; K5: Vektor :=2.0&3.0; -- K5'Length = 2 K6: Vektor :=1.0&K1; Tömbaggregátum type T is array (1..6) of Float; X: T := (1.0, 3.0, 1.0, 2.0, 2.0, 2.0); -- Pozícionális megadás X: T := (2 => 3.0, 1 3 => 1.0, 4..6 => 2.0); -- Névvel jelölt megadás X: T := (2 => 3.0, 1 3 =>1.0, others => 2.0); -- Maradék X: T := (1.0, 3.0, 1.0, others => 2.0); -- Keverés Korlátozás nélküli index esetén type T is array (Integer range <>) of Float; X: T := (1.0, 3.0, 1.0, 2.0, 2.0, 2.0); -- Pozícionális megadás X: T := (2 => 3.0, 1 3 => 1.0, 4..6 => 2.0); -- Névvel jelölt megadás X: T := (2 => 3.0, 1 3 =>1.0, others => 2.0); -- Helytelen: X: T := (1.0, 3.0, 1.0, others => 2.0); -- Helytelen: X: T(1..10) := (1.0, 3.0, 1.0, others => 2.0); --Helyes: X: T(1..10) := (2 => 3.0, 1 3 =>1.0, others => 2.0) -- Helyes: Többdimenziós esetben M: Mátrix(1..2, 1..3):= (1 = > (1.1,1.2,1.3), 2 = > (2.1,2.2,2.3)); D: Mátrix := (1.. 5 = > (1.. 8 = > 0.0));