kategória | ||||||||||
|
||||||||||
|
||
Összetett adattípusok (adatábrázolás, értéktartomány, konstansok, mûveletek, fontosabb függvények, eljárások)
A programozási munka során gyakran találkozunk olyan feladattal, amelynek
megoldásához nem megfelelõek az egyszerû adattípusok. Pld:
Olvassunk be 10 egész számot, majd írjuk ki növekvõ sorrendben. A
feladat megoldása elképezelhetõ egyszerû adattípusok
alkalmazás 727h76h ával is, de létezik ennél sokkal hatékonyabb, gyorsabb megoldás is.
Az ilyen jellegû problémák során alkalmazzuk az összetett típusokat. Az
összetett (másnéven struktúrált) típusok jellemzõje - ellentétben az
egyszerû típusokkal - hogy egyszerre több érték tárolására is képesek. A
struktúrált típusok egyszerû típusokból - ún. komponens típusokból -
felépített, bonyolultabb adattípusok. A Pascal nyelvben használható összetett
adattípusok:
- Tömb típusok
- File típusok
- Record típus
- Halmaz típus
- Objektum típus
A tömb típusok:
A tömb típus olyan összetett típus, amely több azonos típusú érték
egyidejû tárolását teszi lehetõvé. Homogén adathalmaz, elemeinek
típusa nem lehet eltérõ.
Deklarációja:
Var Tomb: Array [n..m, n1..m1, n2..m2, ... , nn..mn] of elemtípus;
A fenti deklaráció a tömbök deklarációjának
általános alakja. A tömb lehet egy vagy több kiterjedésû (dimenziójú) is.
A gyakorlatban leggyakrabban az egy és kétdimenziós tömböket használjuk. (Az
egydimenziós tömböt vektorként, a kétdimenziós tömböt mátrixként szokták
emlegetni.) Az általános deklarációban látható módon szögletes zárójelek között
kell megadni a tömb elemeinek számát (dimenziónként), az elemek számát
résztartományként határozzuk meg.
Az elemek számának meghatározása után meg kell adnunk az elemek típusát is,
amely tulajdonképpen bármilyen (a tömb deklarációjának helye elõtt már
ismert) típus lehet, akár felhasználó által definiált típus is. Egyetlen fontos
megkötés, hogy amennyiben összetett típust szeretnénk megadni a tömb
elemtípusaként, az összetett típushoz a tömb deklarációja elõtt hozzá
kell rendelni egy típusnevet. (Hasonló megkötés, mint a függvények, eljárások
paraméterezésénél.) Nézzünk néhány példát a tömbök deklarációjára:
Öt elemû tömb, mely egész értékeket tartalmazhat: Var T: Array [1..5] of Integer;
Háromelemû tömb, melynek elemei stringek: Var T: Array [1..3] of String;
3x3-as mátrix, amely karaktereket tárol: Var M: Array [1..3, 1..3] of Char;
6x2-es mátrix, amely valós értékeket tárol: Var M: Array [1..6, 1..2] of Real;
A következõ deklarációs részben olyan tömböt deklarálunk, amely felhasználó által definiált (felsorolt) típusú elemek tárolására alkalmas.
Type Het= (Hetfo, Kedd, Szerda, Csutortok,
Pentek, Szombat, Vasarnap);
Var Napok: Array [1..4] of Het;
...
A bonyolult tömbök deklarációja során a tömbtípust általában külön típusként szoktuk deklarálni, azaz ahelyett hogy a deklarációs részben többször leírnánk ugyanazt a tömbtípust, külön nevet rendelünk hozzá, kihasználva a felhasználói típus létrehozásának lehetõségét.
Type Matrix= Array [1..5, 1..3] of Longint;
...
Var Tomb: Matrix;
Tomb2: Matrix;
...
A tömbök deklarálhatók típusos konstansként is. Ebben az esetben a 3. tételben
leírtaknak megfelelõen a deklarációs részben a const foglalt szó után
deklaráljuk a tömböt. A típusos konstansként deklarált tömbnek a
következõ formában adhatunk kezdõértéket:
Const Tomb: Array [1..5] of byte= (1, 2, 3, 4, 5);
Nagyon fontos, hogy a zárójelek között szereplõ értékek száma pontosan annyi lehet, amennyi a tömb elemszáma. Ha ettõl eltérünk, a fordító hibaüzenetet küld.
Természetesen a többdimenziós tömbök is szerepelhetnek a programban típusos konstansként. Nézzünk erre is egy példát:
Const Matrix: Array [1..2, 1..4] of Char=
(('A', 'C', 'E', 'G'),
('B', 'D', 'F', 'H'));
A példában egy 2 sorból és 4 oszlopból álló mátrixot deklaráltunk.
Tehát a kétdimenziós tömbök deklarációja során az elsõ szám a sorok számát, a második szám az oszlopok számát határozza meg!
Az értékadás során itt is zárójelek között adtuk meg a tömb elemeinek értékét. Figyelni kell arra, hogy az értékeket sorfolytonosan adjuk meg, minden sor zárójelbe kerül, a sorokat vesszõvel választjuk el.
A tömbök nem szerepelhetnek
a programban típusnélküli konstansként.
A tömbök memóriában foglalt méretét kiszámolhatjuk az elemtípus mérete és az
elemszám szorzataként. Az utolsó példa Matrix nevû tömbje: 2*4=8 elemet
tartalmaz, azaz mérete 8 byte (a Char 1 byte-os).
A tömbök memóriában történõ ábrázolása a tömb dimenzióinak számától
függõen másképpen történik. Egydimenziós tömbök esetében az elemek
tárolása sorban történik, az egyes elemek egymás után következnek. Kétdimenziós
tömbök esetében a tárolás sorfolytonosan van megvalósítva. Tehát az egy sorban
(logikai sor) található elemek egymás után helyezkednek el a memóriában.
Egydimenziós tömbök ábrázolása:
Tomb[1], Tomb[2], Tomb[3], Tomb[4], Tomb[5]
Kétdimenziós tömbök ábrázolása:
Matrix[1,1], Matrix[1,2], Matrix[1,3],
Matrix[1,4], Matrix[2,1], Matrix[2,2], Matrix[2,3], Matrix[2,4]
Az memóriabeli ábrázolás módját természetesen
befolyásolja a tömb elemtípusa is, de a fenti elvek minden elemtípus esetében
érvényelülnek.
A változóként deklarált tömbök a program futása során kapnak értéket. Leggyakoribb eset az elemenkénti értékadás, azaz a tömb elemeinek értékét egyenként határozzuk meg. A tömb elemeire a tömbnév után kapcsos zárójelek között megadott indexszámmal tudunk hivatkozni. Pld: Tomb[1]:= 4;
A tömbök közötti közvetlen értékadás csak abban az esetben lehetséges, ha a két tömb azonos típusú. A típusazonosságnál azonban nem elégséges feltétel, az elemek számának és típusának azonossága (nem értem miért!?). Egy példán szemléltetve:
Var T1, T2: Array [1..5] of Integer;
T3: Array [1..5] of Integer;
Begin
...
T1:= T2;
T3:= T2;
...
End.
Fontos mûvelet lehet a tömbök összehasonlítása (egyenlõségvizsgálat) is, amely szintén csak azonos típusú tömbök esetében végezhetõ el. Az elõbbi példánál maradva:
...
T1=T2;
T2=T3;
...
A tömbök kezelése során figyelni kell az
indexhatárok átlépésére, amely alapértlmezés szerint fordítási hibához vezet. A
tömb indexének szélsõ értékeit lekérdehetjük a Low és High függvények
segítségével.
A Low függvény a tömb legkisebb indexének értékével tér vissza, a High a
legmagasabb indexértéket szolgáltatja. Pld.:
Var T1, T2: Array [1..5] of Integer;
Begin
Writeln('Also hatar: ', Low(T1));
Writeln('Felso hatar: ', High(T1));
End.
A file típusok:
A file típusok lehtõvé teszik a háttértárakon
található adatállományokhoz történõ hozzáférést, biztosítják azok
kezelését a Pascal programból. Bõvebben lásd a 10. tételben.
A record típusok:
A record típus egy olyan összetett
adatszerkezet, amely egyszerre több adatot képes tárolni, az adatok
különbözõ típusúak lehetnek (szemben a tömbbel). Az egyik legrugalmasabb
Pascal adatszerkezet. Elsõsorban az állománykezelés során használjuk ki
a lehetõségeit, de ezen kívül még nagyon sok helyen hasznos lehet az
alkalmazása.
Deklarációja:
Var R: Record
Azonosito: Word;
Nev: String[50];
Eletkor: Byte;
Lakcim: String[80];
End;
A deklaráció során a record és az end foglalt
szavak között soroljuk fel a rekord mezõit, azaz a rekordot
felépítõ elemeket, és azok típusát.
A record mezõi között szerepelhetnek egyszerû és összetett típusú
mezõk egyaránt, tehát a recordnak lehet akár tömb típusú mezõje
is. Pld:
Var R: Record
Azonosito: Word;
Konyvek: Array [1..10] of String;
End;
(A fenti két record akár egy könyvtári nyilvántartás kiindulási pontja is lehetne... :-)) )
A record típusú változók egymásba is ágyazhatók, tehát a record típusú változónak lehet record típusú mezõje is. Pld:
Var R: Record
Azonosíto: Word;
Adatok: Record
Nev: String;
Eletkor: Byte;
Lakcim: String;
End;
End;
Az elõbbi rekord kicsit másképpen felírva így néz ki.
A record mezõire hivatkozhatunk, a
record típusú változó azonosítója után pontot téve a mezõ
azonosítójával. Tehát: R.Azonosito egy Word típusú változóként kezelhetõ.
A record típusú változók esetében általában a mezõnkénti értékadást
célszerû választani, a recordok közötti közvetlen értékadás feltételei
azonosak a tömb típus esetében leírt feltételekkel.
A bonyolult rekordtípusokat célszerû saját típusként deklarálni. Ha
függvénynek, eljárásnak szeretnénk paraméterként átadni egy rekordot, akkor is
különt kell deklarálni a rekord típust.
Type Rek= Record
Nev: String;
Eletkor: Byte;
End;
Var E, F: Rek;
G: Rek;
Begin
E.Nev:= 'Karoly';
E.Eletkor:= 23;
E:= F;
G:= E;
...
End.
A With utasítás segítségével némelyest egyszerûsíthetõ a rekordok kezelése. A With utasítás segítségével kijelölhetjük azt a rekordot, amelyen dolgozni szeretnénk. Ezek után a rekord mezõire egyszerûen a mezõk azonosítójával tudunk hivatkozni. Példa:
...
With E do
Begin
Nev:= 'Karoly';
Eletkor:= 23;
End;
...
E.Eletkor:= 24;
...
Bonyolult felépítésû, egymásba ágyazott rekordok esetén a With utasítás nagyon hasznos lehet, a program forrását áttekinthetõbbé, érthetõbbé teszi.
A rekordok deklarálhatók típusos konstansként is. Ebben az esetben már a deklaráció során megadhatjuk az egyes elemek kezdõértékét. Rekordok esetén a típusos konstans deklarálása elõtt a rekordtípust külön deklarálni kell, ami a tömb esetében nem volt szükséges. Az alábbi deklaráció hibát eredményez:
Const R: Record
Nev: String= 'Karoly';
Eletkor: Byte= 23;
End;
A megfelelõ forma:
Type Rek= Record
Nev: String;
Eletkor: Byte;
End;
Const R: Rek= (Nev: 'Karoly'; Eletkor: 23);
A tömbökhöz hasonlóan a rekordok sem
deklarálhatók típus nélküli konstansként.
A rekordok memóriában foglalt méretét a mezõk méretének összeadásával
számíthatjuk ki.
A halmaz típus:
A Pascal nyelv egyedülálló lehetõsége a
halmazok kezeléséhez a halmaz típus, és a hozzá kapcsolódó mûveletek. A
halmazokra azonban vonatkoznak bizonyos megkötések: a halmaz elemeinek
maximális száma 256 lehet, a halmaz elemei csak sorszámozott típusok lehetnek.
Deklarációja:
Var Halmaz: Set of Alaptípus;
Pld:
Var Betuk: Set of 'a'..'z, 'A'..'Z';
Lotto: Set of 1..99;
ASCII: Set of Char;
Az alaptípus - mint fentebb írtam - csak
sorszámozott típus lehet, de nem kizárólag a standard típusok közül kerülhet
ki, lehet a felhasználó által definiált (pld felsorolt, vagy résztartomány)
típus is. Ilyen módon nagyon sok feladat megoldására alkalmasak lehetnek a
halmazok akár változó, akár konstans formában.
A változóként deklarált halmazok üres halmazként jönnek létre, a program során
a felhasználónak (programozónak) kell meghatározni a halmaz elemeit. A halmaz
elemeit értékadó utasítással lehet a halmazhoz rendelni, a halmaz elemeit
(illetve az intervallumot) kapcsos zárójelek között kell felsorolni. Példa:
Betuk:= ['a', 'b', 'c', 'd', 'e'];
Lotto:= [7..19];
ASCII:= [#1..#13, #32, 'a'..'z', '0'..'9', 'A'..'Z', #185, #186, #192];
A halmaz elemeit megadhatjuk felsorolással, résztartomány konstansként, vagy akár a kettõt kombinálva is. Felsorolásnál az elemek közé vesszõt kell tenni.
A halmazokat deklarálhatjuk típusos konstansként is. Ebben az esetben a halmaz elemeit azonnal meghatározhatjuk. Példa:
Const Egyjegyu: Set of byte= [0..9];
A halmazokon végzett mûveletek közül a leggyakoribb a tartalomvizsgálat,
azaz megvizsgáljuk, hogy adott érték eleme-e a halmaznak. Pld:
If A in Szamok
then ...
else ...
A tartalomvizsgálat során a vizsgált elem típusának meg kell egyeznie a halmaz alaptípusával. Az eredmény logikai típusú lesz.
Vizsgálhatjuk két halmaz egyenlõségét
is, tehát azt, hogy a halmazok elemei azonosak-e:
Var Szamok1, Szamok2: Set of byte;
Begin
...
If Szamok1=Szamok2
then ...
else ...
...
End.
Az eredmény logikai típusú lesz.
Az elõbbi mûvelethez hasonlóan
vizsgálhatjuk a halmazok különbözõségét (nem különbségét):
If Szamok1<Szamok2
then ...
else ...
Az eredmény logikai típusú lesz.
A halmazok unióját (egyesítését) a Pascal
nyelv a következõképpen jelöli:
Szamok3:= Szamok1+Szamok2;
Az eredmény halmaz típusú lesz.
A halmazok metszetét is képezhetjük:
Szamok3:= Szamok1*Szamok2;
Az eredmény halmaz típusú lesz.
Megvizsgálhatjuk a halmazok különbségét is. A
halmazok különbsége a példában: Az eredményhalmaz (Szamok3) minden olyan elemet
tartalmazni fog, amely Szamok1-nek eleme, de Szamok2-nek nem eleme.
Szamok3:= Szamok1-Szamok2;
Az eredmény halmaz típusú lesz.
A halmazok memóriában történõ tárolása
minden eddigi típustól eltérõen történik. A halmaz elemeinek maximális
száma 256 lehet. Minden elemet 1-1 bit-en tárolunk, hiszen mindössze annyit kell
eldönteni, hogy eleme-e a halmaznak. Amennyiben az érték eleme a halmaznak, a
hozzá tartozó bit értéke 1, egyébként 0. Tehát a legnagyobb halmaz mérete a
memóriában 256 bit, azaz 32 byte. (Példa: H1: Set of Byte)
Ha a halmaz elemeinek lehetséges számát csökkentjük (például az alaptípus
megváltoztatásával), akkor a halmaz memóriabeli mérete ennek megfelelõen
alakul, tehát minden lehetséges elemhez 1 bit tartozik. Tehát a H2: Set of
0..9; deklarációval létrehozott halmaz lehetséges elemszáma 10 (0 és 9 közé
esõ számjegyek), ezért a memóriában számára 10 bit kerül lefoglalásra.
Objektum típus:
A Turbo Pascal nyelvet az 5.5 verziótól
kezdõdõen felkészítették az objektum-orientált programozási
technika megvalósítására. Az objektumok leginkább a rekordokhoz hasonlítanak,
de fontos különbség, hogy az adatok tárolása mellett az adatokat kezelõ
eljárásokat, függvényeket is tartalmazzák. Fontos megjegyezni, hogy a Turbo
Pascal nem objektum-orientált programozási nyelv, de ezt a lehetõséget
is támogatja. (ún. vegyes nyelv)
:
1337