Turbo Pascal 3

Az alább ismertetésre kerül a TURBO PASCAL 3 lehetőségei, igen kimerítő -minden részletre kiterjedő- módon, viszont a kezdők számára egy kicsit nehéz olvasmányt jelent. Ha valakit érdekel a PASCAL, olvassa el az ENTERPRESS Pascal sorozatát is!
További Turbo Pascal példák itt találhatóak.


1. Bevezetés 10. Rekordtípusok
2. Lexikális elemek, elválasztók, megjegyzesek 10.1. A with utasítás
2.1. Kulcsszavak 10.2. Változatok (unionok)
2.2. Azonosítók 10.3. Rekordértékadás
2.3. Konstansok 11. Halmaztípusok
2.4. Megjegyzések 11.1. Halmazkonstansok
3. Standard skalártípusok 11.2. Kifejezések
4. Programszerkezet 11.3. Halmazértékadás
4.1. Programfejléc 12. File-típusok
4.2. Blokk 12.1. Alprogramok
5. Kifejezések 12.2. Szövegfájlok
5.1. Operátorok 12.3. Szövegfájlokon értelmezett műveletek
5.2. Előjelváltó operátor 12.4. Elemtípus nélküli fájlok
5.3. Negációs operátor 12.5. Beviteli és kiviteli műveletek ellenőrzése
5.4. Szorzás jellegű operátorok 12.6. A fájlkezelés általános lépései
5.5. Összeadás jellegű operátorok 13. Mutatótípusok
5.6. Relációk 14. Kezdeti értékadás
5.7. Függvényhívások 15. Függvények és eljárások
5.8. Típuskonverzió 15.1. Rekurzió
6. Utasítások 16. Standard alprogramok
6.1. Értékadó utasítás 16.1. Képernyős eljárások
6.2. Eljáráshívás 16.2. Különleges eljárások
6.3. Ugró utasítás 16.3. Aritmetikai függvények
6.4. Üres utasítás 16.4. Skalárfüggvények
6.5. Csoportosító utasítás 16.5. Konverziós függvények
6.6. Feltételes utasítás 16.6. Segédfüggvények
6.7. Kiválasztó utasítás 17. Állományok beillesztése
6.8. Iterációs utasítások 18. Alprogramok átlapolása
7. Felsorolási és intervallumtípusok 19. Néhány kiválasztott implementációs bővítés
7.1. Felsorolási típusok 19.1. Nyílt helyfoglalás programváltozók számára
7.2. Intervallumtípusok 19.2. Különleges rendszerfüggvények és eljárások
7.3. Értéktartomány-ellenőrzés 19.3. Rendszerrutinok hívása
8. Karakterlánc-típusok 19.4. Gépi szintű programozás
8.1. Karakterláncok összefűzése 19.5. Külső programok indítása
8.2. Relációk 19.6. Paraméterátadás
8.3. Értékadás 20. Az adatok ábrázolása
8.4. Karakterlánc-függvények és -eljárások Függelék
8.5. Karakterlánc- és karaktertípusok A. Kapcsolat az operációs rendszerrel
9. Tömbtípusok B. Grafika Enterprise-on
9.1. Többdimenziós tömbök C. Hibakódok
9.2. Karaktertömbök D. Képernyős szövegszerkesztő
9.3. Értékadások E. A fordító direktívák
9.4. Előre definiált tömbök F. A keretrendszer installálása
  G. ASCII kódtáblázat

1. Bevezetés
A Pascal nyelv története 1698-ban kezdődik, ekkorra készült el Nicklaus Wirth professzor terve, amelyet az addigi legfejlettebb programozási nyelvek - többek között az ALGOL - felhasználásával, azoknak továbbfejlesztésével készített. 1970-ben készült el az első fordítóprogram a nyelvhez, az erről szóló publikáció 1971-ben jelent meg. 1973-ban látott napvilágot a javított (Revised Report) kiadása. Ekkor definiálták a Standard Pascal nyelvet, amely a nyelv különböző implementációjának alapja lett. Több egyetemen is kifejlesztették a nyelv változatait, ereje azonban akkor mutatkozott meg igazán, amikor a megjelentek a személyi számítógépek.
Kezdetben a Pascal nyelvet a strukturált programozás tanítására alkalmas eszközként használták. Az olcsó és jó fordítóprogramok kidolgozása eredményeképpen a nyelv rendkívül gyorsan elterjedt, és jelenleg a modern programozási nyelvek egyik legfontosabb képviselője - különösen a rendszerprogramozás területén.
A szabványos Pascal nyelv legismertebb implementációja a vele 90%-ban kompatíbilis Turbo Pascal nyelv, amelyet elsősorban mikroszámítógépes alkalmazásokra adott ki a Borland cég, és amely piaci megjelenése után azonnal világsiker lett. A Turbo Pascal első kiadása nem a Borland saját fejlesztése volt, hanem egy akkor még ismeretlen dán programozó, Anders Hejlsberg "PolyPascal" nevű termékén alapult. Hejlsberg ugyanakkor maga is elszegődött a Borland szolgálatába. A Turbo Pascal az elsőt követő két kiadása (2.x, 3.x) az eredeti kódbázis inkrementális továbbfejlesztését képezte.
A Borland cég által megvalósított implementáció legfontosabb előnyei közé tartoznak: a fordítóprogram kis mérete, az igen gyors fordító algoritmus, a fordítóprogram és az interaktív képernyős szövegszerkesztő összekapcsolása, a forrásszintű hibajelzések, a nagy szubrutinkönyvtár, valamint azok a bővítések, amelyek a szabványos nyelvhez képest nagymértékben megkönnyítik a rendszerprogramozást.
A Turbo Pascal interaktív programozási rendszer, amely a Turbo Pascal nyelv fordítóprogramjából és a vele összekapcsolt képernyős szövegszerkesztőből áll. A Turbo Pascal szövegszerkesztőjét a közismert WordStar szerkesztőprogramról mintázták. A rendszer nemcsak azért interaktív, mert kényelmes szövegszerkesztést tesz lehetővé, hanem azért is, mert a programban feltárt hibákat a forrásnyelvi szövegben jelöli meg.
A szövegszerkesztés, fordítás és futtatás közötti üzemmódváltás természetes és kevés manipulációt igényel. Emiatt a Turbo Pascal rendszerben a programok "belövése" szinte kizárólag forrásszintű. A jelentős fordítási sebesség miatt a forrásés a futtatható tárgyprogram közötti váltás szinte azonnali, ez számottevően lerövidíti a javítási és újrafuttatási ciklust, meggyorsítva a végleges programváltozat kifejlesztését.
A Turbo Pascal rendszer használatát egy egyszerű program mutatja be, amely az adott sugarú gömb térfogatát számítja ki:

program Terfogat;
var Sugar,Terf:real;
begin
  ClrScr;
  GotoXY(10,11);
  Write('sugar=');
  Readln(Sugar);
  Terf:=4/3*Pi*Sugar*Sugar*Sugar;
  GotoXY(10,13);
  Writeln('terfogat =',Terf);
  repeat until KeyPressed
end.

A programban szerepel az előre definiált Pi konstansnév (a Pi szám közelítése), valamint a Sugar (a gömb sugara) és a Terf (a gömb térfogata) szimbolikus név. (A konstansnév olyan azonosító, amely egy konstans értéket képvisel. E konstans olyan objektum, amely a program végrehajtása során nem változik. Több szerző más fogalmakat használ, és a konstansneveket "állandók"-nak, a változóneveket pedig "változók"-nak nevezi.) A ClrScr eljárás végrehajtása képernyőtörlést eredményez, a GotoXY eljárás pedig pl. a GotoXY(10,13) esetén a képernyő 10. oszlopát és 13. sorát jelenti. A repeat until ciklus leállítja a program további futását mindaddig, amíg a billentyűzetről nem viszünk be egy tetszőleges karaktert. Ez a karakter megmarad a bemeneti pufferben, és a Turbo Pascal rendszer később értelmezheti.
A Turbo Pascal 3.xx verziókhoz több rendszerfile tartozik:

A program lefordításához és a futtatáshoz először el kell indítani - a TURBO név begépelésével - a Turbo Pascal rendszert. A 3.x verzióig a Turbo rendszer egységes kezelőfelülettel rendelkezik. A program indítása után a képernyőn a következő rendszerazonosító üzenet jelenik meg:

A megjelenő szövegben szereplő kérdés arra kíváncsi, akarjuk-e a hibaüzenetek szövegét a rendszerhez csatolni. Mivel a hibaüzenetek helyigénye csak 1,5 kbájt, s használatuk jelentősen megkönnyíti a hibakeresést, ajánlatos az Y (igen) válasz megadása. A választ követően a képernyőn megjelenik a rendszermenü, amelyben az egyes szavak kiválasztandó betűit nagyobb fényerő jelzi.

A kiemelt betűnek megfelelő billentyű leütésével interaktív módon adhatjuk ki a rendszerparancsokat.

Az L parancs
Az L billentyű megnyomása lehetővé teszi az alapértelmezés szerinti mágneslemezes meghajtóegység megváltoztatását. Ha pl. a B meghajtót szeretnénk kijelölni, akkor a feltett
New drive:
kérdésre be kell gépelnünk a B: karakterpárt, és a parancs megadását az Enter billentyűvel kell befejeznünk.

A W parancs
A W billentyű megnyomása után megadhatjuk a forrásprogramot tartalmazó munkaállomány nevét. A megadott név egy létező vagy egy új, létrehozandó állomány neve. A feltett
Work file name:
kérdésre be kell gépelnünk az állomány nevét meghatározó szöveget, amelyet az Enter billentyűvel zárunk le.
A CP/M-80 és a PC DOS operációs rendszerben az állománynév két tagból állhat. Az első tag legfeljebb 8 karakter hosszúságú, a második tag - melyet kiterjesztésnek nevezünk - max. 3 karakter hosszúságú lehet. A név két tagját a . (pont) karakter választja szét. Ha az előző kérdésre csak az állománynév első tagját adjuk meg, akkor az alapértelmezés szerint a név automatikusan kiegészül egy ponttal és a PAS kiterjesztéssel. Ha le akarjuk tiltani az automatikus kiterjesztés-hozzáadást, elegendő begépelni az állománynév első tagját és a pontot.
Megjegyzés: ha egy új munkaállományt jelölünk ki - mielőtt az eddigit kivittük volna a mágneslemezre -, akkor a rendszer előbb megkérdezi, hogy az eddigi forrásszöveget szándékozzuk-e megőrizni. A lehetséges válasz e kérdésre (szokásos módon) Y (igen) vagy N (nem).

Az M parancs
Az M billentyű megnyomása után megadhatjuk a lefordítandó forrásprogramot tartalmazó állomány nevét. Ha ezt a nevet nem határozzuk meg, akkor a lefordítandó forrásszöveget az aktuális munkaállomány tartalmazza.
A lefordítandó forrásprogramot tartalmazó állomány (a továbbiakban főállomány) nevére vonatkozó szabályok megegyeznek a munkaállomány nevére vonatkozó előírásokkal. A főállomány használata akkor kényelmes, ha a forrásprogram tartalmaz olyan direktívákat, amelyek - az előfordulási helyükön - beiktatnak más állományokban szereplő programrészeket. Ha ekkor valamely "beiktatott" programrészben a fordító hibát jelez, az adott programrészt tartalmazó állomány automatikusan munkaállománnyá válik, amely azonnal szerkeszthető, javítható. A javítások befejezése után egyszerűen újraindíthatjuk a főállományban szereplő forrásprogram fordítását.

Az E parancs
Az E billentyű leütésével behívjuk a képernyős szövegszerkesztőt, ezután elkezdhetjük a munkaállományban levő szöveg szerkesztését. Ha még nem határoztuk meg a munkaállomány nevét, akkor először a W parancsnál ismertetett módon a rendszer megkérdezi az állománynevet, s csak ezután kezdődhet el a szerkesztés.

A C parancs
A C billentyű leütésével elkezdhetjük a főállományban levő forrásszöveg fordítását. Ha eddig nem határoztuk meg a főállomány nevét, akkor a munkaállományban szereplő szöveget fordítja le a rendszer. Ha megadtuk ugyan a főállomány nevét, de a munkaállományt szerkesztettük, akkor a rendszer előbb elmenti a munkaállományt a háttértárolóra, s csak ezután kezdi el a fordítást.
A fordítás eredményeképpen keletkező tárgyprogram az operatív tárba vagy .COM, ill. .CHN kiterjesztésű mágneslemezes állományba kerül. A fordítás jellemzői az O paranccsal (fordítási opciók) állíthatók be. Az alapértelmezés szerint a tárgyprogram az operatív tárban kap helyet. Ideiglenesen bármelyik billentyűvel megszakíthatjuk a fordítást. A feltett
Abort compilation (Y/N)?
kérdésre válaszolva, a fordítás véglegesen megszakad (Y), ill. folytatódik (N).

Az R parancs
Az R billentyűvel elindítjuk az operatív tárban levő, lefordított program végrehajtását. Ha az O paranccsal előzetesen beállítottuk a COM-fájl opciót, akkor a rendszer a mágneslemezről előbb betölti a programot. Ha az R parancs előtt nem használtuk a C parancsot, akkor a program fordítása automatikusan megelőzi futtatását.

Az S parancs
Az S billentyű megnyomása után a rendszer mágneslemezre menti az eddig szerkesztett forrásszöveget. A munkaállomány előző, eredeti példányának névkiterjesztése .BAK-ra változik.

Az X parancs (csak a CP/M-80 alatt)
Az X billentyűvel tetszőleges bináris programot futtathatunk le. A feltett
Program:
kérdésre a végrehajtandó - gépi kódú - programot tartalmazó, .COM kiterjesztésű mágneslemezes állomány nevét kell megadnunk.

A D parancs
A D billentyű leütésével egy tetszőleges mágneslemezes alkönyvtár tartalomjegyzéke jeleníthető meg a képernyőn. A feltett
Dir mask:
kérdésre megadhatjuk a konkrét állománynevet vagy egy állománycsoport nevét, pl. B: *.JB? (a" tetszőleges karaktersorozatot, a ? pedig tetszőleges karaktert jelent). Ha a kérdésre nem adjuk meg a meghajtó vagy az alkönyvtár nevét, akkor a főmenü szerinti alapértelmezés a mérvadó.

A Q parancs
A Q billentyű megnyomásával befejeződik a Turbo Pascal rendszer futása, a vezérlés visszakerül az operációs rendszerhez. Ha a Q parancs megadása előtt szerkesztettük a munkaállományt, akkor a rendszer előbb megkérdezi, hogy elmentjük-e mágneslemezre a szerkesztett szöveget.

Az O parancs
Az O billentyűvel fordítási opciókat adhatunk meg:

Ha bármely művelet hatására megváltozik a képernyő és nem látszik a menü, nyomjunk le tetszőleges olyan billentyűt, amely nem szerepel a főmenüben. Ennek hatásár a rendszer újra megjeleníti a menüt.

A fenti leírásból látható, hogy a Turbo Pascal rendszer parancsainak és alparancsainak használata nem túlságosan bonyolult. Egyszerű a forrásprogram írása és javítása is (az E paranccsal vagy automatikusan, a fordítási hibák fellépésekor).
A Turbo Pascal rendszer szövegszerkesztője nagymértékben hasonlít az ismert WordStar programhoz. A függelékben megtalálható a szövegszerkesztő teljes leírása; itt csak a forrásszövegek alapvető feldolgozására alkalmas, minimális parancskészletet mutatjuk be.
Megjegyzés: ha nem követünk el hibákat, akkor közvetlenül a szövegszerkesztő behívása után (E parancs) begépelhetjük a program szövegét karaktersorok formájában, amelyeket az ENTER billentyűvel zárunk le. A szöveg begépelése után a 'CTRL+KD' paranccsal befejezzük a szerkesztést, és visszatérünk a főmenühöz.
A Turbo Pascal rendszer szövegszerkesztőjének többi parancsához hasonlóan - szükség van még a CTRL billentyűre, amelyet lenyomva kell tartanunk a vezérlő-billentyű leütésekor. A képernyőn megjelenített szövegrészen belül fontos szerepe van a kurzor feletti karakternek. A szövegmanipulációk mindig e karakterre (vagy az őt tartalmazó szóra, ill. sorra) vonatkoznak. A kurzor mozgatása egy pozícióval balra, jobbra, felfelé vagy lefelé a beépített borkormány fel, le, jobbra vagy balra döntésével lehetséges.
Karaktertörlésre az ERASE billentyű használható, amely törli a kurzortól balra eső karaktert. Új karakterek beszúrásához (akár szavakon belül, akár szavak közt) nincs szükség semmilyen különleges műveletre; a begépelt karakterek a kurzor fölötti karakter elé szúródnak be, ugyanakkor a sor többi karaktere egy pozícióval jobbra tolódik. Egész sorok törlésére a CTL-Y parancs, szavak törlésére a CTRL T parancs, új sorok beszúrására a CTRL-N parancs alkalmas. A szövegszerkesztő számos más parancsát és lehetőségét a függelék írja le. E fejezet tartalmát összegezve elmondhatjuk, hogy a fejezet elején bemutatott 1. program futtatható változatának előállítása a következő műveletek elvégzését igényli:

E tevékenységek befejezése után a Q paranccsal visszatérhetünk az operációs rendszerhez.
Ha a tárgyprogramot szeretnénk megőrizni egy mágneslemezes állományban (.COM kiterjesztéssel), akkor a fordítás előtt adjuk ki az 0 parancsot, utána pedig a C és a Q alparancsokat. A fordítás és az operációs rendszerhez való visszatérés után a példaprogram már a Turbo Pascal rendszer felügyelete nélkül, önállóan is futtatható.

2. Lexikális elemek, elválasztók, megjegyzesek
A Turbo Pascal programozási nyelv részletes leírását lexikális (szótári) elemeinek felsorolásával kezdjük. A többi programozási nyelvhez hasonlóan ezek a következők: kulcsszavak, azonosítók, konstansok és határolók: A szóközök, tabulátorjelek, sorvégjelek és megjegyzések (kommentárok) nem lexikális elemek; e karakterek és a megjegyzések tetszőleges sorozata (a továbbiakban elválasztó szintaktikai elem) a fordító szempontjából - egy szóköznek tekinthető. Az elválasztó elem használata csak akkor nélkülözhetetlen, ha a forrásprogramban szomszédos azonosítók vagy kulcsszavak szerepelnek.
Az osztályozásnak megfelelően egy Turbo Pascal nyelvű program lexikális és elválasztó elemekből tevődik össze. A program lexikális elemzésekor különíthetjük el az egyes elemeket. Az elemzés természetes sorrendben megy végbe, vagyis balról jobbra, ill. felülről lefelé. A fordító az adott karaktersorozatot akkor tekinti lexikális elemnek, ha nem tartalmaz elválasztót.
A lexikális elemek és megjegyzések a következő alapszimbólumokból épülnek fel:

A :=, <=, >=, <>, (*, *) szimbólumok esetén fontos a karakterek megadási sorrendje. A nyelv nem engedi a karakterpárok felcserélését (pl.: =<). Hibajelzést kapunk akkor is, ha ezekben a szimbólumokban a karakterek közé szóközt teszünk.
A nagy- és kisbetűket az azonosítókban és a kulcsszavakban azonosnak tekinti a nyelvi definíció. Emiatt pl. a filename és a FileName azonosító nem különbözik egymástól.
A forrásnyelvi program sorokból áll. Minden sor maximálisan 126 karaktert tartalmazhat - az ezen túliakat a fordító nem tudja feldolgozni. Ajánlatos a 126 karakter helyett 80-as határt betartani, mert az ennél hosszabb sorok értelemszerűen nem láthatóak egyben a képernyőn, és általában a nyomtatók is sort váltanak a 80. karakter után.

2.1. Kulcsszavak
A felsorolt, kötött jelentésű, összefüggő betűsorozatok a kulcsszavak:

absolute external nil shl
and file not shr
array for of string
begin forward or then
case function overlay to
const goto packed type
div if procedure until
do in program var
downto inline record while
else label repeat with
end mod set xor

A szabványos Pascal packed kulcsszava a Turbo Pascal-ban hatástalan.

Példa
A Turbo Pascal nyelven megírt legrövidebb program a következő:

Begin
end.

A program két kulcsszóból és egy határolóból áll. A program lefuttatása semmilyen következménnyel sem jár.

2.2. Azonosítók
A Pascal programban az általunk létrehozott elemeknek (változóknak, konstansoknak, típusoknak, eljárásoknak, függvényeknek, rekordmezőknek) egyedi nevet kell adni, hogy hivatkozni tudjunk rájuk. A betűvel kezdődő, betűkből és / vagy számjegyekből álló karaktersorozatot (feltéve, hogy nem azonos egyetlen kulcsszóval sem) azonosítónak nevezzük. A "betű" alatt az angol ábécé tetszőleges kis- vagy nagybetűje, ill. az aláhúzásjel értendő. Az azonosító karaktereinek száma nem lépheti túl a 127-et, minden karakter szignifikáns.
Számos azonosító előre definiált; ezek konstansokat, függvényeket és eljárásokat képviselnek. E csoportba a következő azonosítók tartoznak:

Abs Delete Keypressed Read
Addr Dispose Length Readln
ArcTan Eof Ln Real
Assign Eoln Lo Release
Aux Erase LowVideo Rename
Bdos Execute Lst Reset
Bios Exit Mark Rewrite
BiosHL Exp MaxAvail Round
BlockRead False MaxInt Seek
BlockWrite FilePos Mem Sin
Boolean FileSize MemAvail SizeOf
Buflen FillChar Move SeekEof
Chain Frac NormVideo Sqr
Char FreeMem Odd Sqrt
Chr GetMem Ord Str
Close GotoXY Output Succ
ClrEol Halt OvrDrive Swap
ClrScr HeapPtr ParamCount Text
Con Hi ParamStr Trm
Concat Input Pi True
Copy Insert Port Trunc
Cos InsLine Pos UpCase
CrtExit Int Pred Usr
CrtInit Integer Ptr Val
DelLine IOresult Random Write
Delay Kbd Randomize Writeln

Ha a listán szereplő azonosítók valamelyikét deklaráljuk, akkor ezzel a deklaráció érvényességi körén belül "eltakarjuk" az adott azonosító eredeti jelentését.

Példa
Az azonosító jelentésének "eltakarása":

program jb;
const false=true;
begin
  Writeln(false)
end.

A programfuttatás eredményeképpen a TRUE felirat jelenik meg a képernyőn. Ha a programból kitörölnénk az első pontosvessző és a begin közötti szövegrészt, akkor futási eredményként a FALSE felirat jelenne meg.

2.3. Konstansok
A konstansok aritmetikai, karakter, karakterlánc és logikai konstansok lehetnek. Az aritmetikai konstansok tovább csoportosíthatók egész és valós típusú konstansokra. Az aritmetikai konstansokat a továbbiaknak számoknak fogjuk nevezni.

2.3.1. Egész típusú konstansok
Az egész típusú konstans decimális számjegyek sorozata, melyet a + vagy a - jel előzhet meg. Az egész típusú konstans számértékének a [-32768, 32767] zárt intervallumba kell tartoznia. Azon egész típusú konstanst, amelynek számértéke a [0,255] zárt intervallumba tartozik, byte típusú konstansnak nevezzük.
A Turbo Pascal nyelvben az egész és a byte típusú konstansok hexadecimális (tizenhatos számrendszerbeli) számokkal is megadhatók. Ez esetben a konstans a $ jelből és az azt követő hexadecimális számjegyek sorozatából áll. A $ jel előtt szerepelhet a + vagy a - jel.

Példa
Néhány - helyes és hibás - egész típusú konstans:
Egész típusú konstansok: 23, -23, 002, $ABC, -$2B
Olyan karaktersorozatok, amelyek nem képviselnek egész típusú konstansokat:
2B6 (a B betű nem decimális számjegy);
$3G a G betű nem hexadecimális számjegy);
2.6 (a . karakter nem számjegy.)

2.3.2. Valós típusú konstansok
A valós típusú konstans egymás utáni összetevői a következők: előjel egészrész, tizedespont, törtrész, hatványjel (kis vagy nagy E betű), kitevő. Az egészrész, a törtrész és a kitevő decimális számjegyek sorozata; az egészrészt és a kitevőt megelőzheti a + vagy a - jel. Ha elhagyjuk az előjelet, akkor a szám pozitív lesz. A törtrész (a tizedesponttal együtt) és a kitevő (az E betűvel együtt) elhagyható, de az egész részt mindíg meg kell adni. Megengedhető továbbá, hogy a konstans törtrésze üres legyen.

Példa
Néhány - helyes és hibás - valós típusú konstans:
Valós típusú konstansok: -2.3, 2.5e2, 4.E-3, $ABC, 2E3
Olyan karaktersorozatok, amelyek nem képviselnek valós típusú konstansokat:
3e2.0 (a kitevőben nem lehet tizedespont);
.25 (hiányzik az egészrész);
2.3D2 (hibás kitevő).

2.3.3. Karakter, illetve karakterlánc típusú konstansok
A karakterlánc típusú konstansok karaktersorozatokat képviselnek. Ha a karakterlánc egyetlenegy karakterből áll, akkor karaktertípust képvisel. Általános esetben egy karakterlánc típusú konstans a következőkből állhat: két aposztróf közötti karaktersorozatból, vezérlő karakterekből, valamint decimálisan vagy hexadecimálisan ábrázolt karakterekből. A két aposztróf között levő karaktersorozatban tetszőleges látható karakterek (a szóközt is beleértve) fordulhatnak elő; az ' (aposztróf) karaktert pedig egy aposztróf-pár képviseli. A vezérlő karaktereket egy karakterpár ábrázolja, ahol az első karakter egy ^, a második pedig egy látható karakter. Az így ábrázolt vezérlő karakter kódja azonos azzal a kóddal, amely a CTRL billentyű és az adott látható karakter billentyűjének együttes lenyomásával keletkezik. A decimálisan ábrázolt karakterek a # karakterből és az utána következő decimális karakterkódból állnak, a hexadecimálisan ábrázolt karakterek pedig a # karakterből, a $ karakterből és az utána következő hexadecimális karakterkódból.

Példa
Néhány - helyes és hibás - karakterlánc típusú konstans:

2.3.4. Logikai konstansok
A logikai konstansokat a true és a false karaktersorozat képviseli. Közülük az első a logikai "igaz" értéket, a második pedig a logikai "hamis" értéket jelenti.

2.4. Megjegyzések
A megjegyzés nyitó kapcsos zárójellel kezdődő és záró kapcsos zárójellel végződő karaktersorozat. A nyitó és záró kapcsos zárójelek helyett használhatók a ( * és *) összetett szimbólumok is. A { és } karakterekkel határolt megjegyzések beágyazhatók a (* és *) szimbólumokkal határolt megjegyzésekbe; hasonlóképpen a ( * és *) szimbólumokkal határolt megjegyzések beágyazhatók a { és } karakterekkel határolt megjegyzésekbe.
Ha a megjegyzést megnyitó karakter vagy szimbólum után közvetlenül a $ karakter következik, akkor ezt a megjegyzést a fordítóprogram direktívának tekinti. A direktíva nem szerepelhet beágyazott megjegyzésben.

3. Standard skalártípusok
Számítógépes programok többsége a futása során megadott adatokat valamilyen módon feldolgozza és megjeleníti az eredményeket. A program által kezelt adatok sokfélék lehetnek (számok, szövegek, stb.). A programban az adatokat változókban tároljuk. Az adattípus határozza meg, hogy egy változó milyen értéket vehet fel és milyen műveletek végezhetők rajta. A változók számára a fordítóprogram egy vagy több bájtot foglal le a memóriában. Ez a tárterület tartalmazza a változó aktuális értékét, ami a program futása során meg is változhat. Minden változóhoz tartozik egy adattípus (röviden tipus), amely előírja a változó számára lefoglalandó memóriaterület nagyságát és a változóban tárolt adat értelmezését. A típus azt is meghatározza, hegy egy változó milyen értéket vehet fel.
A típus fogalma egy adathalmazhoz kapcsolódik. Ilyen értelemben egy változó bizonyos típusú, ha e típust leíró halmaz elemeit értékéül kaphatja. A Turbo Pascal nyelv megköveteli a program összes változójának nyílt típusmeghatározását. A változó adattípusa előírja a változó számára lefoglalandó memóriaterület méretét és a változóban tárolt adat értelmezését. Így a típus meghatározza, hogy a változó milyen értékeket vehet fel.
A változó nevét és a kiválasztott típust a változó deklarációjában kapcsolhatjuk össze. A változótípusok az alább látható elemi és összetett típusokra oszthatók fel. Elemi típus a skalár- és a mutatótípus; az összetett típusokhoz a karakterlánc-, a tömb-, a rekord-, a halmaz- és a file-típus tartozik. A skalártípusok között megkülönböztethetünk standard skalártípusokat, mégpedig integer (egész-), byte, char (karakter-), boolean (logikai) és real (valós) típusokat. Az első négyet rendezett típusnak is nevezzük. Jellemző tulajdonságuk, hogy mindegyikük egy megszámlálható halmazhoz kapcsolódik.

A logikai (boolean), egész (integer, byte), karakter (char) és felsorolás típusokat (és ezek résztartományait) sorszámozott típusnak is nevezzük.
A standard skalártípusok előre definiáltak. "Rejtett" definíciójuk érvényességi tartománya az egész programra kiterjed, kivéve azokat a részeket, amelyekben nyílt eltakaró deklarációk vannak.

Az integer típus
Az integer típusú adat az egész számok részhalmazának az eleme. E számok értékei a [-32768,32767] zárt intervallumhoz tartoznak. Az integer típusú adatok mindegyike 2 bájt tárhelyet foglal le. Az integer típusú adatokon végzett aritmetikai műveletekben nincs túlcsordulásellenőrzés. Emiatt az eredmény helyességének az a feltétele, hogy a művelet argumentumai és az összes közbenső eredmény az előbb meghatározott intervallumhoz tartozék.
A Turbo Pascal a legnagyobb integer típusú számot (32767) a MaxInt konstansban tárolja.

A byte típus
A byte típusú adat egész számok részhalmazának az eleme, értékei a [0,255] zárt intervallumhoz tartoznak. Ahol a programban egy byte típusú adatra hivatkozunk, majdnem mindenhol hivatkozhatunk egy integer típusú adatra (és fordítva). Fontos kivétel e szabály alól a paraméterek és argumentumok társítása az eljárásokban és a függvényekben; ekkor az adattípusok teljes megfeleltetése a követelmény. A byte típusú adatok mindegyike 1 bájt tárhelyet foglal le.

A char típus
A char típusú adat az ASCII kódkészlet eleme. A char típusú adatok mindegyike 1 bájt tárhelyet fogfal le és egyetlen karakter tárolására alkalmas.

A boolean típus
A boolean típusú adat a kételemű logikai adathalmaz eleme. Ezeket az adatokat a false és a true szabványos azonosítókkal jelölhetjük. A boolean típusú adatok mindegyike 1 bájt tárhelyet foglal le.

A real típus
A real típusú adat valós számhalmaz eleme. E halmazhoz tartozik a 0 szám, ill. azok a pozitív és negatív számok, melyek abszolút értékei a [10^-38, 10^83] intervallumhoz tartoznak.

A Turbo Pascal-ban a nem szabványos String típus is előre definiált, melyet karaktersorozatok tárolására használhatjuk.
A string-ben tárolt karakterek száma változhat, ezért a Turbo pascal egy külön byte-ot rendel (0-s indexszel), ahol tárolja a karakterek aktuális darabszámát. Mivel egy byte-ba írható maximális érték 255, a string típusú változó 255-nél több karaktert nem tárolhat. A változó definícióban szögletes zárójelben meg kell adnunk a string maximális hosszát.

var name:string[30];

A string típusú változóban tárolt szöveget egy darabban és karakterenként is feldolgozhatjuk. A karakteres elérés esetén a string-indexben,a string azonosítója mellett szögletes zárójelben) kell megadni a vizsgálandó karakter sorszámát:

name:='Bielaczky';
name[5]:='e';
Writeln(name[1]);

4. Programszerkezet
A Turbo Pascal nyelvben megírt program programfejlécből, blokkból és . (pont) karakterből áll. A fejlécben a program neve és egy kerek zárójelekkel határolt azonosítólista van, amely leírja a program és környezete közötti adatátvitel módját. A blokk egy deklarációs és egy végrehajtó részből áll. A fejléc és a deklarációs rész el is hagyható.

4.1. Programfejléc
Ha a program fejléccel kezdődik, akkor szerepel benne legalább a program neve. A programnév után megadható - kerek zárójelekkel határolva - a program paraméterlistája. Ez a lista felsorolja azon adatállományok azonosítóit, melyekkel a program kapcsolatot tart környezetével. A fordítóprogram nem értelmezi a lista tartalmát, ezért figyelmen kívül hagyja (a határoló zárójelekkel együtt). Szintaxis:

Program programnév(állománynévlista)

Példák:

program Volume
program Lister(Output);
program Copier(Input,0utput);

4.2. Blokk
A blokk egy deklarációs és egy végrehajtó részből áll. A deklarációs részben vannak a típusdefiníciók, a konstansnév-definíciók, az alprogramok (eljárások és függvények) definíciói és deklarációi, valamint a címkék és a változók deklarációi. Mindezek a definíciók és deklarációk tetszőleges sorrendben következhetnek; az egyes definíciók és deklarációk csoportjai keveredhetnek egymással. Ezt úgy kell érteni, hogy pl. a típusdefiníciók után írhatjuk a változók deklarációit, utánuk újból a típusdefiníciókat és a változódeklarációkat stb. A végrehajtó rész egy csoportosító utasításból áll, amely a program utasításalt tartalmazza.

4.2.1. Címkedeklarációk
A program minden utasítását címkével láthatjuk el, amely vezérlésátadást tesz lehetővé a goto utasítás használatakor. A címke egy azonosítóból vagy egy számjegysorozatból áll. A közvetlenül a címke után következő : karakter a címkét elválasztja egy másik címkétől vagy utasítástól. Mielőtt címkét használnánk a programban, deklarálnunk kell a nevét. A címkedeklarációk a label kulcsszóból és az utána következő - a címkenevekkel azonos - karaktersorozatok listájából állnak, végül a ; következik.Szintaxis:
label címkelista;

