Újra itt van! Újra itt van! Újra itt van a ...! Szóval megint itt vagyunk! És ha már megint itt vagyunk, akkor valamit tenni kellene! Vagy nem? De igen! Múltkor, ha jól emlékszem, a fájlkezelésnél hagytuk abba. Ha nem így van akkor javítsatok ki, de tudjátok , hogy amit én állítok az úgy van, mert nekem mindig igazam van! Ha netalántán előfordulna, hogy nincs igazam, akkor életbe lép az első szabály, ami szerint nekem mindig igazam van!

Na elég volt a mellébeszélésből, térjünk a tárgyra! Mai leckénk anyaga: modulok használata a Turbo Pascalban. Ha ebből valami véletlen folytán nem sokat értettetek, akkor ne búsuljatok, hisz azért vagyunk itt, hogy ezt részletesen kifejtsük, és megértse mindenki (na persze csak az akinek szükséges, a Mari néni a szomszédból úgysem értheti meg).

Mik azok a modulok?

A definíció szerint: a modul önállóan lefordítható programegység (unit), amely jól definiált kapcsolódási felületen (interface) keresztül kapcsolódik a program más részeihez. Alapvető elv a moduláris programozás során, hogy a modulok belső része (implementation) rejtett marad a külvilág számára. A Turbo Pascal modulokat unitoknak nevezzük.

Miért van szükség ezekre a modulokra?

A szabványos Pascal nyelv semmilyen lehetőséget nem tartalmaz arra, hogy nagyobb program esetén a program egyes részeit külön lefordítva állítsuk elő a futtatható kódot. Sőt, az objektumok felhasználás előtti kötelező deklarációja miatt, programkönyvtárat csak forrás nyelven lehet létrehozni, és azt a programba beépíteni. A modulok bevezetésével lehetővé vált a programkönyvtárak kidolgozása, és a moduláris programozás megvalósítása Turbo Pascal nyelven. Nagy méretű programok fejlesztése során a modulok használata feltétlenül szükséges, hisz a fordító a főprogram kódméretét 64 Kbájtban korlátozza. A unitokra nézve ez a korlátozás szintén érvényes, azonban a főprogram és a modulok együttes kódméretének nagysága csak a memória méretétől függ.

A Turbo Pascal modulok felépítése

A unitok felépítési jellegükben emlékeztetnek a főprogram felépítésére, azonban jelentősen el is tér attól:

Unit modulnév;    { a modul fejléce, nem hagyható el } INTERFACE    { a kapcsolódási felület rész }     uses  ...;     const  ...;     type  ...;     var  ...;     eljárások és függvények fejlécei; IMPLEMENTATION  { az implementációs rész }     uses  ...;     label  ...;     const  ...;     type  ...;     var  ...;     eljárások és függvények teljes deklarációja; BEGIN    { az inicializációs rész }     Pascal utasítások; END.

A unitok három jól elkülöníthető részből állnak, amelyek közül az inicializációs rész elhagyható. A továbbiakban részletesen ismertetem az egyes részek használatával kapcsolatos szabályokat és lehetőségeket.

A modulok fejléce - a modulok közötti kapcsolat

A modulok fejléce a unit foglalt szóból és az azt követő modulnévből áll - sohasem hagyható el. A modulnévnek (ellentétben a programnévvel) meg kell egyeznie a modult tartalmazó fájl nevével. Például a:

Unit MyOwn;

modult a MYOWN.PAS fájlba kell elhelyezni.
A modul nevét használjuk más modulokkal illetve a főprogrammal való kapcsolat kialakítására:

uses modulok listája;

ahol a uses foglalt szót a felhasználni kívánt modulok neveinek vesszővel tagolt felsorolása követi. Például:

uses Crt, Graph, MyOwn;
Az interface rész

A kapcsolódási felület részt az interface foglalt szó nyitja meg. Ebben a részben található a unit globális objektumainak (típusok, konstansok, változók és alprogramok) deklarációja, amelyek más modulokból is elérhetőek. A globális eljárásoknak és függvényeknek csak a fejléce adható meg az interface részen belül:

Unit MyOwn; INTERFACEtype KetSzam = record   A, B: Integer;end;procedure SysColor(X: Byte); function Osszeg(X: KetSzam): Integer; function Atlag(X: KetSzam): Real;

Az interface részben deklarált Pascal objektumokra a főprogramból megismert módon hivatkozhatunk. Ha ezek után a főprogramban megadjuk a

