„Adatszerkezetek” tantárgy , 1. félév
1. előadás’2009
(vázlat)

1. Adatok jellemzői

1.1. Azonosító

Az a jelsorozat, amellyel hivatkozhatunk a tartalmára, amely által módosíthatjuk tartalmát.

Például:

            i, j, n, a

változók nevei (szimbolikus nevek)

            p, -128, 3.14, "Eredmény=", IGAZ

konstansokat azonosító jelsorozat

 

Megjegyzés:

x

:=

x+1

 

címhivatkozás

 

értékhivatkozás

 

vagy

 

 

 

Feldolgoz(x)

eljáráshívásnál nem lát­szik, hogy x az adat címét vagy értékét jelenti

 

Eljárás Feldolgoz(Változó x:TX):

Ez már világos beszéd!

1.2. Hozzáférési jog

Adatokat módosítani, illetve értéküket lekérdezni, használni lehet; eszerint egy adat hozzá­férés szempontjából négyféle lehet:

 

módosítható

lekérdezhető

 

Független

Nem

Nem

Független

Input

Nem

Igen

Konstans

Output

Igen

Nem

Virgin

I/O

Igen

Igen

Változó

Háttértár-adat

 

 

Memória-adat

1.3. Kezdőérték

A születéskor hozzárendelt érték. Változóknál deklarációban kaphat értéket, vagy eleve van típushoz rendelt kezdőérték, esetleg speciális ’nem definiált’ érték[1], s így akkor mód van hivatkozás ellenőrzésre is (virgin)!

1.4. Hatáskör

A programszöveg azon tartománya, amelyben az adathoz a hozzáférés lehetséges.

Gondoljunk a blokkstruktúrájú programozási nyelvek egymásba ágyazódó adatdeklarációira! Így beszélhetünk: globális és lokális (sőt saját) adatokról.

A hatáskört „színezi” a láthatóság kérdése: ha egy adat azonosítója megegyezik egy olyan adatéval, amelynek hatáskörébe esik, akkor azt elérhetetlenné teszi a saját hatáskörében, hi­szen az adott név alatt neki van elsősége. Ez az ún. „luk a hatáskörben” jelenség.

Példa:


Változó

  x:TX

Konstans
  y:TY(…)


  [
itt az x TX, az y TY típusú]

Eljárás E1(Változó x:TX2):
  Változó
    y:TY2
  [
itt az x TX2, az y TY2 típusú]
 
Eljárás vége.


  [
itt az x TX, az y TY típusú]

1.5. Élettartam

A futási időnek az az intervalluma, amelyben az adat azonosítója mindvégig ugyanazt az objektumot jelöli.

Meggondolandó a az élettartam hatáskörrel való kapcsolata! Globális –azaz a legfelsőbb szinten deklarált–, lokális –pl. egy eljárásban vagy függvényben deklarált– adatok hatásköre és élettartama bizonyos értelemben azonos, amíg a „dinamikus” –azaz futásközben, a programozó döntése szerint születő és megszűnő– adatok esetében már nincs meg az előbbi pontos párhuzam. L. később!)

1.6. Értéktípus

Az adatoknak az a tulajdonsága, hogy értékei mely halmazból származnak (értékhalmaz) és tevékenységeknek (eljárások, függvények, operátorok) mely „készlete, amely létrehozza, fel­építi, lerombolja és részekre bontja”, alkalmazható rá (asszociált műveletek).

2. Az értéktípus

2.1. Az értéktípusról általánosságban

Összetettség (strukturáltság) szempontjából:

Adatstrukturálási módok:

Strukturálási mód

Adatszerkezet

Keresztszorzat

A´B…

Rekord

(Megkülönböztetett) egyesítés

A´B´…(C´DÈE´FÈ…)

Alternatív rekord

Halmazképzés

2A

Halmaz

Iterált-képzés

A*

Sorozatfélék

2.2. Az asszociált műveletek osztályozása

Az asszociálható műveleteket csoportosítjuk:

Példa:


Típus

  TPont=Rekord(x,y,z:Valós)
Változó
  Origó,Egys,Q:TPont

  Eltol(Origó,Egys)
  Q:=Origó

Eljárás Eltol(Változó p:TPont;Konstans D:TPont):
  [
értékmegosztás jön létre a formális és az
 
 aktuális paraméterpárok között]
  p.x:+
D.x; p.y:+D.y; p.z:+D.z [2]
Eljárás vége.


[
értékmásolások az értékadások két oldala között]

·         típusátviteli függvények:

o   Konstrukciós műveletek (strukturált érték létrehozása)

Példa:


Típus

  TPont=Rekord(x,y,z:Valós)
  TVárakozók=Sor(TEmber)
  TPMut=TPont’Mutató   [l.
később]
Változó
  p,q:TPont
  v:TVárakozók
  pm:TPMut

  p:=TPont(1.0,0.0,0.0)
  Üres(v)
  Létrehoz(pm,p); q:=TPMut(pm)   [l.
később]

o   Szelekciós operációk

Példa:


  hossz:=SQRT(p.x
^2+p.y^2+ p.z^2)
  vevő:=Első(v)
 

o   Azonosság és más relációk

Példa:


Típus
  TNap=(hétfő,kedd,szerda,csütörtök,péntek,
        szombat,vasárnap) [l.
később]
Konstans
  napSzám:Egész(Számosság’TNap) [l.
később]

Típus
  TNapNév=Tömb(1..napSzám:Szöveg)

Konstans
  SNapHu:TNapNév=
         (’hétfő’,’kedd’,’szerda’,’csütörtök’,
          ’péntek’,’szombat’,’vasárnap’)

  SNapEn=
         (’Monday’,’Tuesday’,’Wednesday’,
          ’Thursday’,’Friday’,
          ’Saturday’,’Sunday’)
Változó
  nN:TNapNév
  mn:TNap
  c:Karakter


  Ha c=’E’ és nN=SNapHu akkor nN:=SNapEn

  Ciklus amíg mn
péntek

o   Számosság-függvény

Példa:


Típus
  TNap=(hétfő,kedd,szerda,csütörtök,péntek,
        szombat,vasárnap)

Konstans
  napSzám:Egész(Számosság’TNap)
  SNap:Tömb(1..napSzám:Szöveg)=
       (’hétfő’,’kedd’,’szerda’,’csütörtök’,
        ’péntek’,’szombat’,’vasárnap’)

o   Min és Max típusoperátor, amelyek értelemszerűen csak rendezett típusok ese­tén léteznek. Nem keverendő össze az adatokra (nem típusokra!) alkalmazandó függvényekkel!

Példa:


Típus
  TNap=(hétfő,kedd,szerda,csütörtök,péntek,
        szombat,vasárnap)

Konstans
  SNap:Tömb(Min’TNap..Max’TNap:Szöveg)=
       (’hétfő’,’kedd’,’szerda’,’csütörtök’,
        ’péntek’,’szombat’,’vasárnap’)

Példa:


  első:=Sorszám(hétfő) [első:=0]
  utsó:=Sorszám(vasárnap) [utsó:=6]
  A_Kód:=Sorszám(’A’) [A_Kód:=65]

o   Be/Ki műveletek (konverzió az input/output és belsőábrázolás között)

Példa:


Változó
  nap:TNap

  Be: nap   [nap<Max’TNap]
  Ki: Következő(nap)

Példa:


Típus
  TPont=Rekord(x,y,z:Valós)
Változó
  kövNap,nap:TNap
  p,q:TPont

  kövNap:=Következő(nap)
  táv:=Hossz(p)-Hossz(q)  [Hossz a programozó
                           által definiált fv.]

3. Egyszerű Adattípusok

Alábbiakban definiáljuk az „eredendően” szerkezetnélküli ún. skalár típusokat, megadva ezek értékhalmazát, a hozzátapadó műveletek, relációk halmazát. Két típus „lóg ki” ezek közül. A szöveg (string) és a mutató típus. A szöveg típust azért soroljuk ide, mert a programozási nyelvek majd mindegyike fölkínálja, s így hozzátartozik az ún. elemi (natív) típusokhoz, más­részt abban jócskán eltér a későbbiekben tárgyalt összetettektől (s így oda még kevésbé illik), hogy elemeinek típusa nem választható meg szabadon. A mutató típus valóban szerkezet nél­küli, hisz értékhalmaza a memóriacímek egy részhalmaza (ezért tárgyaljuk itt), de az is két­ségtelen, hogy oly szorosan tapad valamely összetett típushoz, amely címét tartalmazza, hogy anélkül értelme sem lenne bevezetni.

A tárgyalt típusokról a következőket adjuk meg:

A rövid leírás kedvéért időnként alkalmazni fogjuk a Típ jelölést az éppen tárgyalt típusra va­ló hivatkozásra. (Értelemszerűen akkor, amikor a típus nevét a programozó feladata megadni.) Származtatott típus esetén pedig gyakorta a TB az ún. bázistípusra (amelyből kiindulunk) utal.

3.1. Elemi adattípusok

3.1.1. Egész

Értékhalmaz

-32768..32767 Ì Z
(MinEgész..MaxEgész)

Kezdőérték

0

Műveletek

+, , *, Div (egészosztás), Mod, - (unáris mínusz), ^ (pozitív egészkitevős hatványozás)
:=

=, <, , , >,
Be:, Ki:

Ábrázolás

ún. (16-bites) kettes komplemens kódú

Megjegyzés:

A programozási nyelvek többféle értékhalmazzal is felkínálnak efféle típusokat. Pl. a Turbo Pascal megkülönböztet BYTE, SHORTINT (8 bites); INTEGER, WORD (16-bi­tes); LONGINT (24 bites)… Ennek ellenére nem tartjuk fontosnak az algoritmikus nyelvben ezeket megkülönböztetni, annál is kevésbé, mert ha kell, a „szélsőséges érté­keire” tudunk hivatkozni a Min’Egész és Max’Egész típusfüggvénnyel anélkül, hogy letennénk a voksunkat bármelyik konkrét értékhalmaz mellett.

3.1.2. Valós

Értékhalmaz

???..??? Ì R
(MinValós..MaxValós)

Kezdőérték

0.0

Műveletek

+ , , * , /, - (unáris mínusz), ^
:=

=, <, , , >,
Be:, Ki:

Ábrázolás

ún. lebegőpontos ábrázolás (pontosabb lenne, ha e típust racionálisnak nevez­nénk, mert csak racionális számot képes ábrázolni), vagy
ún. pakolt decimális ábrázolás

Megjegyzések:

Vegyük észre, hogy ugyanazok a műveleti jelek most –ha hasonló jelentéssel is, de– mégsem egészen ugyanazzal a jelentéssel bírnak. (Polimorfizmus.)

Itt már föl sem vállaltuk az értékhalmaz pontosítását, mivel ez sokkal inkább implemen­tációfüggő, mint az egész számoké.

3.1.3. Logikai

Értékhalmaz

Hamis..Igaz Í L
(MinLogikai..MaxLogikai)

Kezdőérték

Hamis

Műveletek

nem, és, vagy
:=

=, <, ≤, ≥, >, ≠
Be:, Ki:

Ábrázolás

0 ≡ Hamis, –1 ≡ Igaz – azaz (valamely) egész típusra visszavezetés;
néha 1 ≡ Igaz – ekkor 1 bites az ábrázolás

3.1.4. Karakter

Értékhalmaz

0..255 -kódú jelek
(MinKarakter..MaxKarakter)

Kezdőérték

Min’Karakter

Műveletek

Karakter(.) Karakter: Egész→Karakter
Sorszám(.) – Sorszám: Karakter→Egész  (belső kód)
:=

=, <, ≤, ≥, >, ≠
Be:, Ki:

Ábrázolás

Valamely kódrendszer szerinti kód, mint előjelnélküli szám. (Fix bitszámú kód.)

Megjegyzés:

Sokfajta kód rendszer létezik (legismertebbek: ASCII, UNICODE). Többségük fix bit­számú (ASCII 8 bites, UNICODE 16 bites), de elképzelhető változó bitszámmal dolgo­zó is. (L. Huffman-kódolás.)

3.1.5. (Absztrakt)Felsorolástípus

Értékhalmaz

(konstans1, konstans2, ... , konstansN)  (Típ jelölje a típus azonosítóját)
(MinTíp=konstans
1..MaxTíp=konstansN)

Kezdőérték

Min’Típ vagy NemDef

Műveletek

Következő(Típ-típusbeli érték), Következő: Típ→Típ U {NemDef}
Előző(Típ-típusbeli érték), Előző: Típ→Típ U {NemDef}
Sorszám(Típ-típusbeli érték), Sorszám: Típ→Egész
Típ(egész típusú érték), Típ: [0..Sorszám(Max’Típ)]→Tip
:=

=, <, ≤, ≥, >, ≠ (a felsorolás sorrendje egyben rendezés is)
Be:, Ki:

Ábrázolás

A minimálisan szükséges bitszámú (»log2(Számosság’Típ)) kód, mint előjelnélküli szám.

Megjegyzések:

Az értékhalmazban szereplő, ismétlődés nélküli, szimbolikus nevek (a típus konstansai) nem lehetnek más típus (pl. egy másik felsorolástípus) értékhalmazában, ez a feltétel amiatt szükséges, mert a fordítóprogram így mindig egyértelműen el tudja dönteni a konstans „hovatartozását”. Természetesen „…” nem szerepelhet a felsorolásban, mivel a fordítónak nincsenek „előzetes elképzelései” arról, hogy mik lehetnének ott a felsoro­lásban.

Mindazon típusokat, amelyek értékkészletét konstansainak egyszerű fölsorolásával ad­hatunk vagy adhatnánk meg diszkrét típusnak hívjuk. Tehát ilyen az Egész, a Logi­kai, a Karakter, de lehet bármilyen –a program írója által kreált– absztrakt kons­tansokat tartalmazó fenti absztrakt felsorolástípus is.

Példa:

Típus
  TNap=(hétfő, kedd, szerda, csütörtök, péntek, szombat,
       
vasárnap)
Változó
 
tegnap,ma,holnap: TNap
Konstans
 
ünnepnap: TNap(vasárnap)

  Ha ma=Min’TNap akkor  tegnap:=Max’TNap
               különben tegnap:=Előző(ma)
  Ha ma=Max’TNap akkor  holnap:=Min’TNap
               különben holnap:=Következő(ma)
  első:=Sorszám(hétfő) [első:=0]
  utsó:=Sorszám(vasárnap) [utsó:=6]

3.1.6. (Rész)Intervallumtípus

Csak diszkrét típusból származtatható egyszerű típus. Jelöljük a bázistípust TB-vel.

Értékhalmaz

konstans1..konstans2  Í TB
(MinTíp=konstans
1..MaxTíp=konstans2)

Kezdőérték

Min’Típ vagy NemDef

Műveletek

TB-vel megegyező műveletek (korlátozva persze az értékhalmazra)

Ábrázolás

TB-vel megegyező ábrázolás

 

Példa:

Típus
  TNap=(hétfő, kedd, szerda, csütörtök, péntek, szombat,
        
vasárnap)
  TMunkanap=hétfő..péntek
  THétvége=szombat..vasárnap
Változó
 
tegnap,ma,holnap: TNap
Konstans
 
ünnepnap: TNap(vasárnap)

  Ha ma=Min’TNap akkor  tegnap:=Max’TNap
               különben holnap:=Előző(ma)
  Ha ma=Max’TNap akkor  holnap:=Min’TNap
               különben holnap:=Következő(ma)
  első:=Sorszám(hétfő) [első:=0]
  utsó:=Sorszám(vasárnap) [utsó:=6???]

Megjegyzések:

1.      Érdekes anomáliára vezet a Sorszám és Típ típuskonstrukciós függvény követ­kezetes bevezetése. Miért?

2.      Ha a diszkrétségtől eltekintünk, kiterjeszthető a Valósakra is az intervallumtípus-képzés. Ez persze csak azzal a többlettel képzelhető el, hogy egy lépésközt is meg­adunk a származtatáshoz (amelyre vannak persze elvárások).

3.      További általánosítás lehetséges: nem első és utolsó elem által meghatározott része egy értékhalmaznak, hanem valamilyen (predikátummal definiált) tulajdonságnak eleget tevő elemeinek részhalmaza.

Példa:

Típus
  TTermSzám=Egész
            [Típusinvariáns: i:Egész : i>0]
  TPrímek=TTermSzám
          [Típusinvariáns: n:TTermSzám : Prím?(n)]
          Függvény Prím?(Konstans x:Egész):Logikai
           
          Függvény vége.

3.1.7. Szövegtípus

Értékhalmaz

MaxHossz darabnyi jelből álló karakterláncok halmaza Ì Karakter*
(MinSzöveg..
MaxSzöveg)alfabetikus rendezés szerinti első (=üres szöveg); az utolsó erősen reprezentációfüggő, ezért nem definiáljuk.

Kezdőérték

’’ azaz üres-szöveg (Min’Szöveg)

Műveletek

+, Hossz(.), Balrész(.), Jobbrész(.), Jele(.)

:=