Példák:

label 10,abort,quit;
label 9999;

4.2.2. Konstansnév-definíciók
A program áttekinthetősége szempontjából gyakran hasznos, ha a konstansokat az őket képviselő, megfelelően megválasztott azonosítókkal helyettesítjük. Ilyen esetekben az azonosító azonos a vele összekapcsolt konstanssal. A Turbo Pascal nyelvben az azonosítókat és a konstansokat a konstansnév-definíciók értelmezésekor kapcsolhatjuk össze. A konstansnév-definíció a const kulcsszóból és az utána következő hozzárendelések sorozatából áll. A hozzárendelés az azonosítóból, az = karakterből, a konstanskifejezésből és a ; karakterből áll. A konstanskifejezés lehet szám, karakterlánc, konstansnév vagy - (mínusz) karakterrel megelőzött konstansnév. Az előre definiált konstansnevek a következők:
Pi - real típusú, a 3.1415926536 konstanst képviseli;
Maxlnt - integer típusú, a 32767 konstanst képviseli.

Példa:

const e=2.718282;

A konstansnevek olyan azonosítóval (névvel) ellátott értékek, amelyek nem változnak meg a program futása során. Következésképpen a konstansnevek nem szerepelhetnek értékadó utasítás bal oldalán! A definiált konstansnevek számára a fordító nem foglal helyet a memóriában, ezeket a fordító csak a fordítás során használja. A konstansnevekre a deklarációs részben és a programban egyaránt hivatkozhatunk.

Típusos konstansok
A Turbo Pascal - kibővítve a szabványos Pascal nyelvet - lehetővé teszi olyan (csak nevükben) konstansok használatát, amelyek memóriában tárolódnak és melyek tartalma megváltoztatható. Ezek az ún. típusos konstansok valójában a Pascal nyelv kezdőértékkel ellátott változói. A típusos konstansok másik fontos tulajdonsága, hogy a program indításakor létrejönnek, és a program lefutásáig léteznek.
A típusos konstansok szintén a deklarációs rész const szekciójában helyezkednek el. A típusos konstans definíciójában a konstans kezdőértékét is meg kell adni:

const konstansnév:típus=kezőérték

Például:

const name:string[20]='Micimacko';

A típusos konstans definíciója tulajdonképpen egy olyan változódeklaráció melyet az egyenlőségjel után a kezdőérték követ. A típusos konstansokat a programban csak ott használhatjuk, ahol egyébként változó is szerepelhet. (Ellentétben a normál konstansnevekkel, nem hivatkozhatunk rájuk a deklarációs részen belül.)
A típusos konstanst a fájltípuson (file) kívül tetszőleges típussal készíthetünk.