uses MyOwn;

programsort, akkor a főprogram számára elérhetővé válik a KetSzam típus, a SysColor eljárás, az Osszeg és az Atlag függvény.

A const, type, var, procedure és function deklarációk száma és sorrendje tetszőleges, azonban a forward deklaráció használata nem megengedett. Az interface részben szintén hivatkozhatunk más modulokra (uses), abban az esetben, ha az ott definiált típusokat kívánjuk felhasználni.

Az implementation rész

A modul implentációs része egyrészt az interface részben megadott globális eljárások és függvények teljes leírását, másrészt pedig a unit lokális deklarációit (címke, konstans, típus, változó, eljárás és függvény) tartalmazza. A globális alprogramok fejlécét az implementation részben kétféleképpen is megadhatjuk:
 

  • vagy használjuk az interface részben megadott teljes formát:

  • procedure SysColor(X: Byte);
     
  • vagy a formális paraméterek (függvény esetén a visszatérési érték típusának jelölése) nélkül adjuk meg a fejlécet:

  • procedure SysColor;

Most már megnézhetjük a teljes modult:

Unit MyOwn; INTERFACE type KetSzam = record         A, B: Integer;       end; procedure SysColor(X: Byte); function Osszeg(X: KetSzam): Integer; function Atlag(X: KetSzam): Real;
IMPLEMENTATION uses Crt; procedure SysColor; begin    Case X of      0: begin           TextBackGround(Black);           TextColor(LightGrey);         end;      1: begin           TextBackGround(LightGrey);           TextColor(Black);        end;      end; end; function Osszeg; var S: Integer; begin    S:=X.A+X.B;    Osszeg:=S; end; function Atlag; var S: Real; begin    S:=(X.A+X.B)/2;    Atlag:=S; end; END.
Az inicializációs rész

Az inicializációs rész a modul működéséhez szükséges tevékenységek elvégzésére szolgál (például kezdőértékek beállítása). A program futtatása során a unit inicializációs része egyetlen egyszer hajtódik végre, mégpedig ott, ahol a uses utasításban a modul neve először előfordul. Ez a rész el is hagyható, ekkor az implementációs részt zárja az end. utasítás.

Szabványos modulok

A Turbo Pascal rendszer nyolc szabványos modullal rendelkezik, amelyek sok hasznos típust, konstanst, eljárást és függvényt tartalmaznak. Ezek a modulok: SYSTEM, DOS, CRT, PRINTER, GRAPH, OVERLAY, TURBO3 és a GRAPH3. A GRAPH, TURBO3 és a GRAPH3 modulok különálló fájlokban helyezkednek el (.TPU), míg a többi modult a TURBO.TPL (Turbo Pascal Library) fájl tartalmazza. A SYSTEM unit automatikusan hozzákapcsolódik minden Turbo Pascal programhoz, míg minden más unit eléréséhez a uses hivatkozás szükséges. Most röviden jellemzem ezeket a szabványos modulokat, aztán a következő számunkban részletesen kifejtem őket (csak Nektek):

  • A CRT modul elsősorban a képernyő szöveges üzemmódját támogató eljárásokat és függvényeket tartalmaz. Ezek segítségével lehetőség van a kurzor pozícionálására, a használt színek beállítására és ablakok létrehozására. Ezen kívül a modul tartalmaz néhány eljárást, amelyek segítségével a billentyűzet speciális módon érhető el, és lehetőség adódik hanggenerálásra.

  • A DOS modulban azok az eljárások és függvények vannak összegyűjtve, amelyek segítségével hatékonyabban kihasználhatjuk az MS-DOS operációs rendszer lehetőségeit.

  • A GRAPH unit a képernyő grafikus üzemmódját támogató típusok, konstansok, eljárások és függvények gazdag készletét tartalmazza. Ezek segítségével tetszőleges grafikus kép előállítható illetve a programozható karakterkészlet felhasználásával szövegek is megjeleníthetők. A GRAPH unit rutinjai a megfelelő BGI-vezérlő felhasználásával tetszőleges grafikus kártya esetén használhatók. A Turbo Pascal rendszer a CGA, a Hercules, az EGA, a VGA, az MCGA, az IBM8514, az ATT400 és a PC3270 grafikus adapterekhez tartalmaz BGI-vezérlőt. Más kártya esetén a vezérlőt külön kell beszerezni.

  • Az OVERLAY modul használata akkor szükséges, amikor nagy programok fejlesztése esetén az átlapolási (overlay) technika használata válik szükségessé. Ezzel a technikával a rendelkezésre álló szabad memória méretét (550-620 Kbájt) meghaladó méretű programok is előállíthatók.

  • A PRINTER modul leegyszerűsíti a szöveges információk nyomtatását. A modulban definiált egy Text típusú LST fájl, amely a PRN logikai egységgel áll kapcsolatban. Az eredménynek a nyomtatón való megjelenítése ezáltal egyszerűen végezhető el.

  • A SYSTEM unit tartalmazza a szabványos Pascal nyelv eljárásait és függvényeit illetve azokat a Turbo Pascal rutinokat, amelyek nem kerültek más modulba. Mint ahogy azt már említettem, a SYSTEM modul minden program fordításakor felhasználásra kerül függetlenül attól, hogy a uses utasításban hivatkoztunk rá, vagy sem.

  • A TURBO3 és a GRAPH3 modulokat a Turbo Pascal 3.0-ás verziójával való forrásnyelvű kompatibilitás miatt tartalmazzák az újabb verziójú rendszerek. Az itt definiált rutinok használata nem ajánlott, hiszen az új könyvtárakban bőséges lehetőség kínálkozik minden tevékenység elvégzésére.