=, <, ≤, ≥, >, ≠
Be:, Ki:

Ábrázolás

Rekord(hossz:Egész, jel:Tömb(1..MaxHossz:Karakter)) – Pascal-stílusú
Karakter*
´ SzövegVégJel – C-stílusú

3.2. Mutató típusok

Az alcímbeli többes szám jogos, mert valójában tetszőleges (többnyire összetett) típushoz, mint bázistípushoz (TB) szervesen tartozhat egy-egy ilyen típus. Egy konkrét mutató típusú objektum csak egyfajta (nevezetesen TB-típusú) elemek kezdőcímeit hordozhatja. E szigo­rúság oka: az ellenőrizhetőség, biztonságosság.

Értékhalmaz

Memóriacím, amely valamely TB-típusú elem kezdőcíme, vagy Sehova
(rendezésnek nincs értelme
Þ Ø$MinTíp, MaxTíp)

Kezdőérték

Sehova

Műveletek

Lefoglal(Változó m:Típ, Konstans e:TB) – az eljárás létrehoz a memóriá­ban egy TB-elemet, amelynek értéke éppen ’e’, és a címét teszi ’m’-be; ha nincs elegendő hely, akkor ’m’-be Sehova érték kerül. Elhagyható a kezdő­értéket definiáló paraméter, ekkor a TB-beli iniciális értékű elem keletkezik.

Típ(Konstans m:Típ):TB – a függvény az ’m’-beli címnél kezdődő TB-ele­met adja vissza értékként

Felszabadít(Változó m:Típ) – az eljárás felszabadítja a memória ’m’-ben lévő címtől kezdődő TB-elemnyi tartományát, majd ’m’-be a Sehova érték kerül.

:=

=,, <, £, ³, >

Be:, Ki:

Ábrázolás

Memóriacím

Megjegyzések:

A Lefoglal művelet fent taglalt szemantikája is indokolja a szigorú típusosság kívá­nalmát!

A Pascal-beli Lefoglal művelet, a New, nem foglalkozik kezdőértékadással, sőt a helyfoglalás sikertelenségét sem közli a Sehova, vagyis a Nil értékkel. A Fel­szabadít, Dispose művelet sem törli a mutatót.

Példa:


Típus

  TBlokk=Tömb(1..MaxM:TElem)
  TBMut=TBlokk’Mutató
  TBlokkok=Tömb(1..MaxN:TBMut)

Változó
  e:TElem;    i:Egész
  b:TBlokk;   bk:TBlokkok;   bm:TBMut

  Ciklus i=1-től MaxN Div 2-ig
    Lefoglal(bm)  [bm-be kerül a lefoglalt TBlokk-nyi
                   terület címe, és a bm-nél kezdődő
                   tömb elemei TElem-kezdőértékűek]
    bk(i):=bm     [bk i. eleme a dinamikusan lefoglalt
                   tömb címe; értékmegosztás]
    … [a bk(i) tömbbe értékek kerülnek] …
  Ciklus vége
  b:=TBlokk(bk(1))  [az első blokk b-be]
  bm:=bk(1)         [az első blokk címe bm-be]
  Ciklus
i=1-től MaxM-ig
   
TBlokk(bm)(i):=e  [TBlokk(bm) bm-nél kezdődő blokk
                       mint tömb,
                       TBlokk(bm)(i) a tömb i. eleme]
  Ciklus vége

  [vajon milyen értékek vannak a bk(2..MaxN) elemekben;
   és mit mondhatunk a TBlokk(bk(2..MaxN)) értékéről?]

4. Összetett adattípusok – típuskonstrukciók

Helyesebb összetett típusok helyett típuskonstrukciókról beszélni, mivel valahány összetevő típusból hozunk létre, konstruálunk egy újat; s az ilyeneket létrehozni képes eszközöket típus­konstrukciós eszközöknek hívni.

Többnyire nem magától értetődő az ilyen struktúrák rendezése, ezért sem a Min’, sem a Max’ típusfüggvényt nem jelezzük. (Megjegyezzük: természetesen nem elképzelhetetlen –sőt!–, hogy utólag valamilyen rendezést rájuk is definiáljuk. Erről később még szó esik.)

A korábbi szokásos mondanivalók mellé bekerül a „konstrukció”, amelyben tisztázzuk az al­kalmazás szintaxisát.

Rövidítés miatt a bázistípusokat sorszámozzuk és így jelöljük: TB1, TB2, …

4.1. Összetett típusok osztályozásai

A bázistípusok sokfélesége szerint –

Rákövetkezési reláció az elemei között –

4.2. Rekord

Konstrukció

Rekord(mező1: TB1, mező2: TB2)

Értékhalmaz

TB1´TB2´

Kezdőérték

Az egyes komponensekhez tartozó kezdőérték.

Műveletek

Típ(Konstans m1: TB1, m2: TB2) – létrejön egy Típ típusú konstans m1, m2… mezőértékekből (konstrukciós operáció)

objTip.mezői:TBi – a „szokatlan” szintaxisú művelet értéke az adott Típ tí­pusú objektum (objTip) mezői mezőjének értéke… (szelekciós operáció)

objTip.mezői:TBi:=ei – a „szokatlan” szintaxisú értékadás eredménye az adott Típ típusú objektum (objTip) mezői mezőjének értékül adja ei-t…

:=

=,

Be:, Ki:

Ábrázolás

A mezők folytonos memóriaterületre képezve, a felsorolás sorrendjében.

4.3. Alternatív rekord

Olyan rekordféléről van szó, amelynek valamely mezőjétől (mezőitől) függ további mezőinek típusbesorolása.

Konstrukció

Rekord(
  mező1
: TB1, … mezőK: TBK,
 
Alternatívák
    felt1(mező1,…)
esetén (mező-k sorozata),
   
    feltm(mező1,…)
esetén (mező-k sorozata)
Alternatívák vége)

Értékhalmaz

TB1´…TBK´È(i=1..m)TBi,1´…TBi,ki

Kezdőérték

A nem egyértelműsége miatt NemDef.

Műveletek

A rekordhoz hasonlóan.

Ábrázolás

A mezők folytonos memóriaterületre képezve, a felsorolás sorrendjében, a hosszat a leghosszabb alternatívával számolva.

 

Példa:


Konstans
 
ffi: Egész(1)
 
: Egész(2)

Típus
  TDátum=...
  TNem=ffi..nő
  TKontroll=Függvény(TNem,Dátum,0..999):0..9

  Függvény Kontroll(Konstans n:TNem
                             d:TDátum
                             x:0..999):0..9
    [Kontroll: egy TKontroll típusú konkrét függvény]
   
  Függvény vége.

Típus

  TSzemSzám=Rekord(
    nem:TNem
    szülidő:TDátum
    sorszám:Egész
    ellenőr:TKontroll [itt csak olyan fv-típus képzelhető
                       el, amely értelmezési tartománya:
                       TNem
´TDátum´Egész; értékkészlete
                       most nincs megkötve])

  TSzemély=Rekord(
    szsz:TSzemSzám
    név:Szöveg
    Alternatívák
      nem=nő  esetén (lnév :Szöveg)
      nem=ffi esetén (katsz:Egész)
    Alternatívák vége)

Konstans
  Jézus:TSzemély((ffi,
                  1.12.25,
                  123,
                  Kontroll) [szsz mező tartalma],
                  ’Jézus Krisztus’ [név mező],
                  (123456) [nem=ffi
Þkatsz mező])

4.4. (Hatvány-)Halmaz

Csak diszkrét (többnyire nagyon is korlátozott számosságú) típusnak definiálhatjuk a hatvány­halmaz-típusát.

Konstrukció

Halmaz(TB)

(MinTíp=Æ..MaxTíp=TB-értékhalmaz, a tartalmazás alapján rendezve)

Értékhalmaz

TB*

Kezdőérték

Üres halmaz

Műveletek

Î (eleme), Ç (metszet), È (egyesítés), \ (különbség), Æ vagy Üres (üres halmaz létrehozás), Üres? (logikai értékű függvény)

:=

=, < (Ì), ≤ (Í), ≥ (Ê), > (É), ≠

Be:, Ki:

Ábrázolás

Tömb(TB:Logikai) – azaz bitvektor az adott elem tartalmazása vagy nem tartalmazása szerint;

Lista(TB) – tartalmazott elemeinek felsorolása [l. később]

 

Példa:


Típus
 
TÓra=0..23
  TNap=Halmaz(TÓra)

Változó
 
ma,holnap:TNap

Konstans
 
munkanap:TNap(7..12,14..20)

  Üres(ma)  [ma nincs kötött program
Þ ma „szabad”]
  Ha Üres?(holnap) akkor ma:=munkanap