4.2.3. Típusdefiníciók
A program változóinak deklarálásakor meghatározzuk a változók típusait. A változó típusa lehet előre definiált vagy standard típus (pl. boolean vagy real, de külön is meghatározható egy típusdefinícióban, amely általános esetben a type kulcsszóból és a típusdefiníciók sorozatából áll. A típusdefiníciók mindegyike a definiált típus azonosítójából, az = karakterből, a típusleírásból és a ; karakterből áll.

Példák

type
   Number=integer;
   Color=(Red,Green,Blue,Orange);
   RGB=Red..Blue;
   Name=string[20];
   Matrix=array(1..5,1..5) of real;
   Person=record
      FirstName:string[6];
      LastName:Name;
      Salary:real;
   end;
   
Digits=set of 0..9;
   DataFile=file of Person;
   Ref=Matrix;

4.2.4 Változódeklarációk
A program - egyszerű és összetett - változóját használat előtt deklarálni kell. A változódeklarációk a var kulcsszóból és a deklarációk azt követő felsorolásából állnak. A deklarációfelsorolós az azonosítók listájából, a : karakterből, a típus meghatározásból és a ; karakterből tevődik össze. A deklaráció értelmezése a megadott típusú változó(k) létrehozását eredményezi.

Példák:

Var
   Length,Area,Volume:real;
   Count:integer;
   Buffer:array[0..255] of byte;
   Rejected:boolean;

Egy változó láthatósági tartománya (hatásköre) az a blokk, amelyikben a változót deklaráltuk. Ha ez a blokk más blokkokat is tartalmaz, melyekben ugyanilyen azonosítóval deklarált változók szerepelnek, akkor a deklaráció érvényességi tartománya kisebb, mint a láthatósági tartománya, és nem vonatkozik azokra a belső blokkokra, ahol az eltakaró deklarációk előfordultak. A változó láthatósági tartománya nem a blokk elején, hanem azonosítójának deklarálási helyén kezdődik.

4.2.5. Alprogram-deklarációk
Az alprogramok eljárásokra és függvényekre oszthatók. Az alprogram deklarációja azokat a tevékenységeket határozza meg, amelyek az alprogram hívása során végrehajtódnak. A függvénydeklaráció meghatározza a hívás helyén átadott eredmény típusát is. Az alprogram törzsét tartalmazó deklarációkat definícióknak nevezzük; azokat a deklarációkat, amelyekben a fejléc után a forward kulcsszó következik, előzetes deklarációknak hívjuk.
Az előzetes deklarációt csak akkor kell használni, ha a deklarációkat nem lehet úgy elrendezni, hogy az alprogramokat deklarációjuk hatáskörében hívjuk. (Mint ismeretes a Pascal nyelvben minden azonosítót a felhasználása előtt deklarálni (definiálni) kell. Abban az esetben azonban, ha két egymást kölcsönösen hívó alprogramot készítünk az első alprogram a később definiált alprogram hívását tartalmazza. A probléma a második alprogram előzetes deklarációjával oldható meg.) Az előzetes deklaráció csupán az alprogram fejlécét tartalmazza, amelyet a forward Pascal direktíva és egy pontosvessző követ. Az előzetesen deklarált alprogramra ugyanúgy hivatkozhatunk más alprogramokból, mint a már definiáltra. Az előzetesen deklarált alprogram "teste", vagyis az alprogram teljes definíciója a deklarációs részben belül bárhol megadható.

Példa (Eljárások kereszthívása:)

program jb;
   
...
   procedure second; forward;
   procedure first;
   begin
      
...
      second;
   end;
   procedure second;
   begin
      ...
      first;
   end;
begin
   ...
end.

Mivel a first eljárás deklarációjában benne van a second eljárás hívása, a second eljárás deklarációjában pedig a first eljárásé, a second eljárást előzetesen deklarálni kell:

procedure second;forward;

A definiáló deklarációval ellentétben az előzetes deklaráció csupán "bejelenti" az alprogram azonosítóját (és paramétereit, ha vannak).

5. Kifejezések
Azokat a karaktersorozatokat, amelyek az adat kiszámításához (ill. meghatározásához) végrehajtandó tevékenységeket határozzák meg, kifejezéseknek nevezzük. E tevékenységek végrehajtását a kifejezés kiértékelésének hívjuk. Mivel a kifejezés kiértékelésének az eredménye egy adat, magát a kifejezést az adatot képviselő karaktersorozatnak tekinthetjük. E fejezetben tárgyaljuk azon kifejezések kiértékelési szabályait, amelyek összetevői integer, real, char és boolean típusú adatokat képviselnek. A definiált típusú adatokra hivatkozó kifejezésekkel a megfelelő típusok leírásánál foglalkozunk majd.

5.1. Operátorok
Operátoroknak nevezzük a különféle műveleti jeleket, amelyek összekapcsolják a kifejezésekben szereplő operandusokat (változókat, konstansokat és függvényhívásokat). A Pascal nyelvben bizonyos operátorokhoz többféle művelet is társul. Azt, hogy egy operátor az adott műveletben mit jelöl, az operandusok száma és típusa határozza meg. A műveleteket az operandusok típusa alapján az alábbi csoportokba sorolhatjuk:

Az operátorok egy- vagy kétargumentumosak lehetnek, de elsőbbségük (precedenciájuk) szerint is osztályozhatók. Csökkenő precedencia szerint a következőképpen osztályozhatjuk őket:

Ha egy alkifejezésben két, azonos elsőbbségű operátor van, akkor a megfelelő műveletek balról jobbra hajtódnak végre. Legelőször a kerek zárójelekkel körülvett alkifejezések értékelődnek ki. Ilyen értelemben a kerek zárójelek egyargumentumú, legnagyobb precedenciájú operátornak tekinthetők.
Mivel - más nyelvekkel szemben - a relációs jelek is operátorok, a kifejezés kiértékelésének sorrendje eltér pl. a BASIC-ben megszokottól. Például az

a<2 or a>10

a Pascalban

a<(2 or a)>10

formában értékelődik ki. Ezért az ettől eltérő szükséges műveleti sorrendet zárójelekkel kell jelölni. Az elöbbi művelet helyes felírása:

(a<2) or (a>10)

Ha a szorzás, ill. az összeadás jellegű műveletek argumentumai integer vagy real típusú adatokat képviselő kifejezések, akkor a művelet eredménye csak akkor integer típusú, ha mindkét argumentum integer típusú és a művelet nem osztás. Egyébként a művelet eredménye real típusú.

Példa
A 2+3/4 kifejezés által képviselt adat kiértékelése:

5.2. Előjelváltó operátor
Az egyargumentumú - (mínusz) művelet végrehajtása ellenkezőjére változtatja meg az adat előjelét. Ha az adat értéke 0, akkor a művelet eredménye szintén 0 értékű adat. A - (mínusz) művelet argumentumai csak real és integer típusú adatok lehetnek.

Példa:

Kifejezés Eredmény
-(-4) 4
-3/2 -1.5

5.3. Negációs operátor
Az egyargumentumú not művelet végrehajtása kizárólag a boolean és az integer típusú adatokra vonatkozik. Az első esetben egy false értékű adat true eredményt ad és fordítva; a második esetben az adatreprezentáció minden bitje ellenkező értékűre változik.

Példák:

Kifejezés Eredmény
not false true
not true false
not 0 -1
not $FFFF 0
not -2 1
not -32768 32767

5.4. Szorzás jellegű operátorok
A kétargumentumú *(szorzás) és / (osztás) operátor a real és az integer (beleértve annak byte részhalmazát is) típusú adatokra vonatkozik, a kétargumentumú and operátor a boolean és az integer típusú adatokra, a többi, szorzás jellegű operátor pedig kizárólag az integer típusú adatokra. E követelményeket és az eredmény típusát az alábbi táblázat foglalja össze. A * és a / műveletek végrehajtását nem szükséges magyarázni. Jegyezzük meg, hogy az osztás eredménye mindig real típusú adat.

Operátor
1. argumentum
2. argumentum
Eredmény
*
real
real
real
 
real
integer
real
 
integer
real
real
 
integer
integer
integer
/
real
real
real
 
real
integer
real
 
integer
real
real
 
integer
integer
real
div
integer
integer
integer
mod
integer
integer
integer
and
integer
integer
integer
 
boolean
boolean
boolean
shl
integer
integer
integer
shr
integer
integer
integer

Példák:

Kifejezés Eredmény
25*40 1000
25*40.0 1000.0
0.25*40 10.0
24/3 8.0
24.0/3.0 8.0

Az osztás eredménye mindig real típusú, függetlenül attól, hogy a kifejezés értékének törtrésze nulla-e vagy sem. Így osztás eredményét nem tudjuk közvetlenül integer típusú változóba tölteni. A megoldás a kerekítést végző Round konverziós függvény használata lehet:

a:=Round(i/2);

(ahol a integer típusú változó). Azonban többnyire felesleges kiszámolni egy osztás törtrészét, csak azért, hogy rögtön eldobjuk (kivéve, amikor fontos a pontosabb kerekítés), ezért célszerűbb és gyorsabb megoldás a div operátort - mely az egész számok osztásakor keletkező hányadost adja - használni ilyen esetben:

a:= i div 2;

A div művelet eredménye integer típusú adat, melynek értéke egyenlő a két argumentum osztási eredményének egészrészével. A mod művelet (az egész számok osztásakor keletkező maradékot szolgáltatja) definíciója a következő:

a mod b=a-((a div b)*b)

Tetszőleges a és b (b<>0) egészre igaz az alábbi összefüggés:

a=(a div b)*b+a mod b

Példák:

Kifejezés Eredmény
25 div 7 3
-25 div 7 -3
25 mod 7 4
-25 mod 7 -4

Az and művelet eredménye két boolean típusú adaton az argumentumok logikai szorzata:

a. argumentum b. argumentum a and b
false false false
true false false
false true false
true true true

Az and művelet eredménye két integer típusú adaton olyan integer típusú adat, amelynek bitjei az argumentumok megfelelő bitpárjának logikai szorzatával egyenlők. Egy bitpár logikai szorzata csak akkor 1, ha mindkét bit 1, különben 0.

Példák:

Kifejezés Eredmény
false and true false
2 and 2 2
12 and 22 4
-5 and 0 0

A kétargumentumú shl és shr művelet kizárólag az integer típusú adatokra vonatkozik. A műveletek eredménye is integer típusú. Az eredmény bitképe úgy keletkezik, hogy az első argumentum bitjeit annyi pozícióval balra (shl) vagy jobbra (shr) toljuk el, amennyi a második argumentum értéke. Az eltolás logikai jellegű, vagyis az előjelbit nem sokszorozódik, ugyanakkor az üresedő bitpozíciók 0 értékű bitekkel töltődnek fel.

Példák:

Kifejezés Eredmény
2 shl 1 4
2 shl 3 16
3 shr 1 1
-3 shr 1 32766

5.5. Összeadás jellegű operátorok
A kétargumentumú + és - operátor a real és az integer (beleértve annak byte részhalmazát is) típusú adatokra vonatkozik, a többi, összeadás jellegű operátor pedig az azonos típusú argumentum-párokra. E követelményeket és az eredmény típusát az alábbi. Táblázat foglalja össze.

Operátor
1. argumentum
2. argumentum
Eredmény
+
real
real
real
 
real
integer
real
 
integer
real
real
 
integer
integer
integer
-
real
real
real
 
real
integer
real
 
integer
real
real
 
integer
integer
integer
or
integer
integer
integer
 
boolean
boolean
boolean
xor
integer
integer
integer
 
boolean
boolean
boolean

Példák:

Kifejezés Eredmény
20+40 60
20.0+40 60.0
60.0-40.0 20.0

A + és a - műveletek végrehajtását nem szükséges magyarázni. Jegyezzük meg, hogy a művelet eredménye csak akkor integer típusú, ha mindkét argumentum integer típusú. Egyébként a művelet eredménye real típusú.

Az or művelet eredménye két boolean típusú adaton az argumentumok logikai összege:

a. argumentum b. argumentum a or b
false false false
true false true
false true true
true true true

Az or művelet eredménye két integer típusú adaton olyan integer típusú adat, amelynek bitjei az argumentumok megfelelő bitpárjainak logikai összegével egyenlők Egy bitpár logikai összege csak akkor 0, ha mindkét bit 0, különben 1.

Példák:

Kifejezés Eredmény
false or true true
2 or 3 3
12 or 22 30
$8000 or 1 -32767

A xor művelet eredménye két boolean típusú adaton az argumentumok logika "kizáró VAGY" kapcsolata:

a. argumentum b. argumentum a xor b
false false false
true false true
false true true
true true false

A xor művelet eredménye két integer típusú adaton olyan integer típusú adat, amelynek bitjei az argumentumok megfelelő bitpárjainak modulo 2 összegével egyenlők. Egy bitpár modulo 2 összege csak akkor 0, ha mindkét bit azonos különben 1.

Példa:

Kifejezés Eredmény
true xor true false
$8000 xor 2 32766
12 xor 22 26
-1 xor -1 0

5.6. Relációk
A relációk operátorai tetszőleges integer, real, char és boolean típusú adatokra vonatkozhatnak. A műveletek eredménye mindig egy boolean típusú adat, melynek értéke false vagy true. Ha a reláció egyik argumentuma boolean vagy char típusú, akkor a másik argumentumnak ezzel azonos típusúnak kell lennie. Aritmetikai argumentumok esetén nem követelmény a típusazonosság. Ez lehetővé teszi pl. a real és a integer típusú adatok összehasonlítását.
A relációk operátorai a következők: = (egyenlő), <> (nem egyenlő), < (kisebb), > (nagyobb), <= (kisebb vagy egyenlő), >= (nagyobb vagy egyenlő).

Példák

Kifejezés Eredmény
20=20 true
30.0>20 true
'J'<'B' false
false<true true

5.7. Függvényhívások
A függvényhívás a függvény azonosítójából és az azt követő, kerek zárójelekkel körülvett hívási argumentumok listájából áll. A paraméter nélküli függvény hívása csak a függvény azonosítójából áll.

Példák:

Eof(Input)
KeyPressed

5.8. Típuskonverzió
A Pascal erősen típusos nyelv. Ez a megállapítás azt jelenti, hogy a nyelv mentes a automatikus típusátalakításoktól. Ha egy kifejezésben, különböző, nem kompatibilis kifejezések fordulnak elő (pl. egy értékadó utasítással integer típusú változóba real típusú értéket akarunk tölteni), típuskeveredési hibával (Type mismatch) megszakad a fordítás. Ebben az esetben két lehetőséget választhatunk:

Az első megoldás, hogy a szabványos függvények segítségével végezzük el az átalakítást:

A második megoldást az teszi lehetővé, hogy a Turbo Pascal nyelvben bővítették az ord függvény koncepcióját (ez a függvény egy tetszőleges, rendezett típusú adatot integer típusú adattá konvertál). Bevezették ui. az egyparaméteres operátorok családját (nevük megegyezik a rendezett típusokéval), ezért adatkonverzióra nyíik lehetőség tetszőleges, rendezett típusok között.
A konverziós operátor opr(arg) alakú, ahol az opr egy rendezett típus azonosítója, az arg pedig bármilyen rendezett típusú kifejezés. A konverzió eredménye egy olyan opr típusú adat, amelyre igaz az ord(a) = ord(opr(a)) reláció.

Példák:
Az előre definiált, rendezett típusok és a Color nyílt típusdefiníció

Type
   Color=(Heart,Diamond,Spade,Club);

érvényességi tartományán belül érvényesek a következő összefüggések:

Kifejezés Eredmény
integer(Club) 3
Color(2) Spade
char(65) 'A'
integer('A') 65
boolean(Heart) false
byte(true) 1

Példák:

Writeln(integer('a');
Writeln(byte('b'));
Writeln(char(65));
Writeln(Boolean(12));

6. Utasítások
Az utasítás azon tevékenységek leírása, amelyeket végre kell hajtani az algoritmus megvalósításakor. A Turbo Pascal nyelvben két utasításfajta van: egyszerű és strukturált. Egyszerű utasítás az értékadás, az eljáráshívás, az ugró utasítás és az üres utasítás; strukturált utasítás pedig a csoportosító utasítás, a feltételes utasítás, a kiválasztó utasítás és három iterációs utasítás. A programban szereplő minden szomszédos utasításpárt a ; karakter választja el.

6.1. Értékadó utasítás
Az értékadó utasítás a változónévből, az értékadó szimbólumból és a kifejezésből áll. Egy függvénydefiníción belül szerepelnie kell legalább egy értékadó utasításnak, amelyikben a változót azonosító karaktersorozat a függvény azonosítója.
Az értékadó utasítás végrehajtása során kiértékelődik a kifejezés képviselte adat, és ennek értékét megkapja az értékadó szimbólum bal oldalán álló azonosítóval meghatározott változó. A függvénydefiníción belüli értékadás a függvény értékét adja meg (vagyis azt az adatot, amely hozzáférhetővé válik a függvényhívás helyén).
Az értékadáskor a kifejezés típusának a változó típusával azonosnak kell lennie. Ez a típusazonosság akkor is fennáll, ha a változó real, a kifejezés pedig integer típusú. Egyetlen értékadó utasítással csak egy változónak adhatunk értéket. Ha például az a, b, c és d változók mindegyikének nullát akarunk adni értékül, akkor azt csak négy értékadó utasítással tehetjük meg (persze a négy értékadó utasítás egyetlen sorban is elhelyezhető).
Megjegyzés: a tömb, a rekord és a halmaz típusú adataggregátumban megengedett az értékadás, a file típusú változóban nem.

Szintaxis
változónév:=kifejezés
függvényazonosító:=kifejezés

Példák

i:=i+2
x1:=(-b+sqrt(b*b-4*a*c))/(2*a)
arr[2,3]:=m=n
fun:=false

Mielőtt bármilyen kifejezésben használnánk a programunk elején deklarált változókat, azokat kezdőértékkel kell ellátni, más szóval inicializálni kell. Bár a változó létrejöttekor kap valamilyen értéket, ez azonban mindig véletlenszerű és nem nulla. A változó inicializálás nélküli értéke attól függ, hogy éppen mi volt a változó számára kijelölt memóriaterületen.

Aritmetikai értékadás
Az aritmetikai értékadás során a bal oldalon szereplő változó numerikus értéket vesz fel. Az értékadó utasítások használata során gyakran előforduló hiba a típuskeveredés, amikor a bal és a jobb oldal típusa nem értékadás-kompatibilis. A másik, szintén gyakori hiba, hogy a bal oldalon szereplő változónak nagyobb értéket adunk, mint a típusának megfelelő maximális érték. Valamely változók típusának a megválasztásakor mindig át kell gondolni, hogy a változó milyen értékeket vehet fel. Ugyancsak meg kell vizsgálni, hogy a műveletek következtében a program futása során hogyan alakulnak az értékhatárok.
Például, ha a v integer típusú változó (2 bájton tárolt előjeles egész, melynek értéktartománya -32768..32767), akkor az alábbi értékadások programhibához vezetnek:

v:=23456;
v.=2*v;

Ez a hiba nehezen kideríthető, mivel a v változó hibás értéke a program további részeiben vagy csak az eredményekben jelenik meg hibaként.
Különös figyelemmel kell eljárnunk a változó típusának megválasztása során. Ha előre tudjuk, hogy a változó a típusánál nagyobb (kisebb) értékeket is felvehet, akkor a tágabb értékkészlettel rendelkező real típust kell használnunk.
A következő példában látszólag minden rendben van, hisz a változók típusa és az eredmény típusa elegendő az értékeik tárolására:

var a,b:integer;
     r:real;
begin
   a:=30000; b:=25000;
   r:=a+b;
end.

Az eredmény azonban mégis hibás lesz: 55000 helyett -10536-ot kapunk! A hibát jobb oldalon álló kifejezés kiértékelése okozza. Kétoperandusú művelet elvégzéséhez a számítógép az operandusok típusának megfelelő típusú munkaterületet használ. A bal oldalon szereplő változóba csak a művelet elvégzése után kerül az eredmény. Így a példában hiába szerepel real típusú változó a bal oldalon, a kifejezés kiértékelése során integer típust használ a rendszer.
A problémát (ha sikerült megtalálnunk!) kétféleképpen oldhatjuk meg. Vagy mindhárom változót real típusúra deklaráljuk, vagy az a értékét először betöltjük az r változóba.

var a,b:integer;
     r:real;
begin
   a:=30000; b:=25000;
   r:=a; r=r+b;
end.

6.2. Eljáráshívás
Az eljáráshívás az eljárás azonosítójából és az azt követő, kerek zárójelekkel körülvett hívási argumentumok listájából áll, a paraméter nélküli eljárás hívása pedig csak az eljárás azonosítójából. Az eljárás hívásakor végrehajtódnak az eljárás definíciójában meghatározott tevékenységek. Előtte azonban lezajlik a hívott eljárás argumentumainak meghatározása és a hívásban szereplő kifejezések kiértékelése.

Szintaxis:
eljárásnév (argumentumlista)
eljárásnév

Példák:

Rewrite(OutFile)
Move(source,target)
Exit

6.3. Ugró utasítás
Az ugró utasítás (vezérlésátadás) a goto kulcsszóból és az azt követő címkenévből áll. Az ugró utasítás végrehajtása eredményeképpen a program a címkével ellátott utasítással (és az utána következő utasítássorozattal) folytatódik (feltétel nélküli vezérlésátadás). Ennek feltétele, hogy egy bizonyos címkenevet tartalmazó ugró utasítás e címkedeklaráció hatáskörén belül legyen. Nem megengedett, hogy az ugró utasítás végrehajtása a vezérlést egy strukturált utasítás vagy egy alprogram belsejébe, ill. az alprogramon kívülre adja át.

Szintaxis
goto címkenév

Példák:

goto 345
goto finish

6.4. Üres utasítás
Az üres utasítás a nyelv egyetlen olyan szerkezete, amely nem igényli a nyelvi szimbólumok használatát. Akkor alkalmazzuk, amikor a programon belül szükség van egy utasításra, de semmilyen tevékenységet nem akarunk végeztetni vele. Az üres utasítás végrehajtásának nincs következménye.

Példák (Az üres utasítás helyét egy felkiáltójelet tartalmazó megjegyzés jelöli):

begin {!} end
while false do {!};
repeat {!} until true
begin {!} ; {!} end
case true of false: {!} ; true {!} end

6.5. Csoportosító utasítás
A csoportosító utasítás (röviden csoportos utasítás) a begin kulcsszóból, az utasítások sorozatából és az end kulcsszóból áll. A csoportosító utasítást ott használjuk, ahol a nyelv szintaxisa csak egy utasítást enged meg, itt viszont utasítássorozatra van szükség. A csoportosító utasítás végrehajtásakor végrehajtódik a benne foglalt utasítássorozat.

Szintaxis

Begin
   utasítások sorozata
end

Példák:

begin
   i:=2;j:=3
end

begin
   Writeln(OutFile);
   Close(OutFile)
end

Meghegyzés: az end-et megelőző utasítást nem kell pontosvesszővel zárni, de a fordító nem jelez hibát, ha kitesszük.

6.6. Feltételes utasítás
A feltételes utasítás az if kulcsszóból, az azt követő logikai kifejezésből, a then kulcsszóból és egy utasításból áll (egyágú szelekció). Az utasítás után az else kulcsszó és egy újabb utasítás is következhet (kétágú szelekció). A feltételes utasítás végrehajtása a logikai kifejezés kiértékelésével kezdődik; ha az eredmény true, akkor a then kulcsszó utáni utasítás hajtódik végre. Ha az eredmény false és az utasítás nem tartalmazza az else kulcsszót, akkor az utasítás végrehajtását befejezettnek tekintjük; ellenkező esetben az else kulcsszó utáni utasítás hajtódik végre. Az if ... then ... else ... egyetlen strukturált utasítás, melynek része mindhárom kulcsszó, mégpedig ebben a sorrendben. A szintaktika a THEN illetve az else utasítás után egy-egy utasítást vár (ez lehet összetett utasítás is). A pontosvessző lezárja az if utasítást, így az else elé nem szabad pontosvesszőt tenni, mert szintaktikai hibát eredményezne (ELSE-zel egyetlen utasítás sem kezdődik).
Ha a feltételes utasításban szereplő utasítás is feltételes, akkor csak az else kulcsszó előtt állhat (feltéve, hogy ez az utasítás is tartalmazza az else kulcsszót).

Szintaxis:

if logikai_ kifejezés then utasítás

if logikai_ kifejezés then utasítás
   else utasítás

Példák:

if a=b then a:=5 else b:=5

if a=b then begin
     a:=6;
     b:=6
end

if a=b then
   if a=5 then
      b:=2
   else
      a:=3
else
   a:=13

6.7. Kiválasztó utasítás
A kiválasztó utasítás segítségével könnyen megoldhatjuk a programunk egy értéktől függő többirányú elágaztatását. A kiválasztó utasítás a case kulcsszóból, az azt követő kiválasztó (szelektor-) kifejezésből, az of kulcsszóból, a kiválasztási címkékkel ellátott utasítások sorozatából és az end kulcsszóból áll. A kiválasztási címkék listája konstansokból épül fel; a listát egy : karakter választja el az utasítástól. A szelektor és az egyes eseteket azonosító konstansok csak sorszámozott típusúak lehetnek. A listában szereplő mindegyik konstans típusának azonosnak kell lennie a kiválasztó kifejezés típusával. Ha a konstanslistán belül rendezett típusú, egymás utáni elemek sorozata jelenik meg, akkor a sorozat az
   első.. utolsó
szerkezettel helyettesíthető, mely meghatározza a sorozat első és utolsó elemét. Ha több értékhez ugyanaz az utasítás tartozik, akkor az esetkonstansokat vesszővel elválasztva is megadhatjuk:
   első, második, ...
A kiválasztó utasítás utolsó ágában (az end kulcsszó előtt) szerepelhet az else kulcsszó is (kettőspont nélkül).
A kiválasztó utasítás végrehajtása a kiválasztó kifejezés kiértékelésével kezdődik; utána az az utasítás (ez lehet összetett utasítás is) hajtódik végre, amelyiknek a kiválasztási címkéje egyenlő a kiválasztó kifejezés értékével. Ha nincs ilyen utasítás, akkor az else kulcsszó utáni utasítások hajtódnak végre; ha hiányzik az else ág, akkor egy üres utasítás hajtódik végre.

Példák:

case a=b of
   false: i:=5;
   true: j:=2;
end

case Year of
   1945..1955: Writeln('hard work');
   1956..1969: Writeln('hopes');
   1970..1979: Writeln('prosperity');
   1980..1981: Writeln('euphoria');
   else Writeln('no comment')
end

case st of
   'A','a': c:=65;
   'B','b': c:=66;
end

6.8. Iterációs utasítások
Az iterációs utasításokkal programozott ciklusok szervezhetők. Három fajtájuk van: a for, a while és a repeat. Ha előre (a ciklusba való belépés előtt) ismerjük az ismétlések számát, akkor a for utasítás használata javasolt. Amennyiben a ciklust valamilyen feltétel vezérli (vagyis az ismétlések száma attól függ, hogy mikor válik a feltétel igazzá vagy hamissá), akkor a while vagy a repeat utasításokat használjuk. A ciklusokat a belépési (illetve a kilépési) feltétel ellenőrzésének helye alapján is csoportosíthatjuk.

A for utasítás
A for utasítás a for kulcsszóból, az azt követő ciklusváltozó azonosítójából, az értékadás-szimbólumból, a ciklusváltozó kezdeti értékét meghatározó kifejezésből, a to vagy a downto kulcsszóból, a ciklusváltozó végértékét meghatározó kifejezésből, a do kulcsszóból és egy tetszőleges utasításból áll. A ciklusváltozónak és mindkét kifejezésnek rendezett típusúnak kell lennie.

Szintaxis
for változónév:= kifejezés(a) to kifejezés(b) do utasítás
for változónév:= kifejezés(a) downto kifejezés(b) do utasítás

A for utasítás végrehajtásakor a ciklusban szereplő utasítások a ciklusváltozó összes olyan értékére végrehajtódnak, melyek a "kifejezés(a)" és a "kifejezés(b)" által határolt zárt intervallumhoz tartoznak.
Ha a for utasításban a to kulcsszó szerepel, akkor a ciklusváltozó növekvő sorrendben vesz fel értékeket (a legkisebbtől a legnagyobbig). Ha a downto kulcsszó jelenik meg, akkor a ciklusváltozó csökkenő sorrendben vesz fel értékeket (a legnagyobbtól a legkisebbig). Ha az első esetben igaz a

Kifejezés(a)>kifejezés(b)

reláció, vagy a második esetben igaz a

kifejezés(a)<kifejezés(b)

reláció, akkor a for utasítással meghatározott ciklus egyáltalán nem hajtódik végre. Ilyen esetben a for utasítás végrehajtása csupán a két kifejezés kiértékelését jelenti. Egyéb esetben a ciklus legalább egyszer végrehajtódik; befejezés után a ciklusváltozó értéke egyenlő a "kifejezést" értékével.
Megjegyzés: az említett kifejezések csak egyszer értékelődnek ki (a ciklusba való belépéskor). A ciklusváltozónak nyíltan nem lehet értéket adni.

Példák:

for i:= 2 to 8 do Writeln(i)

for j:=8 downto 2 do Writeln(j)

for toggle:=false to true do
   for letter:='i' to 'n' do
      arr[toggle,letter]:= 2

Program Szorzotabla;
var i,j:integer;
begin
   for i:=1 to 10 do begin
      for j:=1 to 10 do
         Write(i*j:4);
      Writeln
   end
end.

Ha a ciklusszervezés során nem ismerjük előre a szükséges ismétlések számát, akkor a feltételes ciklusutasítások egyikét kell használnunk. Ilyenből kétfélét ismert a Turbo Pascal:

A while utasítás
A while utasítás a while kulcsszóból, az azt követő boolean típusú változóból, a do kulcsszóból és egy tetszőleges utasításból áll. Egynél több utasítás while ciklusban történő végrehajtásához összetett utasítást kell használnunk.

Szintaxis
while kifejezés do utasítás

A while utasítás a következő algoritmus szerint hajtódik végre:

  1. Először a kifejezés értékelődik ki.
  2. Ha a kifejezés értéke false, akkor az utasítás végrehajtása befejeződött.
  3. Ha a kifejezés értéke true, akkor a do kulcsszó utáni utasítás hajtódik végre; ezután a leírt tevékenységek az 1. ponttól kezdve ismétlődnek.

A while szerkezet elöltesztelő ciklusutasítás. Abban az esetben, ha a feltétel értéke már a ciklusba belépéskor hamis, a ciklusmag egyszer sem hajtódik végre. Ha a belépési feltétel igaz értéke hibás ciklusszervezés miatt sosem változik hamisra, végtelen ciklust kapunk.

Példa:

while i<>0 do begin
  i:=i-1;
  Writeln(i)
end

A repeat utasítás
A repeat utasítás a repeat kulcsszóból, az azt követő tetszőleges utasítások sorozatából, az until kulcsszóból és egy boolean típusú kifejezésből áll. A repeat until ciklusban összetett utasítás nélkül is több utasítás helyezhető el. A ciklusmag határait a repeat-until utasításpáros egyértelműen meghatározza.

Szintaxis
repeat utasítások until kifejezés

A repeat utasítás a következő algoritmus szerint hajtódik végre:

  1. Először a repeat kulcsszó utáni utasítások hajtódnak végre.
  2. Kiértékelődik az until kulcsszó utáni kifejezés.
  3. Ha a kifejezés értéke true, akkor az utasítás végrehajtása befejeződött.
  4. Ha a kifejezés értéke false, akkor a leírt tevékenységek az 1. ponttól kezdve ismétlődnek.

Példák:

Repeat
  Writeln(i);
  i:=i-1
until i=0

repeat until KeyPressed

repeat
  read(kbd,k);
until (k>='1') and (k<='5') or (k=chr(27));

A repeat szerkezet hátultesztelő ciklusutasítás. Ezért a ciklusmag legalább egyszer mindenképpen végrehajtódik. Ha a belépési feltétel igaz értéke hibás ciklusszervezés miatt sosem változik hamisra, végtelen ciklust kapunk.

7. Felsorolási és intervallumtípusok
A Turbo Pascal elemi adattípusai a skalártípusok, ezen belül pedig a rendezett típusok. A rendezett típusok mindegyikének fontos tulajdonsága, hogy az őt definiáló halmaz megszámlálható.
Megjegyzés: a real típus - annak ellenére, hogy skalártípus - nem rendezett típus. Ez az oka annak, hogy a case utasítás szelektorkifejezése és címkéi, valamint a vezérlőkifejezések, íll. a for utasításban szereplő kifejezések nem lehetnek real típusúak.

7.1. Felsorolási típusok
A rendezett típusok közül az egyik legfontosabb a felsorolási típus. A felsorolási típusok mindegyike kis elemszámú halmazhoz kapcsolódik, amelynek elemein nem hajtunk végre aritmetikai műveleteket. E halmazok egyes elemeit egyedi azonosítókkal jelöljük, rendezettségük a felsorolási típus leírásában szereplő azonosítók sorrendjén alapul. A felsorolási típus leírása az adott típus elemazonosítóinak listájából és az azt körülvevő kerek zárójelekből áll. Az azonosítók mindegyike egyben az adott típus konstansa is. Lényeges a lista azonosítóinak felsorolási sorrendje.

Példák:

Type
   Day=(Mon,Tue,Wed,Thu,Fri,Sat,Sun);
   Color=(Heart,Diamond,Spade,Club);
   RGB=(Red,Green,Blue);

A felsorolási típus érvényességi tartományán belül nem megengedett egy másik felsorolási típus használata, amely az első típusban szereplő szimbólumok (konstansok) bármelyikére hivatkozik. Ez a korlátozás nem vonatkozik az előre definiált boolean felsorolási típusra; tehát megengedett pl. a (false, true) típusleírás.

Példa:

type
   Day=(Mon,Tue,Wed,Thu,Fri,Sat,Sun);
   WeekEnd=(Sat,Sun);

Mivel a felsorolási típusok megszámlálható halmazokhoz kapcsolódnak, az ilyen halmaz minden eleméhez egy nem negatív egész szám rendelhető hozzá. Ez a szám meghatározza a felsorolási típus azonosító-listáján az elem helyét. Ilyen értelemben a

type
   Direction=(North,South,East,West)

definícióban a North azonosítóhoz a 0-t, a South-hoz az 1-et, az East-hez a 2-t, ill. a West-hez a 3-at rendelhetjük hozzá. A hozzárendelt számok értékeit az előre definiált ord függvény adja meg. E függvény argumentuma a felsorolási típusú adatot képviselő kifejezés, értéke pedig az az inieger típusú nem negatív szám, amely megadja az argumentum 0-tól számított pozícióját (sorszámát) az adatot tartalmazó, rendezett halmazon belül.
A felsorolási típusú adatokon értelmezett két további függvény a pred és a succ. A ered függvény argumentuma egy tetszőleges, rendezett típusú kifejezés, amely a rendezett halmaz egyik elemét képviseli. A függvény értéke a halmaz azon eleme, amely közvetlenül megelőzi az argumentum képviselte elemet.
A pred függvény argumentuma nem képviselheti a halmaz első elemét, mivel ezt az elemet nem előzi meg más elem.
A pred függvényhez hasonló a succ függvény. A függvény argumentuma egy tetszőleges, rendezett típusú kifejezés, amely a rendezett halmaz egyik elemét képviseli. A függvény értéke a halmaz azon eleme, amely közvetlenül követi az argumentum képviselte elemet. A succ függvény argumentuma nem képviselheti a halmaz utolsó elemét, mivel ezt az elemet nem követi más elem.
Az ord, a pred és a succ függvény argumentuma lehet integer, ill. byte típusú adatokat képviselő kifejezés. Ilyen esetben, ha a függvény használata szabályos, érvényesek a következő összefüggések:

ord(n)=n
pred(n)=n-1
succ(n)=n+1

Példák:
Az előre definiált boolean típus és a nyíltan definiált Color típus

type Color = (Heart,Diamond,Spade,Club);

érvényességi tartományán belül érvényesek a következő állítások:

Kifejezés Eredmény
ord(false) 0
pred(true) false
ord(Club) 3
succ(Diamond) Spade

7.2. Intervallumtípusok
Az intervallumtípus a rendezett típusok másik fajtája. Minden ilyen típus egy tetszőleges rendezett halmaz olyan részhalmaza, amelynek elemeit az ord függvény egy 1-es különbségű számtani sorozatra képezi le. Az intervallumtípus leírása az intervallum alsó határát jelölő konstansból, a .. szimbólumból (pont párból) és a felső határt jelölő konstansból áll. Az itt felsorolt konstansok által meghatározott intervallum nem lehet üres halmaz.

Példák:

type
   Quadrant=0..90;
   Upper=A'..'Z';
   Logical=false..true;
   Colour=(Red,Blue,Green,Yellow,Orange);
   Hue=Blue..Yellow;

Megjegyzés: az előre definiált byte adattípus - bizonyos korlátozásokkal - az integer alaptípusból származtatott intervallumtípus, vagyis érvényes rá a következő "rejtett" definíció:

Type
   byte=0..255;

Az intervallum típusú adatokra is alkalmazható az ord, a pred és a succ függvény. E függvények értékképzése az alaptípuson belül megy végbe.

Példák:

A Hue típusdefiníció

type Colour=(Red,Blue,Green,Yellow,Orange);
       Hue=Blue..Yellow;

érvényességi tartományán belül érvényesek a következő összefüggések:

Kifejezés Eredmény
ord(Blue) 1
succ(Yellow) Orange
pred(Yellow) Green

Hangsúlyoznunk kell, hogy a felsorolási intervallumtípusok használata megnöveli a programok áttekinthetőségét és megkönnyíti "belövésüket", mert lehetővé teszi az adatok értéktartományának automatikus vizsgálatát. Ezekkel az adattípusokkal operatívtár-helyeket is megtakarítunk, ugyanis ha az alaptípus halmazelemeinek száma nem haladja meg a 255-öt, akkor a Turbo Pascal az adat tárolására csak egy bájtot használ fel. Hasonlóan takarékos az adatábrázolás, ha integer az alaptípus, és a két tartományhatár a [0,255] zárt intervallumba tartozik.

7.3. Értéktartomány-ellenőrzés
A Turbo Pascal nyelv fordítóprogramja lehetővé teszi, hogy a lefordított forrásprogram végrehajtása közben megtörténjék a skalár típusú adatok értéktartomány-ellenőrzése. Mivel ezek az ellenőrzések lelassítják a program futását, az alapértelmezés szerint ki vannak kapcsolva, de a {$R+} direktívával bekapcsolhatók. A forrásprogram azon részeiben, ahol ezek az ellenőrzések feleslegesek, a {$R-} direktívával kikapcsolhatók. Az értéktartomány-ellenőrzés csak a fordítóprogramnak szóló direktívák között álló értékadó utasítás idejére marad bekapcsolva.

8. Karakterlánc-típusok
A karakterlánc-típusok mindegyike összetett típus. Egy karakterlánc-típus definiálásakor meghatározzuk az e típushoz tartozó változó maximális karakterszámát. Minden karakterlánc-típushoz karaktersorozatok halmaza kapcsolódik. A halmaz elemei az üres karakterlánc és mindazok a karaktersorozatok, amelyek hosszúsága nem lépi túl a (definícióban meghatározott) maximális karakterszámot.
A karakterlánc-típus leírása a string kulcsszóból és az azt követő, szögletes zárójelekbe foglalt maximális karakterszámból áll. E szám kifejezhető egy integer típusú konstanssal vagy egy ilyen konstanssal egyenértékű konstansnévvel.

Szintaxis:
string [méret]

Példák:

type
   Cities=string[20];
   Names=string[12];

A karakterlánc típusú adatok az adott típus maximális karakterszámánál eggyel több bájtot foglalnak le a tárban. Ez a plusz bájt tartalmazza a karakterlánc pillanatnyi hosszát. Ebből következik, hogy egy karakterlánc 255 karakternél hosszabb nem lehet.

8.1. Karakterláncok összefűzése
Két karakterlánc a konkatenáció-operátorral egy lánccá fűzhető össze. Az operátor jele a + karakter, amely tetszőleges típusú karakterlánc-párokat fűzhet össze. A művelet eredménye olyan karakterlánc, amely az első karakterlánc összes karakteréből és az utána következő második lánc összes karakteréből áll. Követelmény, hogy az összefűzés eredményeképpen keletkező karakterlánc ne legyen hosszabb 255 karakternél.

Példák:

Kifejezés Eredmény
'jan'+'ewa' 'janewa'
'5'+'.'+'4' '5.4'
'j'+''+'b' 'jb'

8.2. Relációk
Két karakterlánc a relációs operátorokkal hasonlítható össze. A relációs operátorok a következők: = (egyenlő), <> (nem egyenlő), > (nagyobb),< (kisebb), >= (nagyobb vagy egyenlő), <= (kisebb vagy egyenlő). A relációs operátorok elsőbbsége kisebb az összefűző operátor elsőbbségénél. Ez teszi lehetővé olyan kifejezések szerkesztését, mint pl. jan'= j'+ 'an'- zárójelek használata nélkül.
Két karakterlánc akkor egyenlő, ha azonos a hosszúságuk és azonos karakterekből állnak. Ha nem egyenlőek, akkor a karakterlánc-összehasonlítás helyett az első egymásnak megfelelő, de eltérő karaktereket hasonlítjuk össze. Ha nincs ilyen karakterpár, mert az egyik karakterlánc a másiknak a kezdőrésze, akkor az a karakterlánc kisebb, amelyik rövidebb.

Példák:

Kifejezés Eredmény
'A'>'B' false
'jan'>'Jan' true
''<char(0) true
''='' true
'Jan'<='Jane' true
'2599'<'270' true

8.3. Értékadás
Egy karakterlánc típusú változó az értékadó utasítással kaphat értéket. Az értékadó szimbólum jobb oldalán tetszőleges; karakterlánc típusú kifejezés áll, a szimbólum bal oldalán pedig egy karakterlánc típusú változó neve. Ha a kifejezés által képviselt karakterlánc hosszabb, mint a változóban ábrázolható lánc, akkor az értékadás balról jobbra megy végbe, a többletkarakterek elhagyásával.

type
   Name=string[7]
var
   FirstName,LastName:Name;
...
   FirstName:='Jan';
   LastName:=:'Bielecki'

8.4. Karakterlánc-függvények és -eljárások
A karakterláncokon végezhető műveleteket bővítik a karakterlánc-függvények és -eljárások. Használatuk nagyban megkönnyíti a karakterlánc típusú adatok kezelését.

A Length függvény
Hívása: Length(Str)
A Str egy karaktersorozatot képviselő karakterlánc típusú kifejezés. A Length függvény eredménye e karaktersorozat hosszát (karaktereinek számát) jelentő, integer típusú adat.

Példa:

Length('jb') = 2

A Str eljárás
Hívása: Str(Val,Var)
Az első paraméterben megadott (byte, integer vagy real típusú) számot karakterlánccá alakítja. A Val aritmetikai kifejezés, a Var pedig egy karakterlánc típusú változó neve. Az Str eljárás végrehajtásakor a Var változó új értéket kap, mégpedig a Val kifejezés által képviselt adat számértékét, karakterlánc formájában. Ha a Val kifejezés integer típusú, akkor a keletkező karaktersorozat olyan egész számot ábrázol, amely a legkevesebb számjegyet tartalmazza.
Ha közvetlenül a Val kifejezés után :m alakú módosító tag is van, ahol az m integer típusú kifejezés, akkor a Val képviselte adat átalakításából kapott karakterlánc m hosszúságú lesz. A keletkező számjegysorozat jobbra igazítottan jelenik meg a karakterláncban. Ha a számérték nem ábrázolható m számú karakterben, akkor az m értéke automatikusan annyival nő, amennyi a szám ábrázolásához kell.

Példák (Feltételezzük, hogy a StrVar típusa string[4].)

Hívás Karakterlánc StrVar
Str(45,StrVar) 45 '45'
Str(-250,StrVar) -250 '-250'
Str(45:3,StrVar) b45 '45'
Str(45:5,StrVar) bbb45 ' 4'
Str(-2:5,StrVar) bbb-2 ' -'

Ha a Val kifejezés real típusú, akkor a mintasorozat a következő alakú:
bsd.ddddddddddEsdd
ahol b egy szóköz (space karakter), s a mantissza vagy az exponens (kitevő) előjele és d a számjegy. A mantissza előjelét egy szóköz vagy egy - (mínusz) karakter, az exponens előjelét pedig egy + vagy - (mínusz) karakter ábrázolja.
Ha közvetlenül a Val kifejezés után :m alakú módosító tag is van, ahol az m integer típusú kifejezés, akkor a Val képviselte adat átalakításából kapott karakterlánc m hosszúságú lesz. A keletkező számjegysorozat jobbra igazítottan jelenik meg a karakterláncban. Ha a számérték nem ábrázolható m számú karakterben, akkor a bemutatott mintasorozatból elmaradnak a vezető szóközök; ha ez nem elegendő, akkor csökken a mantissza számjegyeinek száma (legfeljebb két számjegyig). Ekkor az eredmény kerekítve jelenik meg.

Példák (Feltételezzük, hogy az Exp értéke 45.678E1, a StrVar típusa pedig string[10].)

Hívás Karakterlánc StrVar
Str(Exp:9,StrVar) 4.568E+02 '4.568E+02'
Str(Exp:8,StrVar) 4.57E+02 '4.57E+02'
Str(Exp:7,StrVar) 4.6E+02 '4.6E+02'
Str(Exp:6,StrVar) 4.6E+02 '4.6E+02'
Str(Exp:10,StrVar) 4.5678E+02 '4.5678E+02'
Str(Exp:11,StrVar) 4.56780E+02 '4.56780E+0'

Ha közvetlenül a Val kifejezés után :m:n alakú módosító tag is van, ahol m és n integer típusú kifejezés, akkor a keletkező karakterlánc - jobbra igazítva - m hosszúságú lesz, és az m értékétől függetlenül egy n hosszúságú törtrésszel rendelkező, fixpontos, kerekített számkonstansként jelenik meg. Ha a számérték nem ábrázolható m számú karakterben, akkor az m értéke automatikusan annyival nő, amennyi a szám ábrázolásához kell.

A Val eljárás
Hívása: Val(Str,Var,Rep)
Az első paraméterben megadott szövegfüzért integer vagy real típusú számmá alakítja. Az Str karakterlánc típusú kifejezés, a Var integer vagy real típusú változó, a Rep pedig integer típusú változó. A Val eljárás végrehajtásakor a Var változó új értéket kap, mégpedig a Str kifejezés által képviselt, karakterlánc típusú adat számértékét. Ez az adat nem kezdődhet és nem végződhet szóközökkel. Ha a Var változó integer típusú, akkor a konvertálandó számnak is integer típusúnak kell lennie. Ha a konverzió elvégezhető, akkor a Rep változó 0 értéket kap, különben az új értéke olyan pozitív szám, amely sorszáma annak a karakternek (a konvertálandó karakterláncban), amelyik leállította a konverziót. Ekkor a Var változó nem kap új értéket.

Példák (Feltételezzük, hogy az IntVar és az IntRep integer típusú változó.)

Hívás IntVar IntRep
Val(23,IntVar,IntRep) 23 0
Val('23.0',IntVar,IntRep) változatlan 3
Val(-200,IntVar,IntRep) változatlan 5

Ha a futó programban számot kérünk be, de string típusú adatot ad meg a felhasználó, a program hibaüzenettel leáll. A Val eljárással megvalósítható a bolondbiztos adatbevitel, ha előbb string típusú adatot olvasunk be:

repeat
   Write('Input an integer: ');Readln(inp);
   Val(inp,nr,k);
until k=0;

A Copy függvény
Hívása: Copy(Str,Pos,Num)
Visszaadja az első paraméterből kimásolt részsztringet. A Str karakterlánc típusú kifejezés, a Pos és a Num pedig integer típusú változó. A Copy függvény eredménye olyan karakterlánc típusú adat, amely az Str karakterlánc Pos pozíciójától kezdve Num számú karakterből áll. Ha Pos > Length(Str), akkor a függvény eredménye egy üres karakterlánc. Ha (Pos+Num) > Length(Str), akkor az eredmény úgy alakul, mintha a Num értéke csak Length(Str)-Pos+1 lenne. Pos értéke nem lehet 1-nél kisebb és 255-nél nagyobb.

Példák:

Kifejezés Eredmény
Copy('Pascal',3,4) 'scal'
Copy('Pascal',5,3) 'al'
Copy('Pascal',7,2) ''
Copy('Pascal'2,1) 'a'

A Concat függvény
Hívása: Concat (St2, . . ., Stk)
A paraméterként megadott sztringekből összefűzött karakterláncot adja vissza. A St,St2,...,Stk karakterlánc típusú kifejezés. A Concat függvény eredménye a St,+St2+...+Stk karakterlánc típusú adat. A függvény argumentumainak teljes hossza nem lépheti túl a 255-öt.

Példák:

Kifejezés Eredmény
Concat('j','a','n') 'jan'
Concat('j','','b') 'jb'
Concat('jan',' ','b') 'jan b'

A Pos függvény
Hívása: Pos (Src, Trg)
Visszaadja az első paraméterben megadott részsztring kezdőpozícióját a második paraméterben megadott sztingben. Az Src és a Trg karakterlánc típusú kifejezés. A Pos függvény eredménye egy integer típusú adat, amely a Trg karakterláncban azt a karakterpozíciót határozza meg, amelytől kezdve az Src tartalmával azonos karakterek következnek. Ha az Src karakterlánc nem fordul elő a Trg-ben, akkor a függvény eredménye 0.

Példák:

Kifejezés Eredmény
Pos('23','123123') 2
Pos('21','123123') 0
Pos('c','abcabc') 3
Pos(",'Pascal') 0

Az Insert eljárás
Hívása: Insert (Src, Trg, Pos)
Az első paraméterben megadott sztringet beékeli a második paraméterében megadott sztringbe a harmadik paraméterben definiált pozíciótól kezdve. Az Src karakterlánc típusú kifejezés, a Trg karakterlánc típusú változó, a Pos pedig egy integer típusú kifejezés. Az Insert eljárás beszúrja a Trg képviselte karaktersorozatba - a Pos pozíciójú karakter elé - az Src karakterlánc tartalmát. Ha Pos > Length( Trg), akkor feltételezzük, hogy Pos:= Length(Trg)+1. Pos értéke nem lehet 1-nél kisebb és 255-nél nagyobb. Ha a karakterek beszúrása a Trg változó maximális méretének túllépését okozná, akkor a jobb oldali többletkarakterek elvesznek.

Példák
(Feltételezzük, hogy a Trg változó típusa string[5], értéke pedig - az Insert eljárás mindenkori hívása előtt - jb'.)

Kifejezés Eredmény
Insert('an',Trg,2) 'janb'
Insert('jb',Trg,4) 'jbjb'
Insert('Janek',Trg,1) 'Janek'

A Delete eljárás
Hívása: Delete (Str,Pos,Num)
Az első paraméterben magadott szövegfüzérből karaktereket töröl. A Str karakterlánc típusú változó, a Pos és a Num pedig integer típusú változó. A Delete eljárás a Pos pozíciójú karaktertől kezdve Num számú karaktert töröl a Str képviselte karaktersorozatból. Ha Pos > Length(Str), akkor nem történik semmi. Ha Pos+Num-1 > Length (Str), akkor az eredmény úgy alakul, mintha a Num értéke Length(Str)-Pos+1 lenne. Pos értéke nem lehet 1-nél kisebb és 255-nél nagyobb.

Példák
(Feltételezzük, hogy a Trg változó típusa string[5], értéke pedig - az Insert eljárás mindenkori hívása előtt - 'janek'.)

Kifejezés Eredmény
Delete(Trg,4,2) 'jan'
Delete(Trg,6,1) 'janek'
Delete(Trg,5,3) 'jane'

8.5. Karakterlánc- és karaktertípusok
Valamennyi karakterlánctípus megfelel a rendezett char típusnak. Ez azt jelenti, hogy a program mindazon helyein, ahol megengedett a karakterlánc típusú kifejezés használata, használható a char típusú adat, és fordítva. Csak az a követelmény, hogy amikor egy char típusú változónak értéket adunk, az értékadó szimbólum jobb oldalán álló karakterlánc típusú adat 1 karakter hosszúságú legyen. A karakterlánc típusú változó egyes karaktereihez nemcsak az előre definiált Copy függvénnyel férhetünk hozzá, hanem - sokkal egyszerűbben - indexeléssel is. Az indexelés definíciójának elfogadhatjuk a következő azonosságot:

St[i]=Copy(St,i,1)

Ez az azonosság csak akkor igaz, ha teljesül az 1 <= i < Length(St) feltétel. Ezen az intervallumon kívül megengedett az operatív tár szomszédos bájtjainak elérése, különösen az ord(St[0]) kifejezés esetén, amely megadja az St által képviselt karakterlánc hosszúságát.
Megjegyzés: a {$R+} direktíva használata csak kismértékben teszi lehetővé a helytelen indexeléssel kapcsolatos hibák kiderítését. Ez abból ered, hogy a direktíva bekapcsolja ugyan a - deklarációból ismert - maximális index túllépésének vizsgálatát, de nem vezeti be a pillanatnyi mérettúllépés ellenőrzését.

Példa:

Var
   Name:string[5];
...
Name:='Jan';
{$R+}
Name[0]:=chr[5];
Name[4]:='e';
Name[5]:='k';

9. Tömbtípusok
A tömbtípusok mindegyike összetett típus. A tömb meghatározott számú, azonos típusú komponensből (elemből) áll. A komponensek akár elemi, akár összetett típusúak lehetnek. A tömbelemek indexeléssel érhetők el. Az index szögletes zárójelekkel körülvett, tetszőleges skalárkifejezés, melynek megengedett értéktartományát a tömbtípus leírása határozza meg.
A tömbtípus leírása az array kulcsszóból, az azt követő, szögeletes zárójelekbe foglalt indexleírásból, az of kulcsszóból és a komponensek típusleírásából áll.

Szintaxis:
array [indextípus] of elemtípus

Példák:

var tc:array[1..15] of char;
     tb:array['A'..'Z'] of byte;
     tn:[-5..5] of integer;

Egy összetettebb példa:

Type
   Color=(Red,Green,Blue);
   TruthTable=array[boolean] of boolean;
   Height=0..200;
Var
   Square:array[Color] of Height;
   Matrix:array[2..8] of array[2..8] of integer;
   Table:TruthTable;

Korlátozás, hogy a tömbök definiálásakor sem változót, sem kifejezést nem használhatunk a határértékek jelölésére (csak konstanst), azaz a tömbök méretét előre meg kell határozni. Ennek magyarázata, hogy a fordító minden változónak, így a tömböknek is, előre - még a futás előtt - lefoglalja a helyét a tárban. (Ezért van szükség az előzetes változó-deklarációra is.) Minden tömb a memória egy-egy folytonos területén helyezkedik el. Az egydimenziós töm esetén az elemek egyszerűen az indexek növekvő sorrendjében követik egymást.

A tömbelemeket a programokban tömbelem-nevek képviselik. A tömbelem neve a tömbnévből és az azt követő, szögletes zárójelekkel körülvett indexkifejezésből áll. Az indexkifejezés tetszőleges rendezett típusú kifejezés, típusa a tömbtípus leírásában szereplő "indextípus"-sal egyezik meg.
A ($R+} direktíva használata olyan kódgenerálást eredményez, mely lehetővé teszi az indexkifejezések helyességének vizsgálatát. A vizsgálat során a rendszer ellenőrzi, hogy az indexkifejezés értéke a tömbtípus leírásában szereplő indextípus értéktartományán belül van-e.

Példa:

Type
   Color=(Red,Green,Blue);
var
   Matrix:array[Color] of boolean;

9.1. Többdimenziós tömbök
A tömb egy olyan összetett adatstruktúra, melyben azonos típusú elemeket tárolunk. Eddig ezeket az elemeket egyetlen index különböző értékeihez rendeltük hozzá (egydimenziós tömb). Nem mindig kényelmes azonban az összes elemet folyamatosan indexelni. Sok esetben az adathalmaz elemeit nem sorosan látjuk, hanem pl. egy táblázat elemeit kétszintű (oszlop, sor) indexeléssel határolhatjuk be. Ilyenkor kétdimenziós dömböt deklarálunk:

tm:array[1..10] of array[1..15] of integer;

Ugyanez egyszerűbben:

tm:array[1..10,1..15] of integer;

Mivel egy tömbelem tömb is lehet, könnyű létrehozni két- és többdimenziós tömböket. A szintaxisnak megfelelően, egy kétdimenziós tömböt leíró típus definíciója a következő alakú:

Type
   TwoDim=array[2..5] of array [boolean] of real:

Ezt a definíciót egyszerűsítve is felírhatjuk:

Type
   TwoDim=array[2..5,boolean] of real;

vagyis az indextípusok leírása szögletes zárójellel körülvett listát alkothat. Hasonló egyszerűsítéssel élhetünk a tömbelem-nevek esetén; pl. a

Var
   Matrix:TwoDim;

deklaráció érvényességi körén belül helyesek és egyenértékűek a következő nevek (amelyek a Mátrix tömb elemei): Matrix[3][true] és Matrix[3,true].

Példa:

type
   
Pupils=string[20];
   Class=array[1..30] of Pupils;
var
   School:array[1..20] of Class;

Turbo Pascal-ban nincs korlátozva hány dimenziós tömböt hozhatunk létre, egyetlen határ a memória mérete.

9.2. Karaktertömbök
A karaktertömb olyan egydimenziós tömb, amelynek indexe integer típusú, elemei pedig standard char típusúak. A karaktertömbök olyan karakterlánc típusú változónak tekinthetők, amelyek állandó hosszúságú karaktersorozatokat képviselnek. Ennek az értelmezésnek köszönhetően a karaktertömbök és az elemek neve a karakterlánc típusú kifejezésekben mindazon helyeken előfordulhat, ahol egyébként karakterlánc típusú változók állnak. Ez különösen a relációkra érvényes.

Példa:

Type
   Number=2..5;
   StrTyp=string[5];
   ArrTyp=array[Number] of char;
var
   StrVar:StrTyp;
   ArrVar:ArrTyp;
   i:byte;
begin
   for i:=2 to 5 do
      ArrVar[i]:=chr(63+i);
   StrVar:='98765';
   StrVar:=Copy(StrVar,2,2)+ArrVar+'/'+ArrVar[4];
end;

9.3. Értékadások
Összhangban azzal a szabállyal, miszerint tetszőleges típusú változó egyetlen utasítással megkaphatja az azonos típusú adat értékét, egyetlen utasítással egy teljes tömb értékét is átadhatjuk a tömbváltozónak. Megengedett egy karakterkonstans értékének átadása is, de csak akkor, ha a konstans karaktereinek száma egyenlő a tömb méretével. A tömböknek más karakter típusú kifejezés értéke nem adható át. A karakterlánc típusú változók viszont értéket kaphatnak karakterlánc típusú kifejezésektől és karaktertömböktől egyaránt.

Példa:

Type
   Line=string(60);
   Page=array[1..30] of Line;
   Chapter=array[1..50] of Page;
   Word=array[1..5] of char;
Var
   Book1,Book2:array[1..6] of Chapter;
   Arr:Word;
   Brr:array[1..5] of char;
   Str:string[5];

9.4. Előre definiált tömbök
A Turbo Pascal nyelvben a 8 bites mikroszámítógépek számára előre definiáltak két tömböt, amelyek byte típusú elemekből állnak. E tömbök segítségével hozzáférhetünk az operatív tárhoz és a bemeneti, ill. kimeneti portokhoz.

A Mem tömb
A Mem tömbbel hozzáférhetünk az operatív tár bájtjaihoz. A tömbhivatkozásban szereplő index integer típusú kifejezés, amely meghatározza a bájt tárcímét.

Példa:

ByteVar:=Mem[200]
Mem[300]:=$FF

A Port tömb
A Port tömbbel hozzáférhetünk a bemeneti, ill. kimeneti portokhoz. A tömbhivatkozásban szereplő index integer típusú kifejezés, amely meghatározza a port címét. A Port tömb elemei nem lehetnek alprogram-paraméterek; de előfordulhatnak kifejezésekben és az értékadó szimbólum bal oldalán. A kifejezésben a megadott portról származó adatokat jelentik, az értékadó szimbólum bal oldalán pedig azt eredményezik, hogy az adat a megadott portra íródik.

Példa:

Port[34]:=$5F
PortStatus:=Port[35]

10. Rekordtípusok
A rekordtípusok mindegyike összetett típus. A rekord meghatározott számú, nem feltétlenül azonos típusú komponensből áll. A komponensek akár elemi, akár összetett típusúak lehetnek. A rekordelemek, melyeket mezőknek is nevezünk, szelekcióval (kiválasztással) érhetők el. Kiválasztáskor megadjuk a rekord nevét, a . (pont) karaktert és a rekordmező azonosítóját.
A rekordtípus leírása a record kulcsszóból, a rekordmezők listájából és az end kulcsszóból áll. A lista minden eleme egy-egy meződeklaráció. A meződeklarációkat pontosvessző választja el egymástól; a lista utolsó eleme lehet a változó rekordrész. A rekordtípus rugalmasságát növeli az a lehetőség, hogy a megadott feltételtől függően más és más mezői lehetnek. A változó rekordrész a case kulcsszóból, az azt követő vezérlőmező-deklarációból (vagy vezérlőtípus-leírásból), az of kulcsszóból és a változatlistából áll. A változatlista minden eleme a kiválasztási címkék listájából (melyet kettőspont követ), valamint a kerek zárójelekkel körülvett változatmezők listájából áll. A változatlista egyes elemeit pontosvessző választja el egymástól.

Példák:

type
   Days=1..31;
   Date=record
      Day:Days;
      Month:1..12;
      Year:1900..1999
   end;
Person=record
   Name:string[20];
   BirthPlace:string[30];
   case Sex:(male,female,alien) of
   male,female:(BirthDate:Date);
   alien:(BirthDate:real;
      BodyData:record
         H:integer;
         W:real
      
end)
   end;
var
   MyBirthDay:Date;
   EarthMan,Galaxian:Person;

A rekord elemeire (mezőire) úgy hivatkozhatunk, hogy a rekordváltozó neve után ponttal elválasztva írjuk a mező azonosítóját. Pl.:

Date.Years:=1973;
Date.Month:=12;
Date.Days:=24;

Több rekordtípusban is szerepelhet egyazon mezőnév, de egy rekordon belül a mezőnévnek egyedinek kell lennie.

10.1. A with utasítás
A rekordkomponensekre hivatkozás nemcsak a mezőnév megadását igényli, hanem a rekord névét is. Mivel ez bizonyos esetekben számottevően meghosszabbítja a program szövegét, kényelmes a with összekötő utasítás, amely mintegy "kitakarja" a rekordtípus-definíció belsejét.
Általános esetben a with utasítás a with kulcsszóból, az azt követő rekordnévlistából, a do kulcsszóból és egy tetszőleges utasításból áll. Az utasításon belül a listában szereplő rekord mezőinek kiválasztása a mezőnévvel helyettesíthető. A mezők ekkor automatikusan a with utasításban megadott rekordváltozóhoz tartoznak. Definíciószerűen elfogadjuk, hogy a

with a,b,..., z do i

alakú utasítás egyenértékű a

with a do
   with b do
      ...
      with z do i

utasítással.

Példa:

Var
   Alfa:record
      Beta:record
         Gamma:char;
         Delta:real
      end;
      Gamma:integer
   end;
   Beta:array[boolean] of record
      Chi,Tau : real
   end;

10.2. Változatok (unionok)
Ha a rekordban változatok vannak, akkor a Turbo Pascalban elfogadott belső ábrázolás szerint minden változat első mezője ugyanazon a memóriacímen kezdődik. Mivel a vezérlőmező deklarációja típusleírássá egyszerűsíthető, a rekordleírást könnyű átalakítani olyan szerkezet leírásává, amelyet a C nyelvben unionnak hívnak. Tudnunk, kell azonban, hogy a rekordokon végzett műveletektől eltérően az unionokon végrehajtott műveletek megkövetelik a komponensek ábrázolásának - vagy legalább tárolásának és méretének - ismeretét.

Példa:

Var
   Word:record
      case boolean of
         false : (LowByte,HighByte:byte);
         true : (FullWord:integer)
   end

10.3. Rekordértékadás
A tömbváltozókhoz hasonlóan megengedett, hogy egy rekord típusú változó az egész rekord értékét megkapja egy utasítással. Egyetlen követelmény, hogy a rekordváltozó típusa azonos legyen az értékadó rekord típusával.

Példa:

Type
   Name=record
      LastName:string[32];
      Names:array[(fst,snd,trd)] of string[8]
   end;
var
   JohnName,EwaName:Name;
   ...
EwaName:=JohnName;

11. Halmaztípusok
A halmaz bizonyos tulajdonságú elemek összessége. A Pascal nyelv speciális lehetőségei közé tartozik a halmazok nyelvi szinten történő támogatása. A halmaztípusok mindegyike összetett típus. A halmazváltozó olyan változó, amely egy hatványhalmaz részhalmazától kaphat értéket. A hatványhalmaz alaphalmaza rendezett típusú elemek tetszőleges halmaza. A halmazváltozó elemeinek mindegyike ilyen elem.
Két halmaz típusú adat akkor és csak akkor egyenlő, ha azonos elemekből áll. Ha az egyik halmazváltozó minden eleme egyben eleme a másik halmazváltozónak, akkor azt mondjuk, hogy az első változó részváltozója a másiknak.
A halmaztípus leírása a set kulcsszóból, az azt követő of kulcsszóból és az alaptípus leírásából áll. Az alaptípusként felfogható rendezett típus nem tartalmazhat 256 elemnél többet, és az elemek mindegyikére alkalmazott ord függvény értékének a [0,255] zárt intervallumhoz kell tartoznia. A halmaz deklarásakor meg kell adni az alaphalmazt, vagyis az alaptípust.

Példák:

type
   DaysOfWeek=set of (Mon,Tue,Wed,Thu,Fri,Sat,Sun);
   Chars=set of char;
   SmallLetters=set of 'a'..'z';
   DayNumbers=set of 1..31;

11.1. Halmazkonstansok
Egy halmazkonstans szögletes zárójelekkel körülvett, azonos (rendezett) típusú konstansok listájából áll. A lista lehet üres, tartalmazhat ismétlődő elemeket, ill. min..max alakú szerkezeteket, ahol a min és a max azonos típusú konstans. Ekkor a min..max egyenértékű a min-től a max-ig terjedő összes konstanssal, a határértékeket is beleértve. Ha min nagyobb mint max, akkor üres részhalmazról van szó.
Megjegyzés: a halmazkonstans értéke nem függ az őt alkotó alap típusú konstansok sorrendjétől; többszörös fellépésük nem befolyásolja a halmazkonstans értékét.

Példa:

11.2. Kifejezések
A halmazkifejezések a következő alkotóelemekből tevődnek össze: halmazváltozókra, -konstansokra, -szerkezetekre való hivatkozások, valamint az unió, a különbség és a metszet operátorai.
A halmazszerkezetek a halmazkonstansokhoz hasonló alakúak, azzal a különbséggel, hogy a listájukon szereplő elemek nemcsak az alaptípus konstansai, hanem ilyen típusú tetszőleges kifejezések is lehetnek. A halmazműveleteket két csoportra osztjuk. Az első csoport az ún . Boole-algebra műveleteit tartalmazza: A halmazunió-operátor jelölésére a + karaktert, a különbségoperátor jelölésére a - (mínusz) karaktert, a metszetoperátor jelölésére pedig a * karaktert használjuk.
A halmazok uniója olyan halmaz, amely mindkét összetevő összes elemét tartalmazza (az eredményhalmazban a közös elemek csak egyszer szerepelnek!). A halmazok különbsége olyan halmaz, amely a kisebbítendő halmaz azon elemeiből áll, melyek nem elemei a kivonandónak. A halmazok metszete olyan halmaz, amely mindkét tényező közös elemeiből áll.
A halmazműveleteken kívül a következő relációkban fordulhatnak elő halmaz típusú adatok:

a=b igaz, ha a és b azonos elemek halmazai;
a<>b igaz, ha a és b különböző elemek halmazai;
a<=b igaz, ha a üres halmaz, vagy az a minden eleme egyben b eleme is;
a>=b igaz, ha b üres halmaz, vagy a b minden eleme egyben a eleme is;
e in a igaz, ha az e alap típusú elem az a halmaz eleme.

Műveletek precedenciája:

Halmazt nem tudunk a WRITE utasítással kiírni. A halmaz kiírása úgy történik, hogy az alaphalmaz összes eleméről levizsgáljuk, benne van-e a megadott halmazban. Ha igen, akkor kiírjuk. Mivel az alaphalmaz minden esetben sorszámozott típus, a kiíratást egy növekményes ciklussal elvégezhetjük. A ciklus természetéből adódik a kiírt elemek rendezettsége.

Példák:

Var h1,h2: set of byte;
...
h1:=[1,2,6];
h2.=[1,4..7];

A fenti értékadások után a h1 és h2 halmazokon végzett műveletek eredményei:

h1+h2 = [1,2,4..7]
h1*h2 = [1,6]
h1-h2 = [2]

A SetVar változódeklaráció érvényességi körén belül (feltételezve, hogy a változó jelenlegi értéke a [Red,Green] konstans által képviselt halinaz típusú adat):

Type
   Colors=(Red,Green,Blue);
   Paint=set of Colors;
Var
   SetVar:Paint;
...
SetVar:=[Red,Green];

igazak a következők kifejezések:

SetVar=[Red..Blue]-[Blue]
SetVar<>[]
SetVar<=[Red..succ(Green)]
SetVar>=[B1ue..Green]
SetVar*[Red]=[Red]
Green in SetVar

11.3. Halmazértékadás
Az értékadás bal oldalán egy halmazváltozó áll, jobb oldalon pedig egy halmaz típusú kifejezés. A kifejezés operandusai halmazkonstansok, illetve halmazváltozók, operátorai pedig halmazműveletek.

Példák:

Var
   h:set of byte
   b.byte;
...
b:=3;
h.=[b+2];
h:=[1,10..24]+h;
h:=[0..25]-h;
h:=h-[b,b+2,b*2,20..23];





h=[5]
h=[1,5,10..24]
h=[0,2,3,4,6..9,25]
h=[0,2,4,7..9]

A tömbváltozókhoz és a rekordokhoz hasonlóan megengedett, hogy egy halmaz típusú változó egy utasítással az egész halmaz értékét megkapja, de a halmazváltozó típusának azonosnak kell lennie az értékadó halmaz típusával.

Példa:

Var
   SetVar:array[2..5, boolean] of set of 20..30;
   SetVar[3,false]:=[5*5...pred(29)];

12. File-típusok
A fájltípusok mindegyike összetett típus. A fájl komponensekből áll, melyek azonos típusúak. A fájl komponenseit elemeknek nevezzük. A tömbtípusoktól eltérően egy fájl elemeinek számát nem határozzuk meg a fájldeklarációban, hanem a program futásának eredményétől tesszük függővé (elsősorban attól, hogy a fájlt milyen adatállományhoz rendeljük hozzá).
Hangsúlyozni kell, hogy a fájlnak nevezett objektum csupán elvont logikai modellje annak a fizikai adatállománynak, amely leggyakrabban a programon kívül létezik. A fizikai adatállományok - itt röviden állományok - helyet foglalhatnak a számítógép háttértárában vagy operatív memóriájában, de azonosíthatók a külső berendezések segítségével be- és kivihető adatfolyamokkal is.
A programozás szempontjából nagy egyszerűsítést jelent, hogy különböző állományok ugyanazzal a fájllal dolgozhatók fel, ha hozzárendeltük őket egymáshoz. Így a programozónak nem kell ismernie a konkrét operációs rendszer tulajdonságait, sem a háttértárak adatszervezési és -tárolási megoldásait. Ezért a fájl szintű programozás többnyire a fájl megnyitását, a fájl elemein végrehajtandó műveleteket és a fájl lezárását jelenti.
Állományok használatára a Turbo Pascal alapvetően három lehetőséget kínál:

A Turbo Pascal legalapvetőbb állománytípusa a típusos állomány. A típusos fájlok olyan adathalmazok, amelyek azonos típusú adatelemekből épülnek fel. Az adatelemek azonos mérete lehetővé teszi, hogy az adatokat szekvenciálisan és közvetlen (direkt) módon egyaránt elérjük. Az elemek típusát (alaptípust) az állomány deklarálásánál meg kell adni: A fájltípus leírása a file kulcsszóból, az azt követő of kulcsszóból és az elemtípus leírásából áll. A fájlelemek tetszőleges elemi típusúak, ill. összetett típusúak lehetnek (kivéve a fájltípust).
Az elemek típusa meghatározza annak hosszát, ha például az elemek típusa integer, az állomány 2 byte-os, real típus esetén 6 byte-os egységekből áll. Az adatelemek azonos mérete lehetővé teszi, hogy az adatokat szekvenciálisan és közvetlen (direkt) módon is elérjük.

Példák:

Type
   Measurements=file of real;
   Persons=file of Record
      Name : string[20];
      Sex:(male,female);
      Age:18..65
   end;

Var
   Experiment:Measurements;
   Population:Persons;
   Complexes:file of record
      Re,Im:real
   end;
   Arrays:file of array[2..6,4..8,boolean] of byte;

12.1. Alprogramok
A fájlokon végezhető műveletek kizárólag függvényekkel és eljárásokkal valósíthatók meg. E műveletek végrehajtását meg kell előznie a fájl és az adatállomány egymáshoz rendelésének, ha a művelet a fájl elemeire vonatkozik, akkor előzőleg a fájlt meg kell nyitni. A fájlt és az adatállományt az Assign eljárás rendeli egymáshoz; a fájlt a Reset és a Rewrite eljárás nyitja meg. A Reset eljárás használata nem jelenti azt, hogy a fájlt csak olvasásra nyitjuk meg; a Rewrite eljárás sem csak írásra nyitja meg a fájlt. A program befejezése előtt minden fájlt le kell zárni: erre való a Close eljárás. A programfutás befejezése nem jelenti a nyitott fájlok lezárását!
Közvetlenül a megnyitás után a fájl kezdeti pozícióban (az elején) áll. A fájlpozíciót a Seek eljárással változtathatjuk. A fájl aktuális mérete a FileSize függvénnyel, pozíciója pedig a FilePos függvénnyel határozható meg. Ha a fájl közbenső pozícióban van (azaz a kezdeti és a végpozíció között), akkor minden Write eljáráshívás a legközelebbi fájlelemet írja felül. Ez a felülírás nincs hatással a fájl többi elemére, ezért az adott típusú elemekből álló fájlok szekvenciális szervezésű adatállományokat képviselhetnek.

Az Assign eljárás
Hívása: Assign (FileVar,StrExp)
A FileVar egy fájlváltozó neve, a StrExp pedig egy karakterlánc típusú kifejezés. A FileVar névvel azonosított fájl nem lehet nyitva. Az Assign eljárás végrehajtása hozzárendeli a FileVar névvel azonosított fájlt a StrExp kifejezéssel meghatározott adatállományhoz. StrExp egy állományspecifikáció, tehát a név a név és kiterjesztés előtt tartalmazhatja a lemezegység azonosítóját és az útvonalat is. Ez utóbbiak hiányában az állomány az aktuális lemezegység aktuális könyvtárára értendő.
Az adatállományokkal kapcsolatos műveleteknél mindig a logikai névre kell hivatkozni, de a művelet az összekapcsolás miatt mindig a megadott fizikai állományra vonatkozik.

Példa:

var
    Results:file of real;
...
Assign(Results,A:TEST,DAT');

A Reset eljárás
Hívása: Reset(FileVar)
A FileVar egy fájlváltozó neve. Az eljárás hívása előtt a FileVar névvel azonosított fájlt egy létező adatállományhoz kell hozzárendelni. A Reset eljárás megnyitja a FileVar névvel azonosított fájlt. A megnyitás kezdeti pozícióba (az első elem elé) állítja a fájlt.

Példa:

Var
   InpFile:file of record
      Name:string[30];
      Income:real
   end;
...
Assign(InpFile,'INCOME.DOC');
Reset(InpFile);

A Rewrite eljárás
Hívása: Rewrite (FileVar)
A FileVar egy fájlváltozó neve. Az eljárás hívása előtt a FileVar által képviselt fájlt egy adatállományhoz kell hozzárendelni. A Rewrite eljárás megnyitja a FileVar által képviselt fájlt. A megnyitás kezdeti pozícióba (az első elem elé) állítja a fájlt. Ha a Rewrite hívása előtt a fájlhoz hozzárendelt állomány nem létezett, akkor az eljárás végrehajtásakor létrejön. Ha pedig volt már ilyen állomány, akkor törlődik és újra létrejön. Mindkét esetben egy üres adatállomány keletkezik.

Példa:

Var
   OutFile:file of array[1..20] of byte;
...
Assign(OutFile,'B:TESTS.OUT');
Rewrite(OutFile);

A Read eljárás
Hívása: Read(FileVar,VarList)
A FileVar egy fájlváltozó neve, a VarList pedig egy változónév vagy változónév-lista. A FileVar névvel azonosított fájlnak nyitottnak kell lennie. A VarL.ist változó(k) csak a fájltípussal azonos típusú(ak) lehet(nek). A változónév-listát tartalmazó Read eljárás egyenértékű a változóneveket tartalmazó Read eljárások sorozatával. Egy változónévvel hívott Read eljárás beolvas egy elemet a fájlból, és ennek értékét a megadott nevű változónak adja át.

Példa:

Type
   ElmType=record
      Re,Im:real
   end;
var
   InpFile:file of ElmType;
   ArrVar:array[boolean,2..4] of ElmType;
...
Assign(InpFile,'COMPLEX.DAT');
Reset(InpFile);
Read(InpFile,Arr,Var[true,3]);

A Write eljárás
Hívása: Write (FileVar,VarList)
A FileVar egy fájlváltozó neve, a VarList pedig egy változónév vagy változóné-vlista. A FileVar névvel azonosított fájlnak nyitottnak kell lennie. A VarList változó(ak) csak a fájltípussal azonos típusú(ak) lehet(nek). A változónév-listát tartalmazó Write eljárás egyenértékű a változóneveket tartalmazó Write eljárások sorozatával. Egy változónévvel hívott Write eljárás a megadott nevű változó értékét beírja a FileVar változóval azonosított fájlba.

Példa:

Type
   ElmType=record
      Re,Im:real
   end;
var
   OutFile:file of ElmType;
   ArrVar:array[boolean] of ElmType;
...
Assign(OutFile,'COMPLEX.RES');
Rewrite(OutFile);
Write(OutFile,ArrVar[false]ArrVar[true] );

A Seek eljárás
Hívása: Seek(FileVar,PostExp)
A FileVar egy fájlváltozó neve, a PosExp pedig egy integer típusú kifejezés. A FileVar névvel azonosított fájlnak nyitottnak kell lennie. A PosExp kifejezés értékének a [0,FileSize(FileVar)] zárt intervallumon belül kell lennie. (A FileSize függvény értelmezését l. később, ugyanebben a szakaszban.) A Seek eljárás a PosExp kifejezés értékének megfelelő sorszámú elem elé állítja a fájlt: Ha a kifejezés értéke 0, akkor a Seek eljárás a fájlt a kezdeti pozícióba állítja, ha ez az érték FileSize(FileVar), akkor pedig a végpozícióba. Egy típusos állományt úgy tudunk bővíteni (ahhoz elemeket hozzáírni), hogy az utolsó elem utáni helyre pozícionálunk, és onnan folytatjuk a szekvenciális írást.

Példa:

Type
   Name=string[5];
var
   FileVar:file of Name;
   ElmVarl,ElmVar2:Name;
   Len,Pos:integer;
Begin
   Assign(FileVar,'FAMILY');
   Reset(FileVar);
   Len:=FileSize(FileVar)-1;
      for Pos:=0 to Len shr 1 do begin
      Seek(FileVar,Pos);
      Read(FileVar,ElmVar1);
      Seek(FileVar,Len-Pos);
      Read(FileVar,ElmVar2);
      Seek(FileVar,Pos);
      Write(File,ElmVar2);
      Seek(FileVar,Len-Pos);
      Write(FileVar,ElmVar1)
   end;
   Close(FileVar)
end.

A Close eljárás
Hívása: Close (FileVar)
A FileVar egy fájlváltozó neve. A FIIeVar névvel azonosított fájlnak nem kötelező nyitva lennie. A Close eljárás lezárja a FileVar névvel azonosított fájlt. Ha az eljárás hívása előtt a fájl nem volt nyitva, akkor állapota nem változik.
Megjegyzés: a programfutás befejezése nem jelenti a Close eljárás(ok) automatikus hívását!

Példa:

Var
   NewFile:file of boolean;
begin
   Assign(NewFile,'EMPTY');
   Rewrite(NewFile);
   Close(NewFile)
end.

Az Erase eljárás
Hívása: Erase (FileVar)
A FileVar egy fájlváltozó neve. Ajánlott, hogy a FileVar névvel azonosított fájt ne legyen nyitva. Az Erase eljárás törli azt az állományt, amelyet hozzárendeltünk a FileVar névvel azonosított fájlhoz.

Példa:

Var
   KillFile:file of byte;
begin
   Assign(KillFile,'SECRET.DOC');
   Erase(KillFile)
end
.

A Rename eljárás
Hívása: Rename (FileVar, StrEpx)
A FileVar egy fájlváltozó neve, a StrExp pedig egy karakterlánc típusú kifejezés. A FileVar névvel azonosított fájl nem lehet nyitva. A Rename eljárás átnevezi azt az állományt, amelyet hozzárendeltünk a FileVar névvel azonosított fájlhoz. Az állomány nevét a StrExp karakterlánc-kifejezés határozza meg. Az új név nem tartalmazhatja a lemezmeghajtó kijelölését, és ilyen nevű állomány nem létezhet.

Példa:

Var
   RenFile:file of byte
begin
   Assign(RenFile,'SECRET.DOC');
   Rename(RenFile,'SECRET.BAK')
end.

Az Eof függvény
Hívása: Eof(FileVar)
A FileVar egy fájlváltozó neve. A FileVar névvel azonosított fájlnak nyitottnak kell lennie. Az Eof függvény értéke true, ha a FileVar névvel azonosított fájl végpozícióban van, egyébként false.

A FileSize függvény
Hívása: FileSize (FileVar)
A FileVar egy fájlváltozó neve. A FileVar névvel azonosított fájlnak nyitottnak kell lennie. A FileSize függvény értéke integer típusú adat, amely a FileVar változóval azonosított fájl pozícióját adja meg. A kezdeti fájlpozíció sorszáma 0, a végpozícióé pedig FileSize (FileVar).

12.2. Szövegfájlok
A többi fájltípustól eltérően a szövegfájlok nem azonos típusú elemekből, hanem karakterekből összetett sorokból állnak. A szövegfájl minden sora CR/LF (carriage return / line feed, "kocsi vissza" / soremelés) karakterpárral zárul. A fájl utolsó sorát egy Ctrl-Z karakter követi. Ez a karakter a fájl lezárásakor kerül az írásra vagy bővítésre megnyitott fájlba. Mivel a fájl sorai különböző hosszúságúak lehetnek, feldolgozni csak szekvenciálisan tudjuk; a fájl csak olvasásra (Reset), ill. írásra (Rewrite) nyitható meg. A szövegfájl-típust az előre definiált text azonosítóval írhatjuk le.

Példa:

Type
   TextType=text;
var
   OutFile:TextType;
   InpFile:text;

A Turbo Pascal nyelvben külső berendezéseken - konzolon, terminálon, nyomtatón és modemen - keresztül szövegfájlokkal lehet adatokat átvinni. Ezek a szövegfájlok tehát az e berendezéseken át elérhető fizikai állományok modelljei. A külső berendezéseket három betűből és egy kettőspontból álló szimbolikus névvel (logikai eszköznévvel) jelöljük.

CON: konzol
A konzol beviteli, ill. kiviteli berendezés, amelynek beviteli eleme a billentyűzet, kiviteli eleme pedig a képernyő. A konzolról bevitt adat pufferelt, azaz teljes sorok formájában olvashatjuk be. Mivel minden sor CR ("kocsi vissza") karakterrel végződik, bevihetünk a konzolról egy karaktersorozatot, s mielőtt lezárnánk CR karakterrel, átszerkeszthetjük. A következő karakterekkel szerkeszthetünk:

Megjegyzés: a konzol beviteli pufferének méretét az előre definiált BufLen változó határozza meg. E változó max. és alapértelmezés szerinti (default) értéke 127. Ha a BufLen változónak értéket adunk, akkor az csak a legközelebbi beviteli utasításig lesz érvényben; a bevitel után a BufLen újból a 127-es értéket veszi fel.

TRM: terminál
A terminál beviteli, ill. kiviteli berendezés, amelynek beviteli eleme a billentyűzet, kiviteli eleme pedig a képernyő. A konzoltól eltérően az adatbevitel nem pufferelt, ami azt jelenti, hogy minden bevitt karaktert azonnal feldolgoz, és ki is ír a képernyőre. A vezérlőkarakterek közül ez csak a CR karakterre vonatkozik, amely CR/LF karakterpórként íródik ki.

KBD: billentyűzet
A billentyűzet beviteli berendezés. A bevitt karakterek a konzol beviteli eleméből származnak, nem pufferoltak, és nem íródnak ki a képernyőre.

LST: nyomtató
A nyomtató kiviteli berendezés. A kivitt karaktereket a rendszer nem pufferoja, ami azonban megoldható a nyomtatóban. A szövegfájlt az Assign eljárással rendelhetjük hozzá egy logikai eszközhöz. Hívásakor meg kell adni a fájlváltozó nevét, és a logikai eszköz nevét meghatározó karakterlánc-kifejezést. A fájl-adatállomány jellegű hozzárendeléstől eltérően a szövegfájl hozzárendelése egy logikai eszközhöz automatikusan meg is nyitja a szövegfájlt. Ekkor felesleges a Reset és a Rewrite eljárás használata; végrehajtásuk - a Close eljáráshoz hasonlóan - nem jár semmilyen következménnyel. Hibás azonban pl. az Erase vagy a Rename eljárás használata, mivel ezek csak a mágneslemezes háttértárban található állományokon értelmezhetők.

Példa:

Var
   Console:text;
...
Assign(Console,'CON:');

A logikai eszközhöz hozzárendelt szövegfájlok esetén - az egyszerűsítésre törekedve - a Turbo Pascal nyelvben több előre definiált fájlváltozót vezettek be, amelyek szövegfájlokat azonosítanak.
Szövegfájlok és logikái eszközök egymáshoz rendelése:

Fájlváltozó Logikai Eszköz
Input CON: vagy TRM:
Output CON: vagy TRM:
Con CON:
Trm TRM:
Kbd KBD:
Lst LST:

Mint a táblázatból kiderül, a konkrét logikai eszközök hozzákapcsolódnak az előre definiált fájlváltozók nevéhez. E szabály alól kivétel az Input és az Output fájlváltozó: mindegyikük akár a CON:, akár a TRM: logikai eszközhöz hozzárendelt fájlt azonosíthatja.
A CON: és a TRM: közötti választást a fordítóprogram {$B+} és {$B-} direktívái befolyásolják. Alapértelmezés szerint a {$B+} van érvényben; ekkor az Input és Output fájlváltozóval azonosított fájlok a CON: logikai eszközhöz kapcsolódnak. A {$B-} direktíva viszont a TRM: eszközt választja a CON: helyett.
A felsorolt fájlváltozókkal (Input, Output, Con, Trm, Kbd és Lst) azonosított szövegfájlok mindig nyitottak, és a rajtuk végezhető műveletek a konkrét logikai eszközökre vonatkoznak (CON:, TRM:, KBD: és LST:).

Példa:

Begin
   Writeln(Con,'-Hello world-')
end.

12.3. Szövegfájlokon értelmezett műveletek
A szövegfájlok adatállományokhoz vagy logikai eszközökhöz rendelhetők hozzá. Az első esetben a fájlban tárolt adatok feldolgozását meg kell előznie az Assign és a Reset vagy a Rewrite eljárás hívásának. A feldolgozás végét a Close eljárás jelenti. A második esetben (vagyis fájl és eszköz társításakor) használhatjuk az előre definiált fájlváltozót. Ekkor nem megengedett az ilyen változóra vonatkozó Assign, Reset, Rewrite és Close eljárás hívása. Jó megoldás az is, hogy az eszközt egy szimbolikus nevet viselő adatállománynak tekintjük, és az Assign eljárással társítjuk a szövegfájllal (utána már kezelhetjük).
Szöveges állományból a következő típusú adatokat lehet beolvasni, illetve oda kiírni:

Az Assign eljárás
Hívása: Assign (TextVar,StrExp)
A TextVar egy text típusú fájlváltozó neve, a StrExp pedig karakterlánc típusú kifejezés. A TextVar névvel azonosított fájl nem lehet nyitva. A TextVar nem lehet egy előre definiált fájlváltozó. Az Assign eljárás végrehajtása hozzárendeli a TextVar névvel azonosított fájlt a StrExp kifejezéssel meghatározott adatállományhoz vagy logikai eszközhöz.

Példa:

var
   Device:text;
...
Assign(Device,'CON:');

A Reset eljárás
Hívása: Reset (TextVar)
A TextVar egy text típusú fájlváltozó neve. Az eljárás hívása előtt a TextVar névvel azonosított fájlt egy létező adatállományhoz vagy logikai eszközhöz hozzá kell rendelni. A Reset eljárás megnyitja a TextVar névvel azonosított fájlt. Ha ez a fájl egy logikai eszközhöz kapcsolódik, akkor már megnyitottnak tekinthető, és a Reset eljárás hívása nem jár következménnyel.

Példa:

var
   InpFile:text;
...
Assign(InpFile,'OLDBOOK');
Reset(InpFile);

A Rewrite eljárás
Hívása: Rewrite (TextVar)
A TextVar egy text típusú fájlváltozó neve. Az eljárás hívása előtt a TextVar által képviselt fájlt egy adatállományhoz vagy egy logikai eszközhöz kell hozzárendelni. A Rewrite eljárás megnyitja a TextVar által képviselt fájlt. Ha ez a fájl egy logikai eszközhöz kapcsolódik, akkor már megnyitottnak tekinthető, és a Rewrite eljárás hívása nem jár következménnyel. Ha a Rewrite hívása előtt a fájlhoz hozzárendelt állomány nem létezett, akkor az eljárás végrehajtásakor létrejön. Ha pedig volt már ilyen állomány, akkor törlődik és újra létrejön. Mindkét esetben egy üres adatállomány keletkezik.

Példa:

var
   OutFile:text;
...
Assign(OutFile,'NEWBOOK');
Rewrite(OutFile);

A Read eljárás
Hívása: Read (TextVar,VarList)
A TextVar egy text típusú fájlváltozó neve, a VarList pedig egy változónév, ill. char, síring, integer vagy real típusú változónevek listája. Ha a TextVar értéke Input, akkor a hívás Read(VarList) alakra egyszerűsíthető. Ha a hívás explicit vagy "rejtett" Input paramétert tartalmaz, és a {$B+} direktíva van érvényben, akkor a TextVar nevet a fordítóprogram Con névnek tekinti; ha a {$B-} érvényes, akkor pedig Trm névnek. A TextVar névvel azonosított fájlnak mindig nyitottnak kell lennie. A Read eljárás a TextVar változóval azonosított fájlból karakterláncot olvas be, melyet - megállapodás szerinti - adat(ok)nak értelmez; értékét a VarList-ben szereplő változó(k)nak adja át.
Megjegyzés: ha a bevitel a CON: logikai eszközről megy végbe, akkor a Read mindenkori hívása egy új sor beolvasását jelenti, még akkor is, ha a konzol pufferében maradt(ak) még be nem olvasott karakter(ek). Ekkor a pufferben található karakterek csak a CR karakteres sorlezárás után értelmezhetők; az esetleg korábban bevitt Ctrl-Z karakter figyelmen kívül marad. Ez a karakter egyébként mindig a puffer végére kerül, de csak a CR bevitele után.
A TextVar változóval azonosított fájl karaktereinek értelmezése függ a VarList-beli változó(k) típusától:

  1. A char típusú változók
    A rendszer beolvas egy karaktert, és átadja a változónak.

  2. A string típusú változók
    A rendszer beolvassa a lehetséges leghosszabb karakterláncot, és átadja a változónak. A bevitt karakterek száma nem lépheti túl a karakterlánc-változó max. hosszát, és nem lehet több az aktuális sor karakterszámánál.

  3. Az integer, ill. a real típusú változók
    A rendszer beolvas egy egész, ill. valós számot ábrázoló karakterláncot, amely után a következő karakterek valamelyike következik: szóköz, tabulátor, CR vagy Ctrl-Z. A beolvasandó számot megelőző szóközök, tabulátorok, Cr és LF karakterek figyelmen kívül maradnak. A soron következő VarList beli változó a maradó karakterekkel ábrázolt következő egész, ill. valós számot kapja értékül stb. Ha a beolvasott karakterlánc a leírástól eltérő alakú, akkor beviteli vagy kiviteli hiba keletkezik.

Példa:

Var
   IntVar:integer;
   Fixvar:real;
   TextVar:text;
   Ter1,Ter2:char;
   Str:string[8];
begin
   Assign(TextVar,'ONELINE.DAT');
   Reset(TextVar);
   Read(TextVar,IntVar,Terl,FixVar,Ter2,Str);
end.

Ha a Read eljárás végrehajtásakor a fájl végpozícióba kerül, és a VarList változói közül maradt még olyan, amely nem kapott értéket, akkor minden char típusú változó Ctrt-Z karaktert kap értékként, a string típusú változó üres karakterláncot, az integer és a real típusú változók pedig nem kapnak új értéket.
Ha a fájlt a konzolhoz rendeljük hozzá, akkor minden beolvasott sor végén Ctrl-Z karakter lesz. Ennek az a hatása, mintha a fájl minden sor végén végpozícióba kerülne.

Példa:

Var
   IntVar:integer;
   StrVar:string[3];
   ChrVar:char;
begin
  IntVar:=-2;
  StrVar:='jan';
  ChrVar:='b';
  Read(IntVar,StrVar,ChrVar);
  ...
end.

A Readln eljárás
Hívása:
Readln (TextVar)
Readln (TextVar, VarList)

A TextVar egy text típusú fájlváltozó neve, a VarList pedig egy változónév, ill. char, string, integer vagy real típusú változónevek listája. Ha a TextVar értéke Input, akkor a hívás egyszerűsíthető: az első esetben Readln, a másodikban Readln(VarList) alakra. A Readln(TextVar) típusú hívás karaktereket olvas a fájlból, CR/LF-ig (bezárólag); a beolvasott karakterláncot figyelmen kívül hagyja. Ha a fájl egy logikai eszközhöz kapcsolódik, akkor csak CR-ig (bezárólag) olvassa be a karaktereket, és a beolvasott karakterláncot figyelmen kívül hagyja. Ha a TextVar konzolt jelent, akkor a képernyőre CR/LF-et ír ki. A

Readln (TextVar,VarList)

hívás egyenértékű a

Read (TextVar,VarList); Readln(TextVar)

alakkal, ezért nem igényel további magyarázatot.

Példa:

var
   
Count:integer;
   Source:text;
   Line:string[128];
begin
   Assign(Source,'VOLUME.DAT');
   Reset(Source);
   Count:=0;
   while not Eof(Source) do begin
       Readln(Source,Line);
      Count:= Count+l
   end;
   Writeln(Count)
end.

A Write eljárás
Hívása: Write (TextVar,ExpList)
A TextVar egy text típusú fájlváltozó neve, az ExpList pedig char, string, integer, real vagy boolean típusú változó neve (vagy ilyen nevek listája). Közvetlenül a felsorolt kifejezések után következhet a :m alakú minősítő tag; real típusú kifejezés után megengedett még a :m:n alakú minősítő is, ahol az m és az a integer típusú kifejezés. Ha a TextVar értéke Output, akkor a hívás Write(ExpList) alakra egyszerűsíthető. Ha a hívás explicit vagy "rejtett" Output paramétert tartalmaz, akkor a TextVar nevet a fordítóprogram Con (vagy a megfelelő programkörnyezetben ezzel egyenértékű Trm) névnek tekinti. A TextVar névvel azonosított fájlnak mindig nyitottnak kell lennie. A Write eljárás a TextVar változóval azonosított fájlba karakterláncot ír be, amely az ExpList-ben szereplő kifejezések értékét képviselő adatokat ábrázolja.
Az említett karakterlánc alakjának értelmezése az ExpList-beli változók) típusától és az m, a minősítők értékétől függ:

  1. A char típusú kifejezések
    A rendszer kiviszi a kifejezés által képviselt karaktert. Ha van m minősítő, és m>1, akkor a karaktert m-1 szóköz előzi meg.

  2. A string típusú kifejezések
    A rendszer kiviszi a kifejezés által képviselt karakterláncot. Ha van m minősítő, és m nagyobb a karakterlánc I hosszánál, akkor a karakterláncot m-I szóköz előzi meg.

  3. Az integer típusú kifejezések
    A rendszer kiviszi a kifejezés értékét ábrázoló legrövidebb karakterláncot. Ha van m minősítő, és m nagyobb a karakterlánc I hosszánál, akkor a karakterláncot m-l szóköz előzi meg.

  4. A real típusú kifejezések
    A rendszer kiviszi a kifejezés valós értékét ábrázoló bsd.ddddddddddEsdd alakú karakterláncot, amelyben a b szóközt jelent; az első s a szám előjelét ábrázolja, mégpedig szóközként (nem negatív érték esetén) vagy - (mínusz) karakterként (negatív érték esetén). Minden d egy decimális számjegyet jelent; a második s pedig egy + vagy - (mínusz) karaktert. Ha van m minősítő, és m > 18, akkor a karakterláncot m-18 szóköz előzi meg. Ha m=18, akkor a 4. pont elején megadott minta szerint keletkezik a karakterlánc. Ha m<18, akkor pontosan m karaktert visz ki a rendszer, mégpedig úgy, hogy először a kezdő szóközöket, utána pedig a mantissza utolsó számjegyeit hagyja el, kerekítve. Ha az m értéke 2-nél kevesebb számjegyet hagyna a mantisszából, akkor a rendszer csak a harmadik és az utána következő számjegyeket vágja le, kerekítve. Ha a minősítő tag :m:n alakú, akkor a rendszer olyan valós számformátumot képez, amely exponens nélküli, a darab tizedesjegyű, jobbra igazított, m hosszúságú karakterlánc. Ha a szám nem ábrázolható ilyen formában, akkor az m értéke automatikusan annyival nő, hogy a számot ábrázolni lehessen. Ha n=0, akkor a rendszer a számot tizedespont és tizedesrész nélkül viszi ki; a [0,24] zárt intervallumon kívülre eső a értékek esetén a : m:n minősítőt a rendszer - az előzőekben leírt - : m tagként értelmezi.

  5. A boolean típusú kifejezések
    A rendszer kiviszi a kifejezés értékét képviselő TRUE vagy FALSE karakterláncot. Ha van m minősítő, és m nagyobb a képzett karakterlánc I hosszánál, akkor a karakterláncot m-I szóköz előzi meg.
    Példák (A b szimbólum szóközt jelent.)

    Kifejezés Kivitt karakterlánc
    'j' j
    'j':2 bj
    'jan' jan
    'jan':4 bjan
    -44 -44
    44:5 bb44
    23.5 bb2.3500000000E+01
    23.456789:0 2.3457E+01
    23.456789:6 2.3E+01
    23.456789:6:2 b23.46
    -23.456789:6:0 bbb-23
    23.456789:6:-2 2.3E+01

A Writeln eljárás
Hívása:
Writeln (TextVar)
Writeln (TextVar,ExpList)

A TextVar egy text típusú fájlváltozó neve, az ExpList pedig char, string, integer, real vagy boolean típusú változó neve (vagy ilyen nevek listája). Közvetlenül a felsorolt kifejezések után következhet a :m alakú minősítő tag; egy real típusú kifejezés után megengedett még a :m :n alakú minősítő is, ahol az m és az n integer típusú kifejezés. Ha a TextVar értéke Output, akkor a hívás egyszerűsíthető: az első esetben Writeln, a másodikban Writeln(ExpList) alakra.
A Writeln(TextVar) típusú hívás a TextVar változóval azonosított fájlba CR/LF karakterpárt visz ki. A
Writeln(TextVar, ExpList)
hívás egyenértékű a
Write(TextVar,ExpList); Writeln(TextVar)
alakkal, ezért nem igényel további magyarázatot.

Példa:

Begin
   Writeln(false);
   Writeln;
   Writeln(true)
end.

A Close eljárás
Hívása: Close (TextVar)
A TextVar egy text típusú fájlváltozó neve. A TextVar nem (ehet előre definiált fájlváltozó. A Close eljárás lezárja a TextVar névvel azonosított fájlt.

Példa:

Var
   Output:text;
begin
   Assign(Output,'JB.DOC');
   Rewrite(Output);
   Writeln(Output,'jasio');
   Close(Output)
end.

Az Eof függvény
Hívása: Eof (TextVar)
A TextVaregy text típusú fájlváltozó neve. Ha a TextVar értéke Input, akkor a hívás Eof alakúra egyszerűsíthető. Az Eof függvény adatállományhoz és logikai eszközhöz hozzárendelt fájlra is alkalmazható. A függvény mindkét esetben boolean típusú, és false vagy true értéket vehet fel.
Ha a fájl egy állományhoz kapcsolódik, és a Ctrl-Z karakter előtt vagy a végpozícióban állt, akkor az Eof függvény értéke true, egyébként false.
Ha a fájl egy logikai eszközhöz kapcsolódik, és az utolsó értelmezett karakter Ctrl-Z volt, akkor az Eof függvény értéke true, egyébként false.

Az Eoln függvény
Hívása: Eoln (TextVar)
A TextVar egy text típusú fájlváltozó neve. Ha a TextVar értéke Input, akkor a hívás Eoln alakúra egyszerűsíthető. Az Eoln függvény adatállományhoz és logikai eszközhöz hozzárendelt fájlra is alkalmazható. A függvény mindkét esetben boolean típusú, és false vagy true értéket vehet fel.
Ha a fájl egy állományhoz kapcsolódik, és a CR karakter előtt áll, vagy az Eol függvény értéke szintén true lenne, akkor az Eoln függvény értéke true, egyébként false.
Ha a fájl egy logikai eszközhöz kapcsolódik és az utolsó értelmezett karakter CR volt, vagy az Eof függvény értéke szintén true lenne, akkor az Eoln függvény értéke true, egyébként false.

Példa:

var
   ChrVar:char;
   TxtVar:text;
begin
   Assign(TxtVar,'STRANGE.DOC');
   Reset(TxtVar);
   while not Eof(TxtVar) do begin
      Writeln(Eoln(TxtVar));
      Read(TxtVar,ChrVar)
   end
end.

A SeekEof függvény
Hívása: SeekEof (TextVar)
A TextVar egy text típusú fájlváltozó neve. Ha a TextVar értéke Input, akkor a hívás SeekEof alakúra egyszerűsíthető. A SeekEof függvény működése hasonlít az Eof függvényre: a legközelebbi szóközök, tabulátorok, CR és LF karakterek elhagyása után az eredmény az Eof függvényével azonos.

A SeekEoln függvény
Hívása: SeekEoln (TextVar)
A TextVar egy text típusú fájlváltozó neve. Ha a TextVar értéke Input, akkor a hívás SeekEoln alakúra egyszerűsíthető. A SeekEoln függvény működése hasonlít az Eoln függvényre: a legközelebbi szóközök és tabulátorok elhagyása után az eredmény az Eoln függvényével azonos.

Példa:

var
   TxtVar:text;
   Tally:integer;
   ChrVar:char;
begin
   Tally:=0;
   Assign(TxtVar,'TEXT.DOC');
   Reset(TxtVar);
   while not SeekEof(TxtVar) do begin
      while not SeekEoln(TxtVar) do begin
         Tally:=Tally+1;
         Read(TxtVar,ChrVar)
      end
   end;

   Writeln(Tally)
end.

Az alábbi program a megadott nevű szöveges állományt listázza ki a képernyőre oldalanként:

Program Textfile;
var FilVar:text;
     Line:string[80];
     FileName:string[14];
     i:byte;
begin
   ClrScr;
   Write('Enter name of file to list: ');Readln(FileName);
   Assign(FilVar,FileName);
   Reset(FilVar);
   i:=1;
   while not Eof(FilVar) do begin
      Readln(FilVar,Line);
      Writeln(line);
      i:=i+1;
      if i=23 then begin
         repeat until KeyPressed;
         i:=1
      end
   end;
   LowVideo;Write('{ End of file }');NormVideo;
   repeat until KeyPressed
end.

Karakterlánc beolvasásánál feltétlenül a Readln eljárást használjuk, mert a Read(FileVar,Line) beolvassa ugyan a teljes sort, de a sorvégejelen megáll. Ezért a következő Read eljárás üres karakterláncot fog beolvasni.
A szöveges állományba egy egész sort egyszerre a Writeln(FileVar,Line) eljárással írhatunk, ahol Line egy String típusú változó vagy kifejezés.

12.4. Elemtípus nélküli fájlok
A számítógépen tárolt adatok többsége nem tagolható szövegsorokra, és a bennük tárolt adatelemek mérete nem azonos. Az ilyen állományokat sem szöveges, sem pedig típusos fájlként nem kezelhetjük. A Turbo Pascal-ban a típus nélküli fájlok használata nagy segítséget jelent ismeretlen, illetve nem szabályos szerkezetű állományok feldolgozásában. Az elemtípus nélküli fájlok lehetőséget adnak a nem pufferolt beviteli, ill. kiviteli műveletek végrehajtására, közvetlenül a program változói és a külső mágneslemezes háttértár között. Az elemek - megállapodás szerint - olyan objektumok, amelyek 128 bájtnyi memóriát foglalnak le. Az elemtípus nélküli fájl tetszőleges mágneslemezes adatállományt képviselhet; ezért pl. az Erase vagy a Rename jellegű műveletek is végrehajthatók. Az elemtípus nélküli fájl leírása a file kulcsszóból áll.

Példa:

var
   DiskFile:file;
   FileName:string[40];
begin
   Write('FileName:-');
   Readln(FileName);
   Assign(DiskFile,FileName);
   Erase(DiskFile)
end.

Az elemtípus nélküli fájlokon végrehajtható beviteli, ill. kiviteli műveleteket a BIockRead és a BIockWrite eljárás valósítja meg; ezek helyettesítik a megfelelő elemtípusos eljárásokat. Más műveletek (Assign, Reset, Rewrite, Close, Seek és Eof) értelmezése azonos az elemtípusos fájlokéval.

A BIockRead eljárás
Hívása:
BIockRead (FileVar,Buffer,Count,Reply)
BIockRead (FileVar,Buffer,Count)

A FileVar egy elemtípus nélküli fájlváltozó neve, a Buffer tetszőleges változónév, a Count integer típusú kifejezés, a Reply pedig integer típusú változó neve. A BIockRead eljárás a FileVar változóval azonosított fájlból Count számú, 128 bájt méretű objektumot olvas be, a Buffer változó által lefoglalt memóriaterületre. Ha a hívás tartalmazza a Reply paramétert, akkor a Reply változó új értéke a ténylegesen beolvasott objektumok számát adja meg. Ha ez a szám Count nál kisebb, akkor a fájl a végpozícióban van.

A BIockWrite eljárás
Hívása:
BlockWrite (FileVar,Buffer,Count,Reply)
BlockWrite (FileVar,Butfer,Count)

A FileVar egy elemtípus nélküli fájlváltozó neve, a Buffer tetszőleges változónév, a Count integer típusú kifejezés, a Reply pedig egy integer típusú változó neve. A BIockWrite eljárás a FileVar változóval azonosított fájlba Count számú, 128 bájt méretű objektumot ír be, a Buffer változó által lefoglalt memóriaterületről. Ha a hívás tartalmazza a Reply paramétert, akkor a Reply változó új értéke a ténylegesen kivitt objektumok számát adja meg. Ha ez a szám Count-nál kisebb, akkor a kivitel sikertelen volt.

Példa:

Program Copy;
var
   Src,Trg:file;
   Buffer:array [0..255, boolean] of byte;
   Source,Target:string[40];
   Reply:integer;
begin
   Write('Source :-');Readln(Source);
   Write('Target :-');Readln(Target);
   Assign(Src,Source);
   Assign(Trg,Target);
   Reset(Src);
   Rewrite(Trg);
   repeat
      BlockRead(Src,Buffer,4,Reply);
      BlockWrite(Trg,Buffer,Reply)
   until Reply<4;
   Close(Src);
   Close(Trg)
end.

12.5. Beviteli és kiviteli műveletek ellenőrzése
A beviteli és kiviteli műveletek ellenőrzése a program fordításakor kérhető. Az alapértelmezés szerinti {$I+} direktíva érvényességi körén belül a rendszer minden beviteli és kiviteli műveletet ellenőriz. Hiba esetén a program leáll, és hibaüzenet íródik ki a konzolra. A {$I-} direktíva hatáskörében a hibaállapot nem állítja le a program futását, csak felfüggeszti a további beviteli, ill. kiviteli műveleteket. Ez az állapot a beépített IOresult függvény hívásáig áll fenn. A függvény integer típusú értéke megadja a hiba jellegét. Ha ez az érték 0, akkor az eddigi beviteli, ill. kiviteli műveletek hibátlanul végződtek; ha a függvény 0-tól különböző értékkel tér vissza, akkor ez az érték - a Függelékben felsoroltak szerint - a hiba kódját jelenti.

Példa:

Program Delete;
var
   FileVar:file;
   FileName:string[40];
   Flag:Bodean;
Begin
   Write('FileName:-');
   Readln(FileName);
   Assign(FileVar,FileName);
   {$I-} Erase(FileVar);{$I+}
   if not (IOresult=0) then
      Writelnt('File'+FileName+' did not exist')
end.

12.6. A fájlkezelés általános lépései
A számítógépeken az operációs rendszer feladatai közé tartozik a fájlrendszer támogatása és a fájlok elérésének biztosítása. Az állományok tartalmának eléréséhez a programozási nyelvtől és az operációs rendszer fajtájától függetlenül mindig ugyanazokat a főbb lépéseket kell végrehajtani:

  1. Az állomány megnyitása.
  2. Az állomány tartalmának feldolgozása fájlműveletek (olvasás, írás, pozicionálás stb.) felhasználásával.
  3. A szükséges műveletek elvégzése után az állomány lezárása.

Természetesen a Turbo Pascal nyelvben is megtalálhatjuk a fenti lépések elvégzését támogató alprogramokat. Ahhoz azonban, hogy a Pascal programtól használni tudjunk egy fájlt, szükség van egy előkészítő (nulladik) lépésre is.
Mielőtt hozzákezdenénk a fájlkezelés lépéseinek ismertetéséhez, tisztázzunk néhány gyakran használt fájlokkal kapcsolatos fogalmat. A fájlokat a bennük tárolt adatok elérése alapján is csoportosíthatjuk. Azokat a fájlokat, amelyet adatelemeit csak sorban egymás után érhetjük el, soros (szekvenciális) állományoknak nevezzük. Turbo Pascal-ban soros fájlként a szöveges állományokat használjuk. A másik csoportot a közvetlen elérésű állományok alkotják. Ezekben a pozicionálás műveletét használva közvetlenül kiválaszthatjuk a feldolgozni kívánt adatelemeket. A Turbo Pascal-ban a típusos és a típus nélkül fájlok tartalmához soros és közvetlen eléréssel egyaránt hozzáférhetünk.

Nulladik lépés: előkészületek
A Pascal programból a lemezen tárolt állományokat és az eszközöket a fájlműveletek során ún. fájlváltozóval azonosítjuk. A fájlváltozót a fájl típusától függően az alábbi három mód egykével deklarálhatjuk:

változónév: text; szöveges fájl
változónév: file of típus; típusos fájl
változónév: file; típus nélküli fájl

A megfelelő típusú fájl változó létrehozása után, az assign eljárás segítségével össze kell rendelnünk a fájl változót egy létező vagy egy új állomány nevével:

assign(fájlváltozó, fájlnév);

A fájlnév egy 'NNNNNNNN.KKK' formában megadott sztring, ahol az első legfeljebb 8 karakteres rész az állomány igazi neve, és a pont után megadott maximum 3 karakter pedig a kiterjesztés. A fájl neve előtt fájlhoz vezető útvonalat (a fájl elérési útvonalát) is megadhatjuk, amely a meghajtó nevéből és az állományt tartalmazó összes alkönyvtár nevének '\' jellel tagolt listájából áll. Az érési utat mindig meg kell adni, ha az állomány nem az aktuális könyvtárban helyezkedik el.

Első lépés: fájlnyitás
A felhasználni kívánt állományt meg kell nyitni ahhoz, hogy a fájlműveletekkel hozzáférjünk a tartalmához. A Turbo Pascal-ban két eljárással is megnyithatjuk a fájljainkat:

reset(fájlváltozó);
rewrite(fájlváltozó);

A két eljárás működésének lényege az alábbiak szerint foglalható össze:

A fájlnyitó eljárások az adatok áramlásának irányát is meghatározzák. A szöveges állományok a reset eljárással való megnyitás után csak olvashatók, míg a rewrite után csak írhatók lesznek. Nem így van ez a típusos és a típus nélküli fájlok esetén. Alaphelyzetben bármelyik eljárással is nyitunk meg egy ilyen típusú állományt, az egyszerre írható és olvasható is lesz.
Ha a fájl nyitásakor valamilyen hiba lép fel (például hibás fájlnevet adunk meg), akkor a programunk hibaüzenettel leáll. A Turbo Pascal rendszer lehetővé teszi, hogy a be- és kiviteli (I/O) műveletek végzése során fellépő hibákat programon belül dolgozzuk fel. Ha a kritikus programrészletet {$I-} és az {$I+} direktívák közé helyezzük, akkor az ioresult függvény visszaadott értékéből következtethetünk a hiba okára. (A nulla visszatérési érték azt jelzi, hogy nem történt hiba, míg minden más érték valamilyen hibát azonosít.) A függvény használatával biztonságossá tehetjük a fájlnyitást. Az ioresult függvény értékéből mindig csak a legutolsó I/O művelet lefolyására következhetünk. A függvény hívása törli a belső állapotjelző értékét, így ha többször szeretnénk a hibakódot lekérdezni, akkor egy egész típusú változóban kell eltárolnunk a függvény első hívásakor visszaadott értéket.

Második lépés: fájlműveletek
A fájlműveletek alatt a megnyitott állományokon elvégezhető műveleteket értjük. Ebben a tekintetben az egyes fájltípusok között még a nyitásnál is jelentősebb az eltérés. A következő táblázatban felsoroltuk a műveleteket megvalósító eljárásokat és függvényeket. Ugyancsak megadtuk a műveletek rövid leírását, és azt, hogy milyen típusú fájlok esetén alkalmazhatók.

művelet leírás
szöveges file
típusos file
típus nélküli file
BlockRead blokk olvasása    
+
BlockWrite blokk írása    
+
Eof fájlvége lekérdezése
+
+
+
Eoln sorvége lekérdezése
+
   
FilePos fájlpozíció lekérdezése  
+
+
FileSize fájlméret lekérdezése  
+
+
IOresult hibakód lekérdezése
+
+
+
Read adatok olvasása
+
+
 
Readln adatsor olvasása
+
   
Seek pozicionálás  
+
+
SeekEof fájlvége lekérdezés
+
   
Write adatok írása
+
+
 
Writeln adatsor írása
+
   

Harmadik lépés: a fájl lezárása
Munkánk végeztével a fájlt a close eljárás hívásával kell lezárni:

Close(fájlváltozó);

Ez a lépés különösen fontos, ha az adatállomány tartalmát módosítjuk. A close eljárás frissíti az adatállományt, így az utoljára (pufferolt) végrehajtott fájlműveletek eredménye is megjelenik a lemezen tárolt állományban. A Pascal programból kilépve minden még nyitott állományt automatikusan, a fájltartalom frissítése nélkül zár le a rendszer. Ez az írásra megnyitott fájlok esetében adatvesztéssel járhat!
Az állomány lezárása után is megmarad a kapcsolat a fájlnév és a fájlváltozó között, így ha a programunkban újra meg kell nyitni az előzőleg lezárt állományt, akkor nincs szükség újabb assign hívásra.

13. Mutatótípusok
Az eddig használt egyszerű és strukturált típusú változók közös tulajdonsága, hogy rájuk a deklarálás során megadott névvel hivatkozunk. Az így definiált változók mérete a program fordításakor dől el, és a program futása során a módosítható. A Pascal nyelvben ezeket a változókat statikus helyfoglalású változóknak nevezzük.
A hatékony memória-felhasználás érdekében szükség van arra, hogy bizonyos memóriaterülettel a programozó szabadon gazdálkodjon. A Pascal nyelv rendelkezik olyan eszközökkel, amelyek segítségével a programozó maga foglalhat memóriaterületet a változói számára. A lefoglalt területet fel is szabadíthatja, ha már nincs szüksége a változóra. A felszabadított terület egy következő memóriafoglalás során újra felhasználható. A memóriafoglalás és felszabadítás műveleteivel a memória dinamikus felhasználását valósítjuk meg. A dinamikus helyfoglalású változók számára rendelkezésre álló területet a Turbo Pascal-ban halomterületnek (heapnek) nevezzük.
A mutatótípusok mindegyike elemi típus. A mutató típusú adat értéke a mutató (pointer). A mutatótípus leírása a ^ karakterből és az azt követő típusnévből áll. E típusnevet nem kötelező előbb definiálni; ez az egyetlen kivétel azon szabály alól, miszerint csak az előzőleg definiált objektumokra hivatkozhatunk. A mutatók deklarásának általános formája:

var változónév:^típusnév;

ahol a típusnév tetszőleges szabványos vagy felhasználó által definiált típus neve. A Pascal nyelvben a mutatók lényeges tulajdonsága, hogy típussal rendelkeznek. A típus kijelöli, hogy a dinamikus helyfoglalás során mekkora területet kell a mutatóhoz hozzárendelni.

Példa:

Type
   EmployeePtrs=^EmployeeData;
   EmployeeData=record
      Name:string[30];
      Salary:real
   end;
var
   EmployeeRef:EmployeePtr;
   IntRef:^integer;

A mutatótípusokon és -változókon kívül van egy "üres" mutató is a Turbo Pascal-ban, melyet a nil kulcsszó képvisel. E mutató típusa egyenértékű bármilyen más mutatótípussal. A mutató típusú változók neveit és az üres mutatót az = és a <> (nem egyenlő) relációkban használhatjuk. Az értékadó utasításban kötelező a bal és a jobb oldal típusazonossága. Ez csak akkor teljesül, ha az értékadó szimbólum két oldalán álló nevek azonos típusú változókat képviselnek.

Példa:

Type
   Days=(Mon,Tue,Wed,Thu,Fri,Sat;Sun);
   Week=Mon..Sun;
Var
   Day1:^Days;
   Day2,Day3:^Week;

A mutató típusú változók felhasználhatók pl. az operatív tár dinamikus szervezésében (helyfoglalásban). Ehhez nyújtanak segítséget a tárfoglaló és -felszabadító eljárások.

A New eljárás
Hívása: New (PtrVar)
A PtrVar egy mutató típusú változó neve. A New eljárás végrehajtása következtében olyan típusú változó jön létre, mint amilyenre a PtrVar mutat. A művelet elvégzése után a PtrVar éppen a létrehozott változóra fog mutatni. Az új változó a halom-nak (heap) nevezett tárterületen foglal helyet, és ugyanúgy kezelhető, mint tetszőleges más - azonos típusú - változó.

Példa:

Type
   Matrix=array[boolean] of array[boolean] of real;
var
   MatrixPtr:^Matrix;
begin
   New(MatrixPtr);
   MatrixPtr^[true][true]:=23.5;
end.

A Dispose eljárás
Hívása: Dispose (PtrVar)
A PtrVar egy mutató típusú változó neve. A Dispose eljárás végrehajtása következtében megszűnik az a változó, amelyre a PtrVar mutat. A megszüntetendő változót előzőleg a New eljárással kell létrehozni. A változó által eddig lefoglalt tárterület visszakerül a halomba, és más változók létrehozására újra felhasználható.

A Mark eljárás
Hívása: Mark (PtrVar)
A PtrVar egy tetszőleges típusra mutató változó neve. A Mark eljárás végrehajtása következtében a PtrVar változó új értéke a halom pillanatnyi teteje lesz.

A Release eljárás
Hívása: Release (PtrVar)
A PtrVar egy tetszőleges típusra mutató változó neve, amely a Mark eljárással kapott értéket. A Release eljárás végrehajtása következtében megszűnik az a változó, amelyre a PtrVar mutat, és a halmon utána következő összes változó is.
A New-Dispose és a Mark-Release eljárás két különböző halom-szervezési módszert ad a programozónak; egy programban lehetőleg csak az egyiket használjuk! A két módszer közötti lényeges különbséget a következő ábra mutatja, ahol a Ptr változó a var3-ra mutat.

Halom
a Dispose után
a Release után
var1
var1
var1
var2
var2
var2
var3
   
var4
var4
 
var5
var5
 

A GetMem eljárás
Hívása: GetMem (PtrVar,IntExp)
A PtrVar egy mutató típusú változó neve, az IntExp pedig integer típusú kifejezés. A GetMem eljárás lefoglalja a halmon az IntExp értékkel meghatározott (bájtban értendő) tárterületet; a PtrVar mutató a lefoglalt területre fog mutatni.

A FreeMem eljárás
Hívása: FreeMem (PtrVar,IntExp)
A PtrVar egy mutató típusú változó neve, az IntExp pedig integer típusú kifejezés. A FreeMem eljárás visszaadja a halomnak a PtrVar mutatóval megcímzett IntExp méretű (bájtban értendő) tárterületet. A FreeMem eljárással visszaadott tárterületnek pontosan akkorának kell lennie, mint a GetMem eljárással lefoglaltnak.

A MaxAvail függvény
Hívása: MaxAvail
A MaxAvail függvény értéke egy integer típusú adat, amely megadja a halmon hozzáférhető legnagyobb összefüggő tárterület méretét (a 8 bites mikroszámítógépekét bájtban, az IBM PC méretét pedig paragrafusban, ahol 1 paragrafus = 16 bájt). Ha az eredmény negatív, akkor a valódi méretet úgy kapjuk meg, hogy az eredményhez a 65 536 valós számot adjuk hozzá.

Tömb a halomterületen
A dinamikus helyfoglalás előnye természetesen akkor tűnik ki igazán, ha nem néhány bájtos, hanem több kilobájtos dinamikus változót, például tömböt, rekordot használunk. Erre mutat példát a következő program, melyben egy 20,5 kbyte méretű tömböt használunk. A tombt típusú tömböt a tptr mutató segítségével helyezzük el a halomterületen. A tömböt ebben az esetben a tptr^hivatkozással érjük el, a tömb elemeire pedig a tptr[i] kifejezéssel hivatkozhatunk.

Program Tomb;
const n=3500; { elemek szama }
type tombt=array[1..n] of real;
       tombptr=^tombt;
var tptr:tombptr;
     i:integer;
begin
   randomize;
   New(tptr); { helyfoglalas a tomb szamara }
   for i:=1 to n do
      tptr^[i]:=i*pi; { a tomb feltoltese }
   for i:=1 to 20 do begin
      i:=Random(n)+1;
      Writeln(i:10,tptr^[i]:16:5,tptr^[i]/i:10:5);
   end;
   Dispose(tptr)
end.

14. Kezdeti értékadás
A Turbo Pascal nyelv lehetővé teszi, hogy a változóknak kezdeti értéket adhassunk. Ha a program végrehajtásakor ezek a változók megőrzik kezdeti értéküket, akkor konstansoknak tekinthetők. Ha viszont a program futtatásakor más, a kezdeti értéküktől eltérő értéket is kapnak, akkor a program ismételt futtatásakor (ha az az operatív tárban marad) ezek a változók az előző futás befejezése utáni értékkel indulnak. Mivel egy ilyen program futtatásának ismételhetősége elvész, csak a konstans jellegű változók használata ajánlott. Éppen ezért azon változódeklarációk, amelyekben kezdeti értéket adunk, a programban a const kulcsszó (és nem a var kulcsszó) után szerepelnek.

Példa:

Program Increment;
const
   Number:integer=1;
begin
   Writeln('Number=',Number);
   Number:=Number+1
end.

A kezdeti értékadással bővített változódeklaráció tehát a következő: változónév, kettőspont, típusleírás, egyenlőségjel, kezdeti érték, pontosvessző. A kezdeti érték alakja a változó típusától függ. Elemi változókban konstans, tömbváltozókban kerek zárójelekkel körülvett kezdeti értékek listája, rekordváltozókban pedig - szintén kerek zárójelekkel körülvett - kezdeti értékek felsorolása.
Kétdimenziós tömb is deklarálható konstansként. Ez esetben a tömb elemeinek értékét sorindexenként zárójelben kell felsorolnunk:

Const:Number:array[1..5,1..3] of byte=
         ((5,3,1),(4,9,8),(3,3,3),(1,4,6),(2,2,5));

Példák:

Const
   LineLength:byte=132;
   Radius:real=13.64;
   FullName:string[12]='Jan Bielecki';
   CtrlM:char=^M;
   Separator:set of char=[' /',';','.'];
   SexIsMale:boolean=true;
   ShortName:string[3]='Izabela';
   WholeReal:real=44;

Ha a kezdeti értékkel inicializált változó egy tömb, akkor kezdeti értéke kerek zárójelekkel körülvett lista, amely felsorolja a tömb összes elemének kezdeti értékét. Ha a kezdeti értékkel inicializált változó egy rekord, akkor kezdeti értéke kerek zárójelekkel körülvett lista, amely felsorolja a rekord összes (vagy néhány) elemének kezdeti értékét. A kezdeti értékadások felsorolási sorrendjének azonosnak kell lennie a rekordkomponensek deklarációbeli sorrendjével. A lista elemeit pontosvesszők választják el; egy listaelem a rekordmező nevéből, a kettőspontból és a rekordmező kezdeti értékéből áll.

Példák:

Type
   Color=(Red,Black,Fair);
   Person=record
      FirstName:string[3];
      LastName:string [12];
      Hair:Color;
      Age:byte
   end;
   Sex=(male,female);
const
   Vector:array[1..3] of Sex=(male,male,female);
   Matrix:array[Color,2..3] of byte=((0,0),(1,1),(2,5));
   ThreeD:array[boolean,boolean,boolean] of Color=
       (((Red,Red),(Red,Fair)),((Black,Black),(Red,Black)));
   JanB:Person=
      (FirstName:'Jan';
      LastName:'Bielecki';
      Hair:Black;
      Age:44);
   Family:array[1..3] of Person=
     (FirstName:'Jan';
      LastName:'Bielecki';
      Hair:Black;
      Age:44),
     (Firstname:'Ewa';
      LastName:'Bielecka';
      Hair:Black;
      Age:38),
     (FirstName:'Iza';
      LastName:'Bielecka';
      Hair:Black;
      Age:3));

A változó rekordrészt tartalmazó rekordokban a kezdeti értékadásnak csak akkor van értelme, ha azokra a változó rekordrészmezőkre vonatkoznak, amelyek az adott változathoz tartoznak. Ezt a követelményt a fordítóprogram nem ellenőrzi.

15. Függvények és eljárások
A függvények és az eljárások olyan objektumok, amelyek a programmal megvalósított algoritmus jól definiált részeit írják le. Emiatt a továbbiakban alprogramoknak nevezzük őket.
Egyéb strukturált utasításoktól (pl. a kiválasztó utasítástól) eltérően az alprogram végrehajtása igényli az alprogram hívását, azaz - a helyzetnek megfelelően az eljáráshívó utasításnak vagy a függvény hívásának az alkalmazását. Az eljáráshívó utasítás a program mindazon helyein szerepelhet, ahol tetszőleges utasítás állhat; ezzel szemben a függvény hívása csak egy kifejezésben megengedett.
A változókhoz hasonlóan az alprogramokat is deklarálni kell. Az alprogramok deklarációi a blokk deklarációs részében vannak. Az alprogram deklarációja a fejlécből és az alprogram törzsét jelentő blokkból áll. Az eljárás fejléce a következő: a procedure kulcsszó, az eljárásparaméterek felsorolása (kerek zárójelekkel körülvéve) és a pontosvessző. A függvény fejléce a következő: a function kulcsszó, a függvényparaméterek felsorolása (kerek zárójelekkel körülvéve), a kettőspont, a függvény eredményének típusmeghatározása és a pontosvessző. Ha az alprogramnak nincs paramétere, akkor a paraméter-felsorolás a körülvevő zárójelekkel együtt elhagyható.
A függvény végrehajtásakor olyan értékadó utasításnak is lennie kell, amelyben az értékadó szimbólum bal oldalán a függvény azonosítója, jobb oldalán pedig a függvény eredményének típusával azonos típusú kifejezés áll. Ebben az értékadásban a kifejezés értéke a függvény eredménye. A függvény végrehajtása nem korlátozódik az eredmény átadására; a hívás argumentumainak megváltoztatását is jelentheti.
Az alprogram paramétereinek felsorolása pontosvesszővel elválasztott elemekből áll. A felsorolás mindegyik eleme a paraméterazonosítók listája, amelyet kettőspont és a listában szereplő paraméterek típusazonosítója követ.
Az alprogram hívásának pillanatában megtörténik az alprogram paramétereinek és a hívás argumentumainak egymáshoz rendelése. Az argumentumok számának egyenlőnek kell lennie a paraméterek számával; a paraméterek és az argumentumok egymáshoz rendelése az alprogram fejlécében és hívásában meghatározott sorrendű.
A paramétert és az argumentumot kétféleképpen lehet egymáshoz rendelni: érték vagy név szerint. Az érték szerinti hivatkozásban a paraméter az alprogram egyik belső változójának tekinthető, amely az alprogram végrehajtásának pillanatában (az adott hívásra értelmezve) megkapja az argumentum híváskori értékét. A név szerinti hivatkozásban a paraméter magát az argumentumot képviseli. Ennek az az eredménye, hogy a paraméteren értelmezett műveletek úgy hajtódnak végre, mintha az argumentumra vonatkoznának. A név szerinti hivatkozást a paraméterazonosítók listája előtt álló var kulcsszóval jelölhetjük ki.
A név szerinti hivatkozás különleges esetében az argumentum egy alprogram neve. A Pascal nyelv szabványával ellentétben a Turbo Pascal nyelvből hiányzik az ilyen hivatkozás lehetősége.

Paraméter nélküli eljárások
A paraméter nélküli eljárások általában mindig ugyanazt a műveletet végzik. Például az előre definiált ClrScr képernyőtörlést végez. Ha egy paraméter nélküli eljárás működését mégis kívülről kívánjuk vezérelni, akkor globális változókat használhatunk az alprogrammal való kommunikációra. Általánosságban elmondható, hogy a paraméter nélküli eljárások és globális változók együttes használata rossz programozási technikát takar.

Az értékparaméterek
Az eljárás fejlévében szereplő paramétereket formális paramétereknek nevezzük. Ezek határozzák meghatározzák, hogy az eljárás hívásakor hány és milyen típusú adatot kell megadnunk. Az eljárás törzsében a formális paraméterekre mint helyi (lokális) változókra hivatkozhatunk.
A paraméterek deklarációját a változódeklarációhoz hasonlóan kell elvégezni: a paraméternevet kettősponttal elválasztva követi a paraméter típusa:

Procedure PascalT(row:byte)
var c,i,k:integer;
begin
   ClrScr;
   for i:=0 to row do begin
      GotoXY(37-i*3,i+1);
      c:=1;
      for k:=0 to i do begin
         Write(c:6);
         c:=(c*(i-k div k+1))
      end;
      Writeln
   end;
end;

Ha több paramétert használunk, akkor az egyes paraméter-leírások közé pontosvesszőt kell tennünk:

Procedure Out(x:integer; y:integer; value:real);

Az azonos típusú paramétereket együtt is deklarálhatjuk:

Procedure Out(x,y:integer; value:real);

A szabványos Pascal nyelvvel ellentétben a Turbo pascal nem engedi, hogy típusleírást (mint például array[1..100] of char vagy string[100]) helyezzünk el a paraméterlistán. Az ilyen típusokhoz először típusnevet kell rendelnünk (type), amit aztán már minden korlátozás nélkül felhasználhatunk.

type tmat=array[1..10,1..10] of integer;

procedure kiir(m:tmat; n:integer);
var i,j:integer;
begin
   for i:=1 to n do begin
      for j:=1 to n do
         write(m[i,j]:6);
      writeln;
   end;
end;

Az értékparaméter csak egyirányú kommunikációt tesz lehetővé a hívó program és az eljárás között. Eljáráshíváskor minden egyes aktuális (hívási) paraméter értéke a paraméterlista azonos helyén álló formális paraméterbe másolódik. Az eljáráson belül az átadott értékeket a formális paraméteren keresztül érhetjük el. A fordítóprogram az eljárás hívásakor ellenőrzi, hogy az aktuális és a formális paraméterek száma és típusa egyezik-e. Ha a paraméterek száma különböző, vagy ha két típus nem értékadás-kompatibilis (ami enyhébb a típusazonosság feltételénél), akkor hibajelzést kapunk.
Az értékparaméter összetett típusú is lehet. Ekkor a paraméterdeklarációban használt típusnévvel deklaráljuk a hívási paraméterlistában megadott változókat is.

A változó-paraméterek
A programozás során gyakran találkozunk olyan feladattal, amikor egy eljárás a paraméterein fejti ki hatását (például csökkenti, növeli vagy felcseréli azokat). Ekkor a bemenő (egyirányú) paraméterek használatával nem érjük el célunkat, hiszen az ilyen paramétereken elvégzett műveletek hatása csak az eljáráson belül érzékelhető. Megoldást az ún. változó-paraméterek bevezetése jelenti. A változó-paraméter kétirányú adatcserét biztosít a hívó program és a hívott eljárás között.
Az eljárás formális paraméterlistáján bármelyik értékparamétert változó-paraméterré alakíthatjuk, ha a neve elé a var foglalt szót tesszük.

Procedure Swp(var x,y:integer);
var tmp:integer;
begin
   tmp:=x;x:=y;y:=tmp
end;

A lokális deklarációk
Minden eljárás rendelkezhet egy ún. saját (lokális) deklarációs résszel, ahol az eljárásban felhasználni kívánt címkéket, konstansokat, típusokat, változókat és esetleges további alprogramokat deklarálhatjuk. A lokális deklarációs rész az eljárás fejléce és a törzse között helyezkedik el. A lokálisan deklarált azonosítók az eljáráson kívülről nem érhetők el.
A lokális változók a paraméterekhez hasonlóan csak az eljárás hívásakor jönnek létre, és megszűnnek létezni, ha az eljárás visszatér a hívó programhoz. A legtöbb programozási nyelv az ilyen jellegű objektumait egy speciálisan kezelt adatterületen, a veremben (stack) tárolja. Ezzel szemben a főprogram szintjén létrehozott változók a program adatszegmensében helyezkednek el, és statikus élettartamúak. A statikus élettartamú változó a program indításakor jönnek létre, és csak a programból való kilépéskor semmisülnek meg.
A szabványos Pascal nyelvtől eltérően a Turbo Pascal-ban olyan lokális változót is létrehozhatunk, amely az eljáráshívások között is megőrzi értékét. Az ilyen tulajdonságú változókat típusos konstansként kell megadnunk a lokális deklarációs részben. Az alábbi eljárás minden híváskor 2 újabb hatványát írja ki:

Program Kettohat;
var ch:char;

Procedure n2;
   const e:integer=0;
           h:real=1;
begin
   writeln(2,'^',e:2,' =',h:10:0);
   h:=h*2;e:=e+1
end;

begin
   for ch:='A' to 'U' do n2
end.

A példában e és a h változók a megadott értéket (0 és 1) egyetlenegyszer, a program indításakor veszik fel.

Példák:
(1, Egyparaméteres eljárás, érték szerinti hivatkozással:)

Program FiveMessages;
var
   Tally:byte;
Procedure SlowDown(Count:integer);
begin
   for Count:=Count downto 1 do
end;

begin
   for Tally:=1 to 5 do begin
      Writeln('Wake up!');
      SlowDown(400)
   end
end.

Példa:
(2. Kétparaméteres eljárás, név szerinti hivatkozással:)

Program ConvertAndSwap;
var
   theFloat:real;
   theFixed:integer;

Procedure Swap(var Float:real;var Fixed:integer);
var
   Temp:real;
begin
   Temp:=Float;
   Float:=Fixed;
   Fixed:=trunc(Temp + 0.5)
end;

begin
   theFloat:=12.8;
   theFixed:=10;
   Writeln(theFloat,theFixed:3);
   Swap(theFloat,theFixed);
   Writeln(theFloat,theFixed:3)
end.

Példa:
(3. A legrövidebb, egy paraméter nélküli eljárás deklarációját és hívását tartalmazó program:)

Procedure P;
begin
end;
begin
   P
end.

Példa:
(4. Háromparaméteres függvény:)

Program MultiplyDivide;
var
   Product:integer;
Function Divide(SourceOne,SourceTwo:byte;
                     var Target:integer):real;
begin
   Target:=SourceOne*SourceTwo;
   Divide:=SourceOne/SourceTwo
end;
begin
   Writeln(Divide(12,4,Product),Product:3)
end.

Példa:
(4. Az alprogramokat képviselő paramétereket tartalmazó alprogram:

Program VeryComplicated;
Procedure Ext(procedure Par; Flag:boolean);
var
   Fix:byte;
Procedure Int;
begin
   Fix:=Fix+1;
end;
begin {Ext}
   Fix:=0;
   if Flag then Ext(Int,false)
      else Par;
   Writeln(Fix)
end;
begin {VeryComplicated}
   Ext(Ext,true)
end.

Példa:

Program MoveArray;
var
   SourceArray:array[1..3,1..4] of integer;
   TargetArray:array[1..2,1..6] of integer;
...
Procedure MoveBytes(var Source,Target; Count:integer);
var Index:integer;
type
   ByteField=array[1..MaxInt] of byte;
var
   Src:ByteField absolute Source;
   Trg:ByteField absolute Target;
begin
   for Index:=1 to Count do
      Trg[Index]:=Src[Index]
end;
...
begin
   ...
   MoveBytes(SourceArray,TargetArray,24);
   ...
end.

A háromszög területének kiszámítása csak az oldalak hosszúságának ismeretében Hérón-képlettel:

Function Haromsz_ter(a,b,c:real):real;
var s:real;
begin
   s:=(a+b+c)/2;
   Haromsz_ter:=Sqrt(s*(s-a)*(s-b)*(s-c));
end;

A függvényt például az alábbi módon lehet meghívni:

Writeln('Terulet = ',Haromsz_ter(6,8,7):6:2)

Az a program, amelyben meghatározott típusú paraméterhez eltérő típusú argumentumot rendelünk, nyilvánvalóan hibás. Kivétel a real típusú paraméter, mert ehhez integer típusú argumentum is hozzárendelhető.
Kizárólag a karakterlánc típusú paraméterek és argumentumok esetén mellőzhető a típusazonosság követelménye. A {$V-} direktíva hatáskörén belül minden karakterlánc típusú paraméter azonos a hozzárendelt karakterlánc típusú argumentummal. Ezáltal tetszőleges típusú karakterláncok feldolgozására nyílik lehetőség.

A függvények és az eljárások összehasonlítása
A Pascal nyelvben alprogramokat eljárásként (procedure) és függvényként (function) egyaránt készíthetünk. A kétféle alprogram között nincs lényegi különbség, az alkalmazásuk módja határozza meg, hogy melyiket választjuk. A függvények sok mindenben (például a paraméterezés, a lokális deklarációk használata stb.) hasonlítanak az eljárásokra, azonban három lényeges dologban különböznek is tőlük:

15.1. Rekurzió
A többi Algol-szerű nyelvhez hasonlóan a Turbo Pascal nyelvben megírt alprogramok rekurziós változatban is megfogalmazhatók, ez sokszor egyszerűsíti az algoritmust. Egy függvényt vagy eljárás rekurzívnak nevezünk, ha az meghívja saját magát (közvetlen vagy közvetett rekurzióval). Fontos tudni, hogy 8-bites gépeken a fordító alapértelmezés szerint abszolút kódot generál, a lefordított progam így kisebb lesz, a programfutás pedig gyorsabb, rekurzív hívás viszont nem használható ebben a módban. Ha tehát rekurzív algoritmust használó programot akarunk írni, a program elején ki kell adnunk a

{$A-}

direktívát.
Egy eljárás vagy függvény hívásakor a veremre kerülnek a rutin lokális változói, paraméterei, valamint a visszatérési cím. Mindezek helye akkor szabadul fel, ha a vezérlés a rutin befejezésére kerül, vagyis a rutin befejezte a feladatát. Ezért a rekurzív program sokkal jobban igénybe veszi a vermet.

Példa:

Function Fibonacci(Index:byte):integer;
begin
   if Index<3 then
      Fibonacci:=1
   else
      Fibonacci:=Fibonacci(Index-1)+Fibonacci(Index-2)
end

A függvény kiszámítja a Fibonacci-sor elemeit. E sorban az első két elem értéke 1, az összes utána következő elemé pedig egyenlő az őt közvetlenül megelőző két elem összegével.

Ha a rekurziós algoritmus két olyan eljárást használ, amelyben az első hívja a másodikat és a második is hívja az elsőt, lehetetlen úgy átrendezni a deklarációkat, hogy minden hívás a már deklarált objektumra vonatkozzék. Ekkor szükség van az ún. előzetes deklarációra, amely az alprogram fejlécéből, a pontosvesszőből és a forward kulcsszóból áll.
Az előzetes deklaráció után a megfelelő helyen szerepelnie kell az alprogram tulajdonképpeni deklarációjának. Ennek fejléce már nem tartalmazza a zárójelekkel körülvett paraméterfelsorolóst, függvény esetén pedig a kettőspontot és a típusmeghatározást sem.

Példa:

Function FunOne(var Source:byte; Target:byte):char; forward;
Function FunTwo(Count:byte):real;
begin
   ...
   Write(FunOne(Count,2 *Count));
   ...
end;
Function FunOne;
begin
   ...
   Write(FunTwo(Source+Target));
   ...
end;

Hatványozás
A Turbo Pascal előre definiált függvényei között nincs hatványozás (csak négyzetre emelés). Írjunk eljárást, amely kiszámítja az A valós szám X. hatványát.
Ha X>=0, akkor A^X = A*A^(X-1), vagyis A^X kiszámításának problémája visszavezethető A^(X-1) kiszámítására. Ha ugyanis A^(X-1) ismert, akkor már csak A-val kell szorozni azt. A^(X-1) kiszámítását A^(X-2)-re vezethetjük vissza és így tovább. Mivel X=0-ra ismerjük a megoldást (definíció szerint 1), ezért a rekurzió véges számú lépés után befejeződik.
Definíció szerint A^-X = 1-A^X. Ha X<0, akkor -X>=0, ezért ilyen esetben a függvényt a -N paraméterrel hívjuk meg, és az eredmény reciprokát vesszük.

function Pow(a:real;x:integer):real;
begin
   if x=0 then pow:=1
   else if x>0 then
      pow:=a*Pow(a,x-1)
   else
      pow:=1/Pow(a,-x)
end;

16. Standard alprogramok
A standard alprogram megnevezés azokra a beépített alprogramokra vonatkozik, amelyek nyílt deklarálásuk nélkül használhatók. Számos ilyen alprogramot leírtunk már az előzőekben; ide tartoznak azok az alprogramok, amelyek karakterláncokon végeznek műveleteket (pl. a dinamikus társzervező alprogramok, valamint a beviteli, ill. kiviteli műveleteket megvalósító alprogramok). Pascalban az alapvető I/O műveleteket is eljárások végzik.
E terjedelmes csoport kiegészítői a képernyős és a különleges eljárások, az aritmetikai, a skalár és a konverziós függvények, valamint más segédfüggvények.

16.1. Képernyős eljárások
A képernyős eljárások azokban az implementációkban használhatók, amelyekben installálták őket.

A CIrEoI eljárás
Hívása: ClrEol
A CIrEoI eljárásnak nincs paramétere. Az eljárás szóközökkel felülírja a kurzor alatti és a tőle jobbra álló karaktereket a sor végéig. A kurzor pozíciója nem változik.

A ClrScr eljárás
Hívása: ClrScr
A ClrScr eljárásnak nincs paramétere. Az eljárás "törli" a képernyőt, azaz szóközökkel tölti fel. A kurzor a képernyő bal felső sarkába kerül. Az installációtól függ, hogy a - később leírt - LowVideo és NormVideo eljárással beállított jellemzők változnak-e.

A Crtlnit eljárás
Hívása: Crtlnit
A Crtlnit eljárásnak nincs paramétere. Az eljárás a Turbo Pascal rendszer installálásakor meghatározott inicializáló karaktersorozatot küld a képernyőre.

A CrtExit eljárás
Hívása: CrtExit
A CrtExit eljárásnak nincs paramétere. Az eljárás a Turbo Pascal rendszer installálásakor meghatározott lezáró karaktersorozatot küld a képernyőre.

A DeILine eljárás
Hívása: DeILine
A DeILine eljárásnak nincs paramétere. Az eljárás törli azt a sort, ahol a kurzor áll. Az alatta levő sorok eggyel feljebb kerülnek, így a képernyő legalsó sora üres lesz. A kurzor pozíciója nem változik.

Az InsLine eljárás
Hívása: InsLine
Az InsLine eljárásnak nincs paramétere. Az eljárás hatására az a sor, ahol a kurzor áll (és az alatta levő sorok) eggyel lejjebb kerül. Így a képernyőn üres lesz a sor, ahol a kurzor áll, a legalsó sor pedig törlődik. A kurzor pozíciója nem változik.

A GotoXY eljárás
Hívása: GotoXY(xPos,yPos)
Az xPos és az yPos integer típusú kifejezés. Az eljárás az (xPos,yPos) koordinátájú karakterpozícióba állítja a kurzort. A képernyő bal felső sarkának koordinátája (1,1); a vízszintes pozíciók balról jobbra, a függőlegesek pedig felülről lefelé növekednek. Ha az xPos vagy az yPos kifejezés értéke nagyobb a sor- vagy oszlopméretnél, akkor a rendszer azt a moduloméret szerint veszi figyelembe.

A LowVideo eljárás
Hívása: LowVideo
A LowVideo eljárásnak nincs paramétere. Az eljárás hatására a legközelebbi NormVideo eljárás hívásáig a képernyőre kivitt karakterek más színben jelennek meg.

A NormVideo eljárás
Hívása: NormVideo
A NormVideo étjárásnak nincs paramétere. Az eljárás a szokásosra (vö. a LowVideo eljárással) állítja vissza a karaktermegjelenítését.

A Read és ReadLn eljárás
Hívása: ReadLn(változó)
Mindkét eljárás adatok bevitelére szolgál. (Mindkét eljárás file-típusokon is értelmezhető művelet, itt csak a képernyőről való beolvasást tárgyaljuk.) A Read és ReadLn eljárások segítségével adatokat olvashatunk be terminálról a memóriába. Ez azt jelenti, hogy amikor a program vezérlése ehhez az utasításhoz ér, akkor a billentyűzeten leütött karakterek az aktuális kurzorpozíciótól megjelennek a képernyőn, s azokat az ENTER leütéséig szerkeszthetjük. Ha a szerkesztés befejeződött (ezt az ENTER leütése jelenti), akkor azt a paraméterként megadott változóba (változó-azonosítóba) kerül. A Read eljárás paramétereként csak változó adható, vagyis a zárójelben csak változó azonosítója lehet.
A karakter begépelése után a karakter megjelenik, s a kurzor eggyel tovább lép. Ha az sor végén állt, akkor sort vált, és a gépelés a következő sorban folytatódik. A bevitt karaktereket szerkeszthetjük: az ERASE billentyűvel a legutoljára beütött karaktert törölhetjük, az ESC billentyű leütésével az összes most beírt karaktert törölhetjük. A Read és ReadLn eljárások után mindig soremelés következik a képernyőn, vagyis a kurzor a következő sor elejére áll. A begépelt adat természetesen ott marad.
Ha a Read által értelmezett adat nem adható értékül a változónak, akkor futási hiba következik be. A 9.5-öt nem tudja fogadni például egy Integer változó, vagy real típusú változóba string típusú adatot próbálunk bevinni. Ezért célszerű minden paramétert string típusú változóba bekérni, majd a megfelelő típusba konvertálni. A paraméter nélküli ReadLn eljárás nem csinál mást mint vár egy bevitelt, majd üríti a puffert. Felesleges tehát ekkor mást beütnünk, min az ENTER-t.
A Readln eljárás az ENTER billentyű lenyomása után az adatbeviteli puffer teljes tartalmát beolvassa és feldolgozza a paraméterként megadott változók típusának megfelelően. Ha a puffer több adatot tartalmaz a szükségesnél, akkor a fel nem dolgozott karakterek elvesznek. Amennyiben a pufferben nem volt elegendő adat a változók számára, akkor az eljárás az adatbevitel végét jelentő karaktereket - hasonlóan a szóközhöz - tagoló jelként értelmezi és várakozik a további adatbevitelre. Így egy Rreadln hívás után biztosak lehetünk abban, hogy a következő adatbeviteli utasítás csak az újonnan begépelt adatokat dolgozza fel.
Ezzel szemben a Read eljárás az ENTER billentyű lenyomása után csak annyi adatot dolgoz fel az adatbeviteli pufferből, amennyi a híváskor megadott változók számára szükséges. Ha a puffer több adatot tartalmaz, akkor a következő adatbeviteli utasítás megkapja a fel nem dolgozott részt.

A Write és WriteLn eljárás
Hívása:
Write(kifejezés1,kifejezés2,...)
WriteLn(kifejezés1,kifejezés2,...)

Megjelenítés a képernyőn: A képernyőre a Write utasítással írhatunk. A Write és WnteLn utasítások közt mindössze annyi a különbség, hogy a WriteLn (Write Line) a kiírás végén sort emel, vagyis a kurzor a következő sor elejére kerül. A Write utasítás a felsorolt paramétereket egymás után, sorfolytonosan megjeleníti a képernyőn az aktuális kurzorpozíciótól kezdve. A Write-nak több paramétere is lehet. A Write utasítás használata több paraméterrel egyenértékű azzal, hogy ha az összes paraméterre egymás után alkalmazzuk azt. A Write paraméter nélküli használata értelmetlen. A paraméter nélküli WriteLn eljárással sort emelhetünk.
Numerikus kifejezés esetében, ha nem adunk meg mást, a rendszer eldönti, hogy hány karakterhelyen történjen a kiírás. Egész szám esetén a szám karakterlánc megfelelőjének a hossza a mérvadó. Valós szám esetén - ha nem rendelkezünk másképpen, - a lebegőpontos forma kerül kiírásra.
Minden paraméter után - legyen az szám vagy szöveg - megadhatjuk, hogy milyen hosszon kívánjuk a kiírást. Ha megadunk hosszt, és az nagyobb, mint a kiírandó karakterszám, jobbra ütköztetés történik. Ha a megadott hosszba nem fér ki a kiírandó karakterlánc, akkor a hossz felülbírálódik, vagyis több karakter kerül kiírásra, mint az általunk megadott szám.
Real típusú számok esetén egy második hossz is megadható, a tizedesjegyek száma. Egész szám esetén a kiírt tizedesjegy rész természetesen 0 lesz. Valós számoknál ekkor már nem a lebegőpontos forma kerül kiírásra, hanem a egész rész, tizedespont és a tizedesjegyek. Ha a tizedesjegyek számát is megadjuk, akkor az első hossz ekkor is a kiírandó karakterek teljes számát jelenti, tehát beleértve az előjelet, a tizedespontot és a tizedesjegyeket is. Ha a megadott tizedesjegyek száma kisebb, mint a kiírandó számé, akkor a kiírás kerekítve csonkul, ha pedig nagyobb, akkor jobbról nullákkal egészül ki. Az egész rész sem egész, sem valós számok esetén nem csonkul, legfeljebb hosszabban kerül kiírásra. Pl.:

WriteLn(Sin(Pi/3):6:4)
Writeln('':5,'darabszam: ',db:4)

Ha a képernyő utolsó sor utolsó pozíciójába írunk, vagy a WriteLn eljárással az utolsó sorba írunk, akkor képernyőgörgetés (scrollozás) történik, vagyis a képernyő összes sora egyel feljebb kerül, kiszorítva az eddigi legfelső sort, és egy üres alsó sor keletkezik, melybe a kurzor a sorváltás miatt kerül.

A logikai konstansok, változók és kifejezések értékének kilistázásakor kétféle eredményt kaphatunk a képernyőn: a TRUE vagy FALSE szót. Az ilyen eredmények kiíratásakor is megadhatunk mezőszélességet, ekkor a TRUE vagy FALSE szavak jobbra igazítva jelennek meg.

Példaprogram a henger térfogatának kiszámítására:

Program Terfog;
Var sugar,magassag,terfogat:real;
    key:char;
Begin
  repeat
    Sugar:=0;Magassag:=0;
    Clrscr;
    LowVideo;
    Gotoxy(27,8);Write('Henger  terfogatszamitasa');
    NormVideo;
    Gotoxy(28,11);Write('Sugar :               cm');
    Gotoxy(28,13);Write('Magassag :            cm');
    Gotoxy(28,15);Write('------------------------');
    Gotoxy(28,16);Write('Terfogat =            m3');
    Lowvideo;
    Gotoxy(39,11);Readln(Sugar);
    Gotoxy(39,11);Write(Sugar:10:2);
    Gotoxy(39,13);Readln(Magassag);
    Gotoxy(39,13);Write(Magassag:10:2);
    Terfogat:=(Sqr(sugar)*Pi*magassag)/1e6;
    Gotoxy(39,16);Write(Terfogat:10:2);
    NormVideo;
    Gotoxy(48,22);Write('ENTER / ESC');
    repeat
      read(kbd,key)
    until (key=#13) or (key=#27)
  until key=chr(27);
end.

16.2. Különleges eljárások

A Delay eljárás
Hívása: Delay(Time)
A Time integer típusú kifejezés. Az eljárás a program végrehajtását kb. Time ms időtartamra felfüggeszti. Ha a Time kifejezés értéke negatív, akkor 0-nak tekinti a rendszer.

A FiIIChar eljárás
Hívása: FillChar(Var,Cnt,Val)
A Var egy tetszőleges típusú változó neve, a Cnt integer típusú kifejezés, a Val pedig char vagy byte típusú kifejezés. Az eljárás a Var változó által lefoglalt tárterület elejétől Cnt számú bájtot feltölt a Val által képviselt bájtos adat értékével.

Az Exit eljárás
Hívása: Exit
Az Exit eljárásnak nincs paramétere. Az eljárás hatására a vezérlés a blokk - amelyben a hívás szerepel - end kulcsszava elé adódik át. Ezzel befejeződik a blokk végrehajtása, ha pedig a programblokkban szerepelt az Exit hívása, akkor ez a program végét jelenti.

A Halt eljárás
Hívása: Halt
A Halt eljárásnak nincs paramétere. Az eljárás hatására befejeződik a program futása.

A Move eljárás
Hívása: Move(Src,Trg,Cnt)
Az Src és a Trg tetszőleges típusú változók neve, a Cnt pedig integer típusú kifejezés. Az eljárás az Src változó által lefoglalt terület elejéről Cnt számú bájtot másol át a Trg változó által lefoglalt terület elejére. Az eljárás akkor is helyesen másol, ha e területek részben vagy egészben fedik egymást.

A Randomize eljárás
Hívása: Randomize
A Randomize eljárásnak nincs paramétere. Az eljárás véletlen értékű adattal inicializálja az álvéletlenszám-generátort.

16.3. Aritmetikai függvények

Az Abs függvény
Hívása: Abs(Num)
A Num real vagy integer típusú kifejezés. Az Abs függvény értéke a Num képviselte adat abszolút értéke, típusa azonos az argumentum típusával.
Abs (-2) = 2
Abs(Pi) = 3.1415926536

Az ArcTan függvény
Hívása: ArcTan(Num)
A Num real vagy integer típusú kifejezés. Az Arctan függvény értéke a Num képviselte adat arkusz tangense, típusa real.
ArcTan(0) = 0.0
ArcTan(1.0) = 0.7853981634

A Cos függvény
Hívása: Cos(Num)
A Num real vagy integer típusú kifejezés. A Cos függvény értéke a Num képviselte adat koszinusza, típusa real.
Cos(0) -1.0
Cos(Pi) =-1.0

Az Exp függvény
Hívása: Exp(Num)
A Num real vagy integer típusú kifejezés. Az Exp függvény típusa real, értéke az e^num hatványozás eredménye, ahol e a természetes logaritmus alapja: e = 2.7182818285.
Exp(0) -1.0
Exp(-1.0) = 0.36787944117

A Frac függvény
Hívása: Frac(Num)
A Num real vagy integer típusú kifejezés. A Frac függvény értéke a Num képviselte adat törtrésze, típusa real.
Frac(3) = 0.0.
Frac(pi) = 0.1415926536

Az Int függvény
Hívása: Int(Num)
A Num real vagy integer típusú kifejezés. Az Int függvény értéke a Num képviselte adat egészrésze, típusa real.
Int(2) = 2.0
Int(-Pi) = -3.0

Az Ln függvény
Hívása: Ln (Num)
A Num real vagy integer típusú kifejezés. Az Ln függvény értéke a Num képviselte adat természetes alapú logaritmusa, típusa real.
Ln(1)=0.0
Ln(3.0) = 1.0986122887

A Sin függvény
Hívása: Sin(Num)
A Num real vagy integer típusú kifejezés. A Sin függvény értéke a Num képviselte adat szinusza, típusa real.
Sin(0) = 0.0
Sin(Pi/2) =1.0

Az Sqr függvény
Hívása: Sqr (Num)
A Num real vagy integer típusú kifejezés. Az Sqr függvény értéke a Num képviselte adat négyzete, típusa azonos az argumentum típusával.
Sqr(2) = 4
Sqr(2.0) = 4.0

Az Sqrt függvény
Hívása: Sqrt (Num)
A Num real vagy integer típusú kifejezés. Az Sqrt függvény értéke a Num képviselte adat négyzetgyöke, típusa real.
Sqrt(4) = 2.0
Sqrt(4.0) = 2.0

A Turbo Pascal a szögfügvényeket radiánban számolja. A radián-fok konverzió könnyen elvégezhető.
Az x radián szög értékét fokban így határozhatjuk meg:

Function Deg(x:real):real;
begin
   Deg:=x*180/Pi;
end;

Az x fok értéke radiánban, azaz x*PI/180:

Function Rad(x:real):real;
begin
   Rad:=x*Pi/180;
end;

Néhány, a Turbo Pascal 3-ban nem definiált szögfüggvény kiszámítása:

A Tangens függvény

Function Tan(alfa:real):real;
begin
   Tan:=Sin(alfa)/Cos(alfa)
end;

A Kotangens függvény

Function Cot(alfa:real):real;
begin
   Cot:=Cos(alfa)/Sin(alfa)
end;

A Szekáns függvény

Function Sec(alfa:real):real;
begin
   Sec:=1/Cos(alfa)
end;

A Koszekáns függvény

Function Csc(alfa:real):real;
begin
   Csc:=1/Sin(alfa)
end;

A Hiperbolikus szinusz függvény

Function Sinh(alfa:real):real;
begin
   Sinh:=(Exp(alfa)-Exp(-alfa))/2
end;

A Hiperbolikus koszinusz függvény

Function Cosh(alfa:real):real;
begin
   Cosh:=(Exp(alfa)+Exp(-alfa))/2
end;

A Hiperbolikus szekáns függvény

Function Sech(alfa:real):real;
begin
   Sech:=2/(Exp(alfa)+Exp(-alfa))
end;

16.4. Skalárfüggvények

Az Odd függvény
Hívása: Odd (Num)
A Num integer típusú kifejezés. Az Odd függvény "a Num kifejezés értéke páratlan szám" mondat logikai értékét adja meg, típusa boolean.
Odd(3) = true
Odd(4) = false

A Pred függvény
Hívása: Pred (Num)
A Num tetszőleges, rendezett típusú kifejezés. A Pred függvény értéke a rendezett típus azon eleme, amely közvetlenül az argumentum képviselte elem előtt áll, típusa azonos az argumentum típusával.
Pred('B') ='A'
Pred(-20) = -21

A Succ függvény
Hívása: Succ (Num)
A Num tetszőleges, rendezett típusú kifejezés. A Succ függvény értéke a rendezett típus azon eleme, amely közvetlenül az argumentum képviselte elem után áll, típusa azonos az argumentum típusával.
Succ(false) = true
Succ(0) = 1

16.5. Konverziós függvények

A Chr függvény
Hívása: Chr (Num)
A Num integer típusú kifejezés. A Chr függvény típusa char, értéke a Num kódú karakter.

Chr(65) = 'A'

A beépített botkormány az alábbi kódokat adja:

joy jobbra
joy balra
joy fel
joy le
= Chr(28);
= Chr(29);
= Chr(30);
= Chr(31)
SHIFT + joy jobbra
SHIFT + joy balra
SHIFT + joy fel
SHIFT + joy le
= Chr(189);
= Chr(185);
= Chr(177);
= Chr(181)
CTRL + joy jobbra
CTRL + joy balra
CTRL + joy fel
CTRL + joy le
= Chr(190);
= Chr(186);
= Chr(178);
= Chr(182);

Az Ord függvény
Hívása: Ord (Num)
A Num tetszőleges, rendezett típusú kifejezés. Az Ord függvény típusa integer, értéke megadja a Num képviselte adat sorszámát a rendezett típuson belül.
Ord(true) = 1
Ord(-2) = -2

Az alábi program kiírja a lenyomott billentyűt és annak kódját. A programot az ESC megnyomásával szakíthatjuk meg:

var key:char;
begin
   repeat
      Read(kbd,key);
      Writeln(key,' = ',ord(key));
   until key=chr(27)
end.

A Round függvény
Hívása: Round (Num)
A Num real típusú kifejezés. A Round függvény típusa integer, értéke a Num képviselte adathoz legközelebb álló szám.
Round(5.5) = 6
Round(-1.5) = -2

A Trunc függvény
Hívása: Trunc (Num)
A Num real típusú kifejezés. A Trunc függvény típusa integer, értéke a Num képviselte adat egészrésze.
Trunc(3.14) = 3
Trunc(-2.9) = -2

16.6. Segédfüggvények

A Hi függvény
Hívása: Hi (Num)
A Num integer típusú kifejezés. A Hi függvény típusa integer, értéke a Num képviselte adat magasabb helyi értékű bájtja.
Hi(256) = 1
Hi(-1) = 255

A KeyPressed függvény
Hívása: KeyPressed
A KeyPressed függvénynek nincs paramétere. A függvény boolean típusú, értéke "a konzol-pufferban van még be nem olvasott karakter" mondat logikai értékét adja meg. (Azaz, ha van a billentyűzet pufferben várakozó kód, akkor az értéke true.) A puffer tartalma változatlan marad, a függvény onnan nem vesz ki karaktert.

A Lo függvény
Hívása: Lo (Num)
A Num integer típusú kifejezés. A Lo függvény típusa integer, értéke a Num képviselte adat alacsonyabb helyi értékű bájtja.
Lo(256) = 0
Lo(-1) = 255

A ParamCount függvény
Hívása: ParamCount
(Csak a 3.x verziókban.) A ParamCount függvénynek nincs paramétere. A függvény integer típusú, értéke megadja a program hívásakor átadott paraméterek számát. Feltételezzük, hogy a paramétereket szóközök vagy tabulátorok választják el egymástól.

A ParamStr függvény
Hívása: ParamStr (Num)
(Csak a 3.x verziókban.) A Num integer típusú kifejezés. A ParamStr függvény karaktertánc típusú adat, amely a program hívásakor átadott Num sorszámú paramétert jelenti. Feltételezzük, hogy az első paraméter sorszáma 1.

A Random függvény
Hívása:
Random
Random (Num)

A Num integer típusú kifejezés. A Random függvény értéke paraméter nélküli változatban real típusú véletlen szám, amelynek értéke 0.0 vagy annál nagyobb, de 1.0-nél kisebb. Ha a Random függvénynek van paramétere, akkor az eredmény integer típusú véletlen szám, értéke 0.0 vagy annál nagyobb, de Num-nál kisebb.

A SizeOf függvény
Hívása: SizeOf (Nam)
A Nam változónév vagy típusnév. A SizeOf függvény integer típusú, értéke megadja a Nam változónak kiosztott vagy a Nam típusú adat ábrázolásához szükséges bájtok számát.
SizeOf(Boolean) = 1
SizeOf(integer) = 2

A Swap függvény
Hívása: Swap (Num)
A Num integer típusú kifejezés. A Swap függvény integer típusú, értékének magasabb helyi értékű bájtja Lo(Num), alacsonyabb helyi értékű bájtja pedig Hi(Num).
Swap(256) = 1
Swap(1) = 256

Az UpCase függvény
Hívása: UpCase (Chr)
A Chr char típusú kifejezés. Az UpCase függvény char típusú, értéke - ha a Chr betű - nagybetű, különben Char.
UpCase('a') = 'A'
UpCase('.') = '.'

17. Állományok beillesztése
A fordítóprogram fontosabb direktívái közé tartozik az állományt beillesztő direktíva (include). Alakja a következő:
{$I Name}
ahol Name az állomány neve. E direktívát új sorba kell írni. Végrehajtásakor a fordítóprogram helyettesíti a Name nevű állomány tartalmával. Beilleszthetjük vele a programba az előzőleg megírt deklarációs, ill. alprogram-könyvtárakat, forrásnyelvi programrészeket, a beillesztett állományban azonban nem szerepelhet egy újabb beillesztési direktíva.
Figyelembe kell még venni, hogy ha a Name állománynév nem tartalmaz hárombetűs kiterjesztést, akkor a direktívát lezáró kapcsos zárójel és a Name között legalább egy szóköz álljon, mert különben a fordítóprogram az állománynév részének tekinti majd a zárójelet.

Példa:

Legyen a FACTOR.DOC állomány tartalma a következő:

Function Factorial(Num:byte):integer;
begin
   if Num<2 then Factorial:=1
      else Factorial:=Num*Factorial(Num-1)
end;

A program:

Program Demo;
{$I Factor.doc}
begin
   Writeln(Factorial(5))
end.

E program fordítása olyan eredménnyel jár, mintha a következő programot fordítottuk volna le:

Program Demo;
Function Factorial(Num:byte):integer;
begin
   if Num<2 then Factorial:=1
      else Factorial:=Num*Factorial(Num-1)
end;
begin
   Writeln(Factorial(5))
end.

Vagyis amikor a fordító az I direktívához ér, a megadott file tartalmát fordítja, majd azt befejezve, visszatér az eredeti programhoz, és annak soron következő utasításán folytatja a fordítást. A file-ot tehát csak logikailag szúrja be, veszi figyelembe a fordító, annak szövege fizikailag nem jelenik meg a programban, de a lefordított program kódja szempontjából a beszúrt rész egyenértékű azzal, mintha az is a forrásnyelvi szövegben lenne.
Fontos körülmény, hogy ha egy programon dolgozunk és a fordító a beszúrt file-ban talál hibát, akkor a programot elmenti és kurrens file-nak a beszúrt file-t tölti be, megjelölve azon a hiba helyét. Nem vész el tehát ez esetben sem az aktív file-on a legutóbbi módosítás sem. A fordító direktívák - a B és C kivételével - csak arra a file-ra vonatkoznak, amelyben előfordulnak.

A beszúrt file-ok alkalmazhatók a Turbo Pascal egy korlátjának áthidalására. A Turbo rendszer CP/M operációs rendszer alá futó változata egyszerre maximum kb. 24 Kbyte nagyságú forrásnyelvi programokkal tud dolgozni, ennyi szabad memória marad ugyanis a forrásnyelvi program tárolására. Ha ennél nagyobb forrásnyelvű file-ot akarunk lefordítani, akkor szét kell tördelnünk a több, 24 K-nál kisebb részre, majd össze kell fűzni őket logikailag a beszúrásos technikával. Az így keletkező programot már le tudja fordítani a compiler. A beszúrásos technikával készült forrásprogramok nagyságának forrásnyelvi szinten nincs felső korlátja. Csak az szab korlátot, hogy a lefordított - .COM kiterjesztésű - file nagysága nem haladhatja meg a 64 Kbyte-ot.

18. Alprogramok átlapolása
A Turbo Pascal és a CP/M rendszer lényeges korlátozása, hogy a tárgyprogram és adatai valamint maga a futtató környezet nem lehetnek nagyobbak 64 kbájtnál. E korlátozás megkerülhető az átlapolt alprogramok (overlay módszer) alkalmazásával. A tárgyprogram számára kiosztott tárterület két részre bontható: tárrezidens részre (amelyet a program állandó része fogfal le) és átlapolási (overlay) területre (ahova az egyes átlapolt programrészek - alprogram-csoportok töltődnek be). Az átlapolási területen különböző időpontokban más-más modulok kódja helyezkedik el. A lemezen tárolt overlay-modulok a program igényeinek megfelelően töltődnek be a memóriába.
Eljárások és függvények is átlapolhatók; az átlapolt alprogramok azonban nem hívhatók rekurzív módon, és nem szerepelhetnek előzetes deklarációkban sem. Ez nem jelent akadályt, hiszen deklarálható egy nem átlapolt alprogram is, amely a másik - eredetileg rekurzív módon hívandó - alprogramot hívja. Hibakereséskor viszont számíthatunk bizonyos nehézségekre, ezért csak a kipróbált, "belőtt" alprogramokat alakítsuk át átlapolttá.
Minden átlapolt alprogram-csoport több alprogramból áll; a csoporthoz egy átlapolási terület tartozik. A program végrehajtásakor az átlapolási területen a csoport egyetlen tagja tartózkodhat. E terület mérete akkora, hogy a csoport minden alprogramja belefér. Ez azt is jelenti, hogy egy átlapolt csoport használatakor a megtakarított tárterület a csoportméret és a csoporton belüli legnagyobb alprogram méretének különbségével egyenlő.

Az operatív tár megtakarításának ára:

Az átlapolt alprogramcsoportok létrehozási szabálya igen egyszerű: egy vagy több egymás utáni alprogram-deklaráció elé az overlay kulcsszót kell írni. Az így kijelölt alprogramok csoportot alkotnak, melyet a rendszer mágneslemezes állományban tárol. Az állomány neve a főprogram nevével azonos (I. a rendszermenü M parancsát), kiterjesztése háromjegyű. Az első csoport kiterjesztése .000, a másodiké .001 stb. Ha az átlapolt alprogramok között rezidens alprogramok is szerepelnek, akkor az átlapoltak különálló csoportokba kerülnek. Az átlapolt csoportok létrehozási szabálya nem zár ki újbóli átlapolást (az átlapolt alprogramon belül).
Példa:

program OverlayProgram;
overlay procedure One;
begin
   ...
end;
overlay procedure Two;
begin
   ...
end;
procedure Middle;
begin
   ...
end;
overlay procedure Three;
begin
   ...
end;
overlay procedure Four;
begin
   ...
end;
begin
   ...
end.

Az OverlayProgram példaprogram lefordításából keletkezett tárgykód szerkezete:

19. Néhány kiválasztott implementációs bővítés
A Turbo Pascal rendszer - mint beépített képernyős szövegszerkesztővel rendelkező programozási nyelv - különböző operációs rendszerek környezetében installálható. Mindegyikben biztosítja az adott rendszerre és fordítóprogramra jellemző járulékos szolgáltatásokat:

E bővítéseket a CP/M operációs rendszerben érvényes alakban mutatjuk be.

19.1. Nyílt helyfoglalás programváltozók számára
A változódeklaráció absolute kulcsszavával helyet foglalhatunk a változó számára egy másik változóhoz hozzárendelt címen vagy egy előírt című tárhelyen. Az ilyen deklaráció a deklarált változó nevéből, a kettőspontból, az absolute kulcsszóból, a tárhely-meghatározásból és a pontosvesszőből áll. A tárhely meghatározása egy előzőleg deklarált név vagy egy abszolút cím (a 8 bites mikroszámítógépen egy integer típusú konstans, az IBM PC esetén pedig kettősponttal elválasztott szegmens- és eltolás-érték).

Példa (8 bites mikroszámítógépen:)

var
   CharStr:string[6];
   StrLen:byte absolute CharStr;
   Buffer:array[0..15] of byte absolute $2000;
Function Fun(var IntVar:integer):byte;
var
   LSB:byte absolute IntVar;
begin
   if LSB=Lo(IntVar) then ...
   ...
end;

19.2. Különleges rendszerfüggvények és eljárások

Az Addr függvény
Hívása: Addr (Nam)
A Nam egy változó vagy egy alprogram neve. Az Addr függvény értéke integer típusú adat, a Nam változó (vagy alprogram) kijelölt tárcímét adja meg.
Addr(Mem[2])

Az OvrDrive eljárás
Hívása: OvrDrive (Drv)
A Drv integer típusú kifejezés. Az OvrDrive eljárás hatására az átlapolt programrészek a Drv által meghatározott mágneslemezes egységről töltődnek be (0 = alapértelmezés szerinti egység, 1 = A, 2 = B stb.).
OvrDrive(2)

19.3. Rendszerrutinok hívása (8 bites mikroszámítógép)
A rendszerrutinok falprogramok) a Bdos és Bios eljárással, valamint a Bdos, BdosHL, Bios és BiosHL függvénnyel közvetlenül hívhatók.

A Bdos eljárás
Hívása:
Bdos (Fun,Par)
Bdos (Fun)

A Fun és az (elhagyható) Par integer típusín kifejezés. A Bdos eljárás végrehajtásakor a processzor C regiszterébe betöltődik a Fun képviselte adat alacsonyabb helyi értékű bájtja, ezután a program a 0005-ös címen folytatódik (vagyis a Fun sorszámú BDOS rendszerfunkciót hajtja végre). Ha a hívás kétparaméteres, akkor az említett ugrás előtt a Par képviselte adat a DE regiszterbe kerül.

A Bdos függvény
Hívása:
Bdos (Fun,Par)
Bdos (Fun)

A Fun és az (elhagyható) Par integer típusú kifejezés. A Bdos függvényhívás hatása azonos a Bdos eljáráséval; a függvény értéke byte típusú adat, amelyet a BDOS az A regiszterben ad át.

A BdosHL függvény
Hívása:
BdosHL (Fun,Par)
BdosHL (Fun)

A Fun és az (elhagyható) Par integer típusú kifejezés. A BdosHL függvényhívás hatása azonos a Bdos függvényével; a függvény értéke integer típusú adat, amelyet a BDOS a HL regiszterben ad át.

A Bios eljárás
Hívása:
Bios (Fun,Par)
Bios (Fun)

A Fun és az (elhagyható) Par integer típusú kifejezés. A Bios eljárás a Fun sorszámú BIOS alrendszer-funkciót hajtja végre. Ha a hívásban szerepel a Par paraméter, akkor előtte a Par képviselte adat a processzor BC regiszterébe kerül.

A Bios függvény
Hívása:
Bios (Fun,Par)
Bios (Fun)

A Fun és az (elhagyható) Par integer típusú kifejezés. A Bios függvényhívás hatása azonos a Bios eljáráséval; a függvény értéke byte típusú adat, amelyet a BIOS az A regiszterben ad át.

A BiosHL függvény
Hívása:
BiosHL (Fun,Par)
BiosHL (Fun)

A Fun és az (elhagyható) Par integer típusú kifejezés. A BiosHL függvényhívás hatása azonos a Bios függvényével; a függvény értéke integer típusú adat, amelyet a BDOS a HL regiszterben ad át.

19.4. Gépi szintű programozás
Néha szükség van egy gépi kódú alprogram beillesztésére a Turbo Pascal nyelvben megírt programba (vagy legalább egy gépi szintű "betét"-re). E célra az external és az inline kulcsszót használhatjuk. Ha egy alprogram törzsét képező blokk helyett az
external integer_típusú_ konstans
szerkezet fordul elő, akkor ez azt jelenti, hogy a gépi kódú alprogram e konstanssal meghatározott tárcímen található. Fontos, hogy az alprogram végrehajtásának eredményeként az SP regiszter tartalma (a veremméret) ne változzék!

Példa:

Function Factorial(Arg:byte):integer;
external $6000;

Az external szerkezet csupán a gépi kódú alprogram helyét mutatja meg, az inline utasítással azonban gépi kódot is generálhatunk. Az inline utasítás az inline kulcsszóból és az azt követő, kerek zárójelekkel körülvett kódelem-sorozatból áll. A kód elemeit perjelek választják el egymástól; minden kódelem + vagy - (mínusz) jellel elválasztott adatelemekből áll. Az adatelem lehet integer típusú konstans, változó vagy egy alprogram azonosítója és a *-gal jelölt programszámláló (PC) pillanatnyi értéke.

Példa:

inline(20/$40/Fun-2/ *+3)

Minden elem 1 bájtot vagy 1 szót (2 bájtot) hoz létre. Az előállított adat az adatelemeken végrehajtott műveletek eredménye. A változó vagy az alprogram azonosítója e változó (vagy alprogram) címét képviseli, a programszámláló szimbóluma pedig azt a címet, ahova a generált kód kerül.
Ha egy kódelem kizárólag konstansokból és szeparátorokból áll, értéke pedig 0..255 között van, akkor a fordítóprogram 1 bájtot generál. Ha az érték ennél nagyobb, ill, a kódelem változónevet vagy alprogramnevet, esetleg programszámláló-hivatkozást tartalmaz, akkor a fordítóprogram 1 szót generál. E szóban az alacsonyabb helyi értékű bájt megelőzi a magasabb helyi értékűt.
Ez a szabály felülbírálható a kódelem elé helyezett < vagy > jellel. Az első esetben a szó alacsonyabb helyi értékű bájtja generálódik, a másodikban pedig 2 bájt még akkor is, ha a második (magasabb helyi értékű) bájt tartalma 0.

Példa:

inline(>$12/<$3456)

Egy összetettebb példa (A Turbo PAcal Reference Manual, Version 3.0 alapján):

type anystr=string[255];
Procedure UpperStr(var Str:anystr);
begin
inline($2A/Str/$46/$04/$05/$CA/*+20/$23/
         $7E/$FE/$61/$DA/*-9/$FE/$7B/$D2/
         *-14/$D6/$20/$77/$C3/*-20)
end;




L1:










L2:
LD HL,(Str)
LD B,(HL)
INC B
DEC B
JP Z,L2
INC HL
LD A,(HL)
CP 'a'
JP C,L1
CP 'z'+1
JP NC,L1
SUN 20H
LD (HL),A
JP L1

19.5. Külső programok indítása
A fordítóprogram által készített, lefordított (.COM kiterjesztésű) file-ok felépítésében közös, hogy az első 8 kbyte-juk tartalmazza a standard eljárásokat tartalmazó Turbo könyvtárat. A .COM file tehát két részből épül fel: az említett könyvtárból és magából a lefordított kódból. Egy rövidebb program esetében a file méretének nagyobb hányadát is kiteszi a Turbo könyvtár. A fordító képes olyan kódot is generálni, amely nem tartalmazza a könyvtárat, csak a kódot. Az ilyen file .CHN kiterjesztést kap. Hogy melyik lehetőséget választjuk, azt a 'compiler options' menüből választhatjuk ki. A létrehozott .CHN kiterjesztésű file önmagában azonban nem futtatható, azt csak egy másik, .COM kiterjesztéssel fordított programból hívhatjuk meg.

A Turbo Pascal nyelvben írt programokban két segédeljárást használhatunk, ezek külső programok indítását (programok láncolását) teszik lehetővé. E két eljárás az

Execute(FileVar) és a Chain(FileVar),

ahol FileVar egy fájlváltozó neve. E változó azonosítja a betöltendő (külső) programot tartalmazó állományt. Az Execute eljárás .COM kiterjesztésű programot indít, a Chain pedig .CHN kiterjesztésűt.

Ha a meghívott program nincs a lemezen, akkor I/O hibát kapunk, kivéve, ha az 'I' direktívát előtte passzívvá tettük. Ez esetben a hibát a hívó programban kell lekezelni, az IoResult függvény segítségével. Ezt az első input-output műveletig kell megtenni, mivel I/O műveletet mindaddig nem tudunk végrehajtani I/O hiba után, míg az említett függvényt meg nem hívjuk. Ezután a hiba fajtáját a forrásprogramban le tudjuk kezelni.

A Chain-nel meghívott program tulajdonsága, hogy a vívó programot kitörli a tárból. Ezért az eljárás újbóli alkalmazásával lehet visszahívni. A Chain eljárással hívott program adatokat kaphat a hívó programból akár globális változók révén, akár fix cím(ek)en levő változó(ko)n keresztül. A globális változókat - ha használjuk őket - mindkét programban az első helyen és azonos sorrendben kell deklarálni. E szabály betartásával a hívó és a hívott programban szereplő (globális) változóhivatkozások ugyanazokra az adatokra vonatkoznak.

Példa:
Két program, amelyből az első átad a másodiknak egy karakterlánc típusú és egy számadatot.

program First;
var
   LastName:string[8];
   Age:byte;
   NameFile:file;
begin
   Write('Jan ');
   LastName:='Bielecki';
   Age:=44;
   Assign(NameFile,'Second.chn');
   Chain(NameFile)
end.

Program Second;
var
   Surname:string[8];
   Age:byte;
begin
   Writeln(SurName,' is',Age:3,' now')
end.

19.6. Paraméterátadás
A Pascal program és alprogramjai közötti paraméterátadásról már volt szó. A 3.0-ás verziótól kezdve a teljes lefordított programot is lehetőség van paraméterezni, amikor az operációs rendszerből meghívjuk. Ehhez a ParamCount és a ParamStr standard függvényeket kell alkalmaznunk.
A ParamCount függvénynek nincs bemenő paramétere, visszatérési értéke pedig a paraméterek számát adja meg. A ParamStr függvény bemenő paramétere egy egész szám, értéke pedig a bemenő paraméterrel, mint sorszámmal kiválasztott paraméter értéke, azaz például ParamStr(3) értéke a programnak megadott 3. paraméter string formában (akkor is, ha a megadott paraméter pl. egész szám).

program param;
var k:integer;
begin
   for k:=1 to ParamCount do
      Writeln(k:1,'. parameter: ',ParamStr(k))
end.

A fenti lefordított példaprogramot IS-DOS-ból a

param par1 par2 par3

paranccsal elindítva láthatjuk, hogy a paramétereket az elválasztó szóközöktől "megtisztítva" kapjuk meg. Ha nem írunk programindításkor paramétert, a paraméter-számláló (ParamCount) értéke 0 lesz.

20. Az adatok ábrázolása (8 bites mikroszámítógépeken)

20.1. Rendezett típusú adatok
A rendezett típusú adatok az operatív tár 1 vagy 2 bájtját foglalják le.
Egybájtos ábrázolásúak a char típusú adatok, valamint azok a felsorolási típusú adatok, amelyek 256 elemnél kisebb elemszámú halmazhoz kapcsolódnak, ill. azok a min..max intervallum típusú adatok, amelyekben az ord(min) és az ord(max) a 0..255 intervallumhoz tartozik. A boolean és a byte típusú adatok is 1 bájt tárhelyet foglalnak le.
Kétbájtos ábrázolásúak az integer típusú adatok, az 1 bájtban nem ábrázolható intervallum típusú adatok, valamint a 256 elemnél nagyobb elemszámú felsorolási típusú adatok. A 2 bájtot elfoglaló adatokban az alacsonyabb helyi értékű bájt mindig megelőzi a magasabb helyi értékűt.

20.2. Valós típusú adatok
A real típusú adatok az operatív tár 6 bájtját foglalják le. Ezek az adatok egybájtos kitevőből és ötbájtos mantisszából tevődnek össze; a legkisebb címen a szám kitevője van, ezt a mantissza bájtjai követik (a legalacsonyabb helyi értékű bájttól a legmagasabbig). A kitevő értéke $80-nal eltolt; a mantissza normalizált alakú, és a legmagasabb helyi értékű bitje nélkül tárolódik. Ez az ún. implicit bit megadja a mantissza előjelét. Egy real típusú, 0.0 értékű adat kitevője csupa 0-s bitből áll.

20.3. Karakterlánc típusú adatok
A string[n] típusú adatok ábrázolása n+1 bájtot igényel. A karakterlánc típusú adat első bájtja megadja ezen adat karaktereinek számát (a karakterlánc hosszát).

20.4. Halmaz tipusú adatok
A min legkisebb és a max legnagyobb elemű rendezett típuson alapuló halmaz típusú adatok a memória

ord(max) div 8 - ord(min) div 8 + 1

bájtját foglalják le. A halmaz típusú adatok úgy ábrázolhatók, mintha a rendezett alaptípus 256 elemből állna. Így egy változónak 32 bájtra lenne szüksége (elem 1 bitet foglal le, így 256 elem 256/9=32 bájtot., amelyek közül azonban az esetek többségében csak keveset használunk (hiszen a halmaz típusú változó általában 256-nál kevesebb elemből áll), ezért a 32 bájtból a rendszer elhagyja azokat a "szélső" bájtokat, amelyek értéke sosem változik.
A set of 10..16 típusú adat ábrázolásához pl. nem 32 bájtra van szükség (az x-szel az adat "aktív" pozícióit jelöltük).

00000000 ... 00000000 000000x xxxxxx00 00000000,

hanem csak 2 bájt a helyigénye:

0000000x xxxxxx00

(a legalacsonyabb helyi értékű bájttól a legmagasabbig).

20.5. Mutató típusú adatok
A mutató típusú adatok 2 bájtot foglalnak le. Ábrázolásuk azonos az integer típusú adatokéval, tartalmuk viszont más: memóriacímet jelentenek. A nil mutató által képviselt adat csupa 0-s bitből áll.

20.6. Tömb típusú adatok
A tömbök elemei soronként helyezkednek el az operatív tárban.

20.7. Rekordtípusok
A rekordmezők deklarációjuk sorrendjében helyezkednek el a memóriában. Ha a rekord nem tartalmaz változórészt (variánst), akkor mérete azonos a mezőméretek összegével, különben a fix rész és a legnagyobb helyigényű változat méretének összege adja meg a rekord ábrázolásához szükséges tárhelyet. Akár tartalmaznak változórészt, akár nem - a rekordok fix méretűek. Ez a tény lényeges a beviteli, ill. kiviteli műveletek szempontjából.

Példa:

var
   RecVar:record
      case Selector:integer of
      6:(Arr:array (1..3,1..2] of byte);
      8:(aSet:set of A'..'z')
   end;
begin
   with RecVar do
      Write(SizeOf(RecVar),SizeOf(Arr):2,SizeOf(aSet):2)
end.

Függelék

A Függelék: Kapcsolat az operációs rendszerrel
A Turbo Pascal külső rutingyűjteménnyel érheti el az Enterprise operációs rendszerének funkcióit. Erre szolgál az OS.TPU. Használatához közvetlenül a változódeklarációs rész után kell beilleszteni programunkba a következő utasítással:

{$I os.tpu}

A unitban néhány változó deklarálva van; a programban más ilyen nevű változókat nem használhatunk. Ezek rendre: ra,rb,rc,rd,re,rf,rh,rl,raf,rbc,rde,rhl BYTE ill. INTEGER típusú változók, amelyeken keresztül Z80 azonos jelölésű regisztereinek adhatunk át értékeket ill. itt kapjuk az eljáráshívás eredményétől függő értékeket vissza; és egy command nevű STRING ctype típussal.
A használható eljárások:

Az Exos eljárás
Hívása: Exos(funct)
A funct számú Exos funkcióhívás. Hívás előtt a kívánt regisztereknek megfelelő változók értékeit be kell állítani, és az eljárás ezekben a változókban adja vissza az EXOS által szolgáltatott értékeket. Például egy csatornát a következőképpen lehet lezárni:

ra:=(a csatorna szama); exos(3);

Az Isdos eljárás
Hívása: Isdos(funct)
A func számú IS-DOS funkció hívása. Hasonlóan működik, mint az előző eljárás. Pl. a dátum lekérdezése a következőképpen lehetséges:

Isdos($2A);

Ezek után rhl-ben az év, rd-ben a hónap, re-ben a nap sorszáma található, ra-ban pedig, hogy a hét melyik napja.

A Dos_com eljárás
Hívása: dos_com
DOS parancs végrehajtása. Hívása előtt a command változóba be kell tölteni a végrehajtani kívánt parancsfűzért. Például:

command:='dir *.txt'; dos_com;

Ennek hatására megkapjuk a kívánt directory-t. Hibás parancs eseten a hibaüzenet íródik ki.

Az Stlin eljárás
Hívása: stlin(szöveg)
Írás a státuszsorba. Például az

stlin('Fomenu');

utasításra megjelenik a státuszsorban a 'Fomenu' felirat. FIGYELEM! Mivel a státuszsor bal es jobb szélét a rendszer megszakításból írja ill. törli (CAPS, HOLD, stb. feliratok), ezért csak 22-23 karaktert tudunk kiírni.

A SetVar eljárás
Hívása: SetVar(változó,érték)
A 'változó' számú EXOS-változóba beírja a megadott értéket.

A Toggle eljárás
Hívása: Toggle(változó)
A meagdott számú változó értékét átbillenti.

A GetTime eljárás
Hívása: GetTime(óra,perc,másodperc)
A három integer típusú változóba betölti a rendszeridőt 24 órás alakban.

A GetDate eljárás
Hívása: GetDate(év,hónap,nap)
A három integer típusú változóba betölti az aktuális rendszerdátumot. Az évet négy számjegyen adja.

A SetTime eljárás
Hívása: SetTime(óra,perc,másodperc)
A rendszeridő beállítása. Minden változó integer típusú. Az órát 24 órás alakban kell megadni.

A SetDate eljárás
Hívása: SetDate(év,hónap,nap)
A rendszerdátum beállítása. Minden változó integer típusú, az évet négy számjeggyel kell megadni.

A használható függvények:

A Bcd függvény
Hívása: Bcd(nr)
A byte típusú BCD számot decimális alakba konvertálja.

A ToBcd függvény
Hívása: ToBCD(nr)
A byte típusú decimális számot BCD alakba konvertálja.

Az Ask függvény
Hívása: Ask(n)
Az n számú rendszerváltozó állapotát adja vissza. N és az eredmény byte típusú érték.

A Get függvény
Hívása: GET(ch)
A ch számú megnyitott csatornáról beolvas egy karaktert és visszaadja annak kódját integer típusú értékként. Ch byte típusú kifejezés. Ha nincs a csatornában karakter, akkor -1-et ad vissza. A GET grafikus képernyőn is működik, de itt nem a szín kódját adja vissza, hanem a grafikus laphoz tartozó szín-sorszámot. (Az ISDOS a 254-es csatornát rendeli a billentyűzethez.)

A Joy függvény
Hívása: Joy(nr)
Az nr számú botkormány állapotát olvassa le. A visszaadott érték a botkormány helyzetétől függ:
   1 - jobbra dől;
   2 - balra dől;
   4 - lefelé;
   8 - felfelé;
  16 - a tűzgomb benyomva.
Ha a botkormány átlósan áll vagy a tűzgomb is be van nyomva, akkor függvény az egyes értékek összegét adja. A beépített botkormány száma 0, ezenkívül az 1 (EXT1) és a 2 (EXT2) használható. A beépített botkormánynál a szóközbillentyű a tűzgomb. Pl.:

repeat
  j:=Joy(2);
  Gotoxy(10,10);Write(j:2);
until j=16

A ReadKey függvény
A függvény karaktert olvas a billentyűzetről. Ha a billentyűpuffer üres (nincs lenyomott billentyű), a függvény várakozik egy billentyű lenyomásáig. Az eljárásnak nincs paramétere, a visszaadott paraméter char típusú.

B Függelék: Grafika Enterprise-on
A Turbo Pascal kulcsszavak és eljárások nem tartalmaznak grafikus képernyőt kezelő eljárásokat. Ennek az az oka, hogy a grafikus képernyő kezelése hardware és operációs rendszer-függő, így a különböző CP/M-kompatibilis gépekre nem lehet egységes grafikus eljárásgyűjteményt készíteni. Enterprise-ra több ilyen rutingyűjtemény létezik, most az egyszerűen használható és kis méretű GRAFCS.TPU include-file-ban lévő eljárásokat ismertetjük.
Általános szabály, hogy azon programokat, melyekben használunk ilyen rutinokat csak úgy tudjuk futtatni, ha futtatható állományba fordítjuk ezeket! A program elején természetesen csatolni kell a fordítandó programhoz a rutingyűjteményt, esetünkben ezt a

{$I grafcs.tpu}

sorral tehetjük meg. A rutingyűjtemény a következő eljárásokat tartalmazza:

A GRAF_ON eljárás
Hívása: GRAF_ON(ch,vidmode,vidcolor,xsize,ysize)
Megnyitja ch csatornán a vidmode videó módú, vidcolor színüzemmódú, xsize és ysize méretű videólapot.

A GRAF_OFF eljárás
Hívása: GRAF_OFF(ch)
Lezára a korábban megnyitott ch csatornaszámú videólapot. A program befejezése előtt zárjuk le a megnyitott videólapokat!

A DISPLAY eljárás
Hívása: DISPLAY(ch,at,from,to)
Megjeleníti a már megnyitott ch csatornaszámú videólapot a képernyő at sorától kezdve. A videólap a from-adik sorától to számú sort jelenít meg.

A PRINT eljárás
Hívása: PRINT(ch,str)
A ch csatornára kiírja str szövegfüzért a kurzor pillanatnyi pozíciójától kezdve. Írhatunk akár grafikus, akár szöveges videólapra is. Ha szöveges lapra írunk, számolnunk kell azzal, hogy nem használhatjuk az EDITOR eszközkezelő szolgáltatásait! (Nincs sor végi szóátvitel, és a sorok végén nekünk kell gondoskodni a kocsivissza, soremelés karakterek kiírásáról. A WRITE, WRITELN, READ, READLN eljárások természetesen nem működnek ezeken a videólapokon.).
Példa:

Print(102,'Enterprise 128'+chr(10)+chr(13))

A GOXY eljárás
Hívása: GOXY(ch,x,y)
A ch csatornaszámú videólapon a szövegkurzort az x. sor y. oszlopába állítja. A grafikus sugármutató pozíciója változatlan marad. x és y integer típusú érték.

A CLEAR eljárás
Hívása: CLEAR(ch)
Törli a ch csatornaszámú videólap tartalmát.

A PLOT eljárás
Hívása: PLOT(ch,x,y)
A ch csatornaszámú grafikus videólap x,y pozíciójába mozgatja a rajzolósugarat. Ha a rajzolósugarat bekapcsolt állapotban hagyjuk, vonalat húzunk az előző rajzolósugár pozícióból. x és y integer típusú érték.

A PLOTREL eljárás
Hívása: PLOTREL(ch,x,y)
A ch csatornaszámú grafikus videólapon az aktuális pozícióból az x és y távolságba mozgatja a rajzolósugarat. Azaz x és y relatív koordináták, így negatív értéket is felvehetnek. Ha a rajzolósugarat bekapcsolt állapotban hagyjuk, vonalat húzunk az előző rajzolósugár pozícióból. x és y integer típusú érték.

A BEAM eljárás
Hívása: BEAM(ch,sw)
A rajzolósugarat kapcsolja ki-be ch csatornaszámú videólapon. Ha sw=0 a rajzolósugarat kikapcsoljuk, a sw nagyobb mint nulla, bekapcsoljuk. sw integer típusú érték.

A MOVETO eljárás
Hívása: MOVETO(ch,x,y)
A rajzolósugarat az x,y pozícióba mozgatja, anélkül, hogy vonalat húzna. x és y integer típusú érték.

A MOVEREL eljárás
Hívása: MOVEREL(ch,x,y)
Az aktuális rajzolósugár-pozíció áthelyezése relatív koordinátákkal megadott pontba: A ch csatornaszámú grafikus videólapon az aktuális pozícióból az x és y távolságba mozgatja a rajzolósugarat, anélkül, hogy vonalat húzna. x és y integer típusú érték.

A DRAW eljárás
Hívása: DRAW(ch,x1,y1,x2,y2)
Vonalat húz x1,y1 és x2,y2 koordinátájú pontok között, a ch csatornaszámú videólapon. x1, y1 és x2,y2 integer típusú értékek.

A BOX eljárás
Hívása: BOX(ch,x1,y1,x2,y2)
Négyszöget rajzol a ch csatornaszámú videólapon. A négyszög két átellenes sarka az x1,y1 és x2,y2 koordinátájú pont. x1, y1 és x2,y2 integer típusú értékek.

Az ELLIPSE eljárás
Hívása: ELLIPSE(ch,x,y)
Ellipszist rajzol a ch csatornaszámú videólapon, melynek középpontja az aktuális rajzolósugár-pozíció. x az ellipszis vízszintes sugara, y a függőleges sugara, Ha x és y egyenlő, kört kapunk. Ha nem akarjuk, hogy az ellipszis közepén levő pont is megjelenjen a képernyőn, akkor a középpont kijelölése előtt kapcsoljuk ki a rajzolósugarat. x és y integer típusú érték.

A PALETTE eljárás
Hívása: PALETTE(ch,c0,c1,c2,c3,c4,c5,c6,c7)
A ch csatornaszámú videólapra beállítja a színpalettát. 2 és 4 színes üzemmódban és meg kell adni c0-c7 értékeket is, melyek integer típusúak.

Az INK eljárás
Hívása: INK(ch,color)
A tinta színét állítja be a ch csatornaszámú videólapon a színpaletta color sorszámú színére. A color integer típusú érték.

A PAPER eljárás
Hívása: PAPER(ch,color)
A papír színét állítja be a ch csatornaszámú videólapon a színpaletta color sorszámú színére. A color integer típusú érték.

A LINESTYLE eljárás
Hívása: LINESTYLE(ch,mode)
Szaggatott vonalak rajzolását teszi lehetővé a mode paraméter (1-14) értékélől függően a ch csatornaszámú videólapon. A mode integer típusú érték.

A LINEMODE eljárás
Hívása: LINEMODE(ch,mode)
A régi és az új képernyősorok színeinek egymásra hatását adja meg a ch csatornaszámú videólapon. A mode integer típusú érték. Nullás módban (alapértelmezés) az új sorok színei felülírják a régieket, a többi módban viszont a kettő kombinációja alakul ki a következők szerint:
mód 1 - vagy (OR)
mód 2 - és (AND)
mód 3 - kizáró vagy (XOR).

A FILL eljárás
Hívása: FILL(ch)
Zárt alakzat kitöltése az aktuális tintaszínnel, a ch csatornaszámú videólap aktuális sugárpozíciójából kiindulva.

A ch (csatornaszám) minden esetben byte típusú. A rutinok nem végeznek hibaellenőrzést. Ha pl. az újonnan megnyitandó videólapnak már nincs elég memória, vagy nem megnyitott csatornára hivatkozunk, a program nem áll le, hibajelzést nem kapunk, de a művelet sikertelen maradt. Erre teszteléskor legyünk figyelemmel!
Példaprogramok a Felhasználói Kézikönyv bemutató programjai alapján:

Program Ellipse;
{$I grafcs.tpu}
var sugar:integer;
begin
  Randomize;
  Graf_ON(101,1,1,40,20);
  Display(101,1,1,20);
  Plot(101,640,360);
  repeat
    for sugar:=16 downto 1 do begin
      Ink(101,random(3)+1);
      Ellipse(101,sugar*16,sugar*16);Fill(101)
    end;
  until KeyPressed;
  Graf_OFF(101)
end.

Program Csatorna;
{$I grafcs.tpu}
const x:integer=640;y:integer=360;
var a,a1,c,c1:integer;
    r:byte;
Procedure Tuzlabda(szin,x1,y1:integer);
var jel:byte;
    sugar:integer;
begin
  Linemode(101,3);
  Ink(101,szin);Beam(101,1);
  for jel:=1 to 2 do
    for sugar:=1 to 21 do begin
      Plot(101,x1,y1);Ellipse(101,sugar*30,sugar*30)
    end;
  Linemode(101,0)
end;
begin
  Graf_ON(101,1,3,40,20);
  Display(101,1,1,20);
  for r:=1 to 255 do begin
    Ink(101,r);
    a:=x-r-220;a1:=y-r-50;
    c:=x+r+220;c1:=y+r+50;
    Box(101,a,a1,c,c1)
  end;
  MoveTo(101,x,y);
  repeat
    Tuzlabda(random(254)+1,x,y);
  until KeyPressed;
  Graf_OFF(101)
end.

A TURTLE.TPU bővítmény a Logo-ból (és IS-BASIC-ből) ismert teknőcgrafikus utasításokat tartalmazza. A bővítmény használja a GRAFCS.TPU eljárásait, ezért azt is be kell illesztenünk a lefordítandó programba, még a TURTLE.TPU előtt. A bővítmény használja az integer típusú ANGLE változót, amely azt tartalmazza, hogy a rajzolósugár merre nézzen, szögekben kifejezve. A 0 fok a képernyő jobb széle felé, a 90 fok felfelé, a 180 fok balra és a 270 fok lefelé mutat. A bővítmény eljárásai:

A FORWD eljárás
Hívása: FORWD(ch,d)
A ch csatornaszámú videólapon a rajzolósugár d pozíciót halad előre (amerre az ANGLE változó "mutat"). A d integer, a ch itt és a továbbiakban is byte típusú érték.

A BACK eljárás
Hívása: BACK(ch,d)
A ch csatornaszámú videólapon a rajzolósugár d pozíciót halad hátrafelé (ellenkező irányba, mint amerre az ANGLE változó "mutat"). A d integer típusú érték.

A RIGHT eljárás
Hívása: BACK(a)
A rajzolósugár a fokkal jobbra fordul. a integer típusú érték.

A LEFT eljárás
Hívása: LEFT(a)
A rajzolósugár a fokkal balra fordul. a integer típusú érték. A LEFT és RIGHT utasítás az adott szög többszörösét is elfogadja és értelmezi (pl. 10 fok helyett 370 fokot).

A DEG függvény
Hívása: DEG(a)
Megadja az a radián szög értékét fokban.

A RAD függvény
Hívása: RAD(a)
Megadja az a fok értékét radiánban.

Példaprogram:

Program FractalTree;
{$A-}
{$I grafcs.tpu}
{$I turtle.tpu}
Procedure Tree(n:integer);
begin
  if n>24 then begin
    Forwd(1,n);Right(25);
    Tree(Trunc(n*0.75));
    Left(50);
    Tree(Trunc(n*0.75));
    Right(25);Back(1,n)
  end
end;
begin
  Graf_ON(1,1,0,40,20);
  Palette(1,0,170,0,0,0,0,0,0);
  Display(1,1,1,20);
  Plot(1,640,10);Beam(1,1);
  angle:=90;
  Tree(200);
  repeat until KeyPressed;
  Graf_OFF(1)
end.

C. Függelék: Hibakódok

Fordítás alatti hibák

1 Hiányzó ';'
2 Hiányzó ':'
3 Hiányzó ','
4 Hiányzó '('
5 Hiányzó ')'
6 Hiányzó '='
7 Hiányzó ':='
8 Hiányzó'['
9 Hiányzó ']'
10 Hiányzó'.'
11 Hiányzó'..'
12 Hiányzó 'BEGIN'
13 Hiányzó 'DO'
14 Hiányzó 'END'
15 Hiányzó 'OF'
17 Hiányzó 'THEN'
18 Hiányzó 'TO' vagy 'DOWNTO'
20 Hiányzó boolean típusú kifejezés
21 Hiányzó fájlváltozó
22 Hiányzó egész típusú konstans
23 Hiányzó egész típusú kifejezés
24 Hiányzó egész típusú változó
25 Hiányzó egész vagy valós típusú konstans
26 Hiányzó egész vagy valós típusú kifejezés
27 Hiányzó egész vagy valós típusú változó
28 Hiányzó mutató típusú változó
29 Hiányzó rekord típusú változó
30 Hiányzó elemi típus
31 Hiányzó elemi kifejezés
32 Hiányzó karakterlánc típusú konstans
33 Hiányzó karakterlánc típusú kifejezés
34 Hiányzó karakterlánc típusú változó
35 Hiányzó szövegfájl-azonosító
36 Hiányzó típusazonosító
37 Hiányzó elemtípus nélküli fájlazonosító
40 Definiálatlan címke
41 Ismeretlen azonosító vagy szintaxishiba

42 Ismeretlen mutatótípus
43 Újradefiniált címke vagy azonosító
44 Hibás típus
45 Intervallumon kívüli konstansérték
46 Hibás konstanstípus vagy CASE-kiválasztó
47 Hibás argumentum vagy operátor
48 Hibás eredménytípus
49 Hibás karakterlánc-hossz
50 Hibás a karakterlánc-konstans mérete
51 Hibás az intervallumtípus alaptípusa
52 A felső határ kisebb az alsónál
53 Fenntartott szó
54 Hibás értékadás
55 A karakterlánc-konstans egy sornál hosszabb
56 Hibás egész típusú konstans
57 Hibás valós típusú konstans
58 Hibás karakter az azonosítóban
60 Konstans itt nem használható
61 Fájl és mutató típusú változók itt nem használhatók
62 Strukturált változók itt nem használhatók
63 Szövegfájlok itt nem használhatók
64 Szövegfájlok és elemtípus nélküli fájlok itt nem használhatók
65 Elemtípus nélküli fájlok itt nem használhatók
66 Bemeneti, ill. kimeneti műveletek itt nem használhatók
67 A fájlváltozók igénylik a VAR deklarációt
68 A fájlok nem lehetnek fájlelemek
69 Hibás mező-hozzárendelés
70 Túl nagy halmaz
71 Hibás GOTO
72 Az aktuális blokkon kívüli címke
73 Definiálatlan FORWARD eljárás
74 Hibás INLINE utasítás
75 Hibás az ABSOLUTE használata
90 Ismeretlen fájlváltozó
91 Váratlan programvég
97 Túl sok egymásba ágyazott WITH
98 Memóriatúlcsordulás
99 A fordítóprogram túlcsordult

Futásidejű hibák
Egy program végrehajtásakor kétféle hiba fordulhat elő: fatális és beviteli, ill. kiviteli hiba. Fatális hiba esetén a következő felirat íródik ki:
Run-time error NN, PC=addr
Program aborted

ahol NN a hiba kódja, az addr pedig a hibát előidéző utasítás memóriacíme.

Beviteli, ill. kiviteli hiba esetén az üzenet alakja:
I/O error NN, PC=addr
Program aborted

ahol NN és addr jelentése azonos az előbbivel.

Fatális hibák
01 - Fixpontos túlcsordulás
02 - Nullával való osztás
03 - Hibás az Sqrt argumentuma (negatív)
04 - Hibás az Ln függvény argumentuma (negatyv vagy nulla)
10 - 255 karakternél hosszabb karakterlánc létrehozása, ill. 1 karakternél hosszabb karakterlánc char típusú adattá konvertálása
11 - a Copy, Delete vany Insert eljárásokban megadott indexkifejezés értéke nem esik 1 és 255 közé
90 - Hibás tömbindex
91 - Hibás értékadás: az adat értéke a megengedett intervallumon kívülre esik
92 - A Trunc vagy a Round függvény argumentuma a megengedett intervallumon kívülre esik
FF - New vagy rekurzív eljárást híva nincs elég szabad memória.

Beviteli, illetve kiviteli hibák
01 - A fájl nem létezik
02 - A fájl nincs nyitva olvasásra
03 - A fájl nincs nyitva írásra
04 - A fájl nincs nyitva
10 - Számábrázolási hiba
20 - Tiltott művelet
21 - Tiltott művelet
22 - Az Assign eljárás használata nem megengedett
90 - Összeférhetetlenség a rekordméreteknél
91 - Fájlon kívüli hozzáférés kísérlete
99 - Váratlan fájlvég
F0 - A mágneslemez írási hibája
F1 - Katalógustúlcsordulás
F2 - Fájltúlcsordulás
F3 - Túl sok fájl van már nyitva
FF - Hiányzó fájl

D. Függelék: Képernyős szövegszerkesztő

Alapfogalmak
A WordStar képernyős szövegszerkesztőt a MikroPro cég terjesztette el a mikroszámítógépes piacon, 1977-től kezdve. A program fő előnye (és elterjedésének oka) a valódi "full screen" (teljes képernyős) szerkesztési elv, és a program gépfüggetlen installálásának lehetősége. Számos szövegszerkesztő vetélytárs megjelenése után a WordStar megőrizte vezető pozícióját, és néhány "mutációja" a 8 és 16 bites számítógépeken is használható. A következőkben a Turbo Pascal rendszerbeli implementációját mutatjuk be.
Több más szövegszerkesztőtől eltérően a WordStar program főleg a szövegbevitelt támogatja, és kevésbé alkalmas a szövegfeldolgozó parancsok végrehajtására. Ennek következményeként a szövegen végrehajtandó műveletek olyan karakterekkel végezhetők, amelyek láthatóan közvetlenül nem ábrázolhatók. E karaktereket vezérlőkaraktereknek nevezzük; bevitelükhöz a CTRL billentyűt egy vagy két betűjeles billentyűvel együtt kell lenyomni. Mivel a továbbiakban gyakran hivatkozunk a vezérlőkarakterekre, jelképes jelölésükben a ^ jel a CTRL billentyű lenyomását jelenti. Így pl. a CTRL A vezérlőkarakter jelölése ^A, bevitele pedig a CTRL billentyű lenyomott állapotában leütött A billentyűvel lehetséges. Azokban az esetekben, amikor a szövegszerkesztőnek kiadandó parancs két vezérlőkarakterből áll (pl. ^KB), lenyomjuk a CTRL billentyűt, és ezután ütjük le a K és a B billentyűt (a második billentyű leütésekor már nem kell lenyomva tartani a CTRL billentyűt).
A szövegszerkesztő szokásos használata a főmenüből kiadott E paranccsal kezdődik. Ennek hatására elindul a szövegszerkesztő program, amely "kiteríti" a képernyőre az előzőleg W paranccsal azonosított munkaállomány tartalmát (kezdőrészét). A szövegbevitel vagy -módosítás befejeztével a ^KD paranccsal visszatérhetünk a főmenühöz, ahonnan kiadhatjuk az S parancsot, amely mágneslemezre menti ki a munkaállományt.
A szövegszerkesztő program indítása után a számítógép többfunkciós írógépként használható. Az írógép alapvető tulajdonsága, hogy minden bevitt karakter azonnal megjelenik a képernyőn. A hibásan bevitt karaktereket a Backspace billentyűvel törölhetjük. Ha a javítandó hibák a már korábban bevitt szavakban találhatók, akkor a kurzormozgató billentyűkkel a kurzort elvihetjük a javítás helyére, és a módosítást azonnal végre is hajthatjuk. A módosítás szabályait a következő szakasz tartalmazza.

Szövegbevitel, -módosítás és -törlés
Az alábbiakban az alapértelmezés szerinti billentyűzetkiosztást ismerhetjük meg, ezután az ENTERPRISE-on beállított kiosztást.
Mint már említettük, a szövegszerkesztő program indítása után szöveget gépelünk be vagy módosítunk. E tevékenységek lényegében új szavak bevitelét vagy a már bevitt szavakon végzett műveleteket jelentik. Itt a szó fogalmán tetszőleges karaktersorozatot értünk, amelyet egy szóköz vagy más elválasztó-karakter (pl. vessző, pont, kettőspont, aposztróf) zár le. E definíció értelmében példaprogramunk

program JanB;
begin
   Write('I am JanB')
end.

a következő szavakból áll:

program
JanB;
Begin
Write('
I
Am
JanB'
)
end.

A képernyőn megjelenített szövegrészen belül kitüntetett a kurzor feletti karakter szerepe. A szövegmanipulációk mindig e karakterre (vagy az őt tartalmazó szóra, ill. sorra) vonatkoznak. A kurzort karakterenként, szavanként, soronként és laponként mozgathatjuk (a lap több sorból álló szövegrész, mérete egyenlő a képernyő kapacitásával).
A kurzort egy pozícióval balra, jobbra, felfelé vagy lefelé a ^S, ^D, ^E és ^X parancsokkal mozgathatjuk. E parancsok betűjeles billentyűi négyzetet alkotnak. Így könnyű megjegyezni, hogy az ^E parancs egy pozícióval felfelé, a ^X egy pozícióval lefelé, az ^S és a ^D egy pozícióval balra, ill. jobbra mozgatja a kurzort. Látható, hogy a kurzormozgató parancsok ilyen hozzárendelése nem az egyes betűkhöz kapcsolódik, hanem a négy billentyű síkbeli elrendezésén alapul.
A szavankénti kurzormozgatást az ^A és az ^F parancs valósítja meg. Az ^A parancs egy szópozícióval balra (az előző szóra), az ^F pedig egy szópozícióval jobbra (a következő szóra) állítja a kurzort.
Laponkénti kurzormozgatásra (előre- és hátralapozásra) az ^R és a ^C parancs való. Billentyűik az E-X billentyűk által kijelölt tengely jobb oldalán helyezkednek el. E tengely bal oldalán viszont azok a billentyűk kaptak helyet, amelyek a képernyő tartalmát egy sorral lefelé (^W) vagy felfelé (^Z) mozgatják.
Ez az elrendezés könnyen megtanulható, ezért nincs szükség külön billentyűfeliratokra vagy magyarázó táblázatra. A fenti billentyűk jobb oldalán három újabb parancsbillentyűt találunk: ^T, ^Y, ^G. A ^G parancs a kurzor feletti karaktert törli, a ^T parancs a kurzor feletti és a tőle jobbra álló karaktereket a szó végéig, a ^Y parancs pedig az egész sort. Végül megemlítjük a Backspace billentyűt, amely a kurzortól balra eső karaktert törli.

Összefoglalás

^E A kurzor mozgatása egy sorral felfelé; az oszloppozíció nem változik.
^X A kurzor mozgatása egy sorral lefelé; az oszloppozíció nem változik.
^S A kurzor mozgatása egy pozícióval balra; ha a kurzor a sor elején áll (bal szélső pozíció), akkor a parancs hatástalan.
^D A kurzor mozgatása egy pozícióval jobbra; ha a kurzor a sor végén áll (jobb szélső pozíció), akkor a parancs hatástalan.
^A A kurzor mozgatása az előző szó elejére.
^F A kurzor mozgatása a következő szó elejére.
^R Lapozás felfelé.
^C Lapozás lefelé.
^W A képernyőtartalom mozgatása egy sorral lefelé ("roll down").
^Z A képernyőtartalom mozgatása egy sorral felfelé ("roll up").
^G Karaktertörlés.
^T Karaktertörlés a szó végéig.
^Y Sortörlés.
^N Sorbeszúrás
Backspace A kurzortól balra eső karakter törlése.

Ezeket a parancsokat egészíti ki az ^N parancs, amely egy üres sort hoz létre, és az előbbi kurzormozgató billentyűkhöz hasonló hatású, de nagyobb "lépéssel" értelmezendő parancsok: a ^Q vezérlőkarakter után leütött E, R, S, D, X, C billentyűk valamelyike. A ^QE parancs a kurzort a képernyő első sorába viszi, a ^QX parancs az utolsó sorba, a ^QS a sor elejére, a ^QD pedig a sor végére. A ^QR és a ^QC parancs a szöveg elejére, ill. végére viszi a kurzort.
Az itt felsorolt kurzormozgató parancsok lehetővé teszik a szöveghelyesség ellenőrzését és a szöveg módosítását. Módosításkor előfordulhat a már begépelt szöveg kiegészítése vagy a szöveg helyettesítése más karaktersorozatokkal.
Kiegészítéskor (beszúrás, ínsert) elegendő begépelni az új szöveget; a szövegszerkesztő program automatikusan beszúrja (a kurzor pillanatnyi pozíciójától kezdve) úgy, hogy az utána álló karaktereket jobbra tolja.
Módosításkor (felülírás, overwrite) a ^V paranccsal kikapcsolhatjuk ezt a szolgáltatást, így a begépelt karakterek felülírják a régieket. A ^V parancs újbóli kiadása visszaállítja a beszúrás üzemmódot.

Összetett szövegműveletek
Az eddig leírt parancsok nemcsak szöveges állományok létrehozására alkalmasak, hanem a szövegfeldolgozást is lehetővé teszik. Mégis gyakran szükség van olyan műveletekre, amelyek a szöveg egy részét egyszerre kezelik (pl. szövegmásolás vagy -áthelyezés), vagy pedig képesek mintakeresésre és szöveghelyettesítésre. Erre használhatjuk a következő parancsokat.

A ^QF parancs
Először a képernyőn megjelenő
FIND:
kérdésre adjuk meg a keresendő mondatot (mintát). A mondat tetszőleges karaktersorozat, melyet az Enter billentyű zár le. A következő
OPTIONS:
kérdésre adott válasz meghatározza a keresés módját. A leggyakoribb esetben (keresés a kurzor pozíciójától a szöveg végéig) elegendő az ENTER billentyű leütése. Ha a keresett mondat szerepel a szövegben, akkor a kurzor megáll a megtalált mondat utolsó karaktere mögött. Más keresési opciók pl. a következők:
B - visszafelé keres;
W - csak teljes szavakat keres;
U - a kis- és nagybetűket azonosnak tekinti.
Ha egy a számot adunk meg opcióként, akkor a program a megadott mondat n-edik előfordulását keresi meg.

A ^QA parancs
A ^QA parancs a ^QF bővítése: a keresendő (helyettesítendő) mondat megadása után megjelenik a
REPLACE WITH:
kérdés, amelyre válaszként írjuk be a helyettesítő mondatot. A keresés, ill. helyettesítés módját meghatározó opció lehet még:
G - a művelet az egész szövegállományra vonatkozik, a kurzorpozíció közömbös;
N - feltétel nélkül keres és helyettesít.
Ha az N opciót adtuk meg, akkor minden megtalált mondat helyére a helyettesítő mondat kerül. Ha nem adtuk meg az N opciót, akkor a program minden megtalált mondatnál megkérdezi, hogy kérjük-e a helyettesítést. Az Y billentyű leütése jelenti az igenlő választ; minden más billentyű hatására folytatódik a keresés. A keresési, ill. helyettesítési folyamat az ^U paranccsal bármikor megszakítható.

A ^KB parancs
A ^KB parancs egy blokk kezdetének jelöli ki a pillanatnyi kurzorpozíciót; a teljes szövegblokk meghatározásához szükség van még a ^KK blokkzáró parancsra.

A ^KK parancs
A ^KK parancs egy blokk végének jelöli ki a pillanatnyi kurzorpozícióit. A blokk kijelölésének (a ^KB és a ^KK parancsokkal) pillanatában a blokk összes karaktere inverz ábrázolásban vagy kisebb fényerővel jelenik meg. A következő ^Kx parancsok az így kijelölt szövegrészre vonatkoznak.

A ^KC parancs
A ^KC parancs a ^KB és a ^KK paranccsal kijelölt blokkot átmásolja a pillanatnyi kurzorpozícióba. E művelet után a kurzor az átmásolt blokk első karakterére áll; a blokkmásolat kijelölése érvényben marad.

A ^KV parancs
A ^KV parancs a ^KB és a ^KK paranccsal kijelölt blokkot áthelyezi a pillanatnyi kurzorpozícióba. E művelet után a kurzor az áthelyezett blokk első karakterére áll; a blokk kijelölése érvényben marad.

A ^KY parancs
A ^KY parancs törli a ^KB és a ^KK paranccsal kijelölt blokkot. Megjegyzés: a ^KB, ^KK, ^KY parancssorozat egyetlen hatása a blokk-kijelölés megszüntetése (I. még ^KH parancsot).

A ^KR parancs
A ^KR parancs a mágneslemezes állományban található szöveget beszúrja a pillanatnyi kurzorpozícióba. A feltett
Read block from file:
kérdésre válaszként a beillesztendő szövegállomány nevét kell megadni.

A ^KW parancs
A ^KW parancs mágneslemezes állományba menti ki a ^KB és a ^KK paranccsal kijelölt blokkot. A feltett
Write block to file:
kérdésre válaszként annak a létrehozandó szövegállománynak a nevét kell megadni, amelybe a kijelölt blokk kerül. Ha ilyen nevű állomány már létezik, akkor a kimentés előtt törlődik és újból létrejön.

A ^KH parancs
A ^KH parancs megszünteti a ^KB és a ^KK parancs hatását (érvényteleníti a blokk kijelölését).

Segédparancsok

Az ^N parancs
Az ^N parancs a kurzor pillanatnyi pozíciójába beszúrja a CR/LF karakterpárt, azaz új sort hoz létre.

Az ^I parancs
Az ^I parancs a legközelebbi tabulátorpozícióba viszi a kurzort; a tabulátorpozíciókat itt a kurzor feletti sor szavainak kezdőkarakterei jelentik.

Az ^L parancs
Az ^L parancs megismétli az utolsó ^QF parancsot.

Az ^U parancs
Az ^U parancs bármelyik parancs végrehajtását megszakítja.

A ^P parancs
A ^P parancs hatására az utána közvetlenül leütött vezérlőkarakter kódja bekerül a szövegbe. Így pl. a ^P ^M ^P ^J karaktersorozat a sorokat lezáró CR/LF karakterpárokat jelenti.

Összefoglaló az ENTERPRISE beállításhoz:

JOY fel A kurzor mozgatása egy sorral felfelé; az oszloppozíció nem változik.
JOY le A kurzor mozgatása egy sorral lefelé; az oszloppozíció nem változik.
JOY balra A kurzor mozgatása egy pozícióval balra; ha a kurzor a sor elején áll (bal szélső pozíció), akkor a parancs hatástalan.
JOY jobbra A kurzor mozgatása egy pozícióval jobbra; ha a kurzor a sor végén áll (jobb szélső pozíció), akkor a parancs hatástalan.
^W, balra A kurzor mozgatása az előző szó elejére.
^W, jobbra A kurzor mozgatása a következő szó elejére.
^S, fel Lapozás felfelé.
^S, le Lapozás lefelé.
^P, le A képernyőtartalom mozgatása egy sorral lefelé ("roll down").
^P, fel A képernyőtartalom mozgatása egy sorral felfelé ("roll up").
^L, jobbra A kurzor mozgatása a sor végére.
^L, balra A kurzor mozgatása a sor elejére.
^P, fel A képernyőtartalom lapozása egy oldallal felfelé.
^P, le A képernyőtartalom lapozása egy oldallal lefelé.
^F, fel Ugrás a dokumentum első sorába.
^F, le Ugrás a dokumentum utolsó sorába.
^B, fel Ugrás a kijelölt blokk elejére.
^B, le Ugrás a kijelölt blokk végére.
^C Ugrás az előző művelet kurzorpozíciójába.
^G Karaktertörlés. (A jobbra álló karakterek balra lépnek.)
^U Karaktertörlés. (Ugyanaz, mint az előző.)
^T Karaktertörlés a szó végéig.
^Y Sortörlés.
^N Sorbeszúrás
^D, L Törlés a sor végéig.
^D, ^\ Törli a jobbra álló szót.
TAB Ugrás a következő tabulátor-pozícióba (ua., mint a ^I)
ERASE A kurzortól balra eső karakter törlése.
INS Beszúrás üzemmód váltása.
ESC Kilépés a szerkesztőből.

Összetett szövegműveletek (ENTERPRISE-on):

^K, B Blokk elejének kijelölése.
^K, E Blokk végének kijelölése.
^K, S A szó kijelölése, amelyen a kurzor áll.
^K, H A kijelölés megszüntetése.
^K, C A kijelölt blokk átmásolása az aktuális kurzorpozícióba.
^K, M A kijelölt blokk átmozgatása az aktuális kurzorpozícióba.
^K, D A kijelölt blokk törlése.
^K, W A kijelölt blokkot mágneslemezre menti.
^K, R A mágneslemezre mentett blokkot beilleszti az aktuális kurzorpozíciótól.
^F, F String keresése.
^F, R String keresése és cseréje.
^F, L A keresés folytatása.
^P Vezérlőkarakter beszúrása a szövegbe.

E. Függelék: A fordító direktívák

A fordító direktívák a fordítóprogramnak adott utasítások, amelyekkel a keletkező lefordított program néhány tulajdonságát megváltoztathatjuk. Szintaxisuk pl: {$I+} ill.: {$I NEV.KIT}, ahol a '$' után és előtt nem állhat space. '$' jelzi, hogy fordító direktíva következik; ezt követi annak neve. A kapcsoló direktívák neve után csak '+', vagy állhat. '+' a direktíva aktív, bekapcsolt, a '-' passzív állapotát jelzi. A pataméteres direktívák neve után paraméter, pl. egy filenév áll. A direktívákat összevonva is felsorolhatjuk, pl. {$A-,K-,R-}. A következőkben felsoroljuk a 3.x verzióig érvényes fordító direktívákat.

A direktíva: abszolút kód
Csak 8 bites implementációban használhatjuk. Alapértelmezés: aktív. Aktív állapotban abszolút kód lesz generálva, passzív állapotban a lefordított program megenged rekurzív hívásokat. Ez utóbbi több memóriát és valamivel lassúbb végrehajtási időt is jelent.

B direktíva: logikai eszköz kiválasztása
A direktíva az alapértelmezett input-output eszköz kiválasztását végzi. Alapértelmezése: aktív. Ha aktív, akkor a standard input-output file-okhoz a CON: logikai eszköz van hozzárendelve; ha passzív, akkor a TRM: eszköz. A direktíva globális, értéke az egész programban csak egyszer állítható be.
A különbség az, hogy a CON: logikai eszköz pufferelt bemenetet ad, azaz a beírt információt szerkeszthetjük, törölhetjük mindaddig, amíg az ENTER billentyűvel le nem zártuk; a TRM: logikai eszköz viszont a leütött billentyű kódját azonnal továbbítja a programnak.

C direktíva: ^C és ^S karakterek értelmezése
A direktíva a ^C és ^S karakterek értelmezését végzi. Alapértelmezés: aktív. Ha aktív, akkor a Ctrl-C (^C) billentyűkkel a program futását megszakíthatjuk a Read illetve a Readln eljárások végrehajtása közben, ^S-sel pedig megállíthatjuk és újra bekapcsolhatjuk a képernyőre vonatkozó kiíratást. A direktíva passzív állapota mellett mindez hatástalan. A direktíva globális, értéke csak egyszer állítható be. Az aktív állapot lassítja a képernyőre való írás sebességét.

I direktíva: I/O hibakezelés, beszúrt file-ok
A direktíva kettős funkciót tölt be. Egyrészt az input-output hibakezelést, másrészt a beszúrt file-okat vezérli.
Ha a direktívát az input-output ellenőrzésre használjuk, akkor alapértelmezése: {$I+}. Ez azt jelenti, hogy egy hibás I/O művelet esetén a program futása I/O hibával megszakad, s visszakerül a vezérlés az operációs rendszerhez. A passzív állapot esetén az input-output hibát a programozónak kell lekezelnie, az IoResult standard függvény használatával (lásd a függvény leírását).
Ha a direktívát az include file-ok alkalmazására használjuk, a szintaxis a következő: {$I filenév.kit}. Tehát a beszúrandó file nevét írjuk a direktíva jele után.

K direktíva: stack ellenőrzése
Alapértelmezése: aktív. Ha a direktíva aktív, akkor a rendszer minden egyes alprogram hívása előtt ellenőrzi, hogy van-e elegendő hely a stack-ben az alprogram lokális változói számára. Ha nincs, akkor a program futási hibával leáll. Ha a direktíva passzív, akkor ez az ellenőrzés nem történik meg. Csak teljesen 'belőtt' programok esetén kapcsoljuk ki ezt a direktívát. Szintaxis: {$K+}.

R direktíva: érvényességi tartomány ellenőrzése
Ez a direktíva lehetővé teszi az indexek érvényességi tartományának, valamint a skaláris és résztartomány típusok értelmezési tartományának ellenőrzését. Alapértelmezése: passzív. Aktív állapotban a direktíva futás közben ellenőrzi az index-túlcsordulást; ha ilyen hibát talál, a program futási hibával megáll. Aktív állapotban a generált kód nagyobb, a program futása lassabb, mivel az ellenőrzés időt vesz igénybe. A program tesztelésekor azonban célszerű ezt az ellenőrzést igénybe venni. A már belőtt programnál viszont a futás gyorsítására célszerű a direktívát kikapcsolni.

U direktíva: felhasználói megszakítás
Ez a direktíva vezérli a program futásának felhasználói megszakítását. Aktív állapotban a program bárhol megszakítható a felhasználó által Ctrl-C billentyűvel. Ha a direktíva passzív, a billentyű leütése hatástalan. Alapértelmezés: passzív. Enterprise-on sajnos nem lehet bekapcsolni.

V direktíva: paraméterek típusellenőrzése
Ez a direktíva vezérli a string típusú változó-paraméterek típusellenőrzését. Alapértelmezés: {$V+}; ekkor az alprogramok hívásakor a formális és az aktuális paraméterek típusának és hosszának meg kell egyeznie, egyébként a program futási hibával leáll. Passzív állapotban ilyen ellenőrzés nincs, azaz a fordító azt az aktuális paramétert is elfogadja, melynek hossza nem egyenlő a formális paraméterével.

W direktíva: with utasítások mélysége
Csak 8 bites implementációban, használhatjuk. Ez a direktíva vezérli a With utasítások egymásba skatulyázásának maximumát, azaz az utasítással egyszerre 'felnyitható' rekordok maximális számát. Alapértelmezés: {$W2}. A direktíva jele mellett egy 1-től 9-ig terjedő számnak kell állnia.

X direktíva: tömbök optimalizálása
Csak 8 bites implementációban használhatjuk. Ez a direktíva vezérli a tömbök optimalizálását. Ha a direktíva aktív, akkor a fordító olyan kódot generál, amely a tömbök kezelését futási idő szerint optimalizálja. Passzív állapotban pedig olyan kódot generál, mely a tömbök kezelésnél a minimális helyfoglalású, lefordított kódot veszi igénybe. Alapértelmezés: aktív. Szintaxis: {$X+}.

F. Függelék: A keretrendszer installálása

A TINST (Turbo Pascal installation menu) program lehetőséget ad a Turbo Pascal keretrendszer beállítására az általunk használt CP/M kompatibilis számítógép paramétereihez. Ez magában foglalja a képernyő felépítésének beállítását (SCREEN INSTALLATION) és az előző pontban ismertetett billentyűfunkciók beállítását (vagy megváltoztatását igényeink szerint) (COMMAND INSTALLATION).

A SCREEN INSTALLATION menüpontban kiválaszthatjuk a már definiált beállításokat, vagy ha nem találjuk itt az általunk használt platform beállításait, újat hozhatunk létre (NONE OF THE ABOVE). Az ENTERPRISE-hoz két beállítás tartozik: egy monokróm, és egy színes (ENTERPRISE (COL)). Ez utóbbi beállításban az IS-DOS által használt piros szín jelenti az alacsony fényintenzitást, a zöld a normál és a magas színintenzitású szín. A kívánt géptípushoz tartozó beállítást a hozzá tartozó szám megadásával választhatjuk ki, ezután akár meg is változtathatjuk a beállításokat (nem javasolt).

A COMMAND INSTALLATION menüpontban valamennyi billentyűfunkciót sorban átdefiniálhatjuk. Az adott billentyűparancs megnevezése mellett megjelenik a jelenlegi beállítás. Ha ezt nem kívánjuk megváltoztatni, elegendő az ENTER megnyomásával továbblépni. Ha meg kívánjuk változtatni a beállítást, a kívánt billentyűket kell sorban megnyomni, majd az ENTER megnyomásával lezárni a definíciót. Megtehetjük azt is, hogy beírjuk az adott billentyűhöz tartozó decimális vagy hexadecimális kódot (kódolat), space-el elválasztva. A hexadecimális számok elé $ jelet kell írni (pl. 27 59 vagy $1B $2A). Ha a funkcióhoz tartozó billentyűparancsot törölni akarjuk, akkor a '-' karaktert kell megadni. Ezt a program a 'Nothing' üzenettel igazolja vissza, egyébként a definiált karakter (karakterek) kódját írja ki a képernyőre.
Ha végeztünk a beállítással, a program ellenőrzi van-e ütközés (ua. azt a billentyűparancsot állítottuk be két vagy több funkciónak). Ha van, kijelzi, hányas pontok ütköznek és meg kell ismételni a beállítást.
A főmenü QUIT (Q) funkciójával léphetünk ki a programból.

G. Függelék: ASCII kódtáblázat

Dec Hex Char   Dec Hex Char   Dec Hex Char
0 00 NUL   43 2B +   86 56 V
1 01 SOH   44 2C ,   87 57 W
2 02 STX   45 2D -   88 58 X
3 03 ETX   46 2E .   89 59 Y
4 04 EOT   47 2F /   90 5A Z
5 05 ENQ   48 30 0   91 5B [
6 06 ACK   49 31 1   92 5C \
7 07 BEL   50 32 2   93 5D ]
8 08 BS   51 33 3   94 5E ^
9 09 HT   52 34 4   95 5F _
10 0A LF   53 35 5   96 60 `
11 0B VT   54 36 6   97 61 a
12 0C FF   55 37 7   98 62 b
13 0D CR   56 38 8   99 63 c
14 0E SO   57 39 9   100 64 d
15 0F SI   58 3A :   101 65 e
16 10 DLE   59 3B ;   102 66 f
17 11 DC1   60 3C <   103 67 g
18 12 DC2   61 3D =   104 68 h
19 13 DC3   62 3E >   105 69 i
20 14 DC4   63 3F ?   106 6A j
21 15 NAK   64 40 @   107 6B k
22 16 SYN   65 41 A   108 6C l
23 17 ETB   66 42 B   109 6D m
24 18 CAN   67 43 C   110 6E n
25 19 EM   68 44 D   111 6F o
26 1A SUB   69 45 E   112 70 p
27 1B ESC   70 46 F   113 71 q
28 1C FS   71 47 G   114 72 r
29 1D GS   72 48 H   115 73 s
30 1E RS   73 49 I   116 74 t
31 1F US   74 4A J   117 75 u
32 20 szóköz   75 4B K   118 76 v
33 21 !   76 4C L   119 77 w
34 22 "   77 4D M   120 78 x
35 23 £   78 4E N   121 79 y
36 24 $   79 4F O   122 7A z
37 25 %   80 50 P   123 7B {
38 26 &   81 51 Q   124 7C |
39 27 '   82 52 R   125 7D }
40 28 (   83 53 S   126 74 ~
41 29 )   84 54 T   127 7F DEL
42 2A *   85 55 U        

Vissza