A CRT unit

Mint a múltkor leírtam a CRT unit a képernyő szöveges üzemmódját hivatott támogatni, segítségével tudjuk programjainkat olyanra formálni, hogy az valahogy ki is nézzen, de mégsem kelljen a grafika tudományaiba nagyon belemélyedni (Ej ráérünk arra még!). Szóval kurzort pozícionálhatunk, színeket állíthatunk be, sőt, még hangot is generálhatunk.

Mi is az a szöveges üzemmód?

A számítógép a képernyőt alapértelmezés szerint szöveges módban használja. Ez azt jelenti, hogy a matekfüzethez hasonlóan a képernyőt is ilyen négyzethálóhoz lehet hasonlítani, sorokból és oszlopokból áll. Az alapértelmezés a 80x25, ami annyit takar, hogy 80 oszlop, 25 sor, 80 karaktert írhatunk egy sorba, amiből összesen 25 fér el egy képernyőre. Egy gyors számolás fut végig mindenki agyában (Ha mégsem, akkor valami baj van. Fordulj orvoshoz!), ami szerint egy képernyőre összesen 2000 karakter fér (ez csak amolyan megjegyzés). Szóval 80 karakter fér el egy sorban, ha véletlenül mégiscsak többet akarnánk kiírni, a 80 felettiek átkerülnek a következő sorba. Ez nem olyan nagy gond, mert megmarad, viszont ha 25 sornál akarunk többet kiíratni, akkor vigyáznunk kell, mert a képernyő tetején kiszaladnak a képernyőből a felső sorok, és a tartalmuk elvész.
Amint említettem a 80x25 az alapértelmezés, vagyis ez a leggyakoribb, a legelterjedtebb. Mivel régebben nem voltak VGA monitorok - meg most sincs mindenhol -, más "felbontást" használtak a különböző típusokon. A CRT unit lehetőséget nyújt ezen "felbontások" használatára is. Ezeket majd később ismertetem.

Most már tudjátok - ha eddig nem tudtátok -, hogy mi az a szöveges üzemmód. Végre nekiláthatunk a CRT unit tárgyalásának. Mint minden rendes Pascal program, a modulok is tartalmaznak változókat, konstansokat, eljárásokat és függvényeket. Így van ez a mi esetünkben is, tehát végig vesszük a CRT unit felépítését a változóktól a függvényekig.
Először is emlékeztetlek benneteket, hogy hogyan is hivatkozhatunk a CRT unitunkra:

Most már tudjátok - ha eddig nem tudtátok -, hogy mi az a szöveges üzemmód. Végre nekiláthatunk a CRT unit tárgyalásának. Mint minden rendes Pascal program, a modulok is tartalmaznak változókat, konstansokat, eljárásokat és függvényeket. Így van ez a mi esetünkben is, tehát végig vesszük a CRT unit felépítését a változóktól a függvényekig.

Először is emlékeztetlek benneteket, hogy hogyan is hivatkozhatunk a CRT unitunkra:

uses Crt;

Aki elfelejtette, azzal nem tudom mit csinálok, eszerint hiába vesződtem órákat az előző cikkemmel. Na mindegy.