4.5. Tömb

Konstrukció

Tömb(TIndex : TElem)

Értékhalmaz

TElemSzámoság(TIndex)

Kezdőérték

TElem típus kezdőértékei

Műveletek

objTip(i) (a Típ típusú objTip tömb i. TElem típusú eleme),
objTip
(i):=e (a Típ típusú objTip tömb i. eleme legyen ’e’ értékű)

:=

=,
Be:, Ki:

Ábrázolás

Az elemek folytonos memóriaterületre képezve, növekvő index sorrendben.

(L. később)

5. Sorozattípusok

Sorozattípusnak hívjuk azt a típust, amely

  1. homogén (azaz elemei egyetlen bázistípushoz tartoznak),
  2. egyértelmű rákövetkezési reláció van elemei között (az adott elemét legfeljebb egy elem követheti),
  3. egyetlen olyan eleme van, amelyet nem előz meg másik, s egyetlen olyan, amelyet nem követ.

5.1. Sorozatműveletek

Nagyon sokféle sorozattípus alkotható meg, mégha nem különböztetjük meg a különböző bá­zistípusúakat egymástól (azaz a strukturálisan azonosakat). Jellegzetes művelet-együttest ren­delve hozzájuk kapjuk a későbbiekben tárgyalt egyes, fontos alosztályait.

A legfontosabb műveletei, halmozva, a következők:

Művelet

Tevékenység-leírás

Üres

Létrehoz, elemek nélkül.

Létrehoz

Létrehoz, struktúrától függő elemekkel.

Üres?/Teli?

Ellenőrzi, hogy van-e eleme / bővíthető lenne-e?

ElemSzám

Hány eleme van?

Beilleszt

Struktúrától függő helyre új elemet illeszt.

Kihagy

Struktúrától függő helyről elemet hagy el.

Első/Utolsó

Első / utolsó elemének értékét adja.

Elejéről/Végéről

Leválasztja a sorozat első / utolsó elemét, értékét is visszaadja.

ElsőUtániak/UtolsóElőttiek

Eldobja az első / utolsó elemet.

Elejére/Végére

A sorozat első eleme elé / utolsó eleme mögé illeszt egy újat.

Elem

Struktúrától függően meghatározott elemének értékét adja vissza.

ElemMódosít

Struktúrától függően meghatározott elemének új értéket ad.

Elsőre/Utolsóra

A struktúra első / utolsó elem lesz az aktuális (ha volt ilyen).

Előzőre/Következőre

A struktúra aktuális eleme (ha volt ilyen) legyen az eddigit megelőző / követő.

Aszerint, hogy mely műveleteket engedjük meg, egy sorozatfélénél beszélhetünk az alábbi tí­puskonstrukciókról. Nem jelöljük az „altípus-osztályokat”, továbbá a tevékenységeket nem a „hagyományos” nevükön említjük.

Típuskonstrukció

Tevékenységhalmaz

Tömb

(Létrehoz, ElemSzám,) Elem, ElemMódosít

Lista

Üres, Üres?, Teli?, Beilleszt, Kihagy, Elsőre, Utolsóra, Előzőre, Következőre, Elem, ElemMódosít

Sor

Üres, Üres?, Teli?, ElemSzám, Első, Elejéről, Végére

Verem

Üres, Üres?, Teli?, ElemSzám, Első, Elejére, Elejéről

Táblázat

Üres, Üres?, Teli?, ElemSzám, Elem, ElemMódosít…

InputSzekvenciálisFile

Létrehoz, Üres?, Elejéről

OutputSzekvenciálisFile

Üres, Üres?, Teli?, Végére

DirektFile

Üres, Létrehoz, Üres?, Teli?, ElemSzám, Elem, ElemMódosít…

AsszociatívFile

Üres, Üres?, Teli?, ElemSzám, Elem, ElemMódosít…

5.2. Sorozatok ábrázolásának lehetőségei

Folytonos ábrázolás, amikor az elemeket a memóriában a kezdőcímtől szorosan egymásután helyezzük el.

Memória

 

 

 

 

Elemsorszám:

 

1.

2.

3.

N.

 

 

kezdőcím

 

 

 

 

 

 

Láncolt ábrázolás, amelynél az elemek a memóriában elszórva helyezkednek el, a rákövetke­zést mutatóval biztosítjuk.

Blokkolt ábrázolás ötvözi az előbbi kettőt úgy, hogy láncot hoz létre az elemek egy adott szá­mú elemet tartalmazó tömbjéből.

6. A modul mint a típusmegvalósítás kerete

6.1 Mi a típus?

Amit már tudunk – „statikus kellékek

Miket kell megadni ahhoz, hogy mondhassuk: a típust „teljesen” ismerjük?

A statikus kellékeken, ismereteken túl:

Mit értünk a típus megvalósítása alatt?

Annak definiálását, hogy milyen leképezést valósítanak meg az egyes műveletek (szemanti­ka-definíció), és hogyan lehet „megszólítani” őket (szintaktika-definíció):

  1. Definiálhatjuk csak a kapcsolatukat, egymásra hatásukat, axiómák megadásával. (Al­gebrai specifikáció)
  2. Definiálhatjuk az egyes műveletek „egyedileképezésének megadásával. Ez az export modul feladata, amely tartalmazza a szignatúrákat és –esetleg– az elő-utófeltételeket. (Algoritmikus specifikáció)
  3. Rögzíthetjük az egyes műveleteket „egyedimegvalósításukkal, amelyben már figye­lembe vesszük a típus már rögzített ábrázolását. Ez a reprezentációs-implementációs modul feladata.

A fenti 2-3.-at egyaránt vonatkoztathatjuk algoritmusra és konkrét programozási nyelvre. A következő („6.3. A modul”) fejezetben mi az algoritmikus nyelvünket bővítjük ki úgy, hogy kezelhető legyen benne e kérdéskör. Mivel nem állunk meg a puszta elmélet síkján tisztázzuk azt is („7. A modulfogalom és a Pascal nyelv” fejezetben), hogy az általunk használt lingua franca, a Pascal programozási nyelv, milyen lehetőséget ad mindehhez.

6.2. A típus algebrai specifikációjáról

Röviden utalunk a nyelv azon kiegészítésére, amelyben tisztázni fogjuk „globális” elvárásain­kat az adott típussal szemben. Ezt a legabsztraktabb elképzelést formálisan egy algebrai alapú nyelven írjuk le, az alábbi keretben:

Szintaktikai „minta”

Magyarázat

Típus TípusKonstrukció(paraméterek):

Asszociált műveletek:

 Operáció(értelmezési tartomány): Értékkészlet

 

 

A definiálandó típuskon­strukció „alkalmazási sablona” (feje).

Operációinak szignatú­rája (értelmezési tartomá­nya, értékkészlete)

Axiómák:

 Jelölések:

  objektum: Típus(paraméterek) =
                        értelmező megjegyzés

 

1o az axióma informális szövege ...

  a formalizált axióma

2o

 

Az operációk kapcsolatát leíró axiómák, és a ben­nük fölhasznált objektu­mok „deklarációi”.


Axióma-állítások esetleg kibővítve fontos következ­ményállításokkal.

Mint a példából is kiderül, alkalmazunk néhány konvenciót, amelyet most –az idő rövidsége miatt– nem taglalunk. (A részletekhez lásd a Típus-specifikációkban.)

Visszatérő példa legyen a hét napjainak típusa! Nézzük ennek egy lehetséges algebrai leírását! Megjegyzem: a példa nem „tipikus” bizonyos értelemben, mivel a napok típusa egy konkrét típus, így nem tudunk élni a fenti típus-specifikálási „nyelvezet” paraméterezési szolgáltatá­saival.

Példa:

Típus TNap:

Asszociált műveletek:

 Hétfő,Kedd,Szerda,Csütörtök,
 Péntek,Szombat,Vasárnap,
 Min,Max:TNap
 Számosság:Egész
[4]

 Létrehoz:TNap
 Lerombol(TNap)
 Következő(TNap):TNap
È {NemDef}
 Előző(TNap):TNap
È {NemDef}
 Sorszám(TNap):Egész
 TNap(Egész):TNap
È {NemDef}
 <(TNap,TNap):Logikai

Axiómák:

a:TNap

n:Egész

0o A minimális érték a Hétfő, a maximális a Vasárnap, a típus számossága 7.

   Számosság=7  Ù  Min=Hétfő  Ù  Max=Vasárnap

1o Létrehozás utáni értéke Hétfő.

   a=Létrehoz Þ a=Hétfő

2o Lerombolás után nincs értelme a műveletek (a Létrehoz kivételével) alkalmazásának.

   Következő(Lerombol(a))=NemDef  Ù 

3o Nem létezik Hétfőt megelőző és Vasárnapot követő.

   Előző(Hétfő)=NemDef Ù Következő(Vasárnap)=NemDef

4o A Következő és Előző műveletek egymás inverzei.

   $Előző(a) Þ Következő(Előző(a))=a  Ù

   $Következő(a) Þ Előző(Következő(a))=a

5o A Sorszám és TNap műveletek egymás inverzei.

   nÎ[0..Számosság) Þ Sorszám(TNap(n))=n  Ù
                    TNap(Sorszám(a))
=a  Ù
n
Ï[0..Számosság) Þ TNap(n)=NemDef

6o A fenti felsorolás sorrendjében növekvően rendezettek.

   Következő(Hétfő)=Kedd  Ù  Következő(Kedd)=Szerda …

7o A Hétfő sorszáma 0, a Vasárnapé 6.

   Sorszám(Hétfő)=0  Ù  Sorszám(Vasárnap)=6

Állítás: Sorszám(a)Î[0..Számosság); és a

  Sorszám(a)=a fenti felsorolásbeli pozíciója + 1.

Bizonyítás:

  Nyilvánvaló.

8o A felsorolásban előbb szereplő kisebb, mint bármely
későbbi.

   a<b  Û  Sorszám(a)<Sorszám(b)[5]

 

Megjegyzések:

6.3. A modul

Elsőként a programozói felületet leíró, ún. export modul szintaxisát adjuk meg:

ExportModul TípusNév(InputParaméterek):

   [most következnek az exportálandó fogalmak „értelmes” csoportosításban:]

  Típus  [ritkán van ilyenre szükség]
    Tip1,Tip2,... [csak azonosítók felsorolása!]

  Konstans  [ritkán van ilyenre szükség]
    Kons1,Kons2,...[a TípusNév típus néhány kiemelendő konstansa]

  [az alábbi részben soroljuk föl a típushoz tartozó tevékenységek „fejsorait”
   és működésüket leíró elő-utófeltételeket]

  Függvény Fv1(FormParam): FvTip1
    Ef: …
    Uf: …
  Függvény Fv2(FormParam): FvTip2
    Ef: …
    Uf: …
 

  Eljárás Elj1(FormParam)
    Ef: …
    Uf: …
  Eljárás  Elj2(FormParam)
    Ef: …
    Uf: …
 

  Operátor Op1(FormParam): OpTip1
    Ef: …
    Uf: …
  Operátor Op2(FormParam): OpTip2
    Ef: …
    Uf: …
  

Modul vége.

Megjegyzések:

Példa:

ExportModul Tömb(Típus TIndex : Típus TElem):

Modul vége.

  A fenti definíció után a felhasználás szintaxisa:


Típus
 Vektor=Tömb(1..9:Egész)

Ki fogjuk egészíteni az algebrai specifikáció műveletkészletét továbbiakkal is: egyenlőség-vizsgálattal, értékadással, beolvasás és kiírás műveletekkel, valamint a hibás elvégzés tényét rögzítő hiba-flag-et kezelő függvénnyel. (Ezek nélkül ugyanis felhasználhatatlan eszköz ma­radna a legtöbb típus, vagy mindenegyes esetben a programozónak külön kellene jól-rosszul ezekkel a műveletekkel kiegészítenie.) Mindezt annak ellenére tesszük, hogy sok esetben a progra­mozási nyelvek nem adnak mindegyikre (pl. a „típusos” be/ki-re) módot.

Egy-két típusnál szokatlan lehet valamely létrehozó, ill. leromboló művelet használatának ex­plicit felkínálása, mivel a programozási nyelvek legtöbb implementációja automatikusan gon­doskodik a létrehozásról. (Pl. Tömb, Táblázat, Statikus gráf.) A leírás teljességére való törekvés, illetve az esetleges „hagyományostól” eltérő ábrázolás lehetővé tétele mégis in­dokolttá tehetik ezt.

Nézzük visszatérő példánk egy lehetséges export modulját!

Példa:

ExportModul TNap: [kiindulási alap az algebrai leírás]
  Konstans
    Hétfő, Kedd, Szerda, Csütörtök, Péntek, Szombat,
   
Vasárnap:TNap

  Operátor Min:TNap
    Másnéven Min’TNap
    Ef: –
    Uf: Min=Hétfő

  Operátor Max:TNap
    Másnéven Max’TNap
    Ef: –
    Uf: Max=Vasárnap

  Operátor Számosság:Egész
    Másnéven Számosság’TNap
    Ef: –
    Uf: Számosság=7

  Függvény Következő(Konstans x:TNap):TNap
    Ef: x¹Vasárnap [v.ö. a 3. axiómával]
    Uf: Következő(Hétfő)=Kedd  Ù    [v.ö. a 6. axiómával]

  Függvény Előző(Konstans x:TNap):TNap
    Ef: x¹Hétfő [v.ö. a 3. axiómával]
    Uf: Előző(Kedd)=Hétfő  Ù    [v.ö. a 6.&4. axiómával]

  Függvény Sorszám(Konstans x:TNap):Egész
    Ef: –
    Uf: Sorszám(Hétfő)=0  Ù  [v.ö. a 7. axiómával]

  Függvény TNap(Konstans x:Egész):TNap
    Ef: xÎ[0..6]
    Uf: TNap(0)=Hétfő  Ù 

 

 

  Infix Operátor Egyenlő(Konstans x,y:TNap):Logikai
    Másnéven x=y
    [ezt a függvényt nem specifikáljuk, mert az „alapokat” firtatja, és
     elkerülhetetlenül circulum viciosus-ba ütköznénk]

  Infix Operátor LegyenEgyenlő(Változó x:TNap
                               Konstans y:TNap)
    Másnéven x:=y
    [ezt az eljárást nem specifikáljuk, mert az „alapokat” firtatja, és
     elkerülhetetlenül circulum viciosus-ba ütköznénk]

  Infix Operátor Kisebb(Konstans x,y:TNap):Logikai
    Másnéven x<y
    Ef: –
    Uf: Kisebb(Hétfő,y)  Û  y¹Hétfő  Ù 
       

  Operátor Be(Változó x:TNap)
    Másnéven Be:x
    Ef: InputÎ{’hétfő’,’kedd’,’szerda’…}
    Uf: Input=’hétfő’  Þ  x=Hétfő  Ù 

  Operátor Ki(Konstans x:TNap)
    Másnéven Ki:x
    Ef: –
    Uf: x=Hétfő  Þ  Output=’hétfő’  Ù 

  Függvény Hibás?(Változó x:TNap):Logikai
   [teszteli, hogy volt-e hibásan elvégzett művelet (pl. amelynek

    az előfeltétele nem teljesült) az adott TNap típusú (x) adatra;

    majd inicializálódik a hiba-flag]

Modul vége.

Megjegyzések:

·        A Létrehoz és Lerombol műveleteket kihagytuk az algoritmikus specifikációból. Ezzel eltértünk az algebrai specifikációtól. Ok: statikusan kívánjuk megvalósítani e felsorolástípust, építünk a blokk-struktúrájú nyelvek adatlétrehozó, -leromboló mecha­nizmusainak létére. (Gondoljon az eljárás-/függvény-paraméterekre és a lokális adatok kezelésére!) A Létrehoz-axióma persze még fel kell bukkanjon a megvalósításban a szükséges kezdőérték megadása miatt.

·        A Min, Max és Számosság konstansokat (prefix) 0-változós operátorként defi­niáltuk, s nem konstansként, mert alkalmazásuk speciális szintaxisú (típusparaméterű). Vegyük észre, hogy ezek a konstansok minden rendezett, illetőleg véges típus esetén értelmesek. Így a használó program szintjén való megkülönböztetés érdekében olyan szintaxist kell hozzájuk rendelni, amely lehetővé teszi a típushoz kapcsolást. Ilyen probléma nem vetődik föl a többi (Hétfő, Kedd stb.), natív konstanssal kapcsolat­ban. (Ez a magyarázata a Min’Típus, Max’Típus, illetve a Számosság’Típus kü­lönleges szintaxisának.)

Példa:


  Változó
    ma:TNap
    napDb:Egész


  Ciklus ma=Min’TNap-tól Max’TNap-ig
  
  Ciklus vége
  napDb:=Számosság’TNap

·        Látható, hogy akkurátusan törekedtünk –bármi áron is!–, hogy az utófeltételekben ne nyúljunk vissza más művelethez, csak saját „hatáskörben” definiáltuk az elvárásokat. Ha ezt az elvet nem tartottuk volna tiszteletben, akkor egyszerűen meg lehetett volna fogalmazni a := és = operátorok utófeltételét. Például:

Egyenlő.Uf: x=y Û Sorszám(x)=Sorszám(y).

Ekkor azonban könnyen előadódhatna az a helyzet, hogy egymásra kölcsönösen hi­vatkozva specifikáljuk őket, ami egy logikailag értelmezhetetlen specifikációt ered­ményezne.

·        Az értékadás és az értékazonosság operációkról feltesszük, hogy bitről-bitre történő másolást, illetőleg azonosságvizsgálatot jelent, ezért nem tartjuk fontosnak feltételek­kel körülbástyázni. Másrészt, ha ezt formálisan is le akarnánk írni, vissza kellene nyúl­ni (esetleg bit-szintű) reprezentációig, amit effajta specifikációnál elkerülendőnek te­kintünk.

·        Az időnként felbukkanó „” folytatás jelzése formálisan megengedhetetlen, azonban itt csupán egy példáról van szó, így megelégedtünk a kitalálható folytatás jelzésével.

·        Fölvethető kérdés: mennyire ugyanarról szól a kétféle specifikáció. Valóban ez külön vizsgálandó, sőt bizonyítandó probléma.

·        A „Be:” és „Ki:” operátorok működésénél két problémát kell tudni formalizálni:

1.      a külvilággal való kapcsolatét (amely karakteres alapú),

2.      SzövegTNap transzformációét.

Az 1. általános megoldására bevezettünk két függvényt. Az Input megadja azt a szö­veget, amelyet a beolvasó utasítás talál az input-pufferben; az Output szimbolizálja az output-puffer állapotát (azt a szöveget, amely kiíródik a végrehajtás során, pl. a képernyőre). Így a 2. probléma már kezelhetővé vált, hisz az adat és transzformáltja is egy-egy memóriabeli objektumban csücsül. Fel kell figyelnünk a szöveges és a „belsőállapotú” konstansok merev megkülönböztetésére (’hétfő’Hétfő…)!

·        Operátornak azt az alprogramot nevezzük, amely az eljárástól vagy függvénytől eltérő szintaxissal építhető be a programba (azaz hívható). Lehet Infix, ekkor a két operandus közé illeszkedik, lehet Prefix, ekkor megelőzi az egyetlen paraméterét, ill. Postfix esetben követi. S lehet „egyéni” szintaxisa, ekkor a Másnéven kulcs-szónál adhatjuk meg ezt. A leggyakoribb eset a Prefix, ezért ezt a minősítőt elhagyhatjuk.

·        Egyik-másik operátornál „meglepő” a paraméter hozzáférési joga. A várható konstans helyett változó lett azért, mert a végrehajtás során hiba következhet be, amely által az „állapota” kényszerűen és szándékunk ellenére megváltozik. (Következő, ElőzőHibás?. Nagyjából azoknál, amelyeknél nem üres az előfeltétel, tehát van „esélye” a hibás használatnak. Pontosan azoknál, amelyeknek bármi köze is van a hiba-flag-hez.)

Folytassuk a megvalósítást betetéző fogalommal, a reprezentációs-implementációs modullal, röviden a modullal! Ennek feladata, hogy amit eddig elterveztünk, azt kidolgozza: azaz tisz­tázza, hogy

  1. miként ábrázolható a típusbeli érték a memóriában, vagy bárhol (reprezentáció) és
  2. hogyan valósíthatók meg az egyes műveletek, figyelembe véve a választott ábrázolást (implementáció).

A modul-szintaxis a következő:

Modul TípusNév(InputParaméterek):

 Reprezentáció

 
  [a típusábrázoláshoz szökséges adatleíró „kellékek”:
   konstansok, saját típusok,
   a változó-deklarációs rész már magának a típusnak a „mezőit” határozza meg]

 Implementáció

  [itt szerepelnek az export-modulban „megjósolt”
   tevékenységek működésének részletezése…]

  Függvény Fv1(FormParam): FvTip1
    Ef: …
    Uf: …
   

  Függvény Fv2(FormParam): FvTip2
    Ef: …
    Uf: …
   

  Eljárás Elj1(FormParam)
    Ef: …
    Uf: …
    

  Eljárás Elj2(FormParam)
    Ef: …
    Uf: …
   

  Operátor Op1(FormParam): OpTip1
    Ef: …
    Uf: …
   

  Operátor Op2(FormParam): OpTip2
    Ef: …
    Uf: …
   

 Inicializálás

  [egy ilyen típusú adat létrehozása az itt leírt utasításokkal történik]

Modul vége.

Megjegyzések:

·         Az egyes műveletek egyedi specifikációját jelentő elő-utófeltétel párok, amennyiben megegyeznek az exportmodulbelivel, nyilván elhagyhatók. Természetesen „értelme­sen” igazítva a reprezentációhoz, újabb biztonsági támpontul szolgálhat a fejlesztés­hez. (Ekkor persze újabb feladatként járul az eddigiek mellé, hogy ezek következését az „elődjükből” be kell látni:
operációExportmodul.Ef Þ operációModul.Ef Ù operációModul.Uf Þ operációExportModul.Uf.)

A visszatérő példánk egy lehetséges moduljának töredékét tervezzük meg az alábbiakban. A reprezentációs döntésünk, hogy legyen minden TNap adatnak legyen egy hiba-flag-je.

Példa:

Modul TNap: [kiindulási alap az export modul]
 Reprezentáció

   Változó
     felsKód:Egész
     hiba:Logikai

   Konstans
     Hétfő:TNap(0,Hamis) [v.ö. a 7. axiómával]
    
Kedd:TNap(1,Hamis)
    
     Vasárnap:TNap(6,Hamis)

 Implementáció

  Operátor Min:TNap
    Másnéven Min’TNap
    Ef: –
    Uf: Min=Hétfő

    Min:=Hétfő
  Operátor vége.

  Operátor Max:TNap
    Másnéven Min’TNap
    Ef: –
    Uf: Max=Vasárnap

    Max:=Vasárnap
  Operátor vége.

  Operátor Számosság:Egész
    Másnéven Számosság’TNap
    Ef: –
    Uf: Számosság=7

    Számosság:=7
  Operátor vége.

  Függvény Következő(Konstans x:TNap):TNap
    Ef: x.felsKód¹6 [6] [azaz a 7. axióma szerint nem „Vasárnap”]
    Uf: Következő.felsKód=x.felsKód+1 [v.ö. a 6. és 7. axiómával]

    Ha felsKód=6

       akkor    Következő.hiba:=Igaz
       különben Következő.felsKód:=felsKód+1
  Függvény vége.

  Függvény Előző(Konstans x:TNap):TNap
    Ef: felsKód¹0
    Uf: Előző.felsKód=x.felsKód-1

   
  Függvény vége.

  Függvény Sorszám(Konstans x:TNap):Egész
    Ef: –
    Uf: Sorszám=x.felsKód [v.ö. a 7. axiómával és az Állítással]

   
  Függvény vége.

  Függvény TNap(Konstans x:Egész):TNap
    Ef: xÎ[0..6]
    Uf: TNap(0).felsKód=Hétfő.felsKód  Ù 

   
  Függvény vége.

  Infix Operátor Egyenlő(Konstans x,y:TNap):Logikai
    Másnéven x=y
    [ezt a függvényt nem specifikáljuk, mert az „alapokat” firtatja,
     és elkerülhetetlenül circulum viciosus-ba ütköznénk]
   
  Operátor vége.

  Infix Operátor LegyenEgyenlő(Változó x:TNap
                               Konstans y:TNap)
    Másnéven x:=y
    [ezt a függvényt nem specifikáljuk, mert az „alapokat” firtatja,
     és elkerülhetetlenül circulum viciosus-ba ütköznénk]
    
  Operátor vége.

  Infix Operátor Kisebb(Konstans x,y:TNap):Logikai
    Másnéven x<y
    Ef: –
    Uf: Kisebb(x,y) Û x.felsKód<y.felsKód [v.ö. a 8. axiómával]
   
  Operátor vége.

  Operátor Be(Változó x:TNap):
    Másnéven Be:x
    Ef: InputÎ{’hétfő’,’kedd’,’szerda’…}
    Uf: Input=’hétfő’ Þ x=Hétfő  Ù 
   
  Operátor vége.

 

  Operátor Ki(Konstans x:TNap):
    Másnéven Ki:x
    Ef: –
    Uf: x=Hétfő Þ Output=’hétfő’  Ù 

   
  Operátor vége.

  Függvény Hibás?(Változó x:TNap):Logikai
    Hibás?:=hiba; hiba:=Hamis
  Függvény vége.

 

 Inicializálás

   felsKód:=0; hiba:=Hamis

Modul vége.

Megjegyzés:

7. A modulfogalom és a Pascal nyelv

Amire mód van: algoritmikus specifikáció és a megvalósítás; amire nincs: az algebrai specifi­káció. Többféle (Turbo/Free) Pascal-nyelvi lehetőséget lehet a típusgyártás szolgálatába állí­tani:

Az nyilvánvaló, hogy a Pascal-ban

Algoritmikus

Þ

Pascal

Operátor Min:TNap
  Másnéven Min’TNap
  Min:=Hétfő
Operátor vége.

Þ

Procedure Min(Var minKi:TNap);
Begin
  minKi:=Hetfo
End;

Érdemes tudni, hogy

1.      a FreePascal-ban az előbbi korlátozást már feloldották, ui. record-értékű függvény definiálható;

2.      a Min’TNap / Max’TNap implementálása elhagyható, ui. létezik a típusokhoz egy Low / High típusargumentumú függvény. Így a Min’TNap / Max’TNap kódolá­sa történhet ily módon is:

Algoritmikus

Þ

FreePascal

…Min’TNap…
…Max’TNap…

Þ

…Low(TNap)…
…High(TNap)…

7.1. Unit

·         A unit szintaxisa igazodik a Pascal nyelvhez, így túl sok magyarázatra nincs szükség. Annyit elöljáróban: a unit egyesíti az exportmodul (Interface-rész) és a modul (Im­plementation-, inicializáló rész) fogalmat.

Unit TipusNev;{InputParaméterek}

 Interface

 
  {a kívülről láttatandó fogalmak:
   unit-ok, konstansok, típusok, változók; eljárások és függvények fejsorai}
 

 Implementation

 
  {az elrejthető reprezentációs dolgok:
   unit-ok, konstansok, változók, típusok, „saját” eljárások és függvények;
   az exportált eljárások és függvények törzsükkel együtt}
 

Begin

 
  {a típus adatainak inicializálását végző utasítások}
 
End.

Megjegyzések:

Például:  írható saját ClrScr eljárás, amelyben építhetünk a Crt unit hasonló nevű eljárására:


  Uses
…,Crt,…;
 
  Procedure ClrScr(Const cím:String);
  Begin
    Crt.ClrScr;
    Writeln(cím:40+(Length(cím) Div 2));
   
  End;

Begin

  ClrScr(’Ügyes kis program’);

Az alábbi példa bemutatja, hogyan lehet a TNap típust unit-tal megvalósítani. A Pascal nyelv fentebb említett kellemetlen vonásai miatt a TNap-értékű függvényeket procedure-ökkel he­lyettesítettük. (FreePascal-ban szebben is megvalósíthatjuk. Gyakorlásul tegyük is meg!)

Példa:

Unit TNapUnit;{InputParaméterek}

 Interface

  Type
    TNapK=0..6;
    TNap=Record felsKod:TNapK; hiba:Boolean End;

  Const
    Hetfo:TNap=(felsKod:0;hiba:False);
    Kedd:TNap=(felsKod:1;hiba:False);
   

  {ki tudja, h. a Pascal a deklarált adatnak milyen kezdőértéket juttat, ezért plusz
   műveletként az alábbit az asszociált műveletekhöz hozzávesszük:}
  Procedure Inic(Var x:TNap);
    {Ef: –
     Uf: x=TNap(0,Hamis)}

  Procedure Min(Var minKi:TNap);
    {Ef: –
     Uf: minKi=TNap(0,Hamis)}

 

  Function Szamossag:Word;
    {Ef: –
     Uf: Szamossag=7}

  Procedure Kovetkezo(Const x:TNap; Var kovetkezoKi:TNap);
    {Ef: x.felsKod<>6
     Uf: kovetkezoKi.felsKod=x.felsKod+1}

 

  {az alábbira nincs szükség, hiszen az értékadást ismeri a Pascal (:=):
  Procedure LegyenEgyenlő(Var x:TNap
                          Const y:TNap);
  }

  Function Egyenlo(Const x,y:TNap):Boolean;
    {Ef: …
     Uf: …}

  Function Kisebb(Const x,y:TNap):Boolean;
    {Ef: …
     Uf: …}

  Procedure Be(Var x:TNap);
    {Ef: Input ELEME (’HÉTFŐ’,’KEDD’,’SZERDA’…)
     Uf: Input=’HÉTFŐ’  Þ  x=Hetfo  ES  …}

  Procedure Ki(Const x:TNap);
    {Ef: –
     Uf: x.felsKod=0  Þ  Output=’HÉTFŐ’  ES  …}

  Function HibasE(Var x:TNap):Boolean;

 Implementation

  Type
   
TNapS=Array [TNapK] of String[9];

  Const
    NapS:TNapS=(’HÉTFŐ’,’KEDD’,’SZERDA’,
                ’CSÜTÖRTÖK’,’PÉNTEK’,
                ’SZOMBAT’,’VASÁRNAP’);

  Procedure Inic(Var x:TNap);
    {Ef: –
     Uf: x=TNap(0,Hamis)}
  Begin
    x.felsKod:=0; x.hiba:=False
  End;

  Procedure Min(Var minKi:TNap);
    {Ef: –
     Uf: minKi=TNap(0,Hamis)}
  Begin
    minKi.felsKod:=0; minKi.hiba:=False
  End;

 

  Function Szamossag:Word;
    {Ef: –
     Uf: Szamossag=7}

  Begin
    Szamossag:=7
  End;

  Procedure Kovetkezo(Const x:TNap; Var kovetkezoKi:TNap);
    {Ef: x.felsKod<>6
     Uf: kovetkezoKi.felsKod=x.felsKod+1}
  Begin
    With
x do
    Begin
      {Ef-ellenőrzés:}
      If felsKod=6 then
      Begin
      
 kovetkezoKi.hiba:=True;
Exit
      End;
      {művelet-törzs:}
      kovetkezoKi.felsKod:=felsKod+1
    End;
  End;

 

  Function HibasE(Var x:TNap):Boolean;

  Begin
    HibasE:=x.hiba; x.hiba:=False
  End;

Begin

End.

Megjegyzések:

Példa:

Program AProgram;
  Uses …,TNapUnit,….;
  Var
    tegnap,ma,holnap:TNap;
 

Begin
 

  Inic(ma); {most elhagyható lenne; miért?}
  Repeat
   
Write(’Milyen nap van ma?:’); Be(ma);
  Until not HibasE
(ma);

 
  Writeln(’Holnap:’);
  Kovetkezo(ma,holnap); Ki(holnap);
 

End.

Egy más elvű megoldást is találhatunk, ami azonban nem a modulból, hanem az exportmodul­ból indul ki. Ötlete a következő: a napok absztrakt felsorolását egészítsük ki egy további, pl. NemDef-fel elkeresztelt értékkel. Az előbbi TNapK és TNap kettőse helyett ábrázoljuk így:

Típus TNapK=(Hétfő, Kedd, Szerda, Csütörtök, Péntek,
             Szombat, Vasárnap, NemDef)

Változó érték:TNapK

Ekkor egyszerű értéktípusúak lesznek az eleddig rekord-típusú értéket szolgáltató függvé­nyek. Pl.:

Függvény Következő(Konstans x:TNap):TNap
  Ef: x
¹Vasárnap
  Uf: Következő(x)= Következő(érték)
[érték=TNapK(x)!]

  Ha érték=Vasárnap akkor   Következő:=NemDef
                   különben Következő:=Következő(érték)
Függvény vége.

Figyelem: itt semmi rekurzió nincs. Hiszen a definiálandó Következő függvény paramé­te­rének a típusa TNap, amíg a felhasznált Következőé TNapK.

A Pascal-megfeleltetés úgyszólván problémamentes:

 

 

 

Unit TNapUnit;

 Interface

   Type
     TNapK=(Hetfo,Kedd,Szerda,Csutortok,
            Pentek,Szombat,Vasarnap,NemDef);

    {a TNap=Record ertek:TNapK End helyett:}

     TNap=TNapK;

   Procedure Inic(Var x:TNap);
  
   Function
Kovetkezo(Var x:TNap):TNap;
  

 Implementation

    
 
  Procedure Inic(Var x:TNap);
    {Ef: –
     Uf: x=Hetfo}
    Begin
      x:=Hetfo
    End;
   

    Function Kovetkezo(Var x:TNap):TNap;
    {Ef: x<>Vasarnap
     Uf: x=Hetfo
 Þ Kovetkezo(x)=Kedd  ES …}
    Begin
      If x=Vasarnap then Kovetkezo:=NemDef
                    else Kovetkezo:=Succ(x)
    End;

  

