A lecke célja, hogy a programozással még frissen barátkozóknak segítséget nyújtson az algoritmus megírásához az első lépésektől a komolyabb tervezés megkezdéséig. Ebben a leckében a típus fogalma és az egyszerű típusok kerülnek bemutatásra.
Összetettség (strukturáltság) szempontjából beszélhetünk strukturálatlan (vagy skalár) típusról, ha (az adott szinten) szerkezetet nem tulajdonítunk neki; vagy strukturált (más szóval: összetett) típusról, ha (elemibb) összetevőkre bontjuk.
Például ha az (A[],N) vektort
Alapvető adatstrukturálási módok, amelyekkel egyszerűbbekből (bázistípusból) összetettebb (strukturált) adatszerkezetek készíthetők:
strukturálási mód | → | adatszerkezet |
|---|---|---|
keresztszorzat | → | rekord |
(megkülönböztetett) egyesítés | → | változó résszel rendelkező rekord (alternatív rekord) |
halmazképzés | → | halmaz |
iterált megadás | → | sorozatok: tömb, sor, fájl … |
Típusok megadása értékhalmazuk és a típushoz asszociált műveletek kettősének típusnévhez rendelését jelenti. Az értékhalmaz azon konstansok halmaza, amelyből veheti az ebbe a típusba tartozó adat értékeit. Ezen halmazok némelyike – a típus gyakori előfordulása miatt – eleve definiált szokott lenni (elemiek), és mintegy a továbbiak – összetettebbek – bázistípusaként használható föl. A típushoz asszociált műveletek az adott értékhalmazon értelmezett (és a típushoz szorosan kapcsolódó) operációkat (függvényeket, műveleteket) jelentik.
A következőkben példákat is adunk, amelyeket az adatleíró nyelv szintaxisának megfelelően írunk le. Előzetesen – és most nem részletezve – a következő jelöléseket fogjuk alkalmazni.
Névvel látjuk el a konstrukciónak megfelelő típust, hogy későbbiek során egyszerűen – csupán a nevével – lehessen hivatkozni rá:
Típus Típusnév = Típuskonstrukció [típusmegadás]
... ... [további típusdefiníciók]
Az egyes objektumokhoz (akár konstans, akár változó) hozzárendeljük a típusukat, amely rögzíti, hogy milyen halmazból vehetik az értékeiket, és milyen operációk vonatkozhatnak rájuk:
Változó objektumnév : Típusnév
... ... [további deklarációk]
A konstansok deklarálásának két lehetősége.A változók kezdőértékadása a konstansokhoz hasonlóan történhet meg.
Az alábbiakban a típusokhoz hozzárendelendő, hozzáértendő, asszociálható műveleteket csoportosítjuk: értékadás, típusátviteli függvény (konstrukciós, szelekciós függvények, azonosság és más reláció, Számosság, Min- és Max-, Rend-függvény), transzformációs és egyéb függvények.
Az értékadás azonos típusúak közötti adatmozgatás, másolatkészítés. Az értékadás műveleti jele a :=; szemantikája: a céladat értéke ettől a pillanattól kezdve ugyanaz, mint a tárgyadaté (a következő módosításig). A későbbiekben látni fogjuk, hogy nem egyetlen lehetőség az értékadás megvalósításánál a fenti értékmásolás, hanem sok esetben – különösen nagy terjedelmű, dinamikusan épített struktúrák esetében, vagy cím szerinti paraméterátadásnál – értékmegosztással rendelődik az új érték a struktúrához. Ez azt jelenti, hogy ugyanazon memóriatartomány – az érték – több objektumhoz is hozzátartozik. Így nem várt jelenségek is előfordulhatnak: egyes objektumok értékei váratlanul megváltoznak.
A típusátviteli függvények valamely típus értékeit egy másik típus értékeire képezik le.
A típusátviteli függvényeknek nevezetes fajtái vannak, ezek: konstrukciós, szelekciós, illetve speciális (de nélkülözhetetlen) egyéb függvények. Tudnivalók ezekről:
Konstrukciós függvények
Strukturált érték létrehozása (egyesítése) komponensek értékeiből. A függvény neve mindig az adott típus nevével egyezik meg, paraméterei a típusdefinícióban szereplő (al)típusú adatok (definíciós sorrendben) lehetnek. Ha felsorolás- vagy intervallumtípusra (ezeket lásd később) alkalmazzuk, akkor a függvény jelentése értelemszerűen megváltozik. Nevezetesen: a típus értékkészletének argumentumadik konstansát adja értékül. Elemi típusokra alkalmazva (ennek csak konstans deklarálásánál van értelme) magát az argumentumot jelenti (tehát mint egy identikus függvény működik).
Típus Hely = Tömb[1..3:Valós]
Változó pont : Hely
...
Ekkor a Hely(2.0,4.0,6.0) függvény értéke a (2.0,4.0,6.0) valós értékű vektor maga. Így az értékadás utasítást felhasználva a következő tömörítésre van módunk:
Értékadások szekvenciája | → | Egyesített értékadás |
|---|---|---|
pont[1]:=2.0 pont[2]:=4.0 pont[3]:=6.0 | → | pont:=Hely(2.0,4.0,6.0) |
Van úgy, hogy a konstrukciós függvény elrejtve tevékenykedik: amikor a Be: vagy a Ki: utasítás hajtódik végre, akkor automatikusan konverzió történik a Szöveg és az argumentumbeli objektum típusa között. Vagyis a Ki: esetén egy Szöveg-konstrukció zajlik, amíg a Be: esetében egy más típusú érték születik.
Szelekciós függvények
Strukturált adat komponenseihez való hozzáférés eszköze. Ezen függvény jelölését illetően – s a néven túli formalizmusra gondolunk (pl. infix, prefix stb.) – igen nagy változatosság jellemző a nyelvekre.
Típus Hely = Tömb[1..3:Valós]
Változó pont : Hely
x : Valós
...
x:=pont[2]
...
értékadásban a pont[2] kifejezésben a '[.]' szelekciós függvényt használtuk a Helyvektor 2. komponensének (2. vektorkoordinátájának) kiválasztására; vagy a
pont:=Hely(pont[1]^2,pont[2]^2,pont[3]^2)
értékadásban a pont vektor 1., 2. és 3. koordinátáinak négyzetéből összeálló vektor szerepel a jobb oldalán, amelyet (egy Hely típusú tömbértékké egyesít a Hely konstrukciós függvény) ugyancsak a pont vektor kap értékül.
Vannak explicit névvel ellátott szelekciós függvények. Erre példa a vermekre vonatkozó alábbi részlet. Vegyük észre, hogy annak ellenére soroltuk a szelekciós függvények közé, hogy formálisan nem is függvényeljárásként írtuk! Vagyis nem a leírás módja a fontos, hanem az elvégzett leképezés milyensége!
Típus Veremtip = Verem(Egész)
Változó v : Veremtip
e : Egész
…
Veremből(v,e) [v→e]
…
Itt a Veremből(.) tevékenység a tulajdonképpeni szelekciós függvény maga.
Azonosság
Két, azonos típusú adat értékegyezőségét vizsgáló logikai értékű függvény. (A legfontosabb konverziós függvényként is tekinthetjük.) Jele az = (egyenlőségjel).
Típus Hely = Tömb[1..3:Valós]
Változó pont : Hely
…
pont:=Hely(4.5, 5.2, 8.9)
…
értékadás után a pont=Hely(4.5, 5.6, 7.8) reláció értéke hamis.
Számosságfüggvény
Megadja (ha megadható), hogy mennyi az adott típus számossága, azaz az értékhalmazát alkotó konstansok száma. Fontos tudni, hogy ez nem véges típusokra implementációfüggő értékű! (Lásd még a Rend-függvényt, továbbá a későbbi példákat!)
Min/Max függvény
Az értékhalmaz legkisebb, illetve legnagyobb eleme (feltéve, hogy rendezett típusról van szó). A függvény nevére az alábbi konvenció érvényes: Min-nel vagy Max-szal kezdődik, és a típus nevével folytatódik (mintha az adott típus első, illetve utolsó konstansa lenne). Annak érdekében, hogy ne korlátozzuk a szabad azonosítóválasztást, a függvénynév két részét egy olyan karakterrel választjuk el, amely egyéb célú fölhasználása igen ritka, ez a jel az aposztróf ('). Természetesen az azonosítókban való alkalmazásánál ezt figyelembe kell venni! (Nem véges típusnál implementációfüggő vagy nem definiált!)
Típus Index = 0 .. 99
Változó n,m,i : Egész
…
n:=Max'Index; m:=Min'Index; i:=Számosság'Index
…
egyenértékű az n:=99; m:=0; i:=100 értékadásokkal (mivel az Index típus (indextípus) minimális értékű konstansa a 0, a maximális pedig a 99).
Rend-függvény
Rendezett típus esetén az adat értékhalmazbeli sorszámát szolgáltatja. (Nem véges típusnál implementációfüggő vagy nem definiált!) Érdemes észrevenni az előbbi függvények kapcsolatát: Számosság'Típus-1=Rend(Max'Típus)!
Típus Index = -3 .. 3
Változó n,m: Egész
…
n:=Rend(Index(-3)); m:=Rend(Index(3))
…
egyenértékű az n:=0; m:=6 értékadásokkal; ugyanis az intervallumtípus a belső ábrázolásban mindig 0-tól folyamatosan rendeli az intervallumbeli konstansokhoz a (belső) indexeket, egészen a Rend(Max'Típus)-1-ig.
Egyéb relációk
Csak rendezett típusokon a szokásos <, ≤, >, ≥, ≠ relációk.
A transzformációs függvények a típuson (esetleg direktszorzatán) értelmezett, a típusra képező függvények. Ezek – értelemszerűen – típustól függően mások és mások lehetnek.
Például:
Például idesorolhatjuk azokat a transzformációs függvényeket, amelyek kivezetnek az értelmezési tartomány típusából, vagy vegyes típusúak (ti. az értelmezési tartományuk), de specialitásuknál fogva nem kerültek egyik korábbi függvényosztályba sem.
Például:
értelmezési tartomány típusa | → | értékkészlet típusa |
|---|---|---|
egész × vektor | → | vektor |
vektor × vektor | → | vektor |
vektor × mátrix | → | vektor |
Néhány – javarészt a sorozattípusúakra vonatkozó – függvényt is idesorolhatunk, amelyek feladata például egy komponens elérésének csupán előkészítése.
a Következőre(l) vagy az Előzőre(l) függvények egy l Lista típusú objektumra vonatkozólag.
Utolsó megjegyzésként a típusokról általánosságban:
Amikor egy típus kerül szóba a programírás során, akkor az összes vele kapcsolatos kellékére gondolunk, úgy a konstansaira, mint az asszociált műveleteinek teljes garnitúrájára (Min, Max, Rend-, Sorszám- és transzformációs stb. függvények, operátorok ...). Ez különösen akkor válik nem magától értetődő, sőt fontos megjegyzéssé, amikor a típust mint paramétert szeretnénk kezelni.
Ebben a fejezetben az a célunk, hogy definiáljuk az eredendően szerkezet nélküli típusokat. Megadjuk ezek értékhalmazát, a hozzá tapadó műveletek, relációk körét. A definíció mikéntjét a szokás és a kívánalom határozza meg.
-32768..32767
(Min'Egész..Max'Egész)
+, -, *, Div (egészosztás), ^ (pozitív egészkitevős hatványozás), Mod, - (unáris mínusz) .
=, <, ≤, >, ≥, ≠.
ún. kettes komplemens kódú.
Kettes komplemens kódú ábrázolás.Változó i : Egész
Konstans N : Egész(35)
A fentiek a 16 bites Egész típusról szólnak. A programozási nyelvekben általában többféle Egész típus is létezik. Ezeket az ábrázolás hossza különbözteti meg. Például a c++ int-je 4 bájtos, így a Min’int=-2147483648, a Max’int=2147483647; a fenti Egész típust short-nak (short int-nek) nevezik.
????..????
(Min'Valós..Max'Valós nem definiáltak, vagy implementációfüggő)
+, -, *, /, ^, - (unáris mínusz).
=, <, ≤, ≥, >, ≠.
ún. lebegőpontos ábrázolás (mint az alábbiakból kitűnik, pontosabb lenne, ha e típust racionálisnak neveznénk, mert csak racionális számot képes ábrázolni) .
A lebegőpontos számábrázolás.Változó r : Valós
Konstans pi : Valós(3.141592)
Hamis..Igaz
(Min'Logikai..Max'Logikai: Hamis, illetve Igaz)
nem, és, vagy (a szokásos logikai műveletek) .
=, <, ≤, ≥, >, ≠ (a belső ábrázolásuk alapján).
0 = Hamis, -1 = Igaz (néha 1 = Igaz) .
Változó siker : Logikai
Konstans nem : Logikai(Hamis)
0..255-kódú jelek
(Min'Karakter..Max'Karakter: a 0, illetve a 255 kódú karakter)
nincs .
=, <, ≤, ≥, >, ≠ (a belső ábrázolásuk alapján).
Valamely ún. karakter-készlet alapján. Példaként az ASCII karakter-készletből lássunk néhány kód-hozzárendelést:
Változó betű : Karakter
Konstans szóköz : Karakter( )
vagy
Konstans szóköz : Karakter(32)
Mindazon típusokat, amelyek értékkészletét konstansainak egyszerű fölsorolásával adhatjuk meg, diszkrét típusnak hívjuk. Speciálisan tehát ilyen az egész, a logikai, a karakter, de lehet bármilyen – a program írója által kreált – absztrakt konstansokat tartalmazó ún. absztrakt felsorolástípus is.
( konstans1, konstans2, ... , konstansN )
(Min'Típus..Max'Típus: konstans1..konstansN)
A konstansok maguk a típus értékkészletét meghatározó rendezett absztrakt értékek.
a rendezettségre építenek az alábbi függvények; nem értelmezett helyeken nem definiált az értékük:
A deklarációban a kezdőérték megadásához a korábbi szokás szerint használható a Típusnév nevű konstrukciós függvény. Emellett azonban a végrehajtáskor sokszor jó haszonnal jár az alábbi értelmezésű párja:
Típusnév(0..Rend(Max'Típusnév)).
Ez utóbbi függvény jelentése: a paraméterként megadottadik típusbeli konstans. Tehát mintha ez a Rend-függvény inverzeként viselkednék!
=, <, ≤, ≥, >, ≠ (a felsorolás sorrendje egyben a rendezés is).
Típus Hét = ( hétfő, kedd, szerda, csütörtök, péntek, szombat, vasárnap )
Változó tegnap, ma, holnap : Hét
Konstans ünnepnap : Hét(vasárnap)
i : Egész
…
tegnap:=Előző(ma); i:=Rend(ma)
Ha ma=Max'Hét akkor holnap:=Min'Hét
különben holnap:=Következő(ma)
…
konstans1..konstans2
(Min'Típus..Max'Típus: konstans1..konstans2)
A származtatás által meghatározott bázistípus adott részhalmaza, helyesebben részintervalluma.
ugyanazok, amik a bázistípuson értelmezettek (a felsorolástípusoknál említett típuskonstrukciós függvényt itt nem definiáljuk; lásd a példa utáni megjegyzést!).
ugyanazok, amik a bázistípuson értelmezettek.
Típus Hét= (hétfő, kedd, szerda, csütörtök, péntek, szombat, vasárnap)
Munkanap = hétfő..péntek
Hétvége = szombat..vasárnap
Konstans utolsónap : Munkanap(péntek)
Változó mnapindex : Munkanap
Megjegyzés a típuskonstrukciós függvény nem egyértelműségéről:
valós kons1 .. valós kons2 valós kons3-lépéssel
(Min'Típus..Max'Típus: kons1.. kons2)
Olyan valósakat tartalmaz, amelyek előállíthatók a kons1+i*kons3 formulával, ahol i = 0..(kons2-kons1) / kons3.
Korlátozott valós műveletek (csak a formulával előállíthatók jöhetnek ki – automatikus kerekítéssel, ha szükséges), vagy ha nem ilyen, akkor mint egyszerű valós értékkel lehet csak továbbszámolni.
valós relációk.
Konstans LépésKöz : Egész(0.01)
Típus TrigÉrt = -p..p LépésKöz-lépéssel
Konstans Középső : TrigÉrt((((Max'TrigÉrt-Min'TrigÉrt) / LépésKöz) / 2)
*LépésKöz+Min'TrigÉrt)
Változó x : TrigÉrt
Egy érdekes általánosítása az intervallumtípusnak: nem első és utolsó elem által meghatározott része egy értékhalmaznak, hanem valamilyen (predikátummal, azaz logikai formulával definiált) tulajdonságnak eleget tevő elemeinek részhalmaza.
BázisTípus(x : predikátum(x))
Olyan x∈{BázisTípus}, amelyre a predikátum(x) teljesül.
Korlátozott BázisTípus műveletek, ha ez kivezet az értékhalmazból, akkor már csak mint BázisTípus értékkel lehet manipulálni. Minden speciális, csak rá vonatkozó műveletet külön eljárás, illetve függvény formájában kell definiálni. Elsőként magát a predikátumot. Mivel nem feltétlenül alkotnak összefüggő halmazt, ezért a rákövetkezés sincs eleve definiálva.
BázisTípus relációk.
Típus TermészetesSzám = Egész(i : i>0)
PrímSzám = TermészetesSzám(n : Prím?(n))
Függvény Prím?(Konstans x:TermészetesSzám): Logikai
...
Prím?:=...
Függvény vége.
Az adatokkal és elemi típusokkal kapcsolatos tudnivalókat foglaltuk össze az alábbi animációban:
Végezetül figyelmébe ajánljuk a következő dokumentumokat:
![]() ![]() |
![]() |
![]() |