Szöveges mód változói:

Ezek a változók alapértelmezés szerint rendelkeznek egy értékkel. Ha mi ettől az értéktől eltérőt szeretnénk használni, akkor ezt nyugodtan megtehetjük úgy, hogy a változónak megadjuk az általunk használni kí1vánt értéket. Ezek a változók a következők:

var CheckBreak,      CheckEof,      DirectVideo,      CheckSnow  : Boolean;      LastMode,      WindMin,      WindMax    : Word;      TextAttr   : Byte;

A CheckBreak szabályozza a program Ctrl-Breakkel történő megszakítását. Ha a változó értéke true, a program megszakítható, false esetén nem. Az alapértelmezés true.
A CheckEof engedélyezi vagy nem engedélyezi a Ctrl-Z hatására az end-of-file jel írását. Ha a változó értéke true, akkor a képernyőhöz rendelt fájlból való olvasáskor a Ctr-Z leütésére fájl vége esemény generálódik, ha értéke false, akkor nem. Az alapértelmezés false.
A CheckSnow változó az ún. havazás jelenséget szabályozza a CGA monitoroknál. Ez a havazás nem jelentkezik a monokróm, az EGA és a VGA monitorok esetében. Alapértelmezés szerint truera van állítva. Ha nem CGA monitoron futtatunk a TextMode (erről majd később) állítása után érdemes a változót falsera állítani, mert jelentősen gyorsabb outputot eredményez. A havazás nem hatásos, ha a DirectVideo értéke false.
A DirectVideo változó true értéke biztosítja a Write és WriteLn eljárásoknak a képernyőhöz való közvetlen hozzáférést oly módon, hogy az output közvetlenül a képernyő-memóriába történik. A képernyőkezelés így gyorsabb, mint a BIOS-on keresztül. A változó alapértelmezés szerint truera van állítva. Falsera állítjuk akkor, ha a BIOS-on keresztül akarjuk a karakterek megjelenítését. Az értékadás csak a TextMode hívása után lehetséges.
A LastMode változó tartalmazza az utoljára kiválasztott szöveges módot. A rendszer a program indulásakor az aktív videomód kódját tölti be a változóba.
A TextAttr tárolja az aktuálisan kiválasztott szövegszínt, amelyet a TextColor és a TextBackGround segítségével állítottunk be. Ezt a változót közvetlenül is beállíthatjuk némi kis számolgatás után. A bájt tartalma a következő:
 

128
 4 
4
2
1
               
villogás
háttérszín 0 - 7
aktuális szín 0 - 15

A  WindMin és a WindMax változók az aktuális ablak képernyő-koordinátáit tárolják. Az értéküket akkor veszik fel, amikor a Window (erről is később) eljárást meghívjuk. A WindMin az ablak bal felső, a WindMax az ablak jobb alsó koordinátáit tartalmazza. Az X-koordináta az alsó bájtban, az Y-koordináta a felső bájtban kerül tárolásra.

Szöveges mód konstansai
A TextMode eljárás paramétere az alábbi konstansokat fogadja:

const   BW40 = 0;  { 40x25 fekete-fehér    }   CO40 = 1;  { 40x25 színes     }   BW80 = 2;  { 80x25 fekete-fehér    }   CO80 = 3;  { 80x25 színes     }   Mono = 7;  { 80x25 monokróm MDA vagy Hercules monitoron }   Font8x8 = 256;  { 40x43, 40x50 sor EGA és VGA monitorokon }

A TextMode aktiválásával állíthatunk fekete-fehér, illetve színes üzemmódot a megfelelő ablakmérettel. Például:

TextMode(0); fekete-fehér, 40x25 TextMode(BW80); fekete-fehér, 80x25 TextMode(3); színes, 80x25

A szöveg színét a TextColor, a háttér színét a TextBackGround eljárással állíthatjuk be. 

A színkonstansok:

const   Black  = 0;  { fekete  }   Blue  = 1;  { kék  }   Green  = 2;  { zöld  }   Cyan  = 3;  { türkiz  }   Red  = 4;  { piros  }   Magenta  = 5;  { lila  }   Brown  = 6;  { barna  }   LightGray = 7;  { világosszürke }   DarkGray = 8;  { sötétszürke }   LightBlue = 9;  { világoskék }   LightGreen = 10;  { világoszöld }   LightCyan = 11;  { világos türkiz }   LightRed = 12;  { világospiros }   LightMagenta = 13;  { világoslila }   Yellow  = 14;  { sárga  }   White  = 15;  { fehér  }   Blink  = 128;  { villog  }