7.2. Kódtöredék automatikus beillesztése

A unitok nyilvánvaló hátrányát igyekszik kiküszöbölni az „állomány automatikus beillesztés” lehetősége. A lényeg: a Pascal fordítóprogramot „rávesszük”, hogy a kódtöredéket tartalmazó fájlt a befoglaló program adott pontján illessze be. Ennek módja: {$i töredék-fájlnév} direktíva az adott helyen.

Példa:

           Legyen az alábbi töredék a TNap.inc nevű fájlban:

{TNap
 
InputParaméterek – ha lennének. Most nincs.
}

  Type
    TNapK=0..6;
    TNap=Record felsKod:TNapK; hiba:Boolean End;
    TNapS=Array [TNapK] of String[9];

 

 

 

  Const
    NapS:TNapS=(’HÉTFŐ’,’KEDD’,’SZERDA’,
                ’CSÜTÖRTÖK’,’PÉNTEK’,
                ’SZOMBAT’,’VASÁRNAP’);
 

  Procedure Inic(Var x:TNap);
    {Ef: –
     Uf: x=TNap(0,Hamis)}

  Begin
    x.felsKod:=0; x.hiba:=False
  End;

 

  Procedure Kovetkezo(Const x:TNap; Var kovetkezoKi:TNap);
    {Ef: x.felsKod<>6
     Uf: kovetkezoKi.felsKod=x.felsKod+1}

  Begin
    With
x do
    Begin
      {Ef-ellenőrzés:}
      If felsKod<>6 then
      Begin
      
 kovetkezoKi.hiba:=True; Exit
      End;
      {művelet-törzs:}
      kovetkezoKi.felsKod:=x.felsKod+1
    End;
  End;

 

 

           A felhasználás:

Program AProgram;
  Uses …;
 
  {$i TNap.inc – a TNap típus beillesztése}
  Var
    tegnap,ma,holnap:TNap;
 

Begin
 

End.

Megjegyzés:

7.3. Objektum-osztály

Objektum, helyesebben objektum-osztály fogalma számunkra azzal az előnnyel jár, hogy a programon belül megvalósíthatjuk a megfelelő típusfogalmat, azaz az értékhalmaz és műve­lethalmaz egységét, egységbezárását (encapsulation).[7] A szintaxisáról elegendő ennyit tudni:


  Type
   
TipusNev=Object
     

      {mező-deklarációk, amit itt az objektum
       attribútumainak vagy tulajdonságainak hívnak}
     
      {a típus műveleteinek, metódusainak fejsorai következnek:}
      Constructor EljC(…); {elhagyható}
      Destructor EljD(…); {elhagyható}
      Procedure Elj1(…);
     
      Function Fv1(…):TFv1;
     
    End;

    {a típus műveleteinek kifejtése:}
    Constructor TipusNev.EljC(…);
   
    Begin
     
    End;
    Destructor TipusNev.EljD(…);
   
    Begin
     
    End;
    Procedure TipusNev.Elj1(…);
   
    Begin
     
    End;

   
    Function TipusNev.Fv1(…):TFv1;
   
    Begin
     
    End;

 
  Var
    a,b,c:TipusNev;
 

Begin
 
  a.EljC(…); {az a objektum konstruktorának „hívása” a létrehozás kedvéért}
  a.Elj1(…); {az a objektum Elj1 műveletének „hívása”}
 

Megjegyzések:

Példa:

           Legyen a töredék az alábbi, ONap.inc nevű fájlban:

{Osztály ONap[8]

 
InputParaméterek – ha lennének. Most nincs ilyen.
}

  Type
    TNapK=0..6;
    TNapS=Array [TNapK] of String[9];
  Const
    NapS:TNapS=(’HÉTFŐ’,’KEDD’,’SZERDA’,
                ’CSÜTÖRTÖK’,’PÉNTEK’,
                ’SZOMBAT’,’VASÁRNAP’);

  Type
    ONap=Object
      felsKod:TNapK;
      hiba:Boolean;
      {ki tudja, h. a Pascal a deklarált adatnak milyen kezdőértéket juttat,
                  ezért plusz műveletként hozzávesszük:}

      Constructor Inic(Var x:TNap);
      Procedure Min(Var minKi:ONap);
      Procedure Max(Var maxKi:ONap);
      Function Szamossag:Word;
      Procedure Kovetkezo(Var x:ONap; kovetkezoKi:ONap);
      Procedure Elozo(Var x:ONap; elozoKi:ONap);
      Function Sorszam(Const x:ONap):Word;
      Procedure ONap(Var x:Word):ONap;
      Procedure Be(Var x:Word);
      Procedure Ki(Const x:Word);
      Function HibasE(Var x:ONap):Boolean;

    End;

 

 

    Constructor ONap.Inic;
      {Ef: –
       Uf: x=TNap(0,Hamis)}
    Begin
      felsKod:=0; hiba:=False
    End;

    Procedure ONap.Min(Var minKi:ONap);
      {Ef: –
       Uf: minKi=ONap(0,Hamis)}
    Begin
      minKi.felsKod:=0; minKi.hiba:=False
    End;

   

    Function ONap.Szamossag:Word;
      {Ef: –
       Uf: Szamossag=7}
    Begin
      Szamossag:=7
    End;

    Procedure ONap.Kovetkezo(Var kovetkezoKi:ONap);
      {Ef: felsKod<>6
       Uf: kovetkezoKi.felsKod=felsKod+1}
    Begin
      {Ef-ellenőrzés:}
      If felsKod=6 then
      Begin
      
 hiba:=True; Exit
      End;
      {művelet-törzs:}
      kovetkezoKi.felsKod:=felsKod+1
    End;

 

           A felhasználás:

Program AProgram;
  Uses …;
 
  {$i ONap.inc – az ONap osztály beillesztése}
  Var
    tegnap,ma,holnap:ONap;
 

Begin
 

  ma.Inic;
  Repeat
   
Write(’Milyen nap van ma?:’); ma.Be;
  Until not
ma.HibasE;
 
  Writeln(’Holnap:’); ma.Kovetkezo(holnap); holnap.Ki;
 

End.


 

Tartalom

Adatszerkezetek tárgy , 1. félév 1. előadás’2009 (vázlat) 1

1. Adatok jellemzői 1

1.1. Azonosító. 1

1.2. Hozzáférési jog. 1

1.3. Kezdőérték. 1

1.4. Hatáskör 2

1.5. Élettartam.. 2

1.6. Értéktípus. 2

2. Az értéktípus. 3

2.1. Az értéktípusról általánosságban. 3

2.2. Az asszociált műveletek osztályozása. 3

3. Egyszerű Adattípusok. 6

3.1. Elemi adattípusok. 7

3.2. Mutató típusok. 11

4. Összetett adattípusok – típuskonstrukciók. 12

4.1. Összetett típusok osztályozásai 13

4.2. Rekord. 13

4.3. Alternatív rekord. 13

4.4. (Hatvány-)Halmaz. 14

4.5. Tömb. 15

5. Sorozattípusok. 16

5.1. Sorozatműveletek. 16

5.2. Sorozatok ábrázolásának lehetőségei 17

6. A modul mint a típusmegvalósítás kerete. 17

6.1 Mi a típus?. 17

6.2. A típus algebrai specifikációjáról 18

6.3. A modul 20

7. A modulfogalom és a Pascal nyelv. 28

7.1. Unit 29

7.2. Kódtöredék automatikus beillesztése. 34

7.3. Objektum-osztály. 36

Tartalom.. 40

 



[1] Ez a helyzet az interpretált nyelvek (pl. az ún. szkript-nyelvek) esetében.

[2] A Valami1:+Valami2 utasítás szemantikusan ekvivalens a Valami1:=Valami1+Valami2 utasítással.

[3]   És most legkevésbé sem hagyjuk magunkat befolyásolni olyan programozási nyelvektől, amelyben a változók létrejöttét nem kíséri automatikus kezdőértékadás.

[4]  A konstansokat 0-változós függvényeknek tekintjük.

[5]  <:TNap´TNap→Logikai rendezés visszavezetése <:Egész´Egész→Logikai rendezésre.

[6]   Persze szebb lenne így írni:  …≠Vasarnap.felsKód.

[7]  Persze elismerjük, hogy ennél jóval több újdonságot rejt az objektumok fogalma, számunkra most ennyi pontosan elegendő.

[8] Az „O” a „T” helyett utalás, hogy „Objektum-Osztály”-ról van szó. Csak amolyan „szlávis” konvenció!