A színekből a szöveg írására mindegyiket (0-15), a háttérre azonban csak az első nyolcat (0-7) használhatjuk. Például legyen a háttér színe kék, a szöveg színe világos türkiz (használhatunk egyaránt szín- vagy számkonstansot):

TextBackGround(1);   vagy   TextBackGround(Blue); TextColor(11);   vagy   TextColor(LightCyan);
Szöveges mód eljárásai és függvényei
Ezeket az eljárásokat és függvényeket öt csoportba oszthatjuk:
  • szöveg kiírása és kezelése,
  • ablak és mód vezérlése,
  • tulajdonság beállítása,
  • állapotlekérdezés,
  • hangkeltés.
Most nézzük ezeket a csoportokat részletesebben:

Szöveg kiírása és kezelése - írás és olvasás:

  • AssignCrt(var f: Text);

  • A képernyőhöz egy szövegfájlt rendel, amelyet a fájlkezelésnél ismertetett módon használhatunk.
     
  • Write;

  • Aki nem tudja mire jó, az magára vessen. Nézze meg az első számban.
     
  • Read;

  • Szintén!
     
  • ReadKey;

  • Egy karakter leütésére váró függvény.
    Ch:=ReadKey;
     
  • KeyPressed;

  • Egy logikai függvény, mely igaz értékkel tér vissza, ha billentyűzeten megnyomtunk egy billentyűt, egyébként értéke hamis. Nagyon jól használható olyan eseteknél, amikor egy billentyű lenyomására meg kell szakítanunk a programot.

    repeat until KeyPressed;
szöveg és kurzor  mozgatása a képernyőn:
  • ClrScr;

  • Törli az aktuális ablakot (képernyőt), és a kurzort a bal felső sarokba (1,1) helyezi. Az ablak háttere az előzőekben definiált háttérszínt veszi fel.
     

  • ClrEol;

  • A sor kurzortól jobbra eső részét törli, és az előre definiált háttérszínt veszi fel.
     
  • DelLine;

  • Törli a kurzort tartalmazó sort, és az alatta lévő sorok eggyel feljebb csúsznak. A képernyő utolsó sora üres lesz.
     

  • GotoXY(x, y: Byte);

  • A kurzort az x, y koordinátákra pozícionálja. Az aktuális ablak x-edik oszlopába és y-odik sorába helyezi a kurzort. Ezek relatív koordináták, vagyis az aktuális ablak bal felső sarkától számítandók. Érvénytelen koordináták esetén nem kerül végrehajtásra.
     

  • InsLine;

  • Beszúr egy üres sort a kurzort tartalmazó sor alá. Az utolsó sor kicsúszik a képernyőből.
Ablak és mód vezérlése
  • TextMode(Mode: Word);

  • A kívánt szöveges üzemmódot választhatjuk ki. A konstansokat lásd fent.
     
  • Window(x1, y1, x2, y2: Byte);

  • A szöveges képernyőn egy ablakot definiál. Az x1, y1 az ablak bal felső sarokpontjának, az x2, y2 az ablak jobb alsó sarokpontjának koordinátái.

Tulajdonságok beállítása
  • TextColor(Color: Byte);  ,  TextBackGround(Color: Byte);

  • Az előtér és a háttér színeinek beállítása. A konstansokat lásd fent.
     
  • HighVideo;

  • Magas intenzitás beállítása.
     
  • LowVideo;

  • Alacsony intenzitás beállítása.
     
  • NormVideo;

  • Eredeti, normál intenzitás beállítása.
Állapotlekérdezés
  • WhereX;

  • A függvény a kurzor x koordinátaértékével tér vissza, melynek értéke bájt típusú.
     
  • WhereY;

  • A függvény a kurzor y koordinátaértékével tér vissza, melynek értéke bájt típusú.
Hangkeltés
  • Sound(Hz: Word);

  • Adott Hertz frekvenciájú hangot generál a belső hangszórón (Internal PC Speaker).
     
  • Delay(ms: Word);

  • Adott számú ezredmásodpercig felfüggeszti a program futását. Ezzel tudjuk szabályozni, a programot, hogy mennyi ideig tartsa a megadott hangot.
     

  • NoSound;

  • Kikapcsolja a belső hangszórót.
Körülbelül ennyi lenne. Jó programozgatást kívánok!