TV-BASIC

Dr. Kocsis András - 1984
Számítástechnika-alkalmazási Vállalat
Lektorálta: Danis Miklós

Tartalom

Előszó
1. Bevezetés
2. A számítógép használata

     A billentyűzet
     Mágneslemez és kazetta használata
     Néhány szó az operációs rendszerről
3. A programozás módszere I.
     A feladatmegoldás módszere
     A feladatmegoldás folyamata
     1. feladat
4. A programozás módszere II.
     A feladatmegoldás folyamata
     Kódolási alapismeretek
     Az 1. feladat befejezése
5. Elágazások I.
     Elágazásos szerkezetek
     Az IF THEN szerkezet megvalósítása
     Az IF THEN ELSE szerkezet megvalósítása
     2. feladat
6. Elágazások II.
     A vezérlőmodul alkalmazása
     A 2. feladat módosítása
     A szöveges változók
     3. feladat
7. A szubrutinok alkalmazása
     4. feladat

8. Ciklikus Tevékenységek I.
     A ciklus
     A FOR, NEXT utasításpár
     Függvények
     5. feladat
9. Összetartozó adatok kezelése
     A számítógépes feladatok felosztása
     Az összetartozó adatok feldolgozása
     6. feladat
10. Ciklikus tevékenységek
     7. feladat
11. Játékok készítése
     8. feladat
12. Több programból álló szerkezetek
13. Adatállományok és létrehozásuk
14. Az adatállományok feldolgozása és módosítása
15. Grafikai lehetőségek (C64-en)

Függelék
A könyvben szereplő fontosabb fogalmak magyarázatuk
BASIC utasítások, parancsok és kulcsszavak
Gyakrabban előforduló programhibák és javításuk
Programsorok javítása
Állományműveletek C64-en
A Commodore ASCII kód karakterei

Köszöntöm
a tv-nézőket és a könyv olvasóit! Szokatlan vállalkozásba kezdett a Neumann János Számítógéptudományi Társaság, a SZÁMALK és a Magyar Televízió, tanfolyamsorozatot indít a számítástechnika népszerűsítésére és főleg tanítására. A szó nemes értelmében népoktatásra vállalkozunk, arra, hogy mindazok, akik eddig nem kerültek vagy nem kerülhettek közelebbi kapcsolatba a számítástechnikával, a televízió segítségével szerezhessék meg a legfontosabb ismereteket. Indul a Tv-BASIC, s a tanfolyam végén - először a Magyar Televízió történetében - a szorgalmas néző vizsgát tehet, és sikeres vizsga esetén bizonyítványt kap.
A tanfolyam anyagát és a könyvet Kocsis András, a SZÁMALK munkatársa állította össze, a kéziratot, majd az ebből készült forgatókönyvet az NJSZT tagjaiból, a SZÁMALK és az MTV munkatársaiból álló munkabizottság vitatta meg és fogadta el.
Nyilvánvalóan tökéleteset szerettünk volna alkotni, ám nagyon optimistának kellene lennünk, hogy hihessünk, ez sikerült is. Reméljük, hogy a tv-sorozatot és a könyvet is a néző-olvasó könnyen megérti. A feltétlenül szükséges BASIC ismeretek mellett olyasmit is bemutatunk, ami nemcsak a kezdők, de a már bizonyos ismeretekkel rendelkező szakemberek érdeklődését is felkelti.
Amit elmondunk, ahhoz feltétlenül elegendő, hogy bárki több-kevesebb sikerrel programozni tudja a munkahelyi vagy az otthoni számítógépet.
A tanfolyam elsősorban azoknak a felnőtt - ha szabad azt mondani, hogy talán nem is túl fiatal - szakembereknek szól, akiket a személyi számítógépek programozása érdekel, de eddig nem volt alkalmuk ezt a "tudományt" elsajátítani. Mindannyian tudjuk, hogy a mai egyetemisták, középiskolások, de talán az általános iskolai tanulók nagy része is "tudósa" a számítástechnikának, reméljük, azért nekik is tudunk újat mondani.
A BASIC-nek - bármennyire is szabványosított programozási nyelv - különböző típusú gépeken különböző változatai vannak forgalomban. Mi úgy gondoltuk, hogy a mikroszámítógépes klubokban, iskolákban, művelődési és ifjúsági házakban, általában mindazokon a helyeken, ahol szabadidőben számítógéppel lehet dolgozni vagy szórakozni, leginkább Commodore-64, HT-1080Z, PRIMO vagy Sinclair gépek találhatók. Ezért e könyvben az ezeken a gépeken használt BASIC utasításokat mutatjuk be. Minden új utasítást példákkal illusztrálunk. A feladatokat igyekeztünk változatosan összeállítani. Nem is egyszerű elmemunka lesz például a Commodore-mintaprogramot átírni Sinclair-gépre. Arra számítunk, hogy a tanfolyam nézői erre a "kalandra" is váltakoznak. Itt hívjuk fel figyelmüket a Mikroszámítógép Magazin 1985. évi számaira, amelyekben bőségesen szeretnénk további példákat bemutatni a tanfolyam nézőinek.
A könyvet, az adást kísérletnek szánjuk, az eredményt a vizsgák mutatják meg, illetve a nézők véleményéből szeretnénk kiszűrni. Ezért nemcsak várjuk a véleményeket, de kérjük is, hogy a tanfolyam ismétlésekor, illetve a következő tanfolyam (Számítástechnikai alapismeretek) összeállítása során a javaslatokat már figyelembe tudjuk venni.
Szeretnénk a tanfolyam anyagát később is hasznosítani, ezért azt videokazettán a tankönyvvel együtt árusítani fogjuk. Úgy véljük, hogy hasznos segédeszköze lesz a pedagógusoknak, de a vállalatok, intézmények belső tanfolyamaikhoz is jól tudják használni.
E nagy vállakózásért köszönetét mondok az MTV Ifjúsági és Oktatási Főosztály munkatársainak: Kovács Béla, Kelemen Endre, Gál Mihály, Albert József, Hegyi István elvtársaknak, az anyag kidolgozását támogató, lektorálását és megvitatását, valamint a tv-sorozat bírálatát vállaló bizottság tagjainak: Ada-Winter Péternek, Faragó Sándornak, Meskó Andornak, Pál Lászlónak, Páris Györgynek, a könyv gondozásáért felelős Pálfy Adorjánnak, a könyv gyors elkészítéséért a Dabasi Nyomda dolgozóinak és nem utolsósorban a szerzőnek, Kocsis Andrásnak.
Végül előre megköszönöm a néző-olvasó szíves közreműködését, véleményét és javaslatait, amelyeket - mint említettem - megpróbálunk a további adásokban és könyvekben minél hamarabb hasznosítani.

Kovács Győző az NSZJT főtitkára

Előszó

Manapság, amikor a személyi számítógépek robbanásszerűen terjednek hazánkban, érthető módon egyre többen szeretnék megtanulni a módját, hogyan lehet ezeket a gépeket minél jobban hasznosítani akár a gazdasági munkában, akár a magánélet különböző területein. A számítástechnika fejlődése úgy hozta, hogy valamennyi mikro- és személyi számítógép programozható BASIC nyelven. Ez természetesen nem véletlen. A BASIC nyelv a magyar származású John G. Kémény munkájának eredményeként húsz éve indult el hódító útjára. Ez az egyszerű, könnyen megtanulható és széles körben alkalmazható nyelv rendkívül népszerű lett. Éppen ezért vált a személyi számítógépek alapnyelvévé. Ennek köszönhetően a BASIC nyelv egy általános eszköz, amellyel bármely személyi számítógépet lehet használni. Megjegyezzük, hogy az egyes géptípusok BASIC-jei között kisebb-nagyobb eltérések, "tájszólások" vannak. Sorozatunkban az ún. "közös rész"-t igyekeztünk tárgyalni, amely minden gépnél azonos. Emellett elkerülhetetlen, hogy a nyelv eltérő sajátosságait is feltárjuk az egyes megoldásoknál.
A BASIC nyelv alkalmazásához a számítógép használatát is meg kell ismerni, ez viszont már kevésbé általánosítható. Ez is szükségessé teszi, hogy konkrét géptípusokon mutassuk be a nyelvet. Úgy gondoljuk, hogy a ma Magyarországon legelterjedtebb négy géptípus, a Commodore-64, a HT-1080Z, a PRIMO és a Sinclair-gépek felelnek meg a legjobban ennek a célnak. Mivel a Commodore-64 gépből van a legtöbb, könyvünkben ez az alapgép, a többi gépre vonatkozó megállapításokat megkülönböztető jelzéssel látjuk el.
A tanuláshoz segédanyagunkat szánjuk segítségül. A fejezetek a sorozat tagolódását követik: tartalmazzák az egyes részekben tárgyalni kívánt elméleti anyagot és a feladatok megoldási lépéseit. A tv-ben látható műsor csak akkor segíti a BASIC nyelv gyors megtanulását, ha a kedves Néző a műsor előtt már elolvassa az elméleti részt.
A fontosabb fogalmak magyarázatát az 1. függelék tartalmazza ábécérendben, ezenkívül a tárgymutató segíti a fogalmak keresését a könyvben. A 2. függelékben találhatók a számítógép és a nyelv használatához szükséges kulcsszavak (parancsok, függvények és utasítások, valamint rövid, tájékoztató jellegű leírásuk). Itt utalunk arra is, hogy az illető utasítást melyik oldalon tárgyaljuk. Természetesen könyvünk nem tartalmazza az összes parancs, függvény és utasítás leírását, mert erre itt nincs lehetőségünk. Ha olyan utasítást vagy függvényt kíván alkalmazni, amelyről itt nincs szó, javasoljuk, hogy a gép kézikönyvét is lapozza fel.
A 3. függelékben a gyakrabban előforduló hibákat és javításukat, valamint a négy gépre vonatkozó programjavítási lehetőségeket részletesen ismertetjük.
A Commodore-gép állománykezelési műveletei a 4. függelékben találhatók.

1. Bevezetés
Ismerkedés a számítógéppel. Az első programok elkészítése

Ez az első alkalom, hogy számítógépet használunk. Van aki tartózkodóan, van aki kíváncsian közelít a géphez. Szeretnénk megértetni, hogy nem kell előismeret vagy különleges képesség ahhoz, hogy valaki értelmesen tudja használni a számítógépet. Már az első műveletekkel megpróbáljuk ezt az állítást bizonyítani. Remélhetőleg mindenki hamarosan érezni fogja, hogy ha nem is magas fokon, de uralja a gépet. Ne keseredjen el senki, ha valamilyen fogalmat nem ért meg első hallásra. Inkább a műveletekre figyeljen, és abból próbálja megmagyarázni, hogy mi is történik. Egyébként megjegyezzük, hogy a továbbiakban minden itt felmerülő fogalmat részletesen és teljeskörűen megmagyarázunk.
Először is nézzük meg, hogy milyen eszközök szükségesek a programozáshoz! Kell egy számítógép, amely a műveleteket végzi el, továbbá egy olyan eszköz, amelynek segítségével meg tudjuk mondani a számítógépnek, hogy mit csináljon, s végül egy kijelző eszközre is szükségünk van, amelyen az eredmények megjelennek. Egy írógép-billentyűzethez hasonló berendezésen lehet jeleket beírni a számítógépbe, a kijelző eszköz pedig egy tv-készülék (1. ábra). Ez a programozáshoz nélkülözhetetlen minimális eszközkészlet.


1. ábra: A programozáshoz szükséges eszközök

Kapcsoljuk most be az eszközeinket; először a tv-t, majd a gépet. Kisvártatva megjelenik egy üzenet a tv-n, amely mutatja, hogy dolgozhatunk. Az üzenet utolsó szava a
READY

(nyomjuk le a NEW LINE gombot és akkor a képernyő alján jelenik meg a READY üzenet)

jelenik meg.
A kiírás alatti sor elején az ún. helyőr (pozíciómutató, kurzor; angolul cursor) villog.

felirat olvasható, majd az ENTER gomb lenyomása után a felirat eltűnik és helyette a képernyő alján bal oldalt egy K betű (K helyőr) jelenik meg.
Ha ezektől eltérő kiírás olvasható, akkor hiba van.

Az üzenet és a villogó helyőr azt jelenti, hogy a gép készen áll BASIC programok befogadására, végrehajtására stb. írjuk most be az alábbi szöveget:

PRINT "ITT VAGYOK!"

és nyomjuk le a RETURN gombot.

Felhívjuk a figyelmet, hogy az idézőjelek és a felkiáltójel az 1 és 2 feliratú gomb felső részén találhatók, ezért csak akkor jelennek meg a képernyőn, ha a SHIFT billentyűt előzetesen lenyomjuk, és utána ütjük le a kívánt jel gombját.

Ha eltévesztjük a gépelést, ne keseredjünk el, nyomjuk le a RETURN / NEWLINE / ENTER gombot és kezdjük elölről. Hiba esetén mindig megjelenik egy hibaüzenet, ezzel azonban most még ne törődjünk.
Ha hibátlanul beírtuk a fenti szöveget, akkor egy sorral lejjebb megjelenik az ITT VAGYOK! szöveg.

Mi ennek a magyarázata?

A begépelt sorral utasítást adtunk a számítógépnek, hogy írja ki az ITT VAGYOK! szöveget, és a gép ezt végrehajtotta. Az erre vonatkozó utasítást a PRINT szóval közöltük a géppel, a kiírandó szöveget pedig idézőjelbe tettük. Ez jelzi a gépnek, hogy mit kell megjelenítenie. Próbáljuk meg más szövegek kiírását is!
Például

PRINT "GABOR"
PRINT "EZ JOL MEGY!"

Ne felejtsük el minden sor (vagy utasítássor) begépelése után a RETURN / NEWLINE / ENTER gombot lenyomni! A gép csak akkor hajtja végre az utasítást, ha ezt az ún. sorzáró billentyűt lenyomtuk. Erről úgy győződhetünk meg, hogy megnézzük, hol a helyőr. Ha a helyőr az utolsónak begépelt jel után villog, akkor nem nyomtuk le.
Most egy más jellegű utasítássort gépeljünk be:

PRINT 6*8

és nyomjuk le a sorzáró billentyűt. A 6 és 8 közötti ún. csillagjel a BASIC nyelvben a szorzás jele. A helyes begépelés után a gép a következő sor elejére kiírja azt, hogy 48. Nyilvánvalóan arra utasítottuk a gépet, hogy a 6*8 szorzat eredményét írja ki.
Figyeljük meg a lényeges különbséget az előző példához viszonyítva: idézőjelet nem írtunk! Ha a szorzatot idézőjelbe tesszük, akkor a kiírás eredménye más lesz.

PRINT "6*8"
6*8

Ha az idézőjeleket elhagyjuk, a gép először elvégzi a kijelölt számtani műveletet, majd kiírja az eredményt. Próbáljuk meg ezt az utasítást más számokkal is!
A fenti két feladatban a számítógépet utasítottuk valamilyen művelet elvégzésére. Amikor idézőjelek közé írt szöveg kiírására adtunk utasítást, akkor lényegében egy műveletet hajtott végre a gép. A számolási műveleteknél pedig előbb a gépnek ki kellett számítania az eredményt, majd a következő lépésben ezt ki kellett írnia. A lényeg tehát az, hogy mi a gépet utasítottuk valamilyen művelet végrehajtására és az elvégezte.
Látható, hogy ilyen módon a számítógépet úgy lehet használni, mint egy kalkulátort, ezért az ilyen használatot kalkulátor módnak is nevezik. Ez a mód azonban lényegesen több szolgáltatást tud nyújtani a program-készítéshez, mint amit itt bemutattunk, ezért a neve is az általánosabb célt megjelölő közvetlen mód. (Erre később még visszatérünk.)

Oldjunk meg egy nagyon egyszerű feladatot!
Írassuk ki a számítógéppel két szám összegét és szorzatát. Legyen a két szám 6 és 8. Jelöljük a számokat A-val és B-vel: A=6, B=8
Ebből következik, hogy az összeg kiírásakor az A+B műveletet, a szorzat kiírásakor pedig a A*B műveletet kell elvégezni.
A feladat megoldásához négy műveletet kell elvégezni:

  1. Az A értéke legyen 6
  2. A B értéke legyen 8
  3. Számítsa ki az A+B összeget, és az eredményt írja ki
  4. Számítsa ki az A*B szorzatot, és az eredményt írja ki

Valójában ez a feladat is megoldható az előzőleg bemutatott módon, de ennek a módszernek korlátai vannak. Ha ez a feladat még nem is lépi át ezeket a korlátokat, előbb-utóbb találunk olyan nagyobb feladatot, amely már biztosan nem oldható meg így. Ezt a másfajta feladatmegoldást azonban könnyebben megérthetjük egy kisebb feladaton.
Mindenekelőtt azt nézzük meg, hogyan érhetjük el, hogy egy A vagy B nevű változó valamilyen értéket kapjon. Erre a LET szó való. A szó után meg kell adni a változót és az értéket egyenlőség-jellel összekapcsolva:

LET A=6

A gép végrehajtja ezt az utasítást, és eredményeként az A értéke 6 lesz.

A feladat megoldására tehát új módszert kell keresnünk. Ez a módszer a műveletek programban való leírása. Ha nem egy műveletet akarunk a géppel végrehajtatni, akkor az utasításokat a végrehajtás sorrendjében sorszámozva gépeljük be:

10 LET A=6
20 LET B=8
30 PRINT A+B
40 PRINT A*B

Az utasítások elé írt számok mutatják a végrehajtási sorrendet. Először a legalacsonyabb sorszámú utasítást kell elvégezni (10), majd a következő sorszámút (20) és így tovább.
Ne felejtsük el, hogy minden utasítás után le kell nyomni a sorzáró billentyűt! A következő utasítás csak így kerül a következő sorba a képernyőn.
Már most jegyezzük meg, hogy amikor változóknak értéket adunk, akkor az egyenlőségjel nem a hétköznapi értelemben vett "ténymegállapítás", hanem az egyenlőségjel bal oldalán álló változót egyenlővé teszi a jobb oldalon álló értékkel.

Ha begépeltük a fenti négy sort, akkor jól láthatjuk, hogy sem az egyes, sorok begépelésének végén (a RETURN / NEWLINE vagy ENTER) lenyomása után), sem a teljes feladat begépelése után nem történi semmi. Ez azért van, mert most az utasítássorok elé sorszámot is írtunk. Az ilyen sorokat a gép a begépelésnél nem hajtja végre, hanem csak együttesen az egészet. Külön meg kell viszont "mondani", hogy mikor kell a műveleteket elvégezni. Ehhez be kell gépelni a RUN szót.

le kell nyomni a sorzáró gombot, ezután a számítógép a műveleteket elvégzi. Ha hibátlanul gépeltük be a négy sort, akkor a következő eredmények jelennek meg a képernyőn:

14
48

Ha valamelyik sort tévesen gépeltük be, írjuk be még egyszer. A végrehajtás sorrendje ugyanis független a begépelés sorrendjétől, egyedül a sorszámtól függ.
A RUN hatására a számítógép elvégzi a műveleteket. Ilyenkor nem egyetlen, hanem négy művelet elvégzésére adtunk utasítást.
Gépeljük be ismét a RUN szót, nyomjuk le a sorzáró gombot, és figyeljük, mi történik! Az eredmény ugyanaz, mint az előbb. A számítógép megint végrehajtotta a megadott utasításokat anélkül, hogy az utasításokat újra begépeltük volna. Akárhányszor is írjuk be a RUN szót, az eredmény nem változik. Ebből az a következtetés vonható le, hogy a sorszámozott utasítássorokat a számítógép "megjegyzi" és ezek akárhányszor végrehajtathatók. Egy ilyen sorszámozott utasítássorozat egy program. A program eddig megismert néhány jellemzője:

A kiírás formailag nem a legszebb: nem lehet tudni, hogy melyik érték mit jelent. Ha valaki nem sajnálja a fáradságot, akkor értelmesebbé teheti úgy, hogy az érték elé kiíratja az első esetben az A+B = a második esetben az A*B = magyarázó szöveget. Ezt úgy lehet elérni, hogy a PRINT szó után idézőjelek közé írjuk a fenti két szöveget a megfelelő utasítássorban. Ezután viszont még az értéket is ki kell írni. Ha egy sorba több dolgot akarunk kiíratni, akkor ezeket pontosvesszővel kell elválasztani. Ezek szerint a módosított műveletsorozat (program) a következő lesz:

10 LET A=6
20 LET B=8
30 PRINT "A+B=";A+B
40 PRINT "A*B=";A*B

A módosítást az új sorok begépelésével hajthatjuk végre. Ekkor a korábban beírt azonos sorszámú sor elvész.
Oldjunk meg egy újabb példát! Öt szám átlagát kell kiszámítani és az eredményt kiírni. Legyen az öt szám:

B = 6
C = 8
D = 12
E = 2
F = 5

Mint ismeretes, az átlagot úgy kell kiszámítani, hogy a számokat összeadjuk:

S = B+C+D+E+F = 6+8+12+2+5

és az összeget elosztjuk a tagok számával:

A = S/5

Eddigi ismereteink szintjén a feladat könnyen megfogalmazható számítógép-utasításokkal. Először a változók értékeit kell beállítani, majd az összeget kell kiszámítani. Vegyük észre, hogy itt nem elég csupán összeadni az öt számot, mert az összeget meg is kell őrizni az átlagszámításhoz. Tehát egy újabb változót kell bevezetnünk, és az összeget értékeként megadnunk. Ez az S változó. Az átlagra is szükségünk van, ezért az S értékét 5-tel elosztjuk (erre szolgál a / jel), és az A változót a hányadossal tesszük egyenlővé. A kiíráshoz pedig az A-t használjuk fel.
Végül is az alábbi műveleteket kell elvégezni:

  1. B értéke legyen 6
  2. C értéke legyen 8
  3. D értéke legyen 12
  4. E értéke legyen 2
  5. F értéke legyen 5
  6. S (összeg) értéke legyen B+C+D+E+F
  7. A (átlag) értéke legyen S/5
  8. Írja ki A értékét!

Joggal merül fel az olvasóban, hogy most miért választjuk szét például az átlag kiszámítását és kiírását. Az előző példákban ezt egyetlen műveletben végeztettük el a géppel. Azért célszerűbb ez a módszer, mert ha például a szórást is ki kellene számolni a feladatban, vagy más számításnál fel kellene használni az átlagot, akkor az itt bemutatott módszer szerint nem kell minden egyes felhasználásnál külön kiszámítani, hanem csak az értékét átvenni. A korábban bemutatott módszer szerint az átlagot minden felhasználásnál ki kellene számítani.
Ezek után hozzá is kezdhetnénk az utasítássorok begépeléséhez, de valamit szem előtt kell tartanunk. Az előző négy műveletsort (program) a számítógép még őrzi. Most viszont egy más feladat műveleteit akarjuk begépelni, az előzőekre már nincs szükségünk. Mit tegyünk? Azt mi láttuk, hogy ha egy olyan utasítássort gépelünk be, amelynek a sorszáma megegyezik egy meglévőével, akkor csak az újonnan begépelt utasítássor marad meg. Ha tehát az új feladat utasítássorait ugyanazokkal a sorszámokkal gépeljük be, mint az előzőekét, akkor az előző utasítássorokat "töröljük". Ez célravezető megoldás, de sok hibalehetőséget tartalmaz. Mi van akkor, ha a másodiknak beírt program kevesebb utasítássorból áll, mint az előző? Mi van akkor, ha az új programban nincs olyan sorszám, mint ami az előzőben volt (pl. 25)? Ha ugyanis az előző program valamelyik utasítássorát nem töröljük, akkor az megmarad, az új program része lesz, és ezt zavarhatja. Ez a megoldás tehát sok veszélyt rejt magában. Szerencsére van rá lehetőség, hogy elkerüljük.
Ha a NEW szót begépeljük (a Sinclair-gépeknél az A betű gombját nyomjuk le és a sorzáró billentyűt), a meglévő program megszűnik, vagyis a NEW hatására a gép törli (elfelejti) a meglévő programot, és ezután lehet kezdeni az új begépelését. Esetünkben ez a következő lesz:

10 LET B=6
20 LET C=8
30 LET D=12
40 LET E=2
50 LET F=5
60 LET S=B+C+D+E+F
70 LET A=S/5
80 PRINT A

A RUN begépelése után a számítógép végrehajtja a program műveleteit (ha jól gépeltük be őket), és kiírja az átlagot. Ezt a programot is akárhányszor végre lehet hajtatni, az eredmény mindig ugyanaz lesz.
Mi történik viszont akkor, ha azt akarjuk, hogy minden esetben más Jegyen az az öt szám, aminek az átlagát ki akarjuk számoltatni? Ilyenkor minden végrehajtás előtt meg kell adni azt az öt számot, aminek az átlagát ki kell számolni. Hogy oldható ez meg? Már ismerünk rá egy megoldást. Eszerint az első öt sort át kell írni az új számértékeknek megfelelően. Ha például azt akarjuk, hogy B 115 legyen, akkor az első utasítássort így kell begépelni:

10 LET B=115

és így tovább. Ez meglehetősen fárasztó, és a gépelés eltévesztése is sok hibát okozhat. Ebben az esetben is van a BASIC-nek olyan lehetősége, amely ennél egyszerűbb megoldást eredményez. Kiadhatunk ugyanis olyan utasítást, hogy a gép a billentyűzeten begépelt értéket adja meg egy változónak.
Hogy ezt jobban megértsük, töröljük ki a meglévő programot a NEW begépelése és a sorzáró billentyű lenyomása segítségével. Írjuk be az alábbi programműveleteket:

10 INPUT B
20 PRINT B

Írjuk be a RUN szót is a végrehajtáshoz. Azt fogjuk látni, hogy a gép a következő sor elejére kiír egy kérdőjelet. Ez a 10-es sorszámú utasítássor hatása, és azt jelenti, hogy a gép valamilyen érték begépelésére vár. A program végrehajtása mindaddig felfüggesztve marad, amíg be nem gépelünk egy értéket. Írjunk be egy számot: 115 és és nyomjuk le a sorzáró billentyűt. A 10-es sorszámú utasításban lévő B változó értéke 115 lesz, és a program folytatódik. A folytatás egyetlen műveletből áll, a B értékének kiírásából: 115.
Ezt a gép el is végzi.
Az INPUT szó tehát azt eredményezi, hogy a program végrehajtása az INPUT-ot tartalmazó utasítássornál leáll, és a gép mindaddig vár, amíg be nem gépelünk egy értéket. Ezt az értéket az INPUT után írt változónak adja, és a végrehajtás folytatódik. Ezzel lehetővé válik, hogy minden végrehajtáskor új adatokat adjunk meg. Az adatokat a billentyűzeten kell begépelni.
Most már láthatjuk, hogy az átlagszámító feladat első öt sorát ki kell cserélni, és mindegyiket egy-egy beolvasó utasítássorrá kell átalakítani. A NEW művelet végrehajtása után gépeljük be a programot még egyszer, de most már adatbeolvasó utasítássorokkal:

10 INPUT B
20 INPUT C
30 INPUT D
40 INPUT E
50 INPUT F
60 LET S=B+C+D+E+F
70 LET A=S/5
80 PRINT A

Az utolsó három sor változatlan maradt.
Hajtsuk végre most a programot többször egymás után! Látni fogjuk, hogy minden alkalommal új adatokat adhatunk meg, és az eredmény eszerint alakul.
Ismereteink alapján meg lehet oldani az előző (összeg, szorzat) feladatot is úgy, hogy az A és B értékét a billentyűzetről adjuk meg minden esetben.

Végül nézzünk egy játékosabb példát! Próbáljuk ki, mennyire tudunk fejben szorozni 1 és 12 közé eső egész számokat. Építsük fel úgy a feladatot, hogy a gép írjon ki két, 1 és 12 közé eső egész számot (A és B) szorozzuk őket össze fejben, és gépeljük be az eredményt. Ezután a gép írja ki a pontos eredményt. Így ellenőrizni tudjuk, hogy jól számoltunk-e.
Milyen műveleteket kell végrehajtani? Először is a két számnak (A és B) 1 és 12 közötti egész értéket kell adni (pl. A=4, B=12), majd ezeket ki kell írni, hogy elolvashassuk. Ezután nekünk kell "dolgozni". Ki kell számítani a szorzatot, és be kell írni. Vagyis a két szám kiírása után a gépnek be kell olvasni a mi eredményünket. Ezek után a gép kiszámítja a helyes eredményt, és ki kell írni. Lépésekre bontva a következő műveleteket kapjuk:

  1. A értéke legyen 4
  2. B értéke legyen 12
  3. Írja ki A-t
  4. Írja ki B-t
  5. Olvassa be a szorzatot (C)
  6. Szorozza össze A-t és B-t (D)
  7. Írja ki a szorzatot (D)

A műveleteket átalakítjuk BASIC utasítássorokká, és az előző program törlése (NEW szó) után gépeljük be.

10 LET A=4
20 LET B=12
30 PRINT A
40 PRINT B
50 INPUT C
60 LET D=A*B
70 PRINT "SZERINTEM:";D

Hajtassuk végre a programot!
A gép először kiírja a két tényezőt: 4 és 12 majd egy kérdőjellel jelzi, hogy egy érték - jelen esetben a szorzat begépelésére vár. Begépeljük az eredményt, ezután a program kiírja a saját (helyes) eredményét: SZERINTEM: 48
Ezzel a végrehajtás befejeződik. Csalódottan állapítjuk meg, hogy a program ugyan korrektül működik, a feladatát mégsem látja el. Minden végrehajtásnál ugyanazt a kérdést teszi fel, tehát a második futás már teljesen érdektelen mindenki számára. Így nem értük el célunkat. Számunkra ugyanis az lenne a kedvező, ha minden alkalommal más, előre ki nem számítható számokat adna meg. Ekkor ugyanis minden végrehajtás új és érdekes lenne. Eddigi ismereteink alapján ez nem oldható meg, de van ismét olyan lehetőség a BASIC-ben, amivel ez sikerül. Van egy függvény (részletesen lásd a 8. részben), amely véletlenszámot állít elő. Ez a függvény lehetővé teszi, hogy egy változó ne ugyanazt az értéket kapja minden végrehajtáskor, hanem valamilyen véletlenszerű értéket. Ekkor a LET szó utáni részben az egyenlőségjel jobb oldalára nem egy konkrét értéket kell írni, hanem ezt a véletlenszám-előállító függvényt. Azt is meg kell adni, hogy a véletlenszám milyen tartományba essen. Kívánságunk szerint 1 és 12 közötti égész véletlenszámokat kell előállítani. A véletlenszám előállításának részleteit a 11. részben ismerjük meg, itt csak a függvény számunkra érdekes végső formáját mutatjuk be. A Commodore esetén 1 és 12 közötti véletlen egész számot következőképpen állíthatunk elő:

INT(RND(1)*12)+1

Ezt a bonyolult kifejezést az A és B változó értékének meghatározásánál a konkrét érték helyére kell írnunk:

10 LET A=INT(RND(1)*12)+1
20 LET B=INT(RND(1)*12)+1

A módosítás eredményeképpen minden végrehajtás alkalmával mind az A, mind a B valamilyen 1 és 12 közé eső egész értéket kap, ami véletlenszerű (megjósolhatatlan).

10 LET A=RND(12)
20 LET B=RND(12)

10 LET A=INT(RND*12)+1
20 LET B=INT(RND*12)+1

Az INT szó begépeléséhez előbb nyomjuk le a CAPS SHIFT és a SYMBOL SHIFT gombot. Ekkor megjelenik az E helyőr, ilyenkor billentyűk feletti zöld feliratok "élnek". Most nyomjuk le az R betű gombját, és megjelenik az INT a képernyő alsó sorában. A begépelés után visszaáll az L helyőr. Az RND ugyanezzel a módszerrel gépelhető be, de a T gomb lenyomása kell hozzá.

A két első utasítássor módosításával a módosítás be is fejeződik, hiszen az egyetlen hiányosságot pótoltuk. Ha most adunk ki végrehajtási parancsot, akkor a két megadott szám minden alkalommal más lesz a játék pedig "élvezetessé" válik.
Munkánk befejeztével az eszközöket kikapcsolhatjuk (először a gépet, utána a tv-t). Ezzel az utoljára begépelt program is elveszett. Erről meggyőződhetünk, ha újra bekapcsoljuk a gépet, s a RUN begépelése hatására nem történik semmi. Jó lenne, ha nem veszne el a munkánk! Ezzel majd a 2. részben foglalkozunk.
A következőkben rendszeresen fogunk előrehaladni, építve a most megismert fogalmakra, és jelentősen kibővítve, hogy összetett feladatokat is könnyen oldhassunk meg.

2. A számítógép használata
Milyen részekből áll a számítógép?
A billentyűzet leírása.
Programok másolása kazettára és lemezre.

Az első részben megismertük azokat az eszközöket, amelyek ahhoz szükségesek, hogy feladatokat tudjunk megoldani BASIC nyelven (1. ábra). A számítógépből, billentyűzetből és kijelzőből (tv) álló eszközkészlet elegendő ahhoz, hogy programokat (sorszámozott utasítássorozatokat) készítsünk, azokat végrehajtsuk. Ezek az eszközök lehetővé teszik, hogy a program végrehajtása közben a feladatokhoz számértékeket adjunk meg, s a feladatmegoldás eredményei a tv képernyőjén megjeleníthetők legyenek.
Az első rész végén kiderült az is, hogy ennek az ún. minimális eszköz-készletnek korlátai is vannak. Mint emlékszünk rá, minden új feladat megoldásánál az előző feladatot megoldó program "elveszett", mert helyére kellett beírni az új programot. Ezért ha egy korábbi feladatot újra meg akarunk oldani, akkor annak az utasítássorait ismét be kell gépelni. Ha pl. a szorzatkitaláló program használata után újra szeretnénk átlagot számolni, akkor be kell gépelni előbb a NEW szót (parancsot), ezzel kitörölnénk a szorzat kitaláló programot, majd be kell írni a teljes átlagszámító programot. Ez nyilvánvalóan fáradságos és nem lelkesítő munka. Mit tegyünk azért, hogy az újra begépeléstől megmeneküljünk?
Először vizsgáljuk meg röviden, hogy mi is a jelenség oka! Eddig nem beszéltünk róla, de a számítógépnek van egy nagyon fontos része, ahol tárolni lehet mindent, amit mi begépelünk, illetve egyéb adatokat. Ez a számítógép tárja. A tár feladata az adattárolás. A tár tárolási egységekből épül fel. Egy tárolási egység egy betűt vagy számot, vagy írásjelet képes megőrizni. A betűt, számot és írásjelet együttesen karakternek vagy jelnek nevezzük, a tárolási egységet bájtnak. A bájt is még tovább bontható, de ezzel itt még nem foglalkozunk. Csupán annyit jegyezzünk meg, hogy egy bájtban 256 különböző karakter tárolható.
Ha például beírjuk az alábbi BASIC utasítássort:

10 INPUT B

akkor ennek a tárolásához néhány bájtra van szükség.
Látható, hogy a program egy meghatározható helyet foglal el a tárból. De nemcsak a programot kell tárolni, hanem a változókat, vagyis a programban előforduló adatokat is. Milyen hosszú programokat és mennyi adatot tudunk tárolni a számítógép tárjában? Ez a tár méretétől függ. A legkisebb gépekben 1024 bájt (= 1 kilobájt = 1 kbájt) áll a programok rendelkezésére. A nagyobb gépeken 8, 16, 32, 48, 64 kbájt vagy ennél jóval nagyobb méretű tár van. Nekünk ekkorára nincs szükségünk.
Megjegyezzük, hogy a programkészítő nem használhatja a teljes tár-kapacitást, mivel a gép saját maga is leköt egy bizonyos bájtmennyiséget.
A tár egyes bájtjai sorszámmal vannak ellátva, ez a bájtok címe. Ez lehetőséget ad arra, hogy szükség esetén az egyes bájtokat egyénileg is tudjuk kezelni, azaz valamit bele tudjunk írni, illetve a tartalmát ki tudjuk olvasni. Ezt a BASIC nyelv is lehetővé teszi. (Erre majd még később visszatérünk.) Nagyon fontos, hogy tulajdonképpen nem is kell azzal törődnünk, mi hova kerül a tárban, vagy honnan lehet kiolvasni, mivel ezeket a feladatokat a gép (illetve az ún. operációs rendszer) helyettünk elvégzi.
Az általunk használt kis számítógépekben általában kétféle tár van:

A ROM számunkra nem hasznosítható, mivel nem tudunk beleírni. Mi csak a RAM-ot használhatjuk. Ennek viszont az a kellemetlen tulajdonsága, hogy tartalma a tápfeszültség kikapcsolásakor elvész. Ez az oka annak, hogy kikapcsoláskor a gépben, illetve a tárban lévő program elvész. Ezt a hiányosságot úgy tudjuk megszüntetni, ha a tárnak azokat a részeit, ahol a program elhelyezkedik, egy olyan eszközre másoljuk át, amely a beírt adatokat sokáig képes megőrizni. Ilyen eszköz a közismert magnókazetta vagy a kevésbé közismert, de hasonló fizikai elv szerint működő mágneslemez. Itt bemutatjuk ezeknek az eszközöknek a használatát.
Előbb azonban térjünk vissza még egyszer az előző rész feladataihoz. Joggal merül fel olyan igény, hogy a programok által szolgáltatott eredményeket is meg lehessen őrizni valahogy, hiszen a képernyőről előbb-utóbb elvész. Az lenne a jó megoldás, ha a számunkra fontos eredményeket (adatokat) papírra is kiírná a gép, így ezek megmaradnának nekünk. Vagyis jó lenne, ha a géphez egy kiíró is tartozna, amellyel adatokat lehet kiírni.
Ebben a részben a már röviden bemutatott vagy említett eszközök használatát ismerjük meg részletesen:

A nyomtató használatát a 4. részben mutatjuk be.

A billentyűzet
A billentyűzetek felépítése nagyjából hasonló, általában csak apróbb részletekben térnek el egymástól. A billentyűzet nagyon emlékeztet az írógépek billentyűzetére. Az a legnagyobb különbség a kettő között, hogy a terminál jelkészlete nagyobb.
A billentyűket három csoportra oszthatjuk:

A billentyűk többsége két állásban használható (két jel van rajtuk). A normál eset az alsó állás (megfelel az írógépek "kisbetűírás" állásának). Ilyenkor, ha olyan billentyűt nyomunk le, amelyen két jel van, az alsó jel íródik ki. Ha viszont olyan karakterbillentyűt nyomunk le, amelyen csak egy jel van (többnyire betű), akkor a billentyűre rajzolt betű jelenik meg. A SHIFT billentyű lenyomásával a felső állásba kapcsolunk. Ilyenkor a billentyűk felső részén látható jelek írhatók ki.
Mivel a számítástechnika angolszász nyelvterületen alakult ki, a billentyűkön az angol ábécé betűi vannak. Magyar ékezetes betűk általában nincsenek a terminálokon (a PRIMO kivételével). Mi azt javasoljuk - és ezt is fogjuk követni -, hogy azoknál a gépeknél, amelyeken nincs ékezetes betű, az ékezetes betűk helyett ezek ékezet nélküli változatát írjuk ki a szövegekben (pl. É helyett E-t). Bizonyára zavaró és szokatlan első látásra, de véleményünk szerint ezt könnyebb megszokni, mint a kettőzött magánhangzó írását (pl. É helyett EE). A magánhangzó megkettőzése a szavak hosszát is megnöveli, ami a táblázatok fejrovat-beosztásának megtervezésében okoz gondot.
Megfigyelhetjük, hogy a terminál billentyűzetén mind a 10 számjegy szerepel a legfelső sorban. Vigyázzunk, hogy számok írásához csak ezeket a billentyűket használjuk! Aki tud gépelni, annak kezdetben figyelnie kell, hogy külön van O betű és nulla számjegy, valamint hogy az L nem 1-et jelent.
BASIC programokban a billentyűzetnek csak meghatározott karakterei használhatók (pl. betűk és számok). Ezeket részletesen az egyes gépek billentyűzetének ismertetésekor soroljuk fel.
Érdemes minél előbb megtanulni, hogy a tizedesjel - az európai szabványtól eltérően, amerikai szokás szerint - a pont, tehát mindig tizedespontot kell használni! A vessző funkciója más, tizedesként nem használható.
A billentyűk fontos szolgáltatásokat tudnak nekünk nyújtani. Ilyen a képernyő törlése, amelynek eredményeként a képernyőről eltűnik minden kiírás, és a helyőr az 1. sor 1. karakterpozíciójára (bal felső sarok) áll. Ez nem jelenti a program törlését, csak a képernyőt "tisztítja meg".
A funkcionális billentyűk teszik lehetővé, hogy a begépelt szöveget módosítsuk, a téves begépeléseket kijavítsuk. Itt csak az egyszerűbb lehetőségeket tekintjük át, a függelékben részletes leírás található a programok javítási módjairól.
A billentyűk között vannak egyéb speciális funkciókat végrehajtók is. Ezeket, valamint a jelkészletet, a képernyő törlését és a gépelési hibák kijavítását az alkalmazott négy géptípusnál külön-külön mutatjuk be.
Megjegyezzük, hogy a billentyűk egy része ismételni is tud, azaz ha tartósan lenyomva hagyjuk, akkor mindaddig újabb karakter kerül a képernyőre, amíg a billentyűt lenyomva tartjuk.

A Commooore-64 billentyűzete
A Commodore-64 billentyűzete a 2. ábrán látható.


2. ábra: A Commodore-64 billentyűzete

A gépen írt programokban következő karakterek használhatók:

A képernyő a SHIFT és a CLR/HOME billentyű együttes lenyomásával törölhető. Ha csak a CLR/HOME gombot nyomjuk le, akkor a gép csupán a "HOME" funkciót hajtja végre. Ennek eredményeként a helyőr a bal felső pozícióba ugrik, de a képernyő nem változik meg.
Begépelés közbeni hibát az INST/DEL nyomógombbal javíthatunk ki, ha még a RETURN gombot nem nyomtuk le. Tegyük fel, hogy az alábbi sort kell begépelnünk:

100 PRINT A

de eltévesztettük, és az alábbi szöveget gépeltük be:

100 PRIT A

Mielőtt a RETURN gombot lenyomtuk, észrevesszük a hibát. Ekkor az INST/DEL gombot lenyomjuk, amely kitörli az utolsónak begépelt karaktert. Ha többször lenyomjuk, többet töröl visszafelé haladva. A begépelt szöveg nem teljesen rossz, az eleje még helyes:

100 PRI

Elég tehát idáig visszalépegetni az INST/DEL gombbal, majd innen folytathatjuk a beírást, most már helyesen.
Ha olyankor vesszük észre a hibát, amikor a RETURN gombot már lenyomtuk, akkor a javítást a függelékben leírt módon kell végrehajtani.
A Commodore-on van egy STOP RUN feliratú billentyű, amellyel a programok végrehajtását le lehet állítani. A lenyomás pillanatában még folyamatban lévő utasítást a gép végrehajtja, és a

BREAK IN sorszám

üzenet kiírása után a program végrehajtása leáll.

A HT-1080Z számítógép billentyűzete
A gép billentyűzete a 3. ábrán látható.


3. ábra: A HT-1080Z billentyűzete

A gép BASIC jelkészletének karakterei:

A képernyőt a Clear gombbal lehet törölni. A gomb lenyomásakor a képernyőről minden jel eltűnik, és a helyőr a bal felső sarokba ugrik.
Begépelés közben a hibát a Commodore-nál leírt módon lehet javítani. A visszalépés és karaktertörlés itt a - jelű gomb hatására megy végbe.
Ha a hiba a sor elején van, vagy túl sok hiba van a begépelendő sorban, akkor nem érdemes a visszalépéses törlést végrehajtani, mert a SHIFT és a gomb együttes lenyomása törli a teljes sort, és a beírást újra lehet kezdeni.
A program végrehajtása a BREAK gombbal szakítható meg. A gomb lenyomásakor végrehajtás alatt álló utasítás befejeződik, és utána a program leáll a

BREAK IN utasítássorszám

üzenet kiírása után. Az utasítássorszám a leállás helyét jelöli.

A PRIMO számítógép billentyűzete
A PRIMO számítógép billentyűzete a 4. ábrán látható.


4. ábra: A PRIMO számítógép billentyűzete

A gép BASIC jelkészlete a következő karakterekből áll:

A billentyűzet nagy előnye, hogy a magyarban használt ékezete betűk is - a nagy Ó, Ő, Ú, Ű és Í kivételével - megtalálható rajta, és ezek a programokban alkalmazhatók, valamint nemcsak a nagybetűk, hanem a kisbetűk is használhatók. Így a kiírások a magyar nyelvben szokásos módon elvégezhetők. Nem akarjuk befolyásolni a PRIMO-felhasználókat, hogy a programok írásához kis- vagy nagybetűt használjanak. A program-utasítássorok megírásához ugyanis mindkettő használható. Például az alább két sor egyenértékű:

150 print a+b
150 PRINT a+b

A kis- és nagybetű váltás a SHIFT gombbal végezhető el az írógéphez hasonlóan. Ha valaki a többi géphez hasonlóan csak nagybetűket akar használni, akkor (a bekapcsolás után) nyomja le az UPPER billentyűt. Ennek hatására csak a nagybetűk jelennek meg. A többi gombról, ahol két jel van, továbbra is az alsó jelenik meg. A felső jel csak akkor kerül a képernyőre, ha a SHIFT-et is lenyomtuk. Ha még egyszer lenyomjuk az UPPER-t, akkor a gép visszatér a kisbetűs üzemmódba.
A képernyőt a CLS gomb lenyomásával lehet törölni. Ilyenkor a képernyő törlődik, és a helyőr a bal felső sarokba ugrik.
Begépelés közbeni hibát a -gomb segítségével javíthatunk ki, ha a sorzáró RETURN gombot még nem nyomtuk le. A -gomb lenyomásával a helyőr balra megy, és minden lenyomás után törli az útjában álló jeleket. Vissza kell menni a helyes rész végéig, és onnan a bevitelt helyesen meg kell ismételni.
Ha egy sorban sok a hiba, vagy a legelején van hiba, akkor célszerű a sort a és a SHIFT együttes lenyomásával törölni és a bevitelt megismételni.
Ha a RETURN-t már lenyomtuk, akkor a függelékben található módon lehet a hibát kijavítani.
A BRK billentyű lenyomásával a program végrehajtása az éppen végrehajtott utasítás befejezése után leáll, és a

BREAK IN utasítássorszám

szöveget írja ki. Az utasítássorszámmal jelöli, hogy hol állt le.

A Sinclair-gépek billentyűzete
A Sinclair-gépek billentyűzete az 5. ábrán látható.


5. ábra: A Sinclair billentyűzete (Spectrum)

A gépen írt programokban a következő karakterek használhatók:

Mint látható, a kisbetűk is használhatók a gépen.
A képernyőt a CLS (V gomb) lenyomásával lehet törölni, ha a K helyőr villog.
Az alsó, beviteli sorba beírt szöveget az ENTER gomb lenyomása előtt a többi géphez hasonlóan lehet javítani. A begépelt szöveg utolsó jeleit a CAPS SHIFT és a 0 gomb egy-egy lenyomásával lehet kitörölni.
Itt is addig kell törölni (visszafelé haladni), amíg a maradék rész hibátlan nem lesz. Figyeljük meg, hogy ha olyan szövegrészhez ér a helyőr visszafelé haladtában, amelyet egyetlen billentyű lenyomásával írhatunk le (pl. PRINT), akkor ennek a törlése is a CAPS SHIFT és a 0 egyetlen lenyomására megy végbe.
A Sinclair-gépek formailag hibás szöveget nem fogadnak el. Egy kérdőjel jelzi az ENTER lenyomása esetén, hogy hiba van a sorban. A hibát a bemutatott visszafelé haladó törléssel és újra begépeléssel javíthatjuk ki.
A program végrehajtása a CAPS SHIFT és a BREAK gomb együttes lenyomásával szakítható meg. A lenyomás hatására a végrehajtás alatt álló utasítás befejeződik, utána a program leáll, és az

L Break into program sorszám

üzenet jelenik meg.

Mágneslemez és kazetta használata
Mint már korábban láttuk, a mágneslemezegység és a kazettás magnó azt a célt szolgálja, hogy a számítógépben tárolt programokat a gép tárjából lemezre vagy kazettára kimásoljuk megőrzés végett. Ez általában akkor szükséges, ha készítettünk egy új programot, és miután használtuk, vagy ki akarjuk kapcsolni a gépet, vagy más programot kívánunk írni. A tárban lévő program mindkét esetben elveszne, ezért előbb kimásoljuk egy ún. külső tároló berendezésre (mágneslemezegység vagy magnó).
Ha újra akarjuk használni a már kimásolt programot, akkor a külső tárolóeszközről a programot be kell másolni a gép tárjába. Mivel az ilyen másolás hatására a program nem törlődik a mágneslemezről vagy a kazettáról, a tárba bemásolt programot szabadon lehet törölni, nem kell ismételten visszamásolni.
Tegyük fel, hogy mind az átlagszámító, mind a szorzatkitaláló programot kazettára másoltuk. Ha az átlagszámító programot akarjuk használni, akkor a programot bemásoljuk. Ha már nem akarjuk tovább végrehajtani, és helyette a szorzat kitalálót szeretnénk használni, akkor nyugodtan másoljuk be ez utóbbi programot anélkül, hogy az átlagszámítót kimásolnánk (kimentetnénk), mivel az megmaradt a külső tároló-egységen.
Rögtön felmerül a kérdés, hogy mi történik akkor, ha már több programunk van egy kazettán vagy mágneslemezen, hogyan tudjuk kiválasztani a kívánt programot a sok közül. Ez csak akkor lehetséges, ha a programnak valamilyen nevet adunk a másoláskor. A program a megadott névvel kerül a külső háttértárolóra, és ha vissza akarjuk másolni, akkora nevével tudjuk kiválasztani.
Egy jó tanács. Akinek nincs saját számítógépe, és kölcsöngépet tud használni, vegyen magának 1-2 magnókazettát vagy lemezes gép esetén lemezt (a pontos típust a kölcsönadótól meg kell kérdezni!), amelyre a saját programjait gyűjtheti. Mágneslemez esetén a lemezt a használat előtt inicializálni kell (lásd a függelékben).
A kazettás magnó ugyanúgy tárolja a programokat, mint a zeneszámokat. Egy kazettán több program is lehet mindkét oldalon. Ha több kazettánk van, érdemes valamilyen megkülönböztető nevet adni nekik, és feljegyezni, hogy melyiken mi van.
Most nézzük meg, hogy az egyes gépeknél a műveletek hogyan hajthatók végre. Itt nem részletezzük, de nyilvánvaló, hogy a kazettára írás vagy a kazettáról való másolás előtt a kazettát be kell helyezni a magnóba, a kazettaajtót be kell zárni stb.

A magnó és mágneslemezegység használata a Commodore-on
A Commodore-nál mind a mágneslemez, mind a kazettás magnó használatát bemutatjuk.
Kazettára való másoláskor a következő szöveget kell begépelni:

SAVE "programnev", 1

ahol

Jegyezzük meg, hogy a programnév legfeljebb 16 tetszőleges jelből állhat (pl. MINTA1).
A szöveg (parancs) begépelése és a RETURN lenyomása után megjelenik a

PRESS RECORD & PLAY ON TAPE

üzenet a képernyőn, ami azt jelenti, hogy nyomjuk le a felvételt indító gombot a magnón. A másolás végén megjelenik a képernyőn a

SAVING programnev
READY

üzenet, ekkor a magnót le lehet állítani.
A kazettára vagy lemezre másolás közben előfordulhatnak olyan hibák, amelyek miatt a kimásolt program használhatatlanná válik. Ezért jó meggyőződni arról, hogy a kimásolás hibátlan-e. Van a BASIC-ben olyan lehetőség, amellyel meg lehet vizsgálni, hogy a kimásolt és tárban levő program egyezik-e. Ezt a műveletet akkor kell elvégezni, amikor a másolás befejeződött, de a program még a tárban van.
A vizsgálathoz a következő parancsot kell kiadni:

VERIFY "programnev",1

ahol

Ha a parancs kiadása előtt a magnó a vizsgálandó program kezdetén áll, akkor a programnév és a kazettás magnó száma elhagyható:

VERIFY

A parancs kiadása után a

PRESS PLAY ON TAPE

üzenet kéri, hogy indítsa el a magnót. Ekkor megjelenik a

SEARCHING FOR programnev

üzenet, amely jelzi, hogy a gép keresi a megadott nevű programot.
Ha megtalálta, akkor ezt is tudatja:

FOUND programnev

Ha a két program egyezik, akkor az OK és a READY üzenet, másolási hibánál a

? VERIFY ERROR
READY

jelenik meg. Ilyenkor a kimásolást meg kell ismételni.
Arra már nekünk kell vigyázni, hogy a gép ne másoljon egymásra programokat. A kimásolás előtt ezért a magnószámláló segítségével vagy más módon a szalagot szabad helyre kell állítani.
A szalagról való programbeolvasáshoz az alábbi parancsot kell begépelni:

LOAD "programnev",1

ahol

A szöveg begépelése és a RETURN lenyomása után a

PRESS PLAY ON TAPE

üzenet jelenik meg, ami azt jelenti, hogy a magnón meg kell nyomnia lejátszó gombot. Ha ezt megtettük, akkor a gép elkezdi olvasni a szalagon levő programokat, illetve azok neveit.
Ha megtalálta a kívánt nevű programot, akkor kiírja a

FOUND programnev

üzenetet, amellyel jelzi a megtalálás tényét. Ahhoz, hogy a bemásolás is megtörténjék, meg kell nyomni a C=, CTRL, vagy szóköz gombot. Ha ezt megtettük, akkor elkezdődik a másolás. Erre utal a megjelenő

LOADING

üzenet. A bemásolás végét a READY üzenet jelzi; a magnót le lehet állítani. Ekkor a program bent van a tárban, és a RUN paranccsal a program végrehajtható, mintha most gépeltük volna be. A művelet eredményeként a program természetesen a kazettán marad.

A mágneslemezre másolás és az onnan való visszamásolás valamivel egyszerűbben megy végbe, mivel a helykeresést a mágneslemezegység maga intézi, továbbá az indítás és a leállítás is felesleges.
A mágneslemezre másolás a következő paranccsal hajtható végre:

SAVE "programnev",8

ahol

Megjegyezzük, hogy a mágneslemez száma 9, 10, 11 is lehet. A másolás megkezdésekor a

SAVING programnev

üzenet, a végén pedig a READY üzenet jelenik meg. Ez jelenti a másolás befejezését.
A másolás helyességét itt is ellenőrizzük a tárban levő program törlése előtt. A parancs formája hasonló a kazettás magnónál bemutatott parancshoz:

VERIFY "programnev",8

A visszamásolás az alábbi paranccsal végezhető el:

LOAD "programnev",8

A parancs kiadása után a

SEARCHING FOR programnev

üzenet jelenik meg, amely arra utal, hogy a gép keresi a kívánt programot. Ha már megtalálta, akkor a LOADING üzenet mutatja, hogy a beolvasás megkezdődött. A beolvasás végét a READY üzenet jelenti. Ekkor a program már végrehajtható!
A mágneslemezegységnek olyan szolgáltatása is van, hogy meg lehet tudni, milyen nevű programok vannak egy lemezen, tehát nekünk nem kell erről nyilvántartást vezetni. A lemezen levő programok nevét két lépésben lehet kiíratni. Az első lépésben beolvastatjuk a lemez tartalomjegyzékét a már ismert LOAD paranccsal:

LOAD "$",8

ahol $ - a tartalomjegyzék neve.
A READY üzenet megjelenése után a

LIST

szó begépelése és a RETURN lenyomása után (listázási parancs) a képernyőn megjelenik a lemezen levő programnevek listája.
Felhívjuk a figyelmet arra, hogy a lemez érzékeny eszköz. Nem szabad erős mágneses térbe helyezni (villamos, trolibusz), nem szabad hajlítgatni, a lemez felületét valamilyen kemény eszközzel megérinteni, beszennyezni stb. Bármilyen sérülés a lemez tönkremenését okozhatja. Célszerű kemény lapok között tárolni, szállítani.

Magnóhasználat a HT gépen
A HT gépen a mágneskazettára kimásolás a következő paranccsal csal végezhető el:

CSAVE#-1,"programnev"

ahol

A program neve 1 karakter lehet, illetve egynél hosszabb névből csak az első karaktert használja. A másolási parancs begépelése után le kell nyomni együtt a REC és a PLAY gombot, majd NEW LINE gombot. Ezzel a másolás elkezdődik. A másolás befejezését a READY üzenet jelzi.
A kimásolás a HT gépnél is lehet hibás. Ilyenkor a kimásolt program használhatatlan. Ezért a program kitörlése előtt érdemes összehasonlítással ellenőrizni a másolás helyesség. Erre van lehetőség a gép BASIC-jében. Az összehasonlítás előtt a kazettát visszacsévéljük a kimásolt program eleje elindítjuk a magnót a PLAY gomb lenyomásával, és kiadjuk a parancsot:

CLOAD?"programnev"

ahol

A parancs begépelése és a NEW LINE lenyomása után a gép elkezdi keresni a megadott nevű programot. Ha megtalálta, a képernyő jobb felső sarkában két csillag jelenik meg. Ezután a kazettán és a tárban levő programokat összehasonlítja. Ha a kazettán levő program hibátlan, akkor a jobb oldali csillag villog. Hibás esetben a végén a BAD, hibátlan esetben a READY üzenet jelenik meg. Ha a másolt program hibás, a kimásolást meg kell ismételni.
A beolvasás a következő paranccsal hajtható végre:

CLOAD#-1,"programnev"

ahol

Ezután le kell nyomni a magnó PLAY gombját és a NEW LINE gombot. Ekkor a gép elkezdi keresni a megadott nevű programot. Ha megtalálta, két csillag jelenik meg a képernyő jobb felső sarkában. A jobb oldali csillag időről időre felvillanással jelzi, hogy folyik a program bemásolása. A művelet végén a READY üzenet jelenik meg. Ezután a program végrehajtható.

Magnóhasználat a PRIMO-nál
A PRIMO-nál egy program kimásolása az alábbi paranccsal hajtható végre:

SAVE "programnev"

ahol

A programnév legfeljebb 16 jelből állhat (pl. SZORZAT).
Ezután el kell indítani a magnót felvétel állásban, és le kell nyomni a RETURN gombot. A másolás befejeztével az Ok üzenet jelenik meg.
Másolás közben előfordulhatnak hibák, amelyek azt eredményezik, hogy a kimásolt program használhatatlanná válik, nagyon kellemetlen, mert ha a tárból is kitöröljük a programot, a program elvész, és újra be kell gépelni. Ezért célszerű a másolt programot ellenőrizni, hogy hibátlan-e. A PRIMO-nál az ellenőrzés nem a tárban levő program összehasonlításával megy végbe, hanem a kazettán levő program formai helyességének ellenőrzésével. Ha a kazettára másolt program formailag helyes, akkor tartalmilag is hibátlan, ellenőrzés előtt a kazettát legalább az ellenőrzendő program elejére kell állítani, és be kell gépelni az alábbi parancsot:

TEST "programnev"

ahol

Majd lenyomjuk a RETURN gombot és a magnó PLAY gombját. Ezután ugyanaz a folyamat zajlik le, mint a LOAD parancs begépelésekor (lásd később). Ha a hsz (hibaszám) értéke 0, akkor a kazettán levő program hibátlan, egyébként hibás. Az ellenőrzés végén az Ok jelenik meg.
A program visszaolvasását a következő parancs hajtja végre

LOAD "programnev"

ahol

Majd le kell nyomni a RETURN gombot, és el kell indítani a magnót lejátszásra. Ezután a gép keresni kezdi a megadott nevű programot. Ha közben más nevű programot talál, akkor kiírja:

SKIP:programnev

Ha a kívánt programot megtalálja, akkor elkezdi a betöltést, és a művelet végén üzenetet ír ki:

rsz hsz FOUND:programnev

ahol

A betöltés csak akkor helyes, ha a hibaszám nulla. Ellenkező esetben a betöltést meg kell ismételni.

Magnóhasználat a Sinclair-gépeknél
A Sinclair-gépeknél egy program kimásolása a következő paranccsal hajtható végre:

SAVE "programnev"

ahol

A programnév legfeljebb 10 jelből állhat.
A magnó csatlakozóját előzőleg a számítógép EAR-kivezetésébe kell bedugni. Lenyomjuk az ENTER gombot és ezután megjelenik a

Start tape, press any key

üzenet. Ekkor el kell indítani a magnót felvétel állásban, és a gépen valamelyik gombot le kell nyomni. A másolás végén a 0 OK, üzenet jelenik meg.
A kimásolt programban lehet hiba, ilyenkor használhatatlan. Ezért a programot kitörlése előtt hasonlítsuk össze a kimásolt programmal. A kazettát állítsuk vissza a program kezdetére, a magnó csatlakozóját a MIC-kivezetésbe dugjuk be, és adjuk ki a VERIFY parancsot. A parancs formája:

VERIFY "programnev"

ahol

A parancs begépelése után el kell indítani a magnót lejátszásra. Ha a kimásolt és a tárolt program egyezik, akkor az OK üzenet, hibánál az R hibaüzenet jelenik meg. Az utóbbi esetben a kimásolást meg kell ismételni.
Kazettán levő programot a következő paranccsal lehet bemásolni:

LOAD "programnev"

ahol

A bemásolás előtt a magnócsatlakozót dugjuk be a MIC-kivezetésbe. A parancs beírása után nyomjuk le az ENTER sorszáró billentyűt, és indítsuk el a magnót lejátszásra. A bemásolás végén megjelenik a K helyőr. Ezután a program végrehajtható.

Néhány szó az operációs rendszerről
Végül nézzünk még valamit! Az eddigiekben láthattuk, hogy attól kezdve, hogy a gépet bekapcsoljuk, READY vagy Ok üzenet, vagy a K helyőr jelzi, hogy a gép készen áll valamilyen felad végrehajtására. Ha van valamilyen, a gép által megoldható feladatunk, akkor egy megfelelő parancsot beírunk, és a gép azt végrehajtja. Hogy lehetséges ez? A gépben már a bekapcsoláskor vannak programok, amelyek ezeket a parancsokat végrehajtják. Azokat a programokat, amelyek a számítógéprendszer egészét irányítják, elemeinek működését összehangolják, a felhasználót a program készítésében támogatják, együttvéve operációs rendszernek nevezzük.
Az operációs rendszer gondoskodik arról, hogy a begépelt program bekerüljön a tárba, hogy a RUN parancs hatására a program végrehajtódjék, hogy a SAVE jellegű parancs hatására a program kimásolódjék a kazettára, és így tovább.
Az operációs rendszert paranccsal utasítjuk valamilyen művelet végrehajtására. Ilyen parancs az eddig megismertek közül a NEW, a SAVE RUN stb. A programon belüli műveletek parancsait megkülönböztetésül utasításnak nevezzük.
Az operációs rendszer üzenetekkel ad választ egy parancs végrehajtása után, valami hiba esetén, vagy üzenettel tudatja, hogy éppen mit csinál (például a bemásolás közben kiírja, hogy LOADING a betöltés folyamatban van).
Az operációs rendszer szolgáltatásai megkönnyítik a felhasználó munkáját. Több szolgáltatáshoz több program kell, több programhoz nagyobb tár. Azt mondhatjuk tehát, hogy kis tárkapacitású gépben kis operációs rendszer van, nagyobb tárkapacitású gépben nagyobb operációs rendszer lehet, amely több szolgáltatást tud nyújtani, mint egy kisebb gépé. (Azért ne higgyük, hogy az operációs rendszer szolgáltatásainak színvonala egyedül az elfoglalt tár méretétől függ.)
Minden gépnek van saját operációs rendszere. Vannak általános operációs rendszerek, amelyek különböző gépeken (majdnem) ugyanazt a szolgáltatást tudják nyújtani. Ilyen operációs rendszer például a személyi számítógépeken használható CP/M. Ennek néhány fontosabb szolgáltatását a függelék tartalmazza.

Ellenőrző kérdések és feladatok

1. Magyarázza meg, hogy mi a különbség az alábbi két szöveg között:

10 PRINT "VEGRE!"
PRINT "VEGRE!"

Mi történik, ha az elsőt gépeljük be, és mi akkor, ha a másodikat?
Minek a hatására lesz az eredmény ugyanaz mind a két szövegnél?

2. Mi a különbség az alábbi két program között?

a)
10 LET A=8
20 PRINT A

b)
10 INPUT A
20 PRINT A

3. Mi a különbség az alábbi két sor között?

PRINT "5+3"
PRINT 5+3

4. Gépeljük be a szorzatkitaláló programot, és másoljuk ki kazettára vagy lemezre! Ellenőrizzük, hogy jó-e a másolat!
Módosítsuk a programot az 1. részben leírtak szerint úgy, hogy A és B véletlenszerű szerű legyen. A módosítást a 3. függelékben leírtak szerint végezzük el! Az programot szintén másoljuk ki (de más névvel)!

3. A programozás módszere I.
A programkészítés módszere és lépései.
Az 1. feladat megoldásának első része.

Ebben a részben a programkészítés alapelveit ismerjük meg. Számítógépet nem fogunk használni csak a következő részben, amikor az itt elkezdett feladat megoldását befejezzük.

A program
Vizsgáljuk meg az 1. részben megoldott átlagszámítási feladatot megoldó programot! Nézzük meg, hogy az egyes utasítássorok milyen feladatot látnak el:

10 INPUT B
20 INPUT C
30 INPUT D
40 INPUT E
50 INPUT F
60 LET S=B+C+D+E+F
70 LET A=S/5
80 PRINT A

Az első öt utasítás hasonló feladatot lát el: adatokat kér be a billentyűzetről. Az itt beolvasott adatokat a 60-as és közvetve a 70-es sorszámú utasítás felhasználja, ezért ezek az adatok a megoldás kiinduló vagy bemeneti adatai. Ha ezeket nem adjuk meg, akkor a feladatmegoldás elveszti az értelmét.
A program további két utasítása - mint már említettük, a 60-as és 70-es sorszámú - a kiinduló adatokkal egy meghatározott műveletsort végez el, ez az öt szám összeadása és öttel való elosztása. De könnyen beláthatjuk, hogy feladattól függően itt más műveletek is állhatnának.
Az adatokkal való műveletvégzést általános érvénnyel feldolgozásnak nevezzük. Az adatok feldolgozása során a kiinduló vagy bemeneti adatokból új adatok (értékek) készülnek. Ezek az adatok alkotják a feldolgozás célját. A bemutatott példában a feladat célja az átlag kiszámítása volt. Ezért van szükség az egész műveletsorozatra, hogy a végén ezeket az új adatokat megkapjuk. Ezek a feldolgozás eredményei vagy másképpen a megoldás kimeneti adatai.
Bármilyen más, számítógéppel megoldott feladatot vizsgálunk meg, azt látjuk, hogy a feladat a kívánt eredményadatok előállítása valamilyen kiinduló adatból valamilyen feldolgozási műveletsorral:

Kiinduló adat Feldolgozás Eredmény

Ez természetesen nemcsak a programozásra jellemző, hanem bármilyen termelőfolyamatra is.
Számítógépes feladatmegoldásnál a kiindulás és az eredmény is adat: valamilyen számérték, valamilyen szöveg, ezért is nevezzük az ilyen feladatmegoldást adatfeldolgozásnak. Ezt a három művelettípus meg kell jegyeznünk, mert a további feladatok megoldásának magvát fogják alkotni.
A feldolgozás műveletek sorozatából áll, amely a bemeneti adatokból elkészíti az eredményi-(kimeneti) adatokat. A feldolgozás műveleteit és sorrendjüket a feladatnak megfelelően kell összeállítani. Az egy adott feladat megoldását szolgáló műveletsorozatot algoritmusnak nevezzük. A feldolgozási algoritmust a feladat alapján lehet meghatározni.
Egy feladat több különböző algoritmussal, hasonló feladatok ugyanazzal az algoritmussal is megoldhatók, vagyis nem kell minden feladathoz új algoritmust kitalálni.
Az algoritmust a feladat megoldójának kell megfogalmaznia. Ez azt jelenti, hogy a megoldónak kell meghatároznia a műveleteket és sorrendjüket úgy, hogy számítógéppel el lehessen végeztetni őket. A számítógépi műveletekből összeállított algoritmus a program. Másképpen: a program a számítógép nyelvére lefordított algoritmus.
A program - mint láttuk - utasításokból épül fel. Amikor a gép a programot végrehajtja, akkor ezeket a műveleteket a kijelölt sorrendben elvégzi, és hatásukra elkészül az eredmény. Ezekkel a megállapításokkal kiegészíthetjük az 1. részben felsorolt programjellemzőket.
A következőkben ismerjünk meg egy módszert, amely alkalmas arra, hogy feladatokat számítógép segítségével megoldjunk. Figyeljük meg, hogy a cél sohasem egy program megírása, hanem egy feladat megoldása, amelyben egy eszköz a program, így a számítógép is.

A feladatmegoldás módszere
Ha felmerül egy feladat (pl. a babkávé fogyasztását kell megjósolni az elkövetkező öt évre, vagy egy termékszerkezet rendelésállománya alapján a gyártó kapacitást és az alkatrész-szükségletet kell meghatározni, vagy egy vállalat dolgozóinak bérét kell kiszámítani a teljesítmények alapján), amelyet számítógéppel akarunk megoldani, akkor a feladat megfogalmazása után a megoldásig a következő lépéseket kell elvégezni:

Már itt megemlítjük, hogy valamennyi lépésben írásos anyagok is készülnek a megoldásról, amelyek együttesen alkotják a program dokumentációját. Az első három lépéssel itt, a többivel a 4. részben foglalkozunk egy egyszerű feladat megoldásán keresztül.
A programozási feladatok megoldásához olyan módszert mutatunk be, amely az elemzési, tervezési és kódolási szakaszban is hasznosan alkalmazható. Az alapmódszer: a moduláris programozás. A moduláris programozás lényege, hogy a feladatot részfeladatokra (funkciókra) kell felbontani, ezeket önállóan kell kódolni, majd az egyes modulokból össze kell állítani a kész programot. Először tisztázzuk a modul fogalmát.
A modul a programnak egy része, amely

A moduláris programozás leglényegesebb lépése a feladat modulokra bontása. Ez azt jelenti, hogy a feladatot funkciókra (részfeladatokra) kell bontani, és ezek fogják a modulokat alkotni. A modulok a feladat megoldásában betöltött szerepük szerint három csoportba oszthatók:

A vezérlőmodul irányítja egy vagy több modul, vagy az egész program végrehajtását. A vezérlőmodul a benne meghatározott sorrend szerint az 1. alárendelt modul végrehajtására tér át. Ha ezzel elkészült a gép, akkor ismét a vezérlőmodul veszi át a szerepet, és a következő modulra tér át a végrehajtás. Ez addig ismétlődik, míg valamennyi alárendelt modul végrehajtódik. A vezérlőmodulból való áttérést nevezzük hívásnak.
Példaként nézzünk meg egy olyan feladatot, amelyben egy vezérlőmodul van, és ennek három modult kell vezérelnie. Az első modulra öt számértéket kell beolvasnia, a másodiknak ki kell számítania a beolvasott öt adat átlagát, a harmadiknak pedig ki kell írnia az átlagot (6. ábra). A modulok a végrehajtás sorrendjében (balról-jobbra) helyezkednek el a vezérlőmodul alatt.


6. ábra: A vezérlőmodul működése

A vezérlőmodul az alábbiak szerint működik ebben a példában: Előszőr hívja az adatbeolvasást. Ezután ismét a vezérlőmodul fog működni, ami abban, áll, hogy hívja az átlagszámítást. Az átlagszámítás végrehajtása után újra a vezérlőmodul működik az átlagkiírás hívásával. A vezérlőmodul tehát úgy működik, mint egy karmester: az alárendelt modulok valamelyikét végrehajtja. A későbbiekben ennél bonyolultabb vezérlési műveleteket is fogunk látni.
A hívás helyett vezérlésátadást is szoktak mondani. Például a vezérlőmodul átadja a vezérlést az adatbeolvasásnak, majd a végrehajtás után vezérlés ismét a vezérlőmodulra kerül vissza.
Egyszerű szerkezetű programoknál a vezérlőmodul el is hagyható. Ilyenkor a modulok a megoldásnak megfelelő logikai sorrend szerint egymást hívják. A modulszerkezeti ábrán azonban a vezérlőmodult érdemes meghagyni, mert így jobban látszódik a feladat logikai szerkezete.

Az adatmodul a program adatainak meghatározására szolgál. Lényegében passzív modul, a feladat érdemi megoldásához szükséges műveleteket nem tartalmaz, csupán adatokat. A BASIC nyelvben egyszerű az adatmeghatározás: szigorúan véve csupán tömbök (több adatból álló adathalmazok) terjedelmét határozza meg. Adatmodulnak tekinthetjük azonban az olyan modulokat is, amelyekben kiinduló adatokat kell beolvasni, vagy változóknak induló értéket kell adni. Adatmodul például a 6. ábrán az adatbeolvasás modul.
Adatmeghatározás két módon lehetséges a programban:

Tanácsos a program elején az összes adatot egyszerre definiálni, mert így az adatmeghatározások egy helyen lesznek, de adott esetben ettől el is térhetünk.

Az eljárásmodulok valamilyen tényleges műveletet tartalmazó modulok. Ezek a modulok végzik el pl. a különböző feldolgozási műveleteket és a kiírásokat. Egy programon belül eljárásmodulból van a legtöbb, és ezek összessége hajtja végre a tulajdonképpeni feldolgozást. Eljárásmódul a 6. ábra átlagszámítás és átlagkiírás modulja.

Hogyan kapjuk meg egy feladat megoldásához szükséges modulokat? Nézzünk erre egy példát! Tegyük fel, hogy a feladat egy órabéres dolgozó havi bérének kiszámítása és az eredmény kiírása (bizonylat!). Vegyük sorra, hogy egy dolgozó bérének meghatározásához milyen feladatokat kell elvégezni. A feladatot első lépésben két részfeladatra bonthatjuk (7. ábra):


7. ábra: A feladat részfeladatokra bontása

A részfeladatok azonban még nem oldhatók meg egyszerűen, mert több különböző dolgot foglalnak magukban: a levonásokba beletartozik a nyugdíjjárulék levonása, az esetleges letiltások, CSÉB stb. Ugyanígy a bérösszetevők között van időbér, prémium, családi segély stb. Tehát egy következő lépésben a két részfeladatot bontsuk szét további részfeladatokra. Az összetevőkre ezt kapjuk (nem teljeskörűen):

A levonásokat - szintén nem teljeskörűen - az alábbi részfeladatok lehet bontani:

A részfeladatokra bontást addig érdemes csinálni, amíg nem kapunk olyan egyszerű, a többitől jól elkülöníthető részfeladatokat, amelyeket moduloknak tekinthetünk. Ezek után meg kell határozni a modul műveleteit, és a feladatot megoldó programot ezekből a modulokból kell felépíteni.
A fent bemutatott eljárás módszerünk másik fontos eleme, ti. a felülről lefelé haladás a megoldás során. Tehát az első lépésben meghatározzuk a feladatot. Ez a fő, a legmagasabban álló feladat. A következő lépésben megvizsgáljuk, milyen részfeladatot kell elvégezni, hogy a feladat meg legyen oldva. Ekkor megkapjuk a feladat egészének alárendelt részfeladatokat. Ezeket a feladat alá rajzoljuk, hogy jelöljük a felbontást. A részfeladatokat tovább lehet bontani újabb részfeladatokra, amelyeket a részfeladatok alá lehet rajzolni. Lényegében a feladat egészét bontjuk fokozatosan részfeladatokra. Közben szakaszosan haladunk a feladattól lefelé a legapróbb részfeladatokig. Ezért nevezzük az eljárást felülről lefelé haladásnak. A felülről lefelé való lebontás (top-down) során a részfeladatok "szinteket" alkotnak. A lebontást a feladat összetettségétől függően különböző számú szinten végezzük addig, amíg nem kapunk egyszerű, jól elkülöníthető, önállónak tekinthető részfeladatokat, amelyek már egy modulnak foghatók fel.
A módszer előnye, hogy a lebontás eredményeként jól látszik a részfeladatok - modulok - közötti összefüggés. A feladat módszeres felbontása abban is segít, hogy ne hagyjuk ki a feladat megoldásához szükséges részfeladatokat.

A feladatmegoldás folyamata

A feladat elemzése
Az első lépésben a feladatot fel kell bontani részfeladatokra (elegendő egy szinten), hogy lehessen látni, milyen jellegű tevékenységeket kell elvégezni a feladat megoldása érdekében.
Elemezni kell a feladat számítógépben való megoldhatóságát. Ha a feladat egyébként megoldható (ismertek a kiinduló adatok, a megoldási algoritmus, kiszámítható az eredmény stb.), akkor még mindig felmerülhet olyan akadály, amely részben vagy egészben meghiúsíthatja ezt. Ilyen ok például, ha a kiinduló adatok nem kaphatók meg időben az eredményadatok elkészítéséhez, illetve a számítógép képességeit meghaladó bonyolultság vagy adatmennyiség.
Itt kell meghatározni, hogy milyen műveletek nem végezhetők el a számítógéppel (pl. az eredményadatok elszállítása), vagy melyeket nem érdemes számítógéppel elvégezni (pl. túlságosan hosszú listák, amelyeket nem rendszeresen használnak). Az elemzés eredménye a megoldás algoritmusának pontos vagy nagyvonalú kialakítása is.

A program tervezése
A programtervezés a feladat elemzésének eredményeit használja fel. Fontos feladata a program szerkezetének további finomítása a feladatelemzés során kapott modulszerkezet tovább bontása révén. A meglevő funkciókat újabb részfunkciók megállapításával újabb szinteken bontjuk tovább. A bontást addig célszerű folytatni, amíg minden szinten lehetőleg egyszerű funkciót ellátó modulokat kapunk. Ezek a funkciók alkotják a program moduljait.
A bontás eredményeként kapott modulok között kapcsolat van. Ezeknek a kapcsolatoknak kell biztosítaniuk, hogy a modulok végrehajtása a helyes sorrendben történjen.
A programtervezés eredményeként létrehozott modulokat és a közöttük fennálló kapcsolatokat (struktúrát) egyezményes jelekkel ábrázoljuk:

A hívja B-t, majd C-t:
Az A modul előbb a B, majd a C modult hívja. Ha az A modul a B és a C modul vezérlőmodulja, akkor A valódi (a programban kódolt) modul. Ha a B és C modul csupán az A modul tovább bontása, akkor A modul nem létezik, ilyenkor csak a B és a C modul valódi, és ezek valamilyen sorrendben végrehajtódnak.
A szerkezet gyakorlati alkalmazására a 6. ábrán láthatunk példát.
Az A modul egy feltételtől függően vagy a B, vagy a C modult hívja:
Az A modul egy feltételtől függően vagy a B, vagy a C modult hívja. Az A modul feltételvizsgálati feladatot lát el a programon belül. A B és C modul végrehajtása a vizsgált feltételtői függ.
Az A modul ciklikusan hívja a B modult:
Erre akkor van szükség, ha egy adatcsoport valamennyi elemén ugyanazt a műveletet kell elvégezni (pl. egy vállalat dolgozóinak bérét ugyanazzal az eljárással kell kiszámítani). Az A modul annyiszor hívja a B modult, ahányszor a műveleteket végre kell hajtani.
A B modul önmagát hívja (rekurzív hívás).
Ez lényegében az előző pontban leírt szerkezet egyszerűsített változata, ha a vezérlő A modult elhagyjuk, és a ciklikus irányítást a B modulba építjük be.

A modulok végrehajtásának sorrendjét a vezérlőmodul, illetve ha több van, akkor a vezérlőmodulok megfelelő kialakításával kell biztosítani. A funkciókat megvalósító modulokat - mint már korábban utaltunk rá - balról jobbra haladva kell berajzolni a modulszerkezeti ábrába, mert a végrehajtás is majd balról jobbra halad.
A programtervezéshez tartozik annak az eldöntése is, hogy a program egyetlen program legyen, vagy több önálló programból álljon. Felmerül a kérdés, hogy mikor melyik megoldás a célszerűbb. Bonyolult, nagy feladatnál érdemes több programra felosztani az egészet.
Hasonló vagy azonos funkciók ellátására érdemes típusprogramot tervezni. Ezt csak egyszer kell elkészíteni, és ezek után több feladat megoldásában is alkalmazható. Sok fáradságot és időt lehet megtakarítani vele. A többször felhasználható modulprogramok modulkönyvtárat alkotnak.
Összefoglalva megállapíthatjuk, hogy a program modulokra bontásának számos előnye van:

A modulok tervezése
Az egész program megtervezése után a program "építőköveinek" - a moduloknak - a tervezése következik. A tervezés során meghatároztuk a feladat megoldásához szükséges modulokat. Láttuk, hogy a modul egy részfeladatot old meg. Az egész feladat megoldása szempontjából azt is meg kellett határozni, hogy egy modul hogyan kapcsolódjék a többihez, mikor kell feladatát megvalósítania, honnan kapjon adatokat, stb. Ez a modul külső specifikációja. Továbbá le kell írni azokat a belső folyamatokat, amelyek végrehajtásával a modul teljesíti funkcióját.
A külső specifikációhoz tartozik a modul neve, amellyel a programozó az adott modult azonosítja. Ide tartozik a modul típusának (vezérlő-, adat-, eljárás-) meghatározása is. Végül azt is definiálni kell, hogy a modul milyen módon kapcsolódik a környezetéhez, vagyis hogyan lehet hívni, és mi történik a befejezéskor.
Általánosan követendő szabályként javasoljuk az olyan modulok tervezését, amelyek fő jellemzője, hogy egyetlen bejáratuk és egyetlen kijáratuk van. Ez azt jelenti, hogy a modul végrehajtása mindenféleképpen ugyanazon a kezdő utasítássoron indul, és ugyanazon a záró utasítássoron fejeződik be. Ez a modulok zártságát, áttekinthetőségét fokozza, és nem lebecsülendő az sem, hogy ilyenkor a módosítás könnyebben elvégezhető.
A modul belső tervezése három fő lépésből áll:

  1. A kiinduló adatok leírása
    Részletesen le kell írni minden tárolt vagy az előző modulok által készített adatot, amelyet a modul a végrehajtáskor felhasználhat. A meghatározás tartalmazza a kiinduló adatok tárolási módját (külső tárolón, tárban stb.), jelölését, típusát (szöveges, számérték vagy mindkettő) és értéktartományát.
  2. Az eredményadatok leírása
    A modul funkciója az eredményadatok előállításával valósul meg. A modul tervezésekor ezeket is részletesen meg kell határozni (pl. a kiírás formája, a tárolt adatok felépítése, jelölése stb.).
  3. A feldolgozás folyamatának meghatározása
    Meg kell határozni azokat az adatokon végrehajtott műveleteket és végrehajtási sorrendjüket, amelyeknek eredményeként megjelennek a szükséges kimeneti adatok.

A feldolgozási folyamatot folyamatábrával tesszük képszerűbbé és könnyebben áttekinthetővé. Sok olyan művelet van, amely rendszerint több feldolgozási folyamatban is előfordul. Ezeket célszerű egységes folyamatábrajellel jelölni. Így alakultak ki a folyamatábra-szimbólumok, amelyek egy-egy művelettípust vagy eszközt jelölnek.
A következőkben áttekintjük a gyakrabban használt folyamatábra-szimbólumokat:

Tárolóeszközök: Perifériák és velük kapcsolatos műveletek:
Lyukkártyaállomány
(mikrogépeknél nem használt)
  Sornyomtató, bemeneti bizonylat, kiírás (lista)
Mágnesszalag-állomány   Képernyős terminál
Mágneslemez-állomány    
Lyukszalag
(mikrogépeknél nem használt)
  Billentyűzet kézi adatbevitel

Műveletek:
Bemeneti vagy kimeneti művelet   Külön meghatározott művelet, amely önmaga is egy több lépéses folyamatábra lehet. Akkor használjuk, ha a folyamatábrában egy, már meghatározott műveletsorozatot nem akarunk részletezni.
Tetszőleges műveleti jelkép. A művelet meghatározását a téglalapba kell beírni.  
Határoló jelkép. A folyamat kezdetén és végén alkalmazzuk.

Döntés. A döntés valamilyen vizsgálaton alapszik. A vizsgálat eredményeként a program végrehajtása 2-3 irányban haladhat tovább.

  Adatátvitel - jelölés távadatfeldolgozásnál.
(mikrogépeknél nem használt)

Rajztechnikai jelek:
Folyamatvonal a folyamatvégrehajtás irányával.   Kapcsolójel. A folyamatvonal elágazását vagy találkozását jelöli.
Folyamatvonalak keresztezése.   Magyarázó jelkép, amely valamilyen folyamatábra-jelhez kapcsolódik. Akkor használjuk, ha a kívánt szöveg nem fér el a szimbólumban. A kiegészítő szöveget a magyarázó jelkép jobb oldalára írjuk.

A folyamatábra-jelölések egyszerűek és könnyen érthetők. Rajzolásuk megkönnyítésére a kereskedelemben folyamatábra-sablonok kaphatók.
A modul funkcióját megvalósító folyamat sokféleképpen mehet vég be. A programozók körében elfogadottá vált az az elv, hogy az algoritmusokban három algoritmustípust elegendő alkalmazni. Ezeket a folyamat-"építőköveket" fogjuk mi is felhasználni:

Szekvencia
Két vagy több utasításból álló utasítássorozat. Egy szekvencia tetszőleges típusú és számú műveletet tartalmazhat.


8. ábra: Szekvenciális műveletek

Feltételes elágazások
Valamilyen feltételtől függően:


9. ábra: Az IF THEN típusú szerkezet


10. ábra: Az IF THEN ELSE típusú szerkezet


11. ábra: A CASE típusú szerkezet

Megfogalmazhatunk egy olyan részfeladatot, hogy a gép által kiszámított helyes szorzatot csak akkor írja ki a gép a képernyőre, ha a játékos helytelen értéket gépelt be. Ez az első típusú folyamat. Ilyenkor a kiírási műveletet csak akkor kell végrehajtani, ha a számított és a begépelt összegek eltérőek, egyébként nem.
Megfogalmazhatjuk olyan formában is a részfeladatot, hogy ha a játékos eltalálja az eredményt, akkor elismerésként a "GRATULALOK" üzenetet, ha nem találta el, a "SAJNOS, EZ ROSSZ" üzenetet kell ki írni. Ez a második típusú folyamat alkalmazását teszi szükségessé, mivel valamelyik üzenetet mindig ki kell írni. A több műveletből való kiválasztásra a 6. részben fogunk látni egy feladatot.

Ciklus
Ha például egy raktárban levő anyagok értékét kell kiszámítani, akkor minden anyag esetében az egységár és a mennyiség szorzatát kell kiszámolni és az eredményt összegezni. Ilyenkor a művelet elvégzését nem érdemes annyiszor leírni, ahányszor végre kell hajtani, hanem a műveletet ciklikusan kell megismételni az összes anyag adataival. A ciklikus műveletek végét valamilyen feltétel határozza meg (pl. ha minden anyag értékét kiszámítottuk).
A ciklikus műveletek a végfeltétel-vizsgálat helyétől függően két formában hajthatók végre:


12. ábra: Az elöltesztelő ciklusszerkezet


13. ábra: A hátul tesztelő ciklusszerkezet

A "tiszta" esetek mellett vannak olyanok is, amikor az abbahagyás (vagy folytatás) feltételét sem elöl, sem hátul, hanem valahol középen ellenőrizzük.

Most pedig nézzük meg a feladatmegoldás első három lépését egy konkrét feladaton!

1. feladat
Adva van a 14. ábrán látható ellenállásokból álló hálózat. Meg kell határozni az A és B pont közötti eredő ellenállást. Az ellenállások értékei:

R1 = 1000 ohm
R2 = 2000 ohm
R3 = 500 ohm
R4 = 200 ohm


14. ábra: Az I. feladat

A program az alábbi formában írja ki az eredő ellenállás értékét:

AZ EREDO ELLENALLAS (OHM): x

A feladat elemzése
Nézzük meg, mit eredményez a feladat elemzése! A feladat az eredő ellenállás meghatározása ismert adatokból. A feladat számítógéppel megoldható. A feladatot megoldó programnak az alábbi főbb funkciókat kell megvalósítania:

A feladatban felmerült eredő ellenállást az ismert összefüggés alapján lehet kiszámítani:

Végül elkészítjük a feladat modulokra bontásának első közelítését (15. ábra):


15. ábra: A feladat modulszerkezete

A program tervezése
Most pedig végezzük el a programtervezés folyamatát a feladaton!
A probléma egyszerűsége miatt nincs szükség a modulszerkezet további finomítására. Így az elemzéskor kapott modulszerkezetet a programtervezés alapjának is tekinthetjük.
Látható, hogy a modulokat egyszerű szekvencia szerint [(1), (2), (3)] kell véghajtani, ezért a feladat egyszerűsítése végett a vezérlőmodul alkalmazásától eltekintünk (15. ábra).

A modulok tervezése

  1. A bemeneti adatok tárolása
    A modul adat típusú, mert egyetlen funkciója a négy ellenállásérték tárolása. Önálló bemeneti adatai nincsenek, a kimeneti adatokat az ellenállások értékei adják. A modul algoritmusa az R1, R2, R3, R4 változó értékeinek megadása (16. ábra)

  2. Ellenállás-számítás
    A modul eljárás típusú, mert feldolgozást végez. Bemenete a négy ellenállásérték, kimeneti adata az R9 eredő ellenállás. Az alkalmazott algoritmus a soros és párhuzamos ellenállásokból álló hálózat eredőellenállás-számítására vonatkozó ismert kifejezésre épül: R9= 1/(1/R1+1/R2+1/R3)+R4
    Először határozzuk meg a tört nevezőjében álló kifejezést, jelöljük K0-val, majd ennek vegyük a reciprokát. Ezzel a jobb oldal első tagját kiszámítottuk. Az R4 érték hozzáadásával megkapjuk R9-et. Az algoritmust a 16. ábra mutatja.

  3. Eredménykiírás
    Ez is eljárás típusú modul. Bemeneti adata a (2) modulból származó R9 eredő ellenállás értéke. Az eredményadat ugyanez, de kiírva.
    A specifikáció szerint a modulnak egy megadott szöveg után ki kell írnia az eredő ellenállás értékét. Ezt egy lépésben el lehet végezni (lásd 16. ábra). A kiírás után a program befejeződik.


16. ábra: A modulok folyamata

Ellenőrző kérdések és feladatok

1. Egy számítógépes feladat megoldása milyen főbb lépésekből áll?

2. Mi a program?

3. Milyen lépésekből áll egy feladat megoldása?

4. Munkahelyén vagy otthon keressen egy megoldandó feladatot, és végezze el a feladatmegoldás első három lépését!
Milyen feltételek teljesülése mellett oldható meg a feladat számítógéppel?
Mennyivel nyújt többet a számítógépes megoldás, mint a jelenlegi ún. "kézi" megoldás?

5. Milyen rajzjeleket használt a modulok műveleteinek ábrázolásához?

4. A programozás módszere II.
A programkészítés módszere és lépései.
Az első feladat megoldásának befejező része

Ebben a részben folytatjuk a programkészítés lépéseinek részletes bemutatását és a lépések illusztrálásaként befejezzük az 1. feladatot.

A feladatmegoldás folyamata
(folytatás a 3. részből)

A kódolás
A kódolás a folyamatábrában rögzített műveletek megfogalmazása az adott programnyelven, jelen esetben BASIC nyelven. A kódolást modulonként külön-külön, a folyamatábra alapján kell elvégezni. A kódolás eredményei az utasítássorok vagy röviden utasítások. A folyamatábra lefordításánál figyelembe kell venni az adott nyelv lehetőségeit, sajátosságait. Ezért nem csupán szóról szóra kell fordítani, hanem a program-nyelv szerkezeti sajátosságaira is ügyelni kell.
Egy utasítás egy mondatnak felel meg. Az utasítások a BASIC nyelvben "mondattanilag" két részből állnak: a kulcsszóból, amely a mondat állítmányának felel meg, és az utasítás tárgyából, amely azt mutatja, hogy mire vonatkozik az utasítás.
A végrehajtás sorrendjének meghatározásához az utasítások sorszámot is kapnak. A sorrend kijelölésén kívül ez az utasítás azonosítója is, ezzel hivatkozhatunk az utasításra.
Egy BASIC utasítás tehát három részből áll:

sorszám, utasításkulcsszó, az utasítás tárgya

Célszerű, de nem kötelező az egyes részek között legalább egy szóközt hagyni (a Spectrum ezt automatikusan megteszi helyettünk), de a sorszámon és az utasításkulcsszón belül nem lehet szóközt írni. Az elmondottak értelmében formailag helyesek a következő utasítások:

100 LET A=8
100LETA=8

Formailag hibásak az alábbi sorok:

100 L E T A=8
1 0 0 LET A=8

A BASIC utasításokat sorokba írjuk. Általában egy sorba egy utasítás írunk (de megengedett, hogy kettősponttal elválasztva több utasítás álljon egymás után). Könyvünk további részében - néhány esetet kivéve - ezt a szabályt fogjuk alkalmazni.
Felhívjuk a figyelmet, hogy egy sor nem azonos egy, a képernyőt megjelenített sorral (ez a képernyősor). Egy sor addig tart, amíg le nem nyomjuk a sorzáró karaktert. Egy utasítássor tehát több sort is elfoglalhat a képernyőn. Természetesen a sorhossznak van felső határa. Ez különböző gépeknél a következő:

Egy sorba legfeljebb ennyi jelet írhatunk. Ha egy sor betelik az utasítás soron belül, akkor a gép automatikusan sort emel, és a helyőr a sor elejére ugrik.
Megjegyezzük, hogy egy utasítássorba több utasítást is írhatunk, de egy utasítást sohasem szabad két utasítássorba írni! Ha egy sorba több utasítást írunk, akkor ezeket kettősponttal kell elválasztani. Ha egy sorban több utasítás van, akkor ezt többszörös utasításnak nevezzük. A program áttekinthetősége kedvéért a többszörös utasítások használatát kerülni kell, különösen kezdőknek.
Most pedig vizsgáljuk meg az utasítások részeit!

A sorszám
Mint már láttuk, a program utasítássorait sorszámmal kell ellátni. A program futásakor az egyes utasítások a legalacsonyabb sorszámtól a sorszámok növekvő sorrendjében hajtódnak végre. Egy sorban csak a sor elején lehet egy sorszám. Többszörös utasításoknál a sorban levő első utasítás kap sorszámot, a többi nem.
Említettük már, hogy a sorszám az utasítás azonosítója, ezzel hivatkozhatunk rá. Ha egy sorban például valamilyen szintaktikai (formai) hiba van, akkor a gép a hibaüzenetben a hibás sor számát is kiírja. Így programozó rögtön tudja, hol keresse a hibát.
A sorszámot a program készítője határozza meg. A program első utasítása kapja a legalacsonyabb sorszámot, a többi utasítást a végrehajtás sorrendjének megfelelően növekvő sorszámmal kell ellátni. A sorszám téves begépelése az utasítás végrehajtási sorrendjét megváltoztathatja, és a program hibásan fog működni.
Ha két utasítást ugyanazzal a sorszámmal gépelünk be, akkor a másodszorra beírt utasítás az elsőt törli, mivel a gép azt az illető utasítás javításának tekinti.
A sorszám szerinti végrehajtást néhány utasítás megváltoztathatja. Ezeket - a többi utasítással együtt - a következőkben részletesen bemutatjuk.
Bár az utasítások végrehajtási sorrendjét nem a begépelésük sorrendje határozza meg, hanem a sorszámuk, mégis célszerű az utasításokat a végrehajtás sorrendjében begépelni.
Az utasítások sorszámozása a következő lehet:

Ez a szám elég nagy ahhoz, hogy ne okozzon gondot.
Ajánlatos az utasításokat ötösével vagy tízesével sorszámozni. Ha ugyanis a helyes működés végett az utasítások közé újabb utasítást kell beszúrni, akkor ez az utasítás (vagy utasítások) megkaphatja a fel nem használt sorszámot. Ha egyesével számozzuk az utasításokat, akkor egy kényszerű beszúrásnál át kell sorszámozni az egész programot.

paranccsal lehet működtetni. A "sorszám"-mal kezdő sorszámot lehet megadni, a "növekmény" a két egymás után következő utasítás sorszámának különbsége. Ha a növekményt nem adjuk meg, akkor a gép 10-nek veszi. Ha a sorszámot nem adjuk meg, akkor a sorszámozás a 10-nél fog kezdődni.
A parancs kiadása után hozzákezdhetünk a program begépeléséhez. A NEW LINE, illetve a RETURN lenyomása után a következő sor elején megjelenik a következő utasítás sorszáma, így ezt már nem kell begépelni. Ha beírtuk a programot, a HT esetében a BREAK, a PRIMO esetében a BRK gombot kell lenyomni, és ezzel az automatikus sorszámozás befejeződik, a gép visszakerül a szokásos üzemmódba.

Az utasításkulcsszó
Az utasításkulcsszó műveletet határoz meg. Az utasításkulcsszavak meghatározott szavak, a függelékben megtalálhatók. Az utasításkulcsszavakat csak a megadott formában - szintaktika szerint - lehet használni, Mindemellett minden utasításnak a Commodore-on és a PRIMO-n van úgynevezett rövidített - két karakterből álló - formája is.
A Sinclair-gépeknél az utasítások billentyűkön vannak, így egyetlen gomb lenyomásával egy utasítás beírható, elgépelni nem lehet.
Itt most egyetlen utasítást mutatunk be, amely műveletet nem hajt végre, de dokumentációs szempontból fontos. Ez a megjegyzést jelölő, REM utasításkulcsszó:

30 REM ITT KEZDODIK A SZAMOLAS

Ez az utasítás azt jelenti, hogy a számítógépnek semmilyen műveleten sem kell elvégeznie, áttérhet a következő utasítás végrehajtására. Az utasítás tárgyában levő szöveget a programozó saját magának beírja, hogy a program nevezetes pontjait megjelölje, dokumentálási céllal.

Az utasítás tárgya
Az utasítás tárgya legtöbbször valamilyen adat, amellyel valamit elvégez a gép, de lehet utasítássorszám is. Van olyan típusú utasítás is, amelyhez nem tartozik tárgy. Az utasítás tárgyára majd az egyes utasítások bemutatásánál láthatunk példát.

A kódolás módszere
A programkódot tanácsos először kódlapra (vagy más papírra) megírni, és csak ellenőrzés után begépelni. Nem javasoljuk a rögtönzött kódolást a terminálon a folyamatábra alapján, mert az még rövid, egyszerű moduloknál is nagyon sok hibát okozhat. A kódolásnál érdemes néhány szót szólni a dokumentációról.
A programdokumentáció a programról rendelkezésre álló írásos információ. A dokumentációnak írásban kell rögzítenie a program célját, a feladat megoldási és az adatok tárolási módját, a bemeneti-, az eredményadatokat, és általában minden olyan adatot, amely lehetővé teszi, hogy más szakember is megismerje, megértse programunkat. Lényeges, hogy a dokumentáció segítse a program készítőjét vagy javítóját, hogy a programot - ha módosítani kell - 1-2 év után is megértse.
Az alkalmazott módszernek megfelelően a következő dokumentumok készülnek a programmal párhuzamosan:

Valamennyi programdokumentummal kapcsolatban általános követelmény, hogy az érdekeltek hozzáférhessenek. Ezért a felhasználók számának és igényeinek megfelelő példányszámban és minőségben kell a dokumentumokat elkészíteni. A dokumentáció legyen tömör, világos szerkezetű.
A dokumentumok közül kettőt emelünk itt ki, a többit a feladatok megoldása során ismerjük meg. A programkód listája a program egyes sorainak a listája abban a formában, ahogy a program tárolódik. A programlista önmagában nem beszédes dokumentum. Olvashatóságát növeli, ha a REM utasítással különböző magyarázatokat, közléseket helyezünk el benne. REM utasításokkal a program elejére beírhatjuk a program nevét. Egy ilyen megoldás:

10 REM ***********
20 REM *         *
30 REM *  TREND  *
40 REM *         *
50 REM ***********

Sormintának a csillag helyett bármilyen más, BASIC által ismert karaktert alkalmazhatunk. A REM utasítással üzeneteket helyezhetünk el a program kritikus pontjain vagy az egyes programmodulok elején:

200 REM *** OSSZEG KIIRAS ***

Változók jelentését is megadhatjuk:

30 REM IL: IDOLEPTEK

BASIC-ben a programot a

LIST

paranccsal listázhatjuk ki a képernyőre, vagy a program egy részét, ha megadjuk a rész kezdő- (n) és a záró sorának (m) sorszámát a LIST parancsban:

LIST n-m

Ha csak a kezdő sorszámot adjuk meg, akkor a gép a megadott tói kezdve kiírja az egész programot:

LIST n-

Ha viszont csak a záró sorszámot adjuk meg, akkor a gép a program kezdőrészét írja ki az m sorszámig:

LIST -m

Végül egyetlen sort is ki lehet listázni, ha megadjuk a sorszámot:

LIST n

A képernyőn megjelenő lista nem marad meg, és így mint dokumentum nem használható. A lista akkor látja el legjobban feladatát, ha á gép maradandó formában tudja elkészíteni. Erre a legjobb megoldás, ha a lista nyomtatva készül. Ha a számítógéphez nyomtató is tartozik, akkor listát kinyomtathatjuk. Commodore-géppel a program listáját az alábbi többszörös paranccsal lehet elkészíteni:

OPEN3,4:CMD3:LIST

ahol

A parancs hatására a gép kiírja a tárban levő program listáját a nyomtóra. A lista kiírása után a kiírást vissza kell állítani a képernyőre, ezért a gép és a nyomtató közötti utat le kell zárni a következő paranccsal:

PRINT#3:CLOSE3

ahol

A HT gép, a PRIMO és a Sinclair-gépek esetében a tárban levő programot az

LLIST

parancs kiadásával lehet nyomtatóra kiíratni. A parancs ugyanúgy használható, mint a LIST utasítás. (Megjegyezzük, hogy a HT géphez csak egy külön csatolóegységen keresztül lehet nyomtatót csatlakoztatni.).

A felhasználói kézikönyv a program felhasználójának készül. Megmutatja, hogy a programot hogyan lehet használni az adott feladat megoldására. Tartalmaznia kell a végrehajtáshoz szükséges bemeneti adatokat és bevitelük módját, a futtatás (végrehajtás) parancsait, az eredményadatok kezelését, a program üzemszerű szolgáltatásait. Meg kell adnia a különböző hibáknál kiadott hibaüzenetek értelmezését és a hiba elhárításához szükséges tevékenységeket.

A program kipróbálása
A tesztelés a program elkészülése utáni munkafázis, célja, hogy megállapítsa, helyesen működik-e a program. Ha kiderül, hogy nem, akkor a program hibás. Ekkor a hibát meg kell keresni, ki kell javítani, és a programot újra kell futtatni.
A tesztelés általánosan elfogadott elve, hogy

kell elvégezni. A modulonkénti tesztelés azért kedvező, mert egy viszonylag kicsi, jól áttekinthető részt fog át. Valamennyi modul ellenőrzése után az egész programot is tesztelni kell. A megtervezett próbaadatok jelentősége abban áll, hogy minél kevesebb próbaadattal minél teljesebb ellenőrzést lehessen elvégezni.
A tesztelés lényege, hogy különböző bemeneti adatokkal próbáljuk ki a programot (illetve a modulokat), és közben figyeljük, hogy a specifikáció szerint működik-e. A hibakeresés nehezen formalizálható, sok intuíciót követelő tevékenység. Még könyörtelenebb logikát kíván a program készítőjétől, mint a program tervezése vagy írása. Egy program elkészítése során a hibakeresés szokta okozni a legnehezebb perceket, órákat. Gyakran maga a program készítője is "ciklusba esik", és nem tud tud megszabadulni attól a gondolattól, hogy a program biztosan jó, valami rejtélyes dolog okozza a hibát. Ilyenkor logikusan végig kell gondolni, hogy mi a jelenség oka, mi idézi elő, és hogyan javítható ki. Bármilyen hibakeresés alapja, hogy a felhasználó a programlista alapján tájékozódjék, mi lehet a hiba.
Az első futások eredménye a szintaktikai (formai) hibák kimutatása lesz. A szintaktikai hibák kijavítása után olyan tesztadatokat kell megadni, amelyek lehetőleg minden utasítást kipróbálnak, eközben figyelni kell a működés helyességét. Ebbe a fázisba tartoznak a szélsőséges adatok is, amelyek a legszigorúbb követelményeket jelentik (pl. mit csinál a modul akkor, ha a felhasználó tévesen negatív számot ad meg egy dolgozó bérének). Ha a modul nem a specifikáció szerint működik, akkor a hibakeresésre térünk át.
A hibakeresés egyik eszköze a program listája. Hiba esetén a programlista alapján ellenőrizni kell, hogy melyik utasítás vagy utasításcsoport idézi elő a hibát. Lehet, hogy csak egy elgépelés a hiba oka, de lehet az is, hogy valamit nem vettünk figyelembe, valamit kifelejtettünk stb. Ezt kell megkeresni a lista alapján. Ha nem sikerül, akkor más eszközhöz is folyamodhatunk.
Egy másik eszköz a STOP utasítás és a közvetlen mód együttesi használata, amit az 1. részben ismertünk meg. A STOP utasítás a BASIC programokban használható utasítás. Hatására a program leáll, és a

BREAK IN LINE sorszám

üzenetet, a Sinclair-gépeknél a

9 STOP statement

üzenetet írja ki.
A LINE szó után álló szám a STOP utasítás sorszáma, ahol leállt a program.
Ekkor közvetlen módban ki lehet íratni az egyes változók aktuális értékét. Legyen például az alábbi program:

10 LET A=5
20 STOP
30 LET B=4

A program végrehajtása után a

BREAK IN LINE 20

üzenet jelenik meg, és a program leáll.
Ekkor közvetlen módban ki lehet íratni az A változó értékét:

PRINT A

Ezzel a módszerrel meg tudjuk vizsgálni, hogy a program egy adott pontján a változóknak mi az értéke. Ebből nagyon sok következtetést le lehet vonni. Kiderülhet, hogy valamilyen műveletet kihagytunk, valamilyen műveleti jelet rosszul írtunk be stb.
utasítással leállított program a CONT parancs kiadásával folytatható a leállás helyétől. Egy programot több helyen is meg lehet szakítani szükség esetén, és mindenütt folytatható a CONT paranccsal. A közvetlen mód fenti alkalmazása a program végén is lehetséges.
A felfedett hiba jellegétől függően javítható ki. Ha elemzési hiányosság okozta, akkor vissza kell térni az elemzésre, és a programot újra kell tervezni, illetve a tervet módosítani. Ugyanez érvényes a modulokra és a kódra is. Ha a hibát a tervezésben követtük el, akkor csak ide kell visszatérni. A legegyszerűbb esetben pedig csak a kódot kell kijavítani.

A program végrehajtása
Az elkészült (vagy félkész) programot a RUN paranccsal futtathatjuk le. A parancs hatására a számítógép a program utasításait a sorszámoknak megfelelő sorrendben végrehajtja. Ha eközben formai (szintaktikai) hibát talál, a futás leáll, és hibaüzenet jelenik meg. A normális végrehajtást az jelzi, hogy a gép nem ad ki hibaüzenetet, és megjelenik a READY üzenet.

A kapott eredmények értékelése
Ennél a lépésnél feltételezzük, hogy programunk hibátlanul működik. Azt kell vizsgálni, hogy helyes volt-e a megoldás elve, valóban a várt eredményt kaptuk-e stb. Emellett a működés körülményeit is ellenőrizni kell, nevezetesen azt, hogy nem lehet-e lerövidíteni a program végrehajtását, nem tudunk-e biztonságosabb megoldást találni. Ez az utolsó lépés az előzőektől eltérően kevésbé formalizálható, és nagymértékben függ a feladattól.

Kódolási alapismeretek
A programkészítés lépéseinek áttekintése után térjünk vissza az 1. feladat megoldásához, és folytassuk ezt a programkód elkészítésével. Előbb azonban a program elkészítéséhez szükséges kódolási alapismeretekkel és utasításokkal foglalkozunk.

A változó
A számítástechnikában - a matematikában kialakult fogalomhoz hasonlóan - a változó olyan adat, amelynek értéke változhat a feldolgozás közben. Ezért jellemzője nem egy konkrét érték, hanem a logikai funkció, amit a feldolgozásban betölt. A változóra egy szimbolikus névvel hivatkozunk, amely önállósítja és elkülöníti a többi adattól.
A számítástechnikában a változónak mindig konkrét értéke van, és ez a tárban tárolódik. Ha a változóval végzett műveletek során az értéke megváltozik, a korábbi érték elvész, és csak az új marad meg.
A változók tartalmuk szerint három típusba sorolhatók:

Ebben a részben az első kettőt mutatjuk be, a szöveges változókat a 6. részben ismerjük meg.
A numerikus változók értéke egy valós szám lehet. A BASIC nyelvben betűkből és számokból álló neveket kaphatnak. Ez a név nem lehet utasításkulcsszó vagy bármilyen védett BASIC üzenet, parancs, függvénynév. A változónév hossza BASIC-változatonként eltérő, az általunk használt három gépen (Commodore664, HT, PRIMO) legfeljebb 16 karakter lehet, amelyből az első csak betű lehet. A gép viszont csak első két karaktert jegyzi meg. Nézzük például az alábbi két váltózónevet:

ABLAK
ABBA

A gép nem tesz különbséget a két változó között, mivel a két első karakter egyezik mindkét névben. A következőket azonban különbözőnek tekinti:

A1BEM
A2BEM

A tévesztés lehetőségének elkerülésére a továbbiakban csak legfeljebb két karakter hosszúságú váltózónevekét fogunk használni. Az egész értékű változó csak egész értéket vehet fel bármilyen művelet eredményeként.
A változónévben kikötéseket tehetünk a változó típusára is. Így például előírhatjuk, hogy egy változó csak egész (integer) legyen. Ilyen esetben a változó nevéhez a % jelet kapcsoljuk. Ha ilyen megkülönböztetést nem teszünk, akkor a változó értéke vegyes szám lesz.
A fentiek értelmezésére nézzünk néhány helyes, illetve helytelen változónevet:

Helyes Változónevek
Helytelen változónevek
AB
A.B (pontot tartalmaz)
AB%
1F (számmal kezdődik)
X1
F%2 (A % után még áll valami)
X%
ABBA (formailag helyes, de kerülendő)

A Sinclair-gépeken a numerikus változók neve betűvel kezdődik, és betűkből, valamint számokból állnak. Hosszukat a tárméret korlátozza. Egész típusú változó nincs ezeken a gépeken. A változó nevének első karaktere itt is betűnek kell lenni, de a névben megengedett - mégis ellenjavalt - a szóköz karakter használata is. Érdemes megjegyezni, hogy ugyan kis- és nagybetűket is lehet alkalmazni a változók nevéhez, de ugyanannak a betűnek a kis és nagy változatát azonos betűnek tekinti. Néhány példa:

Helyes Változónevek
Helytelen változónevek
OSSZEG
10OSSZEG (számmal kezdődik)
EGY ES KETTO
EE-KK (a kötőjel nem megengedett)
Vacak3
   
VCAK3
   

A gép a két utóbbi helyes változónevet nem tekinti különbözőnek.
A BASIC nyelvben a változókat nem szükséges a program elején meghatározni. A programban bárhol lehet új változókat bevezetni. A BASIC - kivéve a Spectrum BASIC - minden numerikus változónak automatikusan 0 értéket ad, ha valamelyik utasításban nem kap értéket. Spectrumon a változóknak az első használat előtt kezdőértéket kell adni.

Feldolgozási lépések
A feldolgozás során az adatokkal számításokat, illetve logikai műveleteket végzünk. A számítási műveletek a BASIC-ben egyszerűen megadhatók:

összeadás A+B
kivonás A-B
szorzás A*B
osztás A/B
hatványozás A^B

Gyökvonás törtkitevős hatványozással végezhető el, illetve a négyzetgyökvonás az SQR függvénnyel is elvégezhető.
A változók és a közöttük álló műveleti jelek kifejezést alkotnak, amellyel valamit ki tudunk számítani. Egy kifejezés értékének kiszámítását és egy változóban való megőrzését értékadásnak nevezzük. Erre szolgál a már látott LET utasítás.
Ha az A*B szorzatot egy C változóban akarjuk tárolni (megőrizni), akkor ezt a következő utasítással érhetjük el:

70 LET C=A*B

A LET utasításkulcsszót el is hagyhatjuk a Sinclair-gépek kivételével:

70 C=A*B

Az értékadó utasításban tehát egy egyenlőségjel fejezi ki az értékadást (egyenlővé tevést). Az egyenlőségjel bal oldalán mindig egyetlen változó állhat, a jobb oldalán pedig egy tetszés szerinti kifejezés. Megjegyezzük, hogy a bal oldali változó valamelyik jobb oldalon álló változó is lehet:

70 LET A=A*B

Ez azt jelenti, hogy A értéke felveszi az A*B szorzat értékét. Nagyon fontos, hogy az egyenlőségjel jobb és bal oldala akkor sem cserélhető fel, ha mindkettőn egy-egy változó áll. Például a

80 LET A=B

utasítás azt jelenti, hogy A felveszi B értékét. Ha B=5, akkor az utasítás hatására A=5 lesz. Ha felcseréljük az egyenlőség jobb és bal oldalán álló változókat, akkor az eredmény más lesz:

80 LET B=A

Eszerint B veszi fel A értékét. Ha A=10 volt, akkor az utasítás hatására B is 10 lesz. A két eredmény tehát nem egyezik.
A bonyolultabb kifejezések sok műveletet tartalmaznak, ezért azt egyértelműség kedvéért a műveletek között elsőbbségi rangsort kell kialakítani. A BASIC nyelvben is megengedett a zárójelek használata (figyeljük meg, hogy van nyitó és záró zárójel). A zárójelek ugyanolyan műveletvégzési sorrendet írnak elő, mint ahogy azt a matematika is előírja: a legbelső zárójeles kifejezést számítja ki először a program, majd innen fokozatosan halad kifelé. Pl.:

((A1+B1)*(A2+B2))^K

A zárójeles kifejezésrészen belül vagy a zárójel nélküli kifejezésben az egyes műveletek sorrendjében a következő prioritási szabályok érvényesülnek:

  1. Hatványozás.
  2. Szorzás és osztás (ha több van, akkor ezek elvégzése egymás után, balról jobbra halad).
  3. Összeadás és kivonás azonos prioritással (ha több van ezekből a műveletekből, akkor a kiszámítás itt is balról jobbra halad).

Ha egy kifejezésben több azonos szintű szabályba tartozó művelet van, akkora műveletek kifejtése balról jobbra halad:

A*B/C értelmezése:
1. D=A*B
2. E=D/C
A*B+C*D értelmezése:
1. E=A*B
2. F=C*D
3. G=E+F

Az eredmények kiírása
Mint már az 1. részben láttuk, a feldolgozás eredményeit a PRINT kulcsszavú utasítással lehet kiírni. A PRINT utasítás tárgyában idézőjelbe tett karaktereket a program változatlanul kiírja, az idézőjel nélkülieket változóknak vagy kifejezésnek tekinti, s ezek tartalmát írja ki. Ha az utasítás tárgya kifejezés, akkor ennek értékét előbb kiszámítja és utána írja ki.
Ha például az eredő ellenállás szöveget akarjuk kiíratni, akkor ezt a

100 PRINT "EREDO ELLENALLAS"

utasítással lehet elérni.
Ha a feladat a C változó értékének kiíratása, akkor a

110 PRINT C

utasítást kell megadni. Ha az érték mellett a C változó nevét is ki akarjuk íratni, akkor a

120 PRINT "C=";C

utasítással oldhatjuk meg a feladatot. Ennek hatására a program a következő kiírást végzi el (tegyük fel, hogy C értéke 125):

C=125

Figyeljük meg, hogy a kiíratni kívánt adatelemeket pontosvesszővel választottuk el.

A BASIC nyelv csak bizonyos intervallumba tartozó számokat fixpontos (valós) formában. A Commodore esetében ezt az intervallumot a 0.01 ... 999999999 számok határolják. Az intervallumon kívül eső értéket lebegőpontos formában írja ki a gép:

(előjel) X.XXXXXXXX^n

általános formában. A mantissza (a szám jegyei) 9 jegyű, és az n (kitevő) két szélső értéke a -39 és +38.

és a legnagyobb a

+1.70141183E+38

szám.
Egész értékű változó -32768 és +32767 közötti értéket vehet fel.

A program befejezése
A program végét az END utasítással lehet jelölni, de használata nem kötelező. Az END hatására a programvégrehajtás megáll, ezért az END legyen a legnagyobb sorszámú utasítás. Használata egyszerű:

500 END

A Sinclair-gépeken nincs ilyen utasítás, helyette a STOP használható.

Az 1. feladat befejezése
Ezek után térjünk vissza az 1. feladathoz, és oldjuk meg az itt bemutatott ismeretek begyakorlására.

A kódolás

(1) A bemeneti adatok tárolása
Ez a program első modulja, ezért a modul elejére dokumentációs célból elhelyezzük a program nevét REM utasítások között. Ezután a modul kezdetén a modul nevét adjuk meg. A modul tényleges kódjában pedig az egyes ellenállások értékeit kell megadni. Ezt a LET értékadó utasítással végezhetjük el. Ezek alapján a kódot kézzel megírhatjuk.

(2) Ellenállás-számítás
Ez a modul is megoldható értékadó utasításokkal. Figyeljük meg azonban azt a különbséget, hogy itt nem közvetlenül számértéket rendelünk hozzá egy változó hanem az érték egy kifejezés kiszámításával keletkezik. A folyamatábra tagjait egy-egy utasítással lehet kódolni. A modul elejére itt is elhelyezzük a modul nevét. Ez a modul az (1) modul vége után hajtódik végre, ezért az utasításokat az (1) moduli végéhez folyamatosan sorszámozhatjuk.

(3) Eredménykiírás
A modul kiírási feladatát egyetlen PRINT utasítással el lehet végezni. Ezt a modult is célszerű a modul nevével bevezetni. Mivel ez a program utolsó modulja, a végére END utasítást lehet írni (kivéve Spectrum gépeken). A kiíró modul a számítási modul után következik, ezért a sorszámozást a (2) modultól lehet folytatni.

Az első feladt kódja:

10 REM *** EREL ***
20 REM BEMENETI ADATOK TAROLSASA
30 LET R1=1000
40 LET R2=2000
50 LET R3=500
60 LET R4=200
70 REM ELLENALLAS SZAMITAS
80 LET K0=1/R1+1/R2+1/R3
90 LET R0=1/K0
100 LET R9=R0+R4
120 PRINT "AZ EREDO ELLENALLAS (OHM): ";R9

A program bevitele, kipróbálása és a megoldás értékelése
A program teljes tervezése után a programot be kell gépelni. A program bevitele után a program tesztelési célokra futtatható.
Ha gépelési hibát vétettünk, a programfutás a szintaktikai hibánál megszakad, mert a program nem tudta értelmezni a hibás sort. A hibás sort ki kell javítani és újra megkísérelhetjük a futtatást.
A Sinclair-gépeknél ilyen formai hiba nem fordulhat elő, mivel a gép a formailag hibás utasításokat nem fogadja el. Ilyenkor egy kérdőjel jelenik meg az ENTER lenyomásakor. A sort csak a javítás után fogadja el a gép.
Ha a futás eredményes, már csupán azt kell ellenőrizni, hogy a program logikailag is helyesen működik-e. Példánkban ennek legegyszerűbb módja, ha az eredő ellenállás értékét magunk is kiszámítjuk: 475.714 Ohm. Megállapíthatjuk, hogy programunk helyesen működik, a feladatot megoldja. A hibátlan programot ezután a megismert módon kazettára vagy lemezre másolhatjuk.

Ellenőrző kérdések és feladatok

  1. Mi a különbség a képernyősor és az utasítássor között?
    Ha lenyomjuk a sorzáró gombot, akkor új képernyősorba vagy új utasítássori megyünk?

  2. Egy programot az AUTO segítségével kezdett el beírni. Majd abbahagyta a beírást (megszakította az AUTO módot), és most folytatni akarja. Lehet AUTO-val folytatni egy program beírását?

  3. Ha van rá lehetősége, készítse el a meglevő programjai listáit!

  4. Magyarázza meg, mi a különbség a kettő között!

    10 LET A=20
    20 LET B=15
    30 LET A=B
    40 PRINT A

    10 LET A=20
    20 LET B=15
    30 LET B=A
    40 PRINT A

5. Elágazások I.
Az elágazásos (IF THEN, IF HEN ELSE, CASE) szerkezetek megvalósítása
a 2. feladat megoldása

Az előzőekben olyan feladatokat oldottunk meg, amelyekben az utasítások egy meghatározott sorrendben hajtódtak végre minden esetben. Vannak azonban olyan feladatok is, amelyek így nem oldhatók meg. Nézzünk egy példát!

Elágazásos szerkezetek
Egy szállítóvállalatnak vissza kell igazolnia a rendelések értékét. A vállalat egyetlen terméket állít elő, és egységárát a rendelt mennyiségtől teszi függővé. Két árat határoz meg. Ha egy vevő egy meghatározott (M) mennyiséget vagy ennél kevesebbet rendel, akkor a termék egységára A1 lesz. Ha viszont e feletti mennyiséget rendel, akkor alacsonyabb (A2) egységárat számít fel. Foglaljuk össze az elmondottakat egy táblázatban:

 

Mennyiség (R) R<=M R>M
Ár (A) A1 A2

ahol

Ahhoz, hogy az egységárat megállapítsuk, a rendelt mennyiséget (R) és az árengedmény határát rögzítő mennyiséget össze kell hasonlítani. Ha:

Ebben a feladatban a rendelt mennyiség teljes értékét (R*A) vagy az A1, vagy az A2 értékkel kell kiszámítani. Vegyük észre, hogy mindig csak az egyik egységárral kell számolni, sohasem mind a kettővel. Ezt a feladatot tehát soros műveletekkel nem lehet megoldani, mert amikor arra kerül a sor, hogy melyik egységárat vegyük figyelembe, akkor el kell dönteni, hogy a kettő közül melyiket válasszuk. Ha ezt a feladot program formájában is meg akarjuk oldani, akkor az egységár kiválasztása előtt szükség van egy műveletre, amely meghatározza, hogy mi a teendő.
Honnan lehet tudni a példánkban, hogy melyik egységárat kell tekintetbe venni? Jól érzékelhető a példákból, hogy az R és M értéke határozza ezt meg. Tehát a döntés az R és M viszonyától függ, amint már be is mutattuk.
Azt is tudnunk kell, hogy a programba mind az A1-gyel, mind az A2-vel való értékszorzást bele kell írni, mivel mindkettő előfordulhat. A program tehát mind a két alábbi műveletet tartalmazni fogja:

E=R*A1
E=R*A2

ahol E a rendelés értéke.
Most már pontosan látható, hogy hogyan kell ezt a feladatot megoldani:

  1. Össze kell hasonlítani az R-et M-mel.
  2. Ha R<M, akkor E=R*A1,
    egyébként E=R*A2.
  3. Visszaigazolás készítése E összeggel.

Mindhárom lépést el kell végezni, de a másodikban levő kettő közül csak az egyiket. A második műveletben a program végrehajtása elágazik vagy az egyik, vagy a másik műveletre. Ezért az ilyen szerkezetű műveleteket elágazásnak nevezzük. A harmadik műveletet mindenképpen el kell végezni, ez már független az R és M viszonyától.
Látható, hogy egy feltétel határozza meg, hogy a két műveletcsoportból melyiket választjuk ki. Ez a feltétel

R<=M vagy R>M

formában fogalmazható meg. Bármelyik jó, csak arra kell figyelni, hogy melyik műveletet kell a feltétel teljesülése és melyiket nem teljesülése esetén elvégezni.
Akármelyiket is alkalmazzuk, a feltétel teljesülése a megrendelt mennyiségtől függ, mivel M értékét (legalábbis egy elég hosszú időre) konstransnak tekintjük. Ezért R a feltétel változója. Az elágazás tehát az R feltételváltozó értékétől függ.
A BASIC nyelvnek van olyan lehetősége, amely lehetővé teszi az elágazás megvalósítását a programban. Erre szolgál az IF utasítás. Az IF utasítás felépítése a következő:

x IF 1. kifejezés összenasonlítás 2. kifejezés
 THEN utasítás
 THEN sorszám
 GOTO sorszám

Az utasítás kulcsszavai az IF és a THEN vagy a THEN helyett álló GOTO.
Az utasítás lényege, hogy két kifejezést hasonlít össze, és az összehasonlítás eredményétől függő utasítássorozatot hajtja végre. Ha az 1. és 2. kifejezés között az utasításban foglalt feltétel teljesül, akkor a program a THEN utáni részt, illetve a GOTO utasítást hajtja végre, majd a következő sorszámú sorra lép. Ha a feltétel nem teljesül, akkor a program a következő sorszámú utasításra tér át.
Az utasításban kifejezések (változókból és műveletekkel összekapcsolva) és egyedül álló változók lehetnek. Az egyik kifejezés helyett konstans is állhat. Ha van konstans, akkor az rendszerint a második kifejezés helyén áll.
Az összehasonlítást mindig valamilyen relációval fejezzük ki. Ha például a reláció az =, akkor az összehasonlítás tartalmilag azt jelenti, hogy a program egyenlőséget vizsgál a két kifejezés között. Ha teljesül (egyenlőek), akkor a THEN-ág hajtódik végre, ellenkező esetben az utasítás utáni sorszámú utasítást hajtja végre a gép.
Az elvégezhető összehasonlítások műveleti jelei megegyeznek a matematikában használatos relációkkal, csupán a formájukban van kisebb eltérés.

= egyenlő
< nagyobb
<= kisebb vagy egyenlő
> nagyobb
>= nagyobb vagy egyenlő
<> nem egyenlő

A THEN után állhatnak utasítások (kettősponttal elválasztva), vagy állhat egy utasítássorszám. Ilyenkor a programot az itt megadott utasítássorszámtól kell folytatni. Tartalmilag ugyanez érvényesül a GOTO-nál is. Ekkor a GOTO után írt utasítássorszámnál folytatódik a program. A GOTO leírására később visszatérünk.

Jól érzékelhető, hogy a bemutatott IF utasítás IF THEN változata akkor használható a legjobban, ha valamilyen feltételtől függően egy műveletet vagy el kell végezni, vagy nem. Például a szorzatkitaláló feladat egyik megoldási módjánál a gép által kiszámított eredményt csak akkor íratjuk ki, ha az nem egyezik meg az általunk begépelttel. Ekkor a feltétel a két szorzat egyenlősége. Ha ez nem áll fenn, akkor ki kell írni a helyes szorzatot, és a program befejeződik. Ha fennáll reláció, akkor a kiírást nem kell végrehajtani, és a program befejeződik. Ilyenkor tehát nem két művelet közül kell valamelyiket kiválasztani, hanem csak egy művelet elvégzéséről kell dönteni. Megjegyezzük azonban, hogy ezzel az utasítással is meg lehet valósítani a két művelet közül az egyik kiválasztását.
Az IF utasításnak van egy több szolgáltatást nyújtó változatai amely a HT és a PRIMO gépeken használható. Az utasítás formája:

x IF 1. kif. összenasonlítás 2. kif.
 THEN utasítás
 THEN sorszám
 GOTO sorszám
ELSE

utasítás
sorszám
GOTO sorszám

Az utasítás kulcsszavai az IF THEN és ELSE, ezért hogy az IF THEN utasítástól megkülönböztessük, IF THEN ELSE az utasítás neve.
Az utasítás lényegében ugyanúgy működik, mint az IF THEN utasítás. A legnagyobb eltérés az, hogy ha a reláció nem teljesül, akkor a gép az ELSE után álló utasításokat hatja végre.
Megjegyezzük, hogy mind az IF THEN, mind az IF THEN ELSE utasításba további ugyanolyan típusú utasítások is elhelyezhetők:

100 IF A=7 THEN IF B=3 THEN LET A=B

Ez esetben, ha az A=7 és B=3, akkor az A=B értékadás megy végbe: A értéke 3 lesz.
Ismerjük meg még a GOTO utasítást is (A Spectrum gépek GO TO-nak írják). A GOTO utasítás segítségével lehet elérni, hogy a program a sorrendben következő helyett a GOTO utasítás tárgyában megadott sorszámú utasításra ugorjon, és onnan folytassa a végrehajtást. A GOTO utasítás felépítése:

x GOTO sorszám

Amikor a program a végrehajtáskor eléri az x sorszámú utasítást, akkor a GOTO utasítás végrehajtásának eredményeként nem az x után következő sorszámú utasítás hajtódik végre, hanem a GOTO utasítást tárgyában megadott sorszámú utasítás. A GOTO tehát a programon belül ugrást hajt végre.
Ezután azt kell megvizsgálni, hogy az elágazásos szerkezeteket hogyan lehet megvalósítani a programokban.

Az IF THEN szerkezet megvalósítása
Az IF THEN szerkezetet olyan algoritmusban kell használni, amelyben a feltétel teljesülésekor valamilyen A műveletsorozatot kell végrehajtani, és utána a B műveletsorozatra kell áttérni. Ha a feltétel nem teljesül, akkor rögtön a B műveletre kell áttérni. A B műveletsorozatot mindenképpen végrehajtja a program, ezért ezt feltétel nélkül végrehajtandó műveletnek nevezzük. Az IF THEN szerkezet folyamatát a 17. ábra mutatja.


17. ábra: az IF THEN szerkezet

Az IF THEN szerkezet kódolására két változatot mutatunk be. Az első formát akkor célszerű használni, ha az A programrész sok utasításból áll. A kódrészt az IF utasítás vezeti be, és az IF VEG megjegyzéssel (REM) zárjuk le:

k IF feltétel THEN m
GO TO n
m REM * THEN-ag *
...
n REM * IF veg *

A THEN után következő műveletsorozatot az m sorszámtól kezdve, két sorral az IF utasítás alatt (így m=k+20 lehet) helyezzük el. A műveletet egy REM utasítással nyitjuk meg, s ide beírjuk, hogy itt kezdődik a THEN-ág. A THEN-ág utolsó utasítása után az n sorszámú, az IF VEG-et tartalmazó REM utasítás következik, és a vezérlés átkerül a közös műveletsorozat kezdetére.
Ha a feltétel nem teljesül, akkor a program a következő sorra tér át. Logikailag azonban a B műveletsorozatnak kell következnie, amit úgy érhetünk el, hogy egy GOTO utasítást helyezünk az IF utasítás utáni (például k+10 sorszámú) sorba, s ez az n sorszámú utasításra - gyakorlatilag a közös műveletsorozatra - helyezi át a vezérlést.
Ez utóbbi lépésnek az a lényege, hogy az IF THEN zárt szerkezeti egységnek egyetlen "kijárata" legyen, az n sorszámú utasítás. Ez az "egykijáratúság" módosításnál nagyon megkönnyíti a helyzetünket.
Példaként nézzük meg a szorzatkitaláló program eredménykiértékelő részének kódolását. A begépelt szorzat változója az A, a gép által kiszámított szorzat a B változóban van. A kód a következő:

100 IF A<>B THEN GO TO 120
110 GO TO 140
120 REM * THEN AG *
130 PRINT "A SZORZAT: ";B
140 REM * IF VEG *
150 STOP

A második szerkezet akkor használható ésszerűen, ha a THEN-ág csupán egy-két utasításból áll:

IF feltétel THEN utasítások

A THEN-ág egy-két utasítását a THEN kulcsszó után, kettősponttal elválasztva helyezzük el. Az utolsó THEN-ági utasítás után a feltétel nélkül végrehajtandó ág következik, ezért GOTO utasításra nincs szükség, mert a program ettől függetlenül is a következő sorban levő B műveletsorozat első utasítására lép. Ha a feltétel nem teljesül, akkor is a B műveletsorozatra tér át a program, tehát a kódolás helyesen valósítja meg az IF THEN szerkezetet. Nézzük meg az előző példát ezzel az eljárással kódolva! Megtehetjük, mert a THEN-ágban csak egy utasítás lesz:

100 IF A<>B THEN PRINT "A SZORZAT: ";B
110 STOP

Az IF THEN ELSE szerkezet megvalósítása
Az IF THEN ELSE szerkezet akkor használható, amikor egy feltétel teljesülésekor a THEN-ágban levő A műveletsort kell elvégezni, és a C feltétel nélkül végrehajtandó műveletre kell áttérni. Ha a feltétel nem teljesül, az A helyett egy B műveletsort kell elvégezni; ez az ELSE-ág. Ezután C részre kell áttérni (18. ábra).


18. ábra: Az IF THEN ELSE szerkezet

Az IF THEN ELSE szerkezet kódolására is két megoldást mutatunk be. Az első megoldás Commodore és Sinclair gépeken:

k IF feltétel THEN GO TO m
   GO TO n
m REM * THEN-ag *
   ...
   GO TO p
n REM * ELSE-ag *
   ...
p REM * IF veg *

A THEN-ág kódolása az IF THEN szerkezetnél bemutatott módszerhez hasonlóan megy végbe, csak a befejezés tér el. A THEN-ág után most nem a C műveletsor, hanem az ELSE-ág kódja következik, ezért egy GOTO utasítással át kell ugrani a p sorszámú utasításra, ahol az IF THEN ELSE kijárata (a C rész kezdete) van.
Ha a feltétel nem teljesül, akkor az ELSE-ágra kell áttérni. Ezt az IF utasítás után következő sorban elhelyezett GOTO utasítással lehet elérni. Ekkor az ELSE-ág végrehajtódik, és a vezérlés közvetlenül átkerül a p sorszámú megjegyzésre, illetve innen a feltétel nélkül végrehajtandó ágra.
Készítsük el a termékrendelési és visszaigazolási feladatrészlet kódolását az itt bemutatott módszer szerint:

100 IF R<M THEN GOTO 120
110 GOTO 150
120 REM * THEN AG *
130 LET E=R*A1
140 GOTO 170
150 REM * ELSE AG *
160 LET E=R*A2
170 REM * IF VEG *
180 PRINT "A RENDELES ERTEKE: ";E

A HT és a PRIMO BASIC-változatában az ilyen műveletet IF THEN ELSE típusú utasítás felhasználásával kódolhatjuk. Itt a THEN és az ELSE után meg kell adni, hogy melyik sorszám alatt kezdődnek az egyes ágak. A THEN- és az ELSE-ágat hasonló, strukturált módon lehet kódolni. Ilyenkor az IF utáni GOTO utasítás feleslegessé válik:

m IF feltétel THEN n ELSE p
n REM * THEN-AG *
   ...
   GOTO r
p REM * ELSE-AG *
   ...
r REM * IF VEG *

A feladatot most az IF THEN ELSE utasítással kódoljuk:

100 IF R<M THEN 110 ELSE 140
110 REM * THEN AG *
120 E=R*A1
130 GOTO 160
140 REM * ELSE AG *
150 E=R*A2
160 REM * IF VEG *
170 PRINT "A RENDELES ERTEKE: ";E

Ha a THEN-ág csupán egy két utasítást tartalmaz (a feltétel jó megválasztásával eldönthető, hogy melyik ág legyen a THEN-ág), akkor az IF THEN szerkezet megvalósításánál bemutatott egyszerűsített szerkezet alkalmazható. A THEN-ág utasításait a THEN kulcsszó után, kettősponttal elválasztva írjuk le, majd a sor végén egy GOTO utasítással az IF szerkezet végére kell ugrani, s ezután már a közös rész következik. Ha a feltétel nem teljesül, akkor az IF THEN ELSE szerkezetnek megfelelően az ELSE-ág hajtódik végre. Az ELSE-ág befejezése után pedig a feltétel nélkül végrehajtandó rész kerül sorra (Commodore és Sinclair gépeken):

m IF feltétel THEN itasítások: GOTO n
   REM * ELSE-AG *
   ...
n REM * IF VEG *

Ezzel példánk kódja a következő lesz:

100 IF R<M THEN LET E=R*A1: GOTO 130
110 REM * ELSE AG *
120 LET E=R*A2
130 REM * IF VEG *
140 PRINT "A RENDELES ERTEKE: ";E

Az IF THEN ELSE utasítással - HT és PRIMO gépeken - pedig az alábbi lesz az egyszerűsített kód:

100 IF R<M THEN E=R*A1 ELSE E=R*A2
110 PRINT "A RENDELES ERTEKE: ";E

Ha a feladat olyan, hogy egy feltételtől függően nemcsak kétfelé lehet elágazni, hanem többfelé, akkor a feladat folyamatábrája a 19. ábra szerint alakul. Az ilyen típusú elágazást CASE szerkezetnek nevezzük.


19. ábra: A CASE szerkezet

A BASIC-ben a CASE szerkezet az ON GOTO (A Sinclair BASIC-je ezt nem ismeri) vagy az IF THEN utasítással kódolható. Az utóbbi nyújtja az általánosabb és rugalmasabb megoldást, ezért ennek a használatát mutatjuk be. A CASE szerkezet kódolására is két megoldást ismertetünk.
A CASE szerkezetet az 1. feltétel IF utasítása nyitja meg, és a CASE VEG megjegyzés zárja le. A CASE szerkezet elején egymás után helyezkednek el az egyes feltételeket vizsgáló IF utasítások.
Ha a változó értéke valamelyik feltételnek nem tesz eleget, akkor a vezérlés a következő vizsgálatra kerül át. Ha a változó egyik feltételnek sem felel meg, akkor a feltétel nélkül végrehajtandó rész végrehajtása következik, tehát a p sorszámú - utolsó - utasításra kell ugrani. Ha a változó valamelyik feltételnek eleget tesz, akkor a vezérlés az adott feltételhez tartozó műveletsorra ugrik át. Ennek végrehajtása után a közös rész következik, erre egy GOTO utasítással kell áttérni:

   REM * CASE KEZDET *
   IF feltétel1 THEN GOTO m1
   IF feltétel2 THEN GOTO m2
   ...
   IF feltételn THEN GOTO mn
   GOTO p
m1 REM * 1. eset *
   ...
   GOTO p
m2 REM * 2. eset *
   ...
   GOTO p
   ...
mn REM * n. eset *
   ...
p REM * CASE VEG *

A CASE szerkezet egyszerűsített változatában az egyes esetek kódját a megfelelő feltételt vizsgáló IF utasításban, a THEN kulcsszó után helyezzük el:

   REM * CASE KEZDET *
   IF feltétel1 THEN 1. eset: GOTO p
   IF feltétel2 THEN 2. eset: GOTO p
   ...
   IF feltételn THEN n. eset
p REM * CASE VEG *

Ha az i-edik feltétel teljesül, akkor az i. esethez tartozó műveletsor hajtódik végre. Ha valamelyik i eset végrehajtódott, akkora CASE részből egy GOTO utasítással ki kell lépni.

Most pedig ismerjük meg részletesen a billentyűzetről adatot beolvasó INPUT utasítást! Az utasítás formája:

x INPUT "szöveg";változó1,változó2,...

Hatására az idézőjelbe tett szöveg kiíródik, és utána egy kérdőjel jelenik meg, annak jeléül, hogy a gép adatot vár a billentyűzetről. Ilyenkor olyan típusú (pl. egész típusú vagy numerikus) és annyi adatot kell vesszővel elválasztva begépelni, amilyen és ahány az utasítás tárgyában szerepel. Ha az adatbevitel befejezése előtt nyomjuk le a sorzáró gombot, akkor a következő sorban újra kérdőjel látható, és a gép a hiányzó adatok begépelésére vár. A "szöveg" elhagyható, ilyenkor az utasítás csak a kérdőjelet jeleníti meg beolvasáskor.
A Sinclair-gépeknél az INPUT utasítás formája kismértékben eltér a fentitől:

x INPUT "szöveg",változó1,változó2,...

vagy

x INPUT "szöveg1",változó1,"szöveg2",változó2,...

Látható, hogy egy INPUT utasítással több változó értékét be lehet olvasni, és mindegyikhez külön szöveget is meg lehet megadni. A szöveg tudatja a felhasználóval, hogy a gép milyen adatokat kér be. Az utasítás befejeztével az utasítás tárgyában felsorolt változók a begépelt értékeket kapják meg.

2. feladat
Állóeszközök amortizációval csökkentett nettó értékét kell meghatározni. Az állóeszköz beszerzésének éve és ára (bruttó ár) alapján ki kell számítani, hogy jelenleg mennyi az állóeszköz nettó értéke. A két kiinduló adatot a végrehajtás közben billentyűzetről kell beadni.
A vizsgált állóeszközök leírási időszaka 5 év. A leírás lineáris, vagyis az állóeszközök nettó értéke az eredeti (bruttó) érték évenként 20%-kal csökkentet értéke. 5 év után, amikor a nettó értéknek nullára kellene csökkennie, az állóeszközöket könyvelési okokból 100,- Ft eszmei értékre írják le, és ezután ezen az értéken tartják nyilván.
Az eredményt az alábbi formában kell kiírni:

NETTÓ ÉRTÉK SZÁMÍTÁSA

Bruttó érték:
A beszerzés éve:
Életkor:
Nettó érték:
X EFt
19xx EV
X EV
X EFt

vagy nullára leírt állóeszköznél:

NETTÓ ÉRTÉK SZÁMÍTÁSA

Bruttó érték:
A beszerzés éve:
Életkor:
Nettó érték:
X EFt
19xx EV
X EV
0.1 EFt



(eszmei érték)

A feladat elemzése
A feladat leírása szerint az állóeszközök nettó értékét kell kiszámítani a bruttó érték és a beszerzés éve alapján az ide vonatkozó szabályok alkalmazásával. Az eredményt a megadott formában kell kiírni. A Sinclair-gépek képernyőjén az utolsó sor nem fér el, ezért az "ERTEK)" részt az "(ESZMEI" szöveg alá lehet kiírni.
A felhasználó az állóeszközök adatait kartonokon tárolja, ezért ilyenkor számítógépes adattárolásra nincs szükség. A program elején a számításhoz szükséges bemeneti adatokat be kell olvasni és ezekből kell a nettó értéket kiszámítani, végül az eredményt ki kell írni.
Az amortizációszámítást a következő képlet szerint végezhetjük el:

ha (J-E)<5

ahol
N - a nettó érték eFt-ban,
B - a bruttó érték eFt-ban,
J - a folyó év (csak kerek évszámot használunk),
E - a beszerzés éve.

A kiírásnál az állóeszköz életkorát is meg kell határozni, ezért a (J-E) helyett a K (életkor) változót vezetjük be. A nullára leírt (5 éves vagy régebbi) állóeszközök nettó értékét pedig az

N=0.1 eFT

(ha K>=5)
értékadással határozzuk meg. Az állóeszköz életkora dönti el, hogy melyik kifejezést alkalmazzuk a nettó érték kiszámításánál. A feltételváltozó tehát a K (életkor) változó lesz.
A fentiek alapján már meghatározható, hogy a feladat megoldásához milyen modulok kellenek. Először szükség van egy bemeneti adat modulra, az amortizáció-számításhoz egy másik modulra, végül egy kiírás modulra. A modulok a 20. ábrán látható egyszerű szerkezetet alkotják. A programnak az AMOR nevet adjuk.


20. ábra: A 2. feladat programjának szerkezete

A program tervezése
A program szerkezete kialakult. Vizsgáljuk meg, hogy a modulszerkezet hogyan finomítható tovább!
A bemeneti adatok modulban csupán egy állóeszköz beszerzési évének és bekerülési árának adatait kell beolvasni. Ez elég egyszerű feladat ahhoz, hogy egyetlen modul lássa el. A modulban kell meghatározni a számításhoz szükséges J (folyó évszám) adatot is. Láthatjuk, hogy az amortizációszámítás is alapjában véve egyszerű, ezért további finomításra nincs szükség.
Ehhez hasonlóan könnyen belátható, hogy a kiírás modul bontására sincs szükség, mert csak a címet és a négy adatot kell egyszerű formában kiírni. Látnunk kell, hogy az utolsó sor formája nettó érték, és tartalma a K változótól függ.
Mivel a modulok szekvenciális szerkezetet alkotnak, a vezérlőmodul alkalmazásától eltekintünk.

A modulok tervezése

(1) Bemeneti adatok
A modul adat típusú. Bemeneti adatait a B és az E, kimenetét pedig három adat: B, E, J alkotja.
A modul folyamata a J konstans értékadásával kezdődik. A következő lépésben kell beolvasni a B és az E értékét INPUT utasításokkal.

(2) Amortizációszámítás
A modul eljárás típusú. Bemeneti adatai: a B, E és J változó az (1) modulból. A modul állítja elő az életkor (K) és a nettó érték (N) kimeneti adatokat.
Először a K (életkor) értékét kell meghatároznia, mert a K-ra a továbbiakban szükség lesz. Ezután következik a nettó érték kiszámítása (N), illetve az N=100 Ft eszmei értékadás 5 évnél régebbi állóeszközök esetén. Hogy melyik műveletet kell legezni, az a K<5 feltételtől függ. Ha a feltétel teljesül, akkor az amortizációval csökkentett nettó értéket kell kiszámítani, egyébként a nettó értéknek 0.1 eFt értéket kell adni. A soron következő modul kezdő művelete független a K értékétől.

(3) Kiírás
A modul eljárás típusú. Bemeneti adatai a B és E az (1) modulból, valamint K és N a (2) modulból.
A modul kimenete a cím és az eredmények kiírása. A műveletek végrehajtásakor először a címet, majd a B, E és K adatot kell a megfelelő szöveggel kiírni. A következő sor kiírási formája attól függ, hogy az állóeszköz nettó értéke nagyobb-e nullánál, vagy eléri-e a nullát, illetve eszmei értéken tartják-e nyilván. A megfelelő kiírási formát az életkor határozza meg. Ha K<5, akkor a számított nettó értéket, ha K>=5, akkor az eszmei értéket tartalmazó N változó értékét (100,- Ft) kell kiírni, de zárójelben meg kell jegyezni, hogy ez az eszmei érték. Ezután a program véget ér.

A kódolás
A program kezdetén helyezzük el a program nevét tartalmazó REM utasítássort. Az (1) modulban két INPUT utasítás van.
A (2) modulban egy IF THEN ELSE szerkezetet kell kódolni a bemutatott szabályok szerint.
A (3) kiíró modulban először a címet írjuk ki. Ezután a bruttó értéket, a beszerzés évét, az életkort és a nettó értéket kell kiírni. Majd egy IF THEN szerkezet következik a nettó érték szövegének kiírásához. A programot lezáró END / STOP utasítás következik.

10 REM *** AMOR ***
20 REM * BEMENETI ADATOK *
30 LET J=1984
40 INPUT "BRUTTO ERTEK:  ";B
50 INPUT "BESZERZES EVE: ";E
60 REM * AMORTIZACIO SZ. *
70 LET K=J-E
80 IF K<5 THEN LET N=(B*(5-K))/5: GO TO 110
90 REM * ELSE AG *
100 LET N=.1
110 REM * IF VEG *
120 REM * KIIRATAS *
130 PRINT TAB (6);"NETTO ERTEK SZAMITAS"
140 PRINT : PRINT
150 PRINT "BRUTTO ERTEK:    ";B;" EFT"
160 PRINT "A BESZERZES EVE: ";E;" EV"
170 PRINT "ELETKOR          ";K;" EV"
180 PRINT "NETTO ERTEK:     ";N;" EFT"
190 IF K>=5 THEN PRINT TAB (17);"(ESZEMEI ERTEK)"
200 STOP

Ellenőrző kérdések és feladatok

  1. Magyarázza meg, hogy ha egy feltételtől függően vagy egy A műveletsort, vagy egy B műveletsort kell végrehajtani, akkor miért kell mind a két műveletsort belevenni a programba!

  2. Keressen példát a CASE szerkezet alkalmazására a környezetéből!

  3. Alakítsa át a szorzatkitaláló programot, hogy a program hibás szorzat begépelése esetén írja ki:
       "NEM JO, PROBALJA MEG UJRA!"
    és az eredményt lehessen újra beírni. Ha a beírt szorzat jó, akkor az
       "EZ JO!"
    szöveget írja ki a gép, és a program fejeződjék be.

  4. Készítsen programot a másodfokú egyenlet gyökeinek kiszámítására!

6. Elágazások II.
Az elágazások folytatása, a vezérlőmodulok kialakítása.
A modulok mint szubrutinok.
A módosított 2. feladat.
A 3. feladat megoldása.

A vezérlőmodul alkalmazása
Nézzük meg az előző részben megoldott amortizációszámítási feladat modulszerkezetét (20. ábra). A modulszerkezetből kitűnik, hogy a legegyszerűbb - a szekvenciális - esettel állunk szemben. Éppen ezért a (feladat megoldásánál azt mondtuk, hogy a vezérlőmodul elhagyható, és a három modul kódját szekvenciálisán egymás után írjuk a programkódban. Ezzel viszont nem tartottuk be programfelépítési módszerünk egyik szabályát.
Készítsünk vezérlőmodult a feladat három moduljához! A vezérlőmodul a 20. ábra szerinti AMOR lesz, amelyet a megoldás során nem kódoltunk. Ennek az új modulnak az a részfeladata, hogy a feladat moduljainak végrehajtását vezérelje, ami abból áll, hogy a modulokat (1), (2), (3) sorrendben hívja. A modulok hívása után a folyamat befejeződik.
Kérdés az, hogyan kódolható ez a modul. Egy modul hívása azt jelenti, hogy a főmodulból ki kell ugrania a hívott modul első utasításához. Végre kell hajtani a modul egészét, és a befejezéskor nem a következő modulra kell áttérni, hanem a vezérlőmodulba kell visszaugrani, hogy az hívhassa a következő modult. Jelenlegi ismereteink alapján ezt a műveletet a GOTO utasítással meg lehet valósítani.
A program elején egy GOTO utasítással lépünk az (1) modul elejére majd ennek végéről másik GOTO utasítással visszatérünk a vezérlő modulba.
Ha egy újabb modult beszúrunk a programba, akkor ennek a program elején "helyet" kell csinálni. Ez azt jelenti, hogy a programnév után minden utasítást hátrább kell tenni, vagyis az utasítássorszámokat meg kell növelni. Tegyük fel, hogy az (1) modul kódja a 200-as, a (2) modulé a 300-as, a (3) modulé pedig az 500-as soron kezdődik majd. Ezzel a program kiegészítő kódja (vezérlőmodul) a következő lesz:

60 REM *** AMOR ***
70 GOTO 200
80 GOTO 300
90 GOTO 500
100 END
200 REM * BEMENETI ADATOK *
...
260 GOTO 80
300 REM * AMORTIZACIO SZ. *
...
420 GOTO 90
500 REM * KIIRAS *
...
670 GOTO 100

A Sinclair-gépeknél nincs END utasítás, ezért helyette STOP utasítást kell használni.
A feladatot ugyan helyesen oldottuk meg, de a GOTO utasítások nagyon merevvé teszik a programot, mert bármilyen módosításnál a sorszámokat át kell írni, és sok az ugrálás, ami kódoláskor könnyen eltéveszthető. Van azonban ennél kellemesebb megoldás is, a következőkben ezt ismerjük meg.

A GOSUB, RETURN utasításpárral szubrutinokat tudunk kódi a programban, és ezek végrehajtását lehet irányítani velük. A szubrutin egy alfeladat (vagy részfeladat), amely lehet egy modul, modulrészlet vagy akár több modul. A szubrutin sajátossága az, hogy végrehajtását a GOSUB, RETURN utasításpár irányítja.
A szubrutin formában kódolt modulokat a program végére írjuk, hogy a szerkezet könnyebben áttekinthető legyen. A szubrutin kezdetét semmilyen szubrutin-irányító utasítás nem jelzi, így a program olvasója nem veszi észre egy utasításról, hogy az szubrutinkezdés-e, vagy sem. A szubrutin kezdőutasítását sorszáma alapján határozhatjuk meg. A szubrutint minden esetben a RETURN utasítással kell befejezni. A programnak azon a pontján, ahol egy szubrutint kell hívni,

x GOSUB sorszám

szubrutinhívó utasítást adunk meg.
A GOSUB utasítás tárgyában levő szám azt a sorszámot jelöli, ahol a szubrutin kezdődik. Az utasítás hatására a vezérlés átkerül a megadott sorszámra.
Ezután a hívott szubrutin végrehajtódik. Amikor a program eljut a szubrutin végét jelölő RETURN utasításhoz, akkor a szubrutin befejeződik, és a vezérlés visszakerül a hívó GOSUB utasítást követő utasításra, és ezután ott folytatódik. Láthatjuk, hogy a szubrutinhívást a GOSUB, a visszatérést a főágra pedig a RETURN utasítás valósítja meg.
A szubrutinhívási műveletet a 21. ábra mutatja. A GOSUB utasítás hatására a program az m sorszámú utasításnál folytatódik, amely a szubrutin kezdete. A gép végrehajtja a szubrutint, majd a RETURN utasítás hatására a hívó GOSUB utasítást követő (k+10) utasításra tér program.



21. ábra: A szubrutint tartalmazó program

Az ábrából az is látható, hogy ha egy program szubrutint is tartalmaz, akkor a programkód ezáltal két részre osztható:

Felhívjuk a figyelmet arra, hogy a főág végrehajtása után a program rátérne az első szubrutin végrehajtására anélkül, hogy erre szükség lenne. Ilyenkor eljutna az első RETURN-ig, de nem tudna sehova sem visszatérni, mert GOSUB hívás nélkül került a szubrutinba. Ezért a gép hibaüzenetet ad ki, és a végrehajtást befejezi. Ez a program helyes működését is befolyásolhatja, ezért a főág befejezése után GOTO utasítással a program utolsó - END - utasítására adjuk át a vezérlést, hogy a szubrutinokat kikerüljük.
Az elmondottak alapján könnyű belátni, hogy a vezérlőszerkezet egyszerűbb lesz, ha a vezérelt modulokat szubrutinoknak tekintjük, és a vezérlőmodulban ezek hívását helyezzük el.
Ha visszatérünk a 2. feladat vezérlőmodullal való megvalósításához, de most már szubrutinokkal, akkor az (1), (2) és (3) modult szubrutin formájában kell kódolnunk, a vezérlőmodult pedig ezek hívásaiból kell összeállítanunk. Ha feltételezzük, hogy az egyes szubrutinmodulok ugyanazokon a sorszámokon kezdődnek, akkor az eredeti program kiegészítő kódja a következő lesz:

60 REM *** AMOR ***
70 GOSUB 200
80 GOSUB 300
90 GOSUB 500
100 GOTO 700
200 REM * BEMENETI ADATOK *
...
260 RETURN
300 REM * AMORTIZACIO SZ. *
...
420 RETURN
500 REM * KIIRAS *
...
670 RETURN
700 END

A Sinclair-gépeknél a korábbi megállapításunk értelmében

700 STOP

vagy

700 REM

utasítást írunk a program befejezésére.

A 2. feladat módosítása
A 2. feladat úgy módosul, hogy van egy szervezet, amelynek 10 állóeszköze van, és ezek amortizációját kell kiszámítani évente olyan módon, hogy az állóeszközök adatait ne kelljen minden alkalommal beírni. Ez így kevesebb kézi munkát igényel (és kevesebb hiba fordulhat elő).
Mielőtt a módosítást elemeznénk, azt vizsgáljuk meg, hogyan lehet adatokat a programmal együtt tárolni, és van-e olyan lehetőség, hogy az értékadásnál egyszerűbb megoldást kapjunk. A BASIC nyelvben erre szolgál a READ és a DATA utasításpár. Az adatokat a DATA utasítás tárgyában soroljuk fel, és a felsorolás sorrendjében a READ utasítással olvassuk ki. A READ utasítás a kiolvasott adat értékét a READ utasítás tárgyában levő változóhoz rendeli.
A DATA utasításokat célszerű a program végén elhelyezni. A DATA szó után vesszővel elválasztva olyan sorrendben soroljuk fel a használni kívánt adatokat, amilyen sorrendben ki akarjuk őket olvasni:

x DATA adat_1,adat_2,adat_n

A READ utasítást oda kell helyezni, ahol szükség van a változó értékének megadására. A READ utasítás tárgyában meg kell adni azt a változót (vagy változókat) amelynek értékét a DATA-ból kiolvasott adattal kell egyenlővé tenni:

x READ változó

Térjünk vissza a 2. feladat módosításához, és oldjuk meg. A megoldás folyamán az eredeti feladattól való eltéréseket emeljük ki!

A feladat elemzése
A feladat annyiban tér el az eredetitől, hogy az állóeszközök alapadatait (bruttó érték, a beszerzés éve) a programban kell tárolni és nem kartonokon. Ebből az is következik, hogy az alapadatokat a program futása során nem kell begépelni. Mivel a nettó érték számítását évente kell elvégezni - és eredménye is az évszámtól függ - a számításokhoz mindig meg kell adni az évszámot (már csak azért is, mert ez változik, és az eredmények ettől is függnek).
A feladat megoldásához szükség van egy évszámbeolvasó, egy amortin számítási, egy kiírási, valamint egy alapadat-tároló modulra.

A program tervezése
A programban változatlanul szükség van amortizációszámítási és kiírási modulra. A bemeneti adatok modul helyett csak évszámbeolvasó modul szükséges, és új modulként az adattároló modullal bővül a program.


22. ábra: A módosított 2. feladat programjának szerkezete

Az eredeti program egy futása egy állóeszköz nettó értékét számítja ki. A módosított feladatban pedig 10 állóeszközét kell kiszámítani. Ez csak úgy lehetséges, ha a (2) és a (3) modult 10-szer hajtja végre a program, változó adatokkal.
Azt is figyelembe kell venni, hogy a 10 állóeszköz adatai nem férnek el együtt a képernyőn. A program futása során az állóeszközönkénti cím és a 4 adatsor végig szalad a képernyőn, és csak az utolsó két táblázatot lehetne elolvasni. Ez nyilván nem kívánatos, ezért állítsuk meg a kiírást állóeszközönként. Ezt úgy lehet elérni, hogy a táblázat kiírása után egy INPUT utasítást adunk ki. Amíg a felhasználó nem gépel be valamit, a program futása - és a kiírt kép - áll. Tulajdonképpen teljesen mindegy, hogy milyen adatot kérünk be. Nyilvánvaló azonban, hogy a helyzethez legjobban illő adatot kell kérni. Ha a felhasználó folytatni akarja a műveletet, akkor 1-et, ellenkező esetben 0-t kell begépelnie. Ez utóbbi esetben a programi befejeződik.
A feladatot vezérlőmodul alkalmazásával oldjuk meg. Valamennyi modul végrehajtását a vezérlőmodul irányítsa! A többi modult szubrutin formájában kódoljuk.

A modulok tervezése

(1) Vezérlés
A modul vezérlő típusú. Bemeneti adata a folytatást eldöntő T érték. Kimenete a három szubrutin hívása, illetve a program befejezése.
A modulban először a (2) modult kell hívni, utána pedig a (3) és a (4) modult. Ezután be kell olvasni a vezérléshez szükséges T adat értékét. Ha T=1, akkor ismét a |3) és a (4) modult kell hívni egy újabb amortizációszámításhoz és kiírásához. Ha T=0, akkor a program befejeződik.

(2) Évszámbeolvasás
A modul adat típusú. Bemeneti adata a folyó év (J) adat billentyűzetről begépelve.

(3) Amortizációszámítás
A modul megegyezik az eredeti program azonos nevű moduljával, azzal az eltéréssel, hogy a modul elején minden végrehajtás előtt be kell olvasni a soron következő állóeszköz alapadatait.

(4) Kiírás
Ez a modul változatlanul átvehető.

(5) Adatok
A modul adat típusú. Egyetlen feladata, hogy a 10 állóeszköz következőadatait tárolja:

 
Bruttó érték (eFt)
B
Beszerzés éve
E
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
2500
500
3050
162
520
1610
3960
865
32
782
1982
1984
1984
1984
1980
1978
1979
1980
1976
1981

A program kódolása
Az (1) modul kódja a szubrutinhívásokat és a befejezés eldöntését tartalmazza:

10 REM ***** AMOR1 *****
60 REM *** VEZERLES ***
70 GO SUB 200
80 GO SUB 300
90 GO SUB 500
100 INPUT "TOVABB? (1/0) ";T
110 IF T=1 THEN GO TO 80
120 GO TO 860

A (2), (3) és (4) modulokat szubrutinokként kell megírni, ezért az utolsó utasítás mindegyikben a RETURN lesz. A (3) modul kódjában az első utasítás a soron következő gép alapadatainak olvasása lesz. A (4) modul kezdetén töröljük a képernyőt. A HT gép, a PRIMO és a Sinclair-gépek esetében a CLS utasítással lehet ezt elérni.

200 REM *** EVSZAM BEOLVASAS ***
210 INPUT "JELENLEGI EVSZAM: ";J
220 RETURN
300 REM * **AMORTIZACIO SZAMITAS ***
310 READ B,E
320 LET K=J-E
330 IF K<5 THEN GO TO 350
340 GO TO 380
350 REM THEN AG
360 LET N=(B*(5-K))/5
370 GO TO 400
380 REM * ELSE AG *
390 LET N=.1
400 REM * IF VEG *
410 RETURN
500 REM *** KIIRAS ***
510 CLS
520 PRINT TAB (6);"NETTO ERTEK SZAMITAS"
530 PRINT
540 PRINT "BRUTTO ERTEK:    ";B;" EFT"
550 PRINT "A BESZERZES EVE: ";E;" EV"
560 PRINT "ELETKOR:         ";K;" EV"
570 PRINT "NETTO ERTEK:     ";N;" EFT"
580 IF K>=5 THEN PRINT TAB (17);"(ESZEMEI ERTEK)"
590 RETURN

Végül a programot ki kell egészíteni az (5) modul DATA utasításaival.

800 REM *** ADATOK ***
810 DATA 2500,1982,500,1984
820 DATA 3050,1984,162,1984
830 DATA 520,1980,1610,1978
840 DATA 3960,1979,865,1980
850 DATA 32,1976,785,1981
860 STOP

A kapott eredmények értékelése
A program a feladatát hibátlanul ellátja, de ha az utolsó állóeszköz amortizációjának kiírása után T=1 választ adunk, akkor OUT OF DATA hibaüzenet jelenik meg. Ennek az az oka, hogy a 10. számítási és kiírási lépés utáni is a program újabb állóeszköz adatait próbálja beolvasni. Mivel több adatot nem talál, a fenti hibaüzenettel figyelmezteti a felhasználót, hogy a READ utasítást és az utána következő részt nem tudja végrehajtani.
Felhívjuk az olvasó figyelmét, hogy a fenti ugyan egy lehetséges megoldás, de az ún. veszélyes programszerkezetek közé tartozik, mert a GOTO utasításciklust képez a programban, és a programozó nem ellenőrzi, hogy a ciklus mikor fejeződik be. Az ellenőrzést a gépre bízzuk, és az akkor állítja le a programot, amikor elfogynak az adatok. A 8. részben a ciklikus problémák megoldására szabályos szerkezetet mutatunk be, de más szerkezetek alkalmazásával is ki lehet kerülni az ilyen megoldást.
A 3. feladat megoldása előtt ismerjünk meg egy új fogalmat!

A szöveges változók
Egyes feladatok megoldása azt is igényli, hogy a program ne csak numerikus, hanem szöveges változókat is tudjon kezelni. A BASIC nyelvnek vannak ilyen lehetőségei. Egy szöveges adat korlátozott hosszúságú lehet. A Commodore-nál és a HT gépeknél egy szöveges változó 255 jel hosszúságú lehet. A PRIMO-nál csak 50 jelből állhat a sorozat (de kibővíthető max. 9450-re).
Szöveges adat például egy név: KOVÁCS PÁL
A szöveges adatot meghatározáskor idézőjelek közé kell tenni, hogy a program tudja értelmezni. A szöveges adatok a numerikus adatokhoz hasonlóan lehetnek: konstansok és változók. A szöveges konstans a program során nem változtatja tartalmát. Ilyen szöveges konstans a PRINT utasítás tárgyában megadott szöveg:

110 PRINT "NETTO ERTEK SZAMITAS"

Ha a szöveges adat tartalma a program során megváltozik, vagy értékét ugyan nem változtatja meg, de többször kell rá hivatkozni, akkor a szöveges adatot változóként kezeljük. Ekkor a szöveges adat változónevet kap. A szöveges adatok változónevét a numerikus változók nevéhez hasonlóan képezzük, azzal az eltéréssel, hogy a változónév végére $ jelet kell írni. Ilyen lehet például:

A$, C5$

A szöveges változók a már ismert módokon kaphatnak értéket. Értékadás történhet a LET utasítás segítségével:

110 LET B$="NETTO ERTEK SZAMITAS"

3. feladat
Magánszemélyek nettó jövedelmét kell kiszámítani a bruttó jövedelemből a megfelelő jövedelemadó és községfejlesztési hozzájárulás levonása után. A feladatot a 45/1983. (XI. 20.) Minisztertanácsi rendelet előírásai szerint kell megoldani. Egyszerűsítésként személyenként és évente egy alkalommal kell a számolást elvégezni a kumulált éves bruttó jövedelem alapján.
A feladat megoldása során a következő adatokat kell kiírni:

Brutto jovedelem: XXXXXX Ft
Jovedelemado:         XXXX Ft
KOFA:                       XXX Ft
Netto jovedelem   XXXXXX Ft

A feladat elemzése
A feladat megoldási menete az idézett rendelet értelmében a következő: a bruttó jövedelemből le kell vonni 5% költséghányadot és a befizetett társadalombiztosítási összeget. A maradék a jövedelemadó alapja. A jövedelemadó mértékét az alábbi táblázatsegítségével kell meghatározni:

Adóalap
Adó
  20 000 Ft-ig
  20 001 -   40 000 Ft
  40 001 -   60 000 Ft
  60 001 - 100 000 Ft
100 001 - 200 000 Ft
200 001 - 400 000 Ft
400 001 - 600 000 Ft
600 001 -
2%
400 Ft és a 20 000 Ft-on felüli rész 6%-a
1 600 Ft és a 40 000 Ft-on felüli rész 10%-a
3 600 Ft és a 60 000 Ft-on felüli rész 20%-a
11 600 Ft és a 100 000 Ft-on felüli rész 38%-a
49 600 Ft és a 200 000 Ft-on felüli rész 50%-a
149 600 Ft és a 400 000 Ft-on felüli rész 60%-a
269 600 Ft és a 600 000 Ft-on felüli rész 65%-a

A községfejlesztési hozzájárulás (KÖFA) mindig az adó 10%-a. A feladat egyszerű algoritmussal megfogalmazható, ezért számítógéppel megoldható.
A számítás elvégzéséhez két adat szükséges: a bruttó jövedelem és a társadalombiztosítási összeg. Az eredményadatok ezekből már kiszámíthatók.
A feladat megoldásához szükség van egy adatbeolvasó modulra, egy számítási modulra és egy kiíró modulra.

A program tervezése
Vizsgáljuk meg az egyes modulokat kicsit részletesebben! Az adatbeolvasási modulban két adatot (bruttó jövedelem = BJ és társadalombiztosítás = TB) kell beolvasni a billentyűzetről. Egyszerűsége miatt további bontása felesleges.
A nettó értékszámítási funkció két lépésre osztható: a bruttó jövedelemből a szükséges levonásokkal elő kell állítani az adóalapot, majd ebből az adót kell kiszámítani. Ez utóbbi művelet során meg kell vizsgálni, hogy az adóalap melyik sávba esik, majd ki kell számítani a levonásokat. Mivel ez a művelet elég terjedelmes CASE szerkezetet fog alkotni, tanácsos a többi számítást leválasztani róla. Ennek figyelembevételével tekintsük önálló modulnak az adóalap-számítást (levonások), a jövedelemadó-számítást és ismét külön modulnak a KÖFA-számítást is magába foglaló nettójövedelem-számítási modult. A kiírás egy modulban megoldható.
A feladatot 5 modulra bontottuk fel:


23. ábra: A 3. feladat modul szerkezete

A feladat megoldása szempontjából nagyon lényeges a jövedelemadó-számítás, ezért alakítsuk ki ennek algoritmusát.
Az első lépésben meg kell vizsgálni, hogy az adóalap melyik sávba esik. Ezt egy 8-felé szétváló CASE szerkezettel lehet elvégezni. Egy intervallumba tartozást általános esetben két vizsgálattal lehet elvégezni (az értéke nagyobb az alsó határnál, kisebb a felső határnál). Amikor ilyen folyamatosan csatlakozó intervallumokba esést vizsgálunk, akkor az első intervallumnál még két, utána intervallumonként már csak egy vizsgálat is elegendő, ha a vizsgálat során vagy alulról felfelé, vagy felülről lefelé folyamatosan haladunk.
Ha a program kiválasztotta az intervallumot, akkor a következő lépésben az adóalap és az intervallum alsó határa közti különbséget kell képezni. A különbségei előírás szerinti százalékához hozzá kell adni a sávra jellemző konstanst és a művelet befejeződik. Ezzel az adót kiszámítottuk, amelynek 10%-a a KÖFA. Az utolsó lépés a számított eredmények kiírása.
A feladat vezérlési szerkezetének egyszerűsége miatt tekintsünk el a vezérlőmodult alkalmazó szerkezettől.

A modulok tervezése

(1) Adatbeolvasás
A modul adat típusú. A modulban két adatot (BJ és TB) kell billentyűzetről beolvasni INPUT utasítás segítségével.

(2) Adóalap-számítás
A modul eljárás típusú. Bemeneti adatai az (1) modulban beolvasott BJ és TB értékek, kimenete pedig az adóalap (AA).
A számításkor a bruttó jövedelemből előbb levonjuk az 5% költséghányadot (0.95-tel való szorzás), majd ezt a társadalombiztosítási összeggel csökkentjük.

(3) Jövedelemadó-számítás
A modul eljárás típusú. Bemeneti adata az adóalap (AA) a (2) modulból. A modul kimeneti adata a jövedelemadó.
A modul kezdetén meg kell keresni, hogy az adóalap (AA) a 8 lehetséges intervallum közül melyikbe tartozik, majd az intervallumtól függően a következő képlettel lehet a jövedelemadót kiszámítani:

JA = K+(AA-AH)*SZ

ahol

Az AH-t és SZ-t konstansnak tekintjük. Ezzel a modul algoritmusa már felépíthető.

(4) Nettó jövedelem számítása
A modul eljárás típusú. Bemenetei a bruttó jövedelem (BJ) és a levonások (TB, JA). A modulban először a KÖFA-t kell kiszámítani, amely a jövedelem 10%-a:

KF = 0.1*JA

Majd a bruttó összegből le kell vonni valamennyi csökkentő tételt, és megkapjuk a nettó jövedelmet:

NJ = BJ-(TB+JA+KF)

(5) Nettó jövedelem kiírása
A modul eljárás típusú. Bemenetét a kiírni kívánt adatok (BJ, JA, KF és NJ) alkotják, és ezek a kimeneti adatok is a kísérő szövegekkel.
A kiírás a korábban megismert módon elvégezhető. Hogy ne kelljen minden sorban az FT szövegrész kiíratásával konstansként foglalkozni, alakítsunk ki egy szöveges változót, amely az összeg utáni szóközt és az FT szöveget tartalmazza:

F$=" Ft"

Ezzel elérjük, hogy minden sor végén ezt a szöveges változót kell kinyomtatni.

A kódolás

10 REM ***** JOVSZ *****
60 REM *** ADATBEOLVASAS ***
70 INPUT "Brutto jovedelem: ";BJ
80 INPUT "Tarsadalom biztositas: ";TB
120 REM *** ADOALAP SZAMITAS ***
130 LET AA=0.95*BJ
140 LET AA=AA-TB
150 REM *** JOV. ADO SZAMITAS
160 REM * CASE KEZDET *
170 IF AA<=20000 THEN LET JA=AA*0.02: GO TO 480
180 IF AA<=40000 THEN LET JA=400+(AA-20000)*0.06: GO TO 250
190 IF AA<=60000 THEN LET JA=1600+(AA-40000)*0.1: GO TO 250
200 IF AA<=100000 THEN LET JA=3600+(AA-60000)*0.2: GO TO 250
210 IF AA<=200000 THEN LET JA=11600+(AA-100000)*0.38: GO TO 250
220 IF AA<=400000 THEN LET JA=49600+(AA-200000)*0.5: GO TO 250
230 IF AA<=600000 THEN LET JA=149600+(AA-400000)*0.6: GO TO 250
240 LET JA=269600+(AA-600000)*0.65
250 REM * CASE VEG *
500 REM *** NETTO JOV SZAMITAS ***
510 LET KF=0.1*JA
520 LET NJ=BJ-(TB+JA+KF)
530 REM *** NETTO JOV. KIIRAS ***
540 LET F$=" Ft"
550 PRINT "Brutto jovedelem: ";BJ;F$
560 PRINT "Jovedelem ado:    ";JA;F$
570 PRINT "KOFA:             ";KF;F$
580 PRINT "Netto jovedelem:  ";NJ;F$
590 STOP

A CASE szerkezet kódjánál hét IF utasítást írtunk le. A 8. felesleges mert ha az adóalap nem esik bele a 400 001 és 600 000 forint közötti sávba, akkor a megoldás értelmében az adóalap 600 000 Ft-on felül van.

Ellenőrző kérdések és feladatok

  1. Mi a főág a programban?

  2. A módosított 2. feladatban a bemeneti adatok modul a 200-as soron, az amortizációszámítás a 300-as soron kezdődik. Megcserélhető a két modul kódja a programban (az amortizációszámítás a 200-as soron, a bemeneti adatok a 300-as soron kezdődne)?
    Ha elvileg igen, akkor a program többi része változatlan maradhat a helyes működéshez?

  3. Milyen típusú változókat ismer? Mi jellemzi ezeket?

  4. Egészítsük ki a 3. feladatot úgy, hogy részfizetések esetén is helyesen működjék. Ehhez a bruttó jövedelem mellett az év során korábban kifizetett bruttó jövedelmek összegét is be kell kérni. A levonásokat és a nettó jövedelmet a teljes bruttó jövedelemből kell kiszámítani, de a korábbi levonásokat és a nettó jövedelmet le kell vonni a kapott eredményből. Készítsük el a programot!

  5. Készítsen programot, amely 1 és 5 közötti számokat kér be. A beírt számnak megfelelő sorszámú sorba írjunk ki egy csillagot. Ha a felhasználó nem 1 és 5 közötti számot írt be, akkor írja ki a program: HIBÁS ADAT; ÍRJA BE ÚJRA!

7. A szubrutinok alkalmazása
A szubrutinok alkalmazása többször végrehajtható részfeladatok megvalósítására
A 4. feladat megoldása

Az előző részben megismert GOSUB, RETURN utasításpár nemcsak vezérlőszerkezetek kialakításához alkalmazható, hanem olyankor is, amikor egy műveletsorozatot vagy egy modult többször is végre kell hajtani. Itt nem valamilyen műveletsorozat ciklikus ismétlésére gondolunk, hanem olyan esetre, amikor ugyanazt a műveletsorozatot (modul) a program több pontján kell végrehajtani. A program készítőjében jogosan merül fel az az igény, hogy ilyenkor az ismétlődő modult csak egyszer kelljen kódolni, és a megfelelő helyekről - ahol végre kell hajtani - hívni lehessen.
A szubrutin valamilyen részfeladatot lát el a programon belül. Nem biztos, hogy a különböző hívási pontokon ugyanazokkal az adatokkal kell a feladatát végrehajtani. Ilyenkor a hívás előtt a szubrutin bemeneti változóinak aktuális értékét meg kell határozni értékadási utasításokkal. Ezt nevezzük a szubrutin paraméterezésének.
Mint már láttuk, egy programban több szubrutin is lehet, egy szubrutint több helyről lehet hívni, és szubrutinból is lehet szubrutint hívni. Az utóbbiakat egymásba ágyazott szubrutinnak nevezzük. Az egymásba ágyazás (egymásból hívás) szintjeinek száma nem tetszőleges. Ez a szám gépenként változik, de elég nagy ahhoz, hogy ne okozzon gondot.

4. feladat
Egy anyagot (ceruza) tartalmazó "mini" raktár készletnyilvántartását kell elvégezni. A számítógépben tárolni kell az anyag mindenkori készletét. Anyag be- és kivétel esetén ki kell írni a mozgás főbb adatait:

A feladat elemzése
A feladat értelmében az anyag mindenkori készletét kell tárolni a számítógépben. Kis mennyiségű adatnál ez a programon belül megoldható a DATA utasítás segítségével. Ahhoz, hogy a DATA utasításban levő változó adatot változtatni lehessen, az utasítást minden programvégrehajtás után át kell írni (programmódosítás) Erre tehát figyelmeztetni kell a felhasználót.
Alapvetően két tevékenységet kell elvégezni. Az egyik az anyagbevételezés, a másik az anyagkiadás. Mivel ezek vagylagosak, a felhasználóra kell bízni, hogy eldöntse, melyiket akarja elvégezni, vagy esetleg az egészet befejezi. Ezért a programelem egy "menüt" kell a felhasználó elé tárni, hogy a kívánt műveletet kiválaszthassa:

KESZLETNYILVANTARTAS
(1) BEVETELEZES
(2) KIADAS
(3) BEFEJEZES

Az egyes műveletek esetében a következő feladatokat kell elvégezni:

Megállapíthatjuk, hogy a feladat elvégzéséhez az alábbi adatokat kell tárolni anyaghoz:

A program tervezése
Vizsgáljuk meg a program egyes moduljait! A menü modul további bontása felesleges. A bevételezett mennyiség modul egyetlen összeadásból áll, míg a kiadott mennyiség modulnál előbb meg kell vizsgálni, hogy megvan-e a kivenni kívánt mennyiség az anyagból. Ha nincs, akkor hibaüzenetet kell kiírni: "ENNYI NINCS".
Ezután az anyagkiadási művelet elejére kell visszatérni, hogy a felhasználó módosíthassa a kiadni kívánt mennyiséget. Ezek a műveletek egy modulban elvégezhetők. A többi modult sem kell tovább bontani, mivel eléggé egyszerűek.
Mind a bevétel, mind a kiadás esetén a művelet befejeztével a menü modul kezdetére kell adni a vezérlést, hogy a felhasználó kiválaszthassa a következő műveletet.
Az adatokat DATA utasításban tároljuk. Célszerű vagy egyszerre beolvasni mind a két adatot, vagy ha egyenként olvassuk, akkor fokozottan kell ügyelni az olvasás sorrendjére, mivel az olvasó utasítások nem egymás után helyezkednek el. Az előbbi megoldást választjuk, mivel ez az egyszerűbb. Ezt a műveletet a program kezdetén kell elvégezni.
Az adatkezelésnél figyelembe kell venni, hogy a tárolt készletadatot a programfutás végén módosítani kell az aktuális értékre a ki- és bevételek miatt. A program a befejezés előtt a tényleges készletadat alapján felszólítja a felhasználót az adat átírására.
Mindkét készletmódosítási műveletnél az értékszámítás modul azonos, ezért ezt csak egyszer kódoljuk szubrutin formájában, és ahol végre kell hajtani, onnan hívjuk.
Vegyük szemügyre a modulszerkezetet!


24. ábra: A 4. feladat programszerkezete

Jól felismerhető, hogy a (2) menü modul nem csupán a menükiírást végzi el, hanem vezérlő funkciót is ellát az anyagbevételezési, anyagkiadási és befejezési feladatok hívásával. Ezért ezt a modult vezérlőmodulnak alakítjuk ki, amely a 3 műveletcsoportot szubrutinként hívja.
Az anyagbevételezés, anyagkiadás és befejezés modulokat a tervezéskor további modulokra bontottuk, és csupán azért tartottuk meg őket, hogy az ábra jobban áttekinthető legyen. Mivel szekvenciálisán végrehajtandó modulokat vezérelnek, kódolásuktól most eltekintünk.
A feladat megoldásának egyszerűsége végett az anyagbevételezés, anyagkiadás és befejezés részfeladatait műveletenként egy-egy szubrutinban foglaljuk össze: a (3), (4) és (5) modul egy szubrutin, a (6), (4) és (7) egy másik, valamint a (8) és (9) egy szubrutin.

A modulok tervezése

(1) Készletmásolás
A modul eljárás típusú. Bemenetei a DATA utasításban tárolt két adat (készlet, egységár). Kimenete a programban használt készletadat (K).
A modulban beolvassuk a tárolt adatokat.

(2) Menü
Vezérlő típusú modul. Bemenete a felhasználó által begépelt adat, amellyel a műveletet választja ki. Kimenete a kiválasztott modul hívása.
A modul kezdetén töröljük a képernyőt. Ezután az üres képernyőre ki kell írni a menüt (lásd a feladatelemzésben), majd le kell olvasni a felhasználó döntését (D adat) a "MELYIKET VALASZTJA?" kérdésre. A D értéke dönti el, hogy melyik szubrutint kell hívni. A választott műveletet egy CASE szerkezettel lehet kiválasztani.
Itt kell figyelembe venni, hogy a CASE szerkezetben egy szubrutint hívunk. A szubrutin végrehajtása után a hívó utasítás utáni utasításra kerül a vezérlés. Ez pedig a CASE szerkezet értelmében a D értékének vizsgálata. Ez nem okoz gondot, hiszen a szubrutin végrehajtása során D értéke nem változik meg, és így a következő vizsgálat eredménye nem lehet egy újabb szubrutinhívás. Ha például a felhasználó az anyagkiadási műveletet hívja, akkor 2-t gépel be (D=2). Ekkor a D=2 feltétel teljesül, a gép hívja az anyagkiadási szubrutint. Ennek végrehajtása után a D=3 feltétel vizsgálatára tér vissza a program. Ez a feltétel nem teljesül, vagyis a befejezést sem hajtja végre. Tehát a vezérlés helyesen fog működni.
A befejezés kivételével minden művelet után újra a menü kiírására kell visszatérni, hogy a felhasználó újabb műveletet hajthasson végre. Ezért a CASE szerkezet végén egy újabb vizsgálatot kell beiktatni, hogy előzőleg a felhasználó a befejezést kérte-e (D=3). Másik oldalról megközelítve erre azért van szükség, mert a két befejezési modul is szubrutint alkot. A szubrutin végrehajtása után a vezérlés visszakerül a hívó utasítást követő utasításra. A modul akkor működik helyesen, ha itt egy olyan utasítás áll, amely még egyszer megvizsgálja D értékét. Ha D<>3, akkor újra ki kell írni a menüt, de ha D=3, akkor a program végére kell ugrani.
Ha a második D=3 vizsgálat helyén egy GOTO utasítás állna, amely a menükiírásra vinné a vezérlést, akkor a programot sohasem lehetne befejezni, mert a CASE szerkezet után a program mindig újra kezdené a menükiadást.

(3) Bevételezett mennyiség
A modul eljárás típusú. Bemeneti adata a bevételezett mennyiség (BM). Kimeneti adata az új készlet (K).
A képernyő törlése után be kell olvasni a bevételezett mennyiséget. Az adatot hozzá kell adni a készlethez, hogy az új készletet megkapjuk.

(4) Értékszámítás-hívás
A modul eljárás típusú. Bemeneti adata az egységár (AR) és a mozgó anyagmennyiség (MA), kimenete pedig a kettő szorzata (ER).
Magát a műveletet szubrutinként kódoljuk, és mind a bevételezésnél, mind a kiadásnál használjuk, ezért az anyagmennyiség az egyik esetben a bevételezett mennyiség (BM), a másik esetben a kiadott mennyiség (KM). Hogy a modul mindkét esetben használható legyen, a mozgó anyagmennyiség (BM), a modul hívása díj adunk értéket. Ezután a szubrutin befejeződik, és újra a (2) modul következik, amely a menüt kiírja. Ez a kiírás viszont törli a bevételezés kiírását, s a felhasználó el se tudná olvasni az eredményt, ezért a képet "le kell állítani". Csak akkor szabad folytatni a programot, ha a felhasználó már "eleget nézte" az eredményt. Ezt legegyszerűbben egy bármilyen jel beolvasásával lehet megvalósítani (Lásd az AMOR1 programnál!) A program csak akkor folytatódik, ha a felhasználó beüt valamilyen billentyűt.

(5) Adatkiírás (B)
A modul eljárás típusú. Bemeneti adatai a bevételezett mennyiség (BM) és a bevételezett érték (ER). Ezeket az adatokat írja ki a modul.

(6) Kiadott mennyiség
A modul eljárás típusú. Bemeneti adata a kiírni kívánt mennyiség (KM). Kimeneti adata az új készlet (K).
A képernyő törlése után fel kell szólítani a felhasználót, hogy gépelje be a kit kívánt anyagmennyiséget. Ellenőrizni kell, hogy a kívánt mennyiség kiadható-e. Ha igen, akkor a művelet a (4) modullal folytatódik, ellenkező esetben a modult újra kell hívni, hogy a felhasználó javíthasson.

(7) Adatkiírás (K)
A modul eljárás típusú. Bemeneti adatai a KM és az ER. Ezek alkotják a modult kimenetét is.
A modul az (5) modulhoz hasonlóan kiírja a kiadás adatait.

(8) Készletátírás
A modul eljárás típusú. Kimenete egyetlen emlékeztető kiírás a felhasználónak, hogy a készletet tartalmazó DATA utasítás tárgyában levő adatot az aktuálisra írja át. Ehhez természetesen ki kell írni az aktuális készletadatot is.

(9) Befejezés
A modul eljárás típusú. A program végén kiírja, hogy a program befejeződött.

Kódolás
A kész program:

10 REM ***** KESZL *****
60 REM *** KESZLET MASOLAS ***
70 READ K,AR
90 REM *** MENU ***
110 CLS
120 PRINT : PRINT
130 PRINT TAB (6);"KESZLETNYILVANTARTAS"
140 PRINT : PRINT
150 PRINT TAB (9);"(1) Bevetelezes"
160 PRINT TAB (9);"(2) Kiadas"
170 PRINT TAB (9);"(3) Befejezes"
180 PRINT : PRINT : PRINT TAB (5);"Aktualis keszlet: ";K
190 INPUT "Melyiket valasztja? ";D
200 IF D=1 THEN GO SUB 250
210 IF D=2 THEN GO SUB 440
220 IF D=3 THEN GO SUB 750
230 IF D=3 THEN GO TO 960
240 GO TO 110
250 REM *** BEVETELEZETT M. ***
260 CLS
270 PRINT : PRINT
280 INPUT "A bevetelezett mennyiseg: ";BM
290 LET K=K+BM
300 REM *** ERTEK SZAM. ***
310 LET MA=BM
320 GO SUB 900
330 REM *** ADATKIIRAS (B) ***
340 CLS
350 PRINT : PRINT
360 PRINT TAB (8);"Anyagbevetelezes"
370 PRINT : PRINT
380 PRINT "A bevetelezett mennyiseg: ";BM
390 PRINT
400 PRINT "A bevetelezett ertek: ";ER
410 PRINT : PRINT
420 INPUT "Ha befejezte, nyomjon ENTER-t!";F$
430 RETURN
440 REM *** KIADOTT M. ***
460 CLS
470 PRINT : PRINT : PRINT "Aktualis keszlet: ";K
480 INPUT "A kiadott mennyiseg: ";KM
490 IF KM>K THEN GO TO 510
500 GO TO 550
510 REM * THEN AG *
520 PRINT : PRINT
530 PRINT "Ennyi nincs!"
540 GO TO 480
550 REM * ELSE AG *
560 LET K=K-KM
570 REM * IF VEG *
580 REM * ERTEK SZAMITAS *
590 LET MA=KM
600 GO SUB 900
620 REM * ADATKIIRAS (K) *
630 CLS
640 PRINT : PRINT
650 PRINT TAB (10);"Anyagkiadas"
660 PRINT : PRINT
670 PRINT "A kiadott mennyiseg: ";KM
680 PRINT
690 PRINT "A kiadott ertek: ";ER
700 PRINT : PRINT
720 INPUT "Ha befejezte, nyomjon ENTER-t!";F$
730 RETURN
750 REM * KESZLET ATIRAS *
760 CLS
770 PRINT "Ne felejtse atirni a keszletet!"
780 PRINT
790 PRINT "940 DATA ";K
800 REM * BEFEJEZES *
810 PRINT "Vege"
820 RETURN
900 REM * ERTEKSZAM. SZUBRUTIN *
10 LET ER=MA*AR
920 RETURN
930 REM * ADATOK *
940 DATA 100
950 DATA 2.3
960 STOP

Értékelés
A feladat megoldásában alkalmazott programmódosítás (a DATA utasítás átírása) nem a legszerencsésebb módszer. Különösen, ha azt is figyelembe vesszük, hogy ezután a kazettán vagy a lemezen tárolt programot az újjal ki kell cserélni. Ez kazetta esetén a tárolt program újra kimásolásával végezhető el.

8. Ciklikus Tevékenységek I.
Különböző ciklikus szerkezetek megvalósítása a programban
Néhány függvény
Az 5. feladat megoldása

A ciklus
Tegyük fel, hogy feladatunk egy raktárban levő anyagok értékének kiszámítása számítógépes program segítségével. Az anyagok értékét úgy lehet megkapni, ha az egyes anyagok egységárait megszorozzuk a mennyiséggel:

E=A*M

ahol

Egy raktárban többféle anyag van, és az összértéket úgy kapjuk meg, hogy a fenti szorzatot minden anyagra kiszámítjuk:

E1=A1*M1
E2=A2*M2

Végül az E értékeket össze kell adni, és megkapjuk az összes értéket:

F=E1+E2+E3+...+En

Ha most ezt a feladatot egy programmal kívánjuk megoldani, akkor elvileg azt kellene csinálni, hogy az értékszámító szorzatokat annyiszor írjuk be a programba, ahányszor végre kell hajtani:

100 LET E1=A1*M1
110 LET E2=A2*M2
...

Nyilvánvaló, hogy ez nehézkes, ráadásul megvalósíthatatlan is. Képzeljük el ezt a megoldást egy 1000-féle anyagot tartalmazó raktárban! Ennyi utasítást a kisebb gépekbe be sem lehet írni. Ennyi változónevet sem tudunk adni. Azonfelül az anyagok is változhatnak (valamilyen anyag megszűnik, új anyagok jönnek), és a programot minden anyagféleség változása után módosítani kellene.
Észre lehet venni a szabályosságot a példákban. Az elvégzendő művelet mindig ugyanaz. Tehát az elvégzendő műveletet csak egyszer kódoljuk, és minden alkalommal más adatokkal (a következő anyag) kell végrehajtani. Lépésekre bontva a következőt kapjuk:

  1. adatmeghatározás (következő anyag A, M)
  2. értékszámítás (E=A*M)

A 2. lépés után ismét az első, majd a következő anyag adataival a2. lépés, utána megint az 1., és így tovább következik. A műveletet ciklikusan ismételve hajtja végre a program, ezért az ilyen szerkezetet ciklusnak nevezzük.
Az összértéket az egyes anyagok értékének kiszámítása utáni kell meghatározni. Ilyenkor minden anyag értékét meg kellene jegyezni egy-egy változóban, és az egyedi értékszámítás után ezeket kell összegezi. Nem lehetne ezt valahogy egyszerűbben meghatározni? Az összegzést lépésenként is végre lehet hajtani, vagyis az F értékéhez minden értékszámítás után hozzáadjuk az aktuális értéket (E). Ennek eredményeként az összeg is rendelkezésre fog állni. Bővítsük ki ezzel a lépéssel a kiszámítás menetét:

  1. adatmeghatározás
  2. értékszámítás
  3. az érték hozzáadása az összeghez (F+E)

Könnyen észrevehető, hogy az értékösszegezés csak akkor működik helyesen, ha a művelet elején F értéke nulla. Ellenkező esetben az induló érték hozzáadódna az összes értékhez.
Jól látható a ciklus előnye: ha egy műveletsort különböző adatokkal akarunk végrehajtani, akkor csak egyszer kell kódolni és minden adattal végrehajtani.

Meddig kell a ciklust ismételni? Addig, amíg van adat, amellyel a műveletet el kell végezni. Ezért a ciklusban valahol meg kell vizsgálni, hogy van-e még adat, amellyel a műveletet végre kell hajtani. A vizsgálat a ciklus kezdetén vagy végén állhat. Akárhol is legyen a vizsgálat, a ciklusból tovább kell menni (be kell fejezni), ha a vizsgálat eredménye ezt mutatja.
A ciklus kezdete előtt kell egy művelet (pl. F=0), amelyet csak egyszer kell ugyan végrehajtani, de a ciklushoz kapcsolódik. Az ilyen műveletek alkotják a ciklus előkészítését. Magát a műveletsort, amelyet ismételten végre kell hajtani, ciklusmagnak nevezzük. A ciklus folytatásával vagy befejezésével kapcsolatos vizsgálatot ciklusfeltétel-vizsgálatnak nevezzük. Az az adat, amelynek értéke meghatározza a ciklus folytatását vagy befejezését, a ciklus változója. Példánkban az anyagszám a ciklusváltozó. A ciklust addig kell ismételni, amíg minden anyagot sorra nem vettünk.
Összefoglalva, egy ciklus három részből áll:

A ciklusszerkezetet kétféle algoritmusban valósíthatjuk meg, attól fügően, hogy hol helyezkedik a ciklusfeltétel-vizsgálat:


25. ábra: Az elöl tesztelő típusú ciklusszerkezet


26. ábra: A hátul tesztelő típusú ciklusszerkezet

A két szerkezetet összehasonlítva látható, hogy a feltételvizsgálat helye és a vizsgálat jellege eltér egymástól. Az elöl tesztelő szerkezetben a folytatás feltételét kell vizsgálni, a hátul tesztelő szerkezetekben a befejezés feltételét kell vizsgálni.
Többnyire bármelyik szerkezetet lehet használni. Vannak azonban olyan feladatok, ahol vagy csak az egyiket, vagy csak a másikat lehet használni. Ezek a tiszta esetek néhányszor nem alkalmazhatók, mert arra kényszerülünk, hogy a ciklusfeltétel-vizsgálatot sem a ciklus elején, sem végén, hanem valahol a közepén helyezzük el.
A ciklikus tevékenységek kódolásához is érdemes a ciklus szerkezetét kifejező kódolási formát alkalmazni.
Az elöl tesztelő ciklusszerkezet kódolása:

m REM CIKLUSKEZDET
    IF folytatási feltétel THEN n
    GO TO p
n REM CIKLUSMAG
    ...
    GO TO m
p REM CIKLUSVEG

A hátul tesztelő ciklusszerkezet kódja:

n REM CIKLUSKEZDET
    ...
    IF befejezési feltétel THEN GO TO p
    GO TO n
p REM CIKLUSVEG

A bemutatott két szerkezeten kívül a BASIC-ben van kifejezetten ciklusutasítás: ez a FOR, STEP, NEXT utasításhármas, amelyet azonban röviden csak FOR, NEXT utasításpárnak hívunk. Nézzük meg, hogy a FOR és a NEXT utasításpárral hogyan lehet ciklust kialakítani.

A FOR, NEXT utasításpár
Ha a ciklusmagban van olyan változó, amelynek értéke minden ciklusmag végrehajtása során egyenletesen (lineárisan) változik (nő vagy csökken), és értéke alapján a ciklus befejezése eldönthető, akkor a ciklus kódolásához a FOR, NEXT utasításpár felhasználható. Az említett változó pedig a ciklusváltozó lesz. A FOR, NEXT utasításpárral felépített ciklusban azt kell meghatározni, hogy a ciklusváltozó milyen kezdőértéktől, milyen lépésenként haladva, milyen végfeltételértékig kell a ciklus végrehajtani. A program a ciklusmagot mindaddig végrehajtja, amíg ciklusváltozó értéke meg nem haladja a záróértéket, ha a ciklusváltozó értéke növekszik, illetve ha a ciklusváltozó értéke csökken, akkor addig, amíg a ciklusváltozó a záróérték alá nem csökken. A ciklusváltozó értékének módosítását a program minden ciklusmag végrehajtásakor automatikusan elvégzi, és ha a folytatási feltétel nem teljesül, a gép a ciklust befejezi.
A FOR, NEXT utasításpárral kialakított ciklust számlált menetű ciklusnak is nevezzük.
A FOR utasítás vezeti be a ciklust. Definiálja a ciklusváltozót, valamint ennek kezdő- és záróértékét. A FOR utasítás formája:

x FOR ciklusváltozó = 1. kifejezés TO 2. kifejezés STEP 3.kifejezés

ahol

A ciklusmagot a

NEXT ciklusváltozó

utasítás zárja le. Hatására a program visszaadja a vezérlést a FOR utasításnak, amely kiszámítja a ciklusváltozó következő értékét. A ciklusmag utolsó végrehajtása után a vezérlés a NEXT utasítás utáni utasításra kerül át. A FOR, NEXT utasításokból felépített ciklus befejezésekor a ciklusváltozó értéke azt az értéket veszi fel, amellyel az utolsó ciklusmag végrehajtódott.
Ha a növekmény 1, akkor az utasításból a 2. kifejezés utáni rész (STEP ...) elhagyható. A Sinclair-gépeken a ciklusváltozó neve csak egyetlen betű lehet.

Függvények
Tegyük fel, hogy egy feladaton belül van egy olyan részfeladat, amelyben meg kell határozni egy A változó abszolút értékét. Közismert, hogy az abszolút érték mindig nem negatív szám. Ezt ki lehet számítani az alábbi utasítással:

200 IF A<0 THEN LET A=-A

Mindezt el is hagyhatjuk, mivel a BASIC-ben van olyan függvény, amellyel az abszolút értéket közvetlenül meghatározhatjuk. Ez az ABS függvény. Az abszolút érték kiszámításához a bemutatott példában a kővetkezőképpen lehet felhasználni:

200 LET A=ABS(A)

Sinclair-gépeknél a zárójel elhagyható:

200 LET A=ABS A

A BASIC nyelvben több ilyen "beépített" függvény van, amelyet a programozó programíráskor felhasználhat. A függvények valamilyen szabály szerint egy független változó értékből (argumentumból) egy eredményértékét számítanak ki. Általános formában felírva:

eredmény=függvény(argumentum)

Az eredmény és az argumentum mindig valamilyen konkrét számérték, a függvény pedig a kiszámítás módját határozza meg. Például az ABS függvény az argumentumból mindig az argumentum számértékének megfelelő pozitív eredményt állít elő.
De van ennél több segítséget nyújtó függvény is. Például a SIN függvény, amely az argumentum szinuszát számítja ki (az argumentumot ívmértékben feltételezi a gép):

200 LET A=SIN(B)

Sinclair-gépeknél megengedett a zárójel elhagyása:

200 LET A=SIN B

Az A (eredmény) értéke a B szinusza lesz. A függelék tartalmazza valamennyi függvényt. Számunkra azért előnyös a függvények használata, mert lehetővé teszik, hogy valamilyen eredményt egyetlen utasítással számítsunk ki ahelyett, hogy több lépéses műveletet végeznénk el az érték kiszámításához. Van olyan függvény is, amelyet más BASIC utasításokkal egyáltalán nem vagy csak roppant erőfeszítések árán tudunk pótolni.
A meglevő függvényeken kívül a felhasználó is definiálhat függvényeket az 5 alapműveletből és a BASIC könyvtári függvényeiből. Ezek a felhasználói függvények.
A felhasználói függvényeket használatuk előtt definiálni kell a programban az alábbi utasítással:

x DEF FNnév(változó)=kifejezés

ahol

A HT és a PRIMO gépen ez a lehetőség nincs meg.
A Sinclair-gépeknél a név egy betű lehet.

Tekintsünk most egy részfeladatot, amelynek értelmében egy valós számot kerekíteni kell! A részfeladat viszonylag egyszerűen megoldható eddigi ismereteink segítségével, de még jobban egyszerűsíthetjük, ha egy függvényt is felhasználunk a megoldásban.
Az INT függvény segítségével vegyes számokból le lehet "választani" a törtrészt. A függvény formája:

x eredmény=INT(argumentum)

A Sinclair-gépeknél az argumentumot nem kell zárójelbe tenni:

x eredmény=INT argumentum

A függvény eredménye az a legnagyobb egész szám (vagy zérus), amely nem nagyobb a kifejezésnél. Például:

INT(16.25)=16
INT(0.47) =0
INT(-4.3) =-5

A függvény jól használható pozitív számok kerekítésére. Előtte azonban úgy kell alakítani, hogy a törtrész leválasztása után a kerekítésnek megfelelő értéket kapjuk meg. Ezt úgy érhetjük el, hogy a kerekítendő számhoz hozzáadunk 0.5-öt. Ha az A törtrésze 0.5 volt vagy annál nagyobb, akkor az A egész része az összeadás következtében eggyel nagyobb lett. Ha ennek vesszük az egész részét, akkor az eredeti szám kerekített összegét kapjuk. Például:

A=1.53
A=1.53+0.5 = 2.03
INT(A)=2

Ha az A törtrésze 0.5-nél kisebb volt, akkor az összeadás után az A egész része változatlan marad, és a törtrész leválasztása után a kerekített számot kapjuk. Például:

A=2.27
A=2.27+0.5 = 2.77
INT(A)=2

A kerekítés elvégzésére definiálhatunk egy függvényt is. Ha a fenti A változó értékét kell kerekíteni, akkor ehhez például egy K nevű függvényt definiálunk:

100 DEF FN K(A)=INT(A+0.5)

Hatására a gép "ismerni fogja" az FN K felhasználói függvényt. Ha bárhol a programban kerekíteni akarjuk az A értékét, akkor az FN K függvénnyel meg lehet határozni a kerekített értéket:

500 LET B=FN K(A)

B értéke az A kerekített értéke lesz, amit a gép a függvénydefiniálásban megadott kifejezés szerint számít ki.

5. feladat
Ki kell írni egy egyéves lejáratú áruvásárlási kölcsön havi részletfizetési összegét, a hónapokra esedékes kamatot, az alapösszegből havonta visszafizetett összeget és a kölcsön maradék összegét a következő táblázatos formában:

RESZLET
OSSZEG
KAMAT OSSZEG
VISSZA
FIZ. OSSZEG
KOLCSON
OSSZEG
xxxx
xxxx
xxxx
xxxx

Az összesítő eredményeket egy sor kihagyással a 14. sorba kell írni.

A feladat elemzése
A kamatos kölcsönök egyenlő részletben való visszafizetésekor az egyes részletek összegét a következő képlettel lehet meghatározni:

ahol

Mivel a feladatban egy 1 évre kapott kölcsönt kell havi részletekben törleszteni, a kifejezést módosítani szükséges. A kamat éves szinten értendő, ezért havi törlesztésre az 1/12-ét kell figyelembe venni. A tartam (T) évekre vonatkozik, tehát meg kell szorozni 12-vel, hogy a részlet havi összeg legyen. Ennek megfelelően a felhasznált képlet:

Megjegyezzük, hogy negatív F vagy K esetén az eredmény is negatív lesz, ami nyílván értelmetlen a feladat szempontjából. Ezért csak pozitív F-et és K-t szabadd fogadni.
Havi törlesztés esetén az adott hónapra esedékes kamat összegét az előző havi maradék összeg alapján kell kiszámítani:

HK = F*K/12

ahol

A kölcsön összege a havi részlet és a havi kamatösszeg különbségével csökken:

CK = F-HK

ahol

CK - a kölcsönből az adott hónapban visszafizetett összeg.

Ez nyilvánvaló, hiszen a kamat a kölcsönösszegen felüli összeg, így a kamatfizetés nem csökkentheti a kölcsönösszeget. A maradék kölcsönösszeg tehát a tárgyhó végén:

FJ = FM-CK

ahol

A fentiekből látható, hogy a havi részlet (F) kivételével mind a havi kamatösszeg |HK), mind a havi kölcsön-visszafizetés összege (CK) minden hónapban az előző havi maradék kölcsönösszegből származik.
A feladat elején meg kell ismerni a kölcsön adatait, a kölcsön összegét és a kamatot. A program ezeknek az adatoknak a beolvasásával fog kezdődni. Ezután ki kell számítani a havi részlet összegét, és rátérhetünk a táblázat adatainak kiszámítására és kiírására. Mint láthattuk, a havi változó adatok (HK, CK, FJ) az előző havi maradék kölcsönösszegből (FM) kiszámíthatók - mindig azonos kifejezések segítségével -, ezért ezt a műveletsort csak egyszer kell kódolni a programban, és annyiszor végrehajtani, ahányszor erre szükség van (12-szer). A művelet tehát ciklust fog alkotni.
A havi részlet-, a havi kamat- és a havi visszafizetés-összegeket a havi számítások eredményével meg kell növelni, és a havi adatok után ki is kell írni.

A program tervezése
Tekintsük át az egyes funkciókat részleteiben! Az adatbeolvasás és a havi részlet kiszámítása zárt, egyszerű feladat, ezek önálló modulként megmaradhatnak.
Az (1) modulban az adatbeolvasást ellenőrzéssel kell kiegészíteni. Csak akkor szabad elfogadni a begépelt adatokat, ha pozitívak. Negatív adat esetén "CSAK POZITIV LEHET!" hibaüzenetet kell kiírni, és meg kell ismételni a beolvasást.
Alaposabb tervezést igényel azonban a havi adatok kiszámítása. Ez a funkció a következő műveleteket foglalja magában:

Ezt a modult tehát tanácsos három modulra tovább bontani (27. ábra). A (3), (4) és |5) modult annyiszor kell végrehajtani, ahány hónap van egy évben. Ez a három modul együtt egy ciklus magját alkotja. A ciklusváltozó a hónapok száma, a ciklusfeltétel pedig a 12. hónap adatainak feldolgozása. Ezután ugyanis a művelet véget ér. Ezt a ciklust a FOR, NEXT utasításpárral jól meg lehet valósítani. A ciklusműveletek számát a H (hónap) változó értéke szabja meg. A (3) modul számításait az elemzésnél megismertük.
A (4) összegezéseit az ún. "gyűjtő" módszerrel végezzük el. Minden összeghez kijelölünk egy változót, induló tartalmát nullázzuk (bár ez a legtöbb BASIC változatban felesleges), és minden számítási művelet után a kapott eredményeket hozzáadjuk a megfelelő változó értékéhez. Ezzel az összegek a ciklus befejezésére készen állnak a megfelelő gyűjtőkben.
Az (5) és (6) modul kiírásait a PRINT utasítással fogjuk megvalósítani. A (6) modult csak egyszer kell végrehajtani, és ezután a program befejeződik.
A kiírás nem tartalmazza a bemeneti adatokat, ezért csak a program elején célszerű a képernyőt törölni, a táblázat kiírása előtt nem, hogy a bemeneti adatok is láthatók legyenek.
A programban a ciklus vezérléséhez nem célszerű vezérlőmodult alkalmazni, mivel a ciklust FOR, NEXT utasításpárral kódoljuk. A FOR, NEXT utasításpár önmaga gondoskodik a ciklus vezérléséről. A cikluson kívüli 3 modul szekvenciális végrehajtása szintén megoldható vezérlőmodul nélkül.


27. ábra: Az 5. feladat programjának terve

A modulok tervezése

(1) Adatbeolvasás
A modul adat típusú. Bemeneti és kimeneti adatai a beolvasott és ellenőrzött F és K adatok.
A modulban kell beolvasni a kölcsönösszeget (F) és a kamatot (K). Mindkét adatot ellenőrizni kell, hogy pozitívak-e. Negatív vagy 0 bemenet esetén hibaüzenetet kell kiadni, és a beolvasást meg kell ismételni. A kamat összegét (K) el kell osztani 100-zal, hogy a számításhoz megfelelő értéket kapjunk. Megjegyezzük, hogy mindkét adatbeolvasás hátul tesztelő ciklusban megy végbe.

(2) Részlet számítása
A modul eljárás típusú. Bemeneti adatai az F és K érték az (1) modulból, kimeneti adata a havi részlet összege.
A modulban a kifejezés egyszerűbb kiszámítása végett a K/12-t egy K1 váltóval helyettesítjük a K1 = K/12 értékadás után. Majd egyetlen utasítással kiszámítható az R érték.

(3) HK, CK, FJ szám
A modul eljárás típusú. Bemeneti adatai a kölcsön összege (F) és a kamatláb (K) az (1) modulból.
Ez a ciklus első modulja, tehát a FoR utasítás ide kerül. Előtte azonban ki kel írni az oszlopok fejléceit. A modulban előbb a HK értéket számítjuk ki, majd ennek alapján a CK-t, végül az FJ-t.
Az első havi számításoknál az FJ a begépelt F értéke lesz. A továbbiakban az eredeti F értékre nem lesz szükségünk, ezért nem követünk el hibát, ha mindig az F változó tartalmazza a mindenkori FJ (a maradék kölcsön) összeget, vagyis F-et csökkentjük a visszafizetéssel.
A modul harmadik művelete tehát az F módosítása lesz: F=F-CK
Így a következő számítási lépésnél már ez az új összeg lesz a kiinduló érték.

(4) Összegezés
A modul eljárás típusú. Bemeneti adatai az R, HK és CK értékek. A modul kimenetét három összeg alkotja.
A modulban három összegérték gyűjtését kell elvégezni. A részletösszegeket az SR, a kamatokat az SK, a visszafizetett összegeket az SC változó tartalmazza.

(5) Kiírás
A modul eljárás típusú. Bemeneti adatai az R, HK, CK és F adatok. A modul ezeket az adatokat egyetlen sorba írja ki.
Ebben a modulban fejeződik be a ciklusmag, ezért a modul végére kerül a ciklust záró NEXT utasítás.

(6) Összegkiírás
Hasonló az (5) modulhoz, azzal a különbséggel, hogy először egy üres sort ír (soremelés), majd az összegeket írja ki. Ezzel a program befejeződik.

Kódolás
Külön meg kell nézni a (4), (5) és (6) modulokban végbemenő négyoszlopos táblázat kiírását.

alakú tabuláló függvény. Az argumentum csak pozitív és 42-nél kisebb lehet. A TAB függvényt csak a PRINT utasítással együtt lehet használni, önállóan nem. Az

x PRINT TAB(argumentum);A

utasítás hatására az A értékének kiírása az argumentum értékével egyenlő sorszámú pozíción kezdődik. Például, ha a TAB argumentuma 10, akkor az A értékének nyomtatása a 10. pozíción kezdődik.
Ezzel az eljárással tehát tabulálni tudjuk a kiírást, vagyis az adatelemek kiírását a megfelelő pozícióra tudjuk állítani. A képernyőt itt is 10 pozíció széles mezőkre célszerű felbontani a TAB alkalmazásával. Az első adatelem kiírása a képernyő bal szélén kezdődik, ezért csak a második adatelemtől kezdve kell a TAB függvényt használni.

Bár itt nem használjuk, de megjegyezzük, hogy a Commodore esetében az

x PRINT TAB (n);"szöveg"

utasítás n szóközt hagy ki a képernyő bal szélétől vagy a legutolsónak kiírt jeltől jobbra, és ezután kezdi kiírni a szöveget.

A program:

10 REM ***** KAMAT *****
20 DEF FN K(A)=INT (A+0.5)
30 REM *** ADATBEOLVASAS ***
40 INPUT "A kolcson osszege: ";F
50 IF F<1 THEN PRINT "Csak pozitiv lehet!": GO TO 40
60 INPUT "Kamatlab (%): ";K
70 IF K<1 THEN PRINT "Csak pozitiv lehet!": GO TO 60
80 LET K=K/100
90 REM *** RESZLET SZAMITAS ***
100 LET K1=K/12
110 LET R=F*K1/(1-(1/(1+K1)^12))
120 REM *** HK, CK, F SZAMITAS ***
130 PRINT : PRINT
140 PRINT "Reszlet";TAB (8);"Kamat";TAB (16);"Vissza";TAB (24);"Kolcson"
150 PRINT "osszeg";TAB (8);"osszeg";TAB (16);"fiz.o.";TAB (24);"osszeg"
160 PRINT
170 LET SR=0: LET SK=0: LET SC=0
180 REM * CIKLUS KEZDET *
190 FOR H=1 TO 12
200 LET HK=F*K1
210 LET CK=R-HK
220 LET F=F-CK
230 REM * OSSZEGZES *
240 LET SR=SR+R
250 LET SK=SK+HK
260 LET SC=SC+CK
270 REM * KIIRAS *
280 PRINT FN K(R);TAB (8);FN K(HK);TAB (16);FN K(CK);TAB (24);FN K(F)
290 NEXT H
300 REM * CIKLUS VEG*
310 REM *** OSSZEG KIIRAS ***
320 PRINT
330 PRINT FN K(SR);TAB (8);FN K(SK);TAB (16);FN K(SC)

Ellenőrző kérdések és feladatok

1. Alakítsa át az 5. feladat programját úgy, hogy hosszú lejáratú kölcsönök (20, 25 év) havi részletét lehessen vele kiszámítani. A kiírási képbe vegyen fel egy külön oszlopot (az első helyre), amelyben az év és a hónap van (pl. 1985. 6.).

2. Egy beruházás hozama a következő képlettel számítható ki:

ahol

100 000 Ft-os beruházásnál az éves jövedelem (J) 10 000 és 20 000 Ft között változhat 1000 forintos lépésekben (10 000, 11 000, 12 000, ...) az üzemeltetési költség pedig 3000 és 5000 Ft között, 500 forintos lépésekben. A kamat 6% vagy 8%. Milyen éves jövedelem és üzemeltetési költség mellett és melyik kamatlábbal lehet legalább 300 000 Ft hozamot elérni 10 év alatt?

3. Készítsen egy programot, amely a képernyő bal szélétől annyi karakterből álló vonalat ír ki, amilyen értéket a program a billentyűzetről beolvasott. Csináljuk meg a képernyő jobb szélétől számított vonalhosszra is!

4. Készítsünk programot, amely a billentyűzetről beolvasott szám (1 nem lehet) négyzetét kiírja, majd ennek a négyzetét, és így tovább! Mit tapasztal 1-nél nagyobb és kisebb számoknál?

9. Összetartozó adatok kezelése
Egyedi adatok - összetartozó adatok.
Tömbök és használatuk. Ciklikus műveletek tömbváltozókkal.
A 6. feladat megoldása

A számítógépes feladatok felosztása
A számítógéppel megoldható feladatok körében több szempontból is jól elkülöníthető csoportot alkotnak az egyedi adatok feldolgozását célzó feladatok. Erre a feladatcsoportra az jellemző, hogy a feladaton belül viszonylag kevés (legfeljebb néhányszor 10) és lényegében egymástól független adatot kell feldolgozni. A hangsúly inkább az utóbbin van, ami azt jelenti, hogy a feladat szinte valamennyi adatát külön kell kezelni és feldolgozni.
A feladatok másik csoportjába azok tartoznak, amelyekben több, valamilyen szempontból összetartozó adatot kell feldolgozni.
Az előző részekben egyedi adatok feldolgozására láttunk példákat, itt bemutatjuk az összetartozó adatok feldolgozását.

Az összetartozó adatok feldolgozása
Az egyedi adatok és az összetartozó adatok fogalmának pontos meghatározása nehézségekbe ütközik, jobb megértésükhöz három fogalmat ismerjünk meg. Ezek: az egyed, a tulajdonság és az érték.
Az egyed egy rendszernek olyan eleme, amelyet adatokkal kívánunk leírni. Egy vállalatnál egyed lehet egy termék, egy dolgozó, egy anyagféleség stb. A tulajdonság az egyedek jellemzője, amellyel leírhatók. Egy termék tulajdonsága pl. az ára, a súlya, a színe stb. Egy dolgozó tulajdonsága a szakmája, az életkora stb. Az érték egy tulajdonság konkrét megjelenése. Érték például egy termék számszerűen kifejezett ára, valamilyen mértékegységben meghatározott súlya, egy dolgozó szakmájának pontos megnevezése stb.
Egyedi adatok feldolgozásánál kevés egyed vesz részt a műveletben (pl. ellenállás-számítás). Általában a műszaki, tudományos számítások tartoznak a feladatoknak ebbe a körébe. Jellemzője ennek a feladatcsoportnak, hogy a feldolgozásban kevés számú (1-50) adat vesz részt. Ezek az adatok egy, vagy kevés egyed tulajdonságainak az értékei. A kevés számú adat jelenlétéből következik, hogy a programban nem sok gondot kell fordítani az adatok beadására, ellenőrzésére, azonosítására, módosítására, rendszerezésére stb. Ezek a műveletek együttesen alkotják az adatkezelést. Egyedi feladatok esetében az adatkezelés kis helyet foglal el a programban, a nagyobb részt a feldolgozás teszi ki. Az adatok megőrzése sem merül fel problémaként, mivel ezek a programban változóként egyszerűen és problémamentesen tárolhatók.

Egészen más szemléletet igényel az összetartozó adatok feldolgozása. Ebben a feladatcsoportban sok egyed több-kevesebb tulajdonságának értékeit kell feldolgozni.
Ilyen feladat például egy raktárban levő termékek készletének nyilvántartása. Itt az egyes anyagféleségek az egyedek, és a mennyiségi tulajdonságaikat leíró értékeket (darabszám, súly stb.) kell feldolgozni. Az ilyen feladatokban sok adat szerepel (egyedenként legalább egy), és a sok adat kezelésére több energiát kell fordítani. Jelentős munka a részt vevő adatok számítógépbe vitele, a bevitel során végrehajtott ellenőrzések, az adatok megkülönböztetése (azonosítása). Ezt a későbbiekben alaposabban is szemügyre vesszük.
Nagy feladatot jelent továbbá az adatok tárolása, visszakeresése, törlése, módosítása is. Mindebből következik az is, hogy az összetartozó adatok kezelése a programra is hatással van, és a programok adatkezeléssel foglalkozó része lényegesen nagyobb, mint amit a feldolgozási műveletek foglalnak el. Ez az arányeltolódás azt is eredményezheti, hogy egy feldolgozási folyamatban olyan programok is vannak, amelyek csak adatkezelési lépést (pl. adatbeolvasás) hajtanak végre.
Az összetartozó adatok feldolgozása során egy fontos kérdés az adatok tárolása és a tárolt adatok megkülönböztetése. Hogyan tároljuk egy 5000-féle anyagot tartalmazó raktár 40-50 000 adatát? Hogyan tudjuk megmondani, hogy a 40 000 adat közül melyik tartalmazza a festékhígító aktuális mennyiségét? Először az első kérdést válaszoljuk meg. Ennyi adatot nem lehet az eddig megismert módon, azaz a programban tárolni. Nincs helyünk ilyen hosszú programok tárolására, de ennél prózaibb ok, hogy nincs annyi változónév, amit ennyi adatnak tudnánk adni. A programban néhány száz adatnál többet nem tudunk tárolni.
Nagy mennyiségű adatot úgy kell tárolni, hogy bármelyiket biztosan és könnyen megtaláljuk. Ez pedig csak úgy érhető el, ha az adatokat rendszerezve tároljuk. Ha például egy raktár anyagainak készletét kell nyilvántartanunk, akkor az egyedekről (anyagféleségek) legalább két tulajdonság értékét kell tárolni: az anyag azonosítására szolgáló számot (ez a "név") és a készlet tulajdonságértékét: a mennyiséget. Ezeket az adatokat valamilyen szempontból rendszerezni kell. Általában célszerű egy egyed tulajdonságainak értékeit együtt tárolni, ebből következik, hogy az anyagok azonosítóját és készletét együtt kell tárolni. Ezzel csoportokat hozunk létre, és tudjuk, hogy egy csoporton belül egy egyed adatai találhatók.
Tovább segítjük az adatok azonosítását, ha meghatározzuk, hogy a csoporton belül milyen sorrendben következnek az egyes adatok. Példánkban a sorrend lehet: azonosító - mennyiség. Így az adatcsoport első adata egy azonosító, az adathalmaz második eleme egy készletmennyiség. Ez ismétlődik minden egyed adatcsoportján belül. Ábrázolása a következő:

A1, M1
A2, M2
A3, M3
...

Látható, hogy egy sorban egy egyed tulajdonságértékei, egy oszlopban pedig azonos tulajdonságok értékei szerepelnek. Összetartozó adatok tárolására ez a fajta rendszerezés terjedt el.
Adatok fizikai tárolására két lehetőség adódik:

Az utóbbival a 13. és 14. részben foglalkozunk, itt a programon belüli adattárolást vizsgáljuk meg.
A programon belüli tárolási mód a tömb. A tömb egyedenként több, elvileg kötetlen számú tulajdonságértéket tartalmaz. A tömbben mindig van lehetőség az egyedi azonosító tárolására, ha szükséges. Tömbben lehet tárolni pl. egy méréssorozat adatait, ha mérésenként több jellemző értéket kell mérni. Megállapodás szerint egy egyed adatai egy sorba, az azonos tulajdonságra vonatkozó adatok pedig egy oszlopba kerülnek.

t(1,1) = 22.3 t(1,2) = 20.8 t(1,3) = 19.2
t(2,1) = 20.8 t(2,2) = 18.2 t(2,3) = 17.6
t(3,1) = 15.6 t(3,2) = 14.1 t(3,3) = 13.1
... ... ...

Az együvé tartozást az indexek is kifejezik. A kéttagú index első tagja az egyedre, a második a tulajdonságra utal. Ha az egyedek száma m, a tulajdonságok száma n, akkor m sorból és n oszlopból álló mxn méretű tömb szükséges az adatok tárolására. A BASIC általában több dimenziós tömböket tud kezelni.
A tömb egy konkrét elemére az indexeivel lehet hivatkozni. Annyi indexet kell megadni, ahány dimenziós a tömb. Egy kétdimenziós tömb elemeire például az alábbiak szerint hivatkozunk:

t(2,3)=17.6

A vektor egy speciális tömb, amelynek csak egy dimenziója van. A vektor elemei egyedenként egyetlen tulajdonság értékeit (az adatokat) tárolják. Ez lehet vagy az egyed azonosítója, vagy ha ez nem fontos, akkor csak valamelyik tulajdonságának az értéke. Például olyan méréseknél, amikor mérésenként csupán egyetlen jellemzőt kell mérni, az adatokat tárolhatjuk egy vektorban. Ekkor a mérések azonosítóját külön nem lehet tárolni (mert nincs rá hely), de a tárolás sorrendje erre is utalhat. Tegyük fel, hogy a mérési eredmények a következők:

t(1) = 22.3
t(2) = 20.8
t(3) = 15.6
t(4) = 9.2
t(5) = 12.7
t(6) = 19.8

Ha t indexei a mérés sorszámára utalnak, akkor az adatokat a megadott sorrendben tárolva az azonosítókat is közvetve tároljuk. A vektorban csak az értékek szerepelnek:

t = [22.3, 20.8, 15.6, 9.2, 12.7, 19.8, ...]

A vektor valamelyik adott elemére az elem indexével hivatkozunk:

t(5)=12.7

Az összetartozó adatok feldolgozását jellemzi, hogy

A sok összetartozó adatot tartalmazó problémánál az adatok szervezése, az adatállomány definiálása, értékének meghatározása külön tervezési lépést igényel. Először azt kell eldönteni, hogy milyen egyedek vannak, és ezek milyen tulajdonságai vesznek részt a feldolgozásban. Egy programban több tömb is szerepelhet. Mindegyik méretét, felépítését pontosan meg kell tervezni.
A tömbelemek ugyanazokkal a jelekkel jelölhetők, mint a változók. Az eltérés az, hogy a tömbnév után a zárójelbe tett számértékkel mutatjuk, hogy nem egyszerű változóról van szó. A zárójelbe írt szám az illető szám indexe.

Egyedi változó Tömbváltozó
A8
C
K2$
A8(40) - az A8 vektor 40. eleme
C(200,50) - A C tömb 200. sorának 50. eleme
K2$(2,20) - A K2$ tömb 2. sorának 20. eleme

Látható, hogy egy tömbön belül az elemek (változók) neve ugyanaz (tömbnév), és az indexszel azonosíthatók. A tömbök nevét ugyanolyan szabályok szerint lehet képezni, mint a változókét. A névvel a tömbben tárolt adatok típusára is utalhatunk. A tömbnév után írt $ jel azt jelenti, hogy a tömbben szöveges változókat, a % jel pedig azt, hogy a tömbben egész számokat tárolunk.
A Sinclair-gépeknél a tömbnév egyetlen betű lehet.

A program elején - vagy legalábbis a tömb használata előtt - a DIM utasítással kell helyet foglalni a tömbnek:

x DIM V(egész szám1, egész szám2, egész szám3,...)

ahol

Ennek hatására a gép minden dimenzióban az egész számok által meghatározottnál eggyel nagyobb méretű V tömb számára foglal helyet, melynek elemei közé tartozik a 0 indexű is.
A Spectrum-gépeken az elemek sorszámozása nem nullától, hanem egytől kezdődik.
Például:

20 DIM T(15,3)

Ebben az esetben a sorok indexe 0-tól 15-ig (Spectrum-on 1-től 15-ig), az oszlopoké 0-tól 3-ig (Spectrum-on 1-től 3-ig) van megengedve.
Egy DIM utasításban több tömböt definiálhatunk (kivéve a Spectrum-gépeken, ott ez nem megengedett). Ekkor a tömbök nevét vesszővel kell elválasztani.
A tömb elemeire a vektor, illetve a tömb jelével és az elem sorszámával, illetve az indexeivel (zárójelben) hivatkozhatunk, amelyek nem lehetnek nagyobbak, mint a DIM utasításban meghatározott megfelelő méretek. Például:

T(3,2)

6. feladat
Legfeljebb 100, de esetenként változó számú mérési sorozat eredményeit (hőmérséklet) kell kiértékelni. Meg kell határozni a mérések átlagát és szórását. Az eredményeket a következő formában kell kiírni:

A MERESEK EREDMENYEI
A MERESEK SZAMA: x
AZ ATLAGOS HOMERSEKLET: x CELSIUS FOK
AZ ERTEKEK SZORASA: x.x

A feladat elemzése
A mérést - a probléma leírása alapján - nem a számítógép vezérli, ezért a mért értékeket a mérést végző olvassa le és adja a számítógépnek akár közvetlenül minden mérés végén, akár az adatok összegyűjtésével a méréssorozat befejezésekor. A mérési sorozat legfeljebb 100 mérésből állhat. Hogy a mérést végző ezt ne lépje túl, a mérések számát előre be kell kérni. Ezek alapján az adatbevitel programozható. Az adatbevitel után az átlagot és a szórást a jól ismert kifejezések segítségévei lehet meghatározni:

ahol

D - szórás

A program adatait egy vektorban lehet tárolni. Mivel a vektor hőmérsékletadatokat tartalmaz, legyen a jele T. A vektor elemeit a felhasználó gépeli be. Minden esetben csak annyi adatot kell beírni, ahány mérést végez a felhasználó. Az adatokból előbbi átlagot, majd szórást kell számítani.
A számítógépes programban szükség van egy adatrögzítő modulra, amely rögzíti a bemeneti adatokat. Ezekből kell átlagot, majd szórást számítani. Az első modult kivéve mindegyik modulhoz tartozik kiírás is. Megoldásunkat úgy készítjük el, hogy a modulfunkciókhoz a kiírást is hozzávesszük.

A program tervezése
A program első modulja végzi az adatok bevitelét. Mérésenként legfeljebb 100 adat lehetséges. A felhasználó minden konkrét esetben megtervezi, hogy hány mérés végez, ezért az adatbevitel elején tudni lehet, hány adatot kell a modulnak beolvasnia a terminálról. Ezt a felhasználó közli. Az adatbevitelt ciklikusan kell elvégezni, mivel a feldolgozandó adatok beírása is hasonló. A modul további bontása felesleges.
A következő modul funkciója az átlagszámítás. Ehhez a mért értékeket összegezni kell, majd el kell osztani a mérések számával, a végén az eredményt ki kell írni. Tanácsos a modult két modulra bontani: az egyik végzi a feldolgozást, a másik pedig a kiírást.
A szórásszámítás a következő funkció, amely felhasználja az átlagszámítás eredményét. Ezt a modult is célszerű kettévágni: az egyik modul végzi a számítást, a márpedig a kiírást. A feladat finomított modulszerkezetét a 28. ábra mutatja.
A feladat programját vezérlőmodul nélkül készítjük el az egyszerű programszerkezet miatt.


28. ábra: A 6. feladat programterve

A modulok tervezése

(1) adatbevitel
A modul adat típusú, mivel fő funkciója a mérési adatok beolvasása. Bemeneti adatai a mérési adatok, amelyeket a felhasználó ad be. Kimenete a számítógép tárjában levő adathalmaz, valamint a mérések száma.
Ebben a modulban kap helyet a programnév, majd le kell kötni a mérési adatokat tároló 100 elemű, T nevű vektor helyét a megismert DIM T(100) utasítással. Ezután kezdődhet a modul "érdemi" feladatának ellátása, az adatok beolvasása. Első lépésként az adott mérési folyamat méréseinek számát kell bekérni, erre a felhasználó begépeli az M változó értékét.
A mérési adatok beolvasásakor minden egyes adat begépelése előtt tanácsos kiírni, hogy hányadik adat következik. Ezzel segíthetjük a felhasználót, hogy mindig helyes adatot írjon be. Az adatbevitelt ciklusban kell végezni, hiszen hasonló művetet kell M-szer ismételni.
A ciklusmagban két művelet kap helyet: a következő adat sorszáma és az adatolvasás. A ciklust addig kell folytatni, amíg a beolvasott adatok száma eléri M-et. Ekkor a ciklusból ki kell lépni, és az adatbeolvasás befejeződött.
Az adatbeolvasási ciklusban fontos követelmény, hogy a beolvasott adatok a megfelelő indexű vektorelembe kerüljenek, ami azt jelenti, hogy az első beolvasott adat a T(1) értéke, a második adat pedig a T(2) értéke stb. legyen. Ez elérhető, ha az indexek értékét minden beolvasás előtt eggyel növeljük. Ez úgy oldható meg, hogy az indexet I változónak tekintjük, és értékét minden adatbevitel előtt eggyel növeljük. Így biztosítjuk, hogy az adott sorszámú mérési adat az ugyanolyan sorszámú vektorelembe kerüljön. A ciklust egyszerűen meg lehet szervezni a FOR, NEXT utasításokkal, ciklusváltozóként az l-t vezetjük be, és ez 1-től M-ig minden egész értéken végigfut a feldolgozáskor. Hogy mindig a ciklusváltozónak megfelelő vektorelemet dolgozza fel a program, a vektorelem indexét az I jelöli: T(l).
Ezzel a modul algoritmusát meghatároztuk.

(2.1) Átlagszámítás
A modul típusa: eljárás. Bemeneti adatai a T(l) mérési adatok és a mérések száma az (1) modulból. Kimeneti adata a mérési adatok átlaga.
Az átlagot a már ismert képlet alapján kell kiszámítani. Először a T(l) adatok értékeit kell összegezni. Ezt az összeget az S változó tartalmazza. Az összegezést ciklusban kell végrehajtani. A ciklusmagban az S = S+T(I) összegezést kell elvégezni. Ekkor is FOR, NEXT típusú feldolgozó ciklust alkalmazunk, amely biztosítja, hogy a program mindig a soron következő T(l) értéket adja hozzá az S-hez. A ciklus előkészítő műveletében az S gyűjtőt nullázzuk. Az összeget M-mel el kell osztani, és megkapjuk az átlagot.

(2.2) Átlag kiírás
A modul eljárás típusú. Bemeneti adata az A átlagérték, amely egyúttal a kimenete is. A modul egyetlen művelete az átlag kiírása a specifikáció szerint.

(3.1) Szórásszámítás
A modul eljárás típusú. Bemeneti adatai a mérési adatok és az adatok száma az (1) modulból, valamint a szórás számításához szükséges A átlagérték a (2.1) modulból. A modul kimenete a szórás (D2).
Először az (A-T(I))^2 különbségek négyzetét kell képezni a K változóban:

K = K+(A-T(I))^2

Ezt a műveletet is egy M-szer végrehajtott ciklusban célszerű elvégezni FOR, NEXT szervezéssel. A kapott eredményt el kell osztani M-mel, és négyzetgyökvonás után megkapjuk a szórás értékét:

D2=SQR(K/M)

(3.2) Szóráskiírás
A modul eljárás típusú. Bemeneti adata a D2 jelű szórásnégyzetet tartalmazó változó a (3.1) modulból, amely egyúttal a modul kimeneti adata is.

A program kódolása
A program kódolásában az egyedüli újdonság a vektorméret meghatározása:

30 DIM T(100)

A többi művelet az eddig bemutatott kódolási szerkezetek felhasználásával megoldható.

10 REM ***** MERES *****
20 REM *** ADATBEVITEL ***
30 DIM T(100)
40 LET K=0
50 CLS
60 PRINT "Adatbevitel"
70 PRINT
80 INPUT "Meresek szama: ";M
90 IF M>100 THEN PRINT "max 100 meres lehetseges!": GO TO 80
100 PRINT
110 REM * CIKLUS KEZDET *
120 FOR I=1 TO M
130 PRINT "A(z)";i;". adat kovetkezik: ";
140 INPUT T(I)
150 PRINT T(I): PRINT
160 NEXT I
170 REM * CIKLUS VEG *
180 REM *** ADTLAGSZAMITAS ***
190 LET S=0
200 REM * CIKLUS KEZDET *
210 FOR I=1 TO M
220 LET S=S+T(I)
230 NEXT I
240 REM * CIKLUS VEG *
250 LET A=S/M
260 REM * ATLAGKIIRAS *
270 CLS
280 PRINT TAB (8);"A meres eredmenyei"
290 PRINT
300 PRINT "A meresek szama: ";M
310 PRINT
320 PRINT "Az atlagos homerseklet: ";A;"C"
330 REM *** SZORASSZAMITAS ***
340 REM * CIKLUS KEZDET *
350 FOR I=1 TO M
360 LET K=K+ABS (A-T(I))^2
370 NEXT I
380 REM * CIKLUS VEG *
390 LET D2=SQR (K/M)
400 REM *** SZORAS KIIRAS ***
410 PRINT "Az ertekek szorasa: ";D2
420 STOP

10. Ciklikus tevékenységek
Adatok rendezése tömbben, egymásba ágyazott ciklusok.
A 7. feladat megoldása.

Ebben a részben egy újabb feladatot oldunk meg a ciklikus tevékenységek gyakorlására és a tömbök alkalmazására.

7. feladat
Egy vállalat pénztára nem bérfizetési napokon a dolgozóknak nem bérjellegű kifizetéseket teljesít. Ezek a vállalat jellegéből fakadóan főleg helyi (taxi) és távolsági közlekedési költségek (kiküldetések útiköltsége, napidíj, szállásköltségek), valamint mások. A költségek fő jellegzetessége, hogy valamilyen munkaszámra rá kell őket terhelni. Naponta legfeljebb 100 ilyen kifizetés várható.
A könyvelés megkönnyítésére minden nap végén egy kimutatást kell készíteni, amelyben az azonos munkaszámra terhelhető költségek egy csoportban vannak, Így a könyvelőnek egy munkaszám könyvelési kartonját csak egyszer kell kézbe vennie. További segítséget jelent, ha a kimutatáson a munkaszámonként csoportosított bizonylati adatok sorrendje ugyanolyan, mint a könyvelési kartonoké. Ez utóbbiak növekedő sorrendben vannak, tehát a munkaszámoknak a kimutatáson is növekvő sorrendben kell szerepelniük. A kimutatás elején legyenek a legalacsonyabb munkaszámhoz tartozó kifizetési bizonylati adatok, utána a következő munkaszámhoz tartozók, és így tovább.
Mi legyen még a kimutatáson? Mivel könyvelési célra kell, a kifizetett összegnek feltétlenül szerepelnie kell, valamint a későbbi ellenőrizhetőség végett az adatok származási helyét - a bizonylat azonosítóját, azaz a bizonylat sorszámát - is fel teli tüntetni. Természetesen nem maradhat el a kifizetés kelte sem. Mivel a kimutatás naponta készül, elég a kimutatásra egyszer felírni az aznapi dátumot. A munkaszámok négyjegyű számok, a kifizetések nem haladják meg a tízezer forintot, és a bizonylatsorszám legfeljebb 8 jegyből áll.
A kimutatást a kifizetésekről sornyomtatóval kell elkészíteni a következő formában:

NAPI KIFIZETESEK
KELT 1985. EV 2. HO 23. NAP
MUNKASZAM
KIFIZETET
OSSZEG
BIZ. SORSZ.
9999
9999.99
99999999

(A 9-es számjegyek azt jelölik, hogy helyükre számjegyeket kell írni, és legfeljebb annyi helyértéken, ahány 9-es ott van.)

A feladat elemzése
A feladat értelmében egy vállalati pénztár napi kifizetéseiről kell naponta munkaszámonként, a munkaszámok emelkedő sorrendjében kimutatást készíteni.
A kimutatás elkészítéséhez kifizetésenként az alábbi adatok szükségesek:

A munkaszámot tehát mindig rá kell írni a bizonylatra. A kifizetett összeg természetesen rajta van a bizonylaton, hiszen éppen az a célja. Sorszáma is minden bizonylatnak van. így a kimutatáshoz szükséges adatok biztosíthatók.
A nap végén a bizonylati adatokat a munkaszámok növekvő sorrendjében kell összegyűjteni és kiírni. A nap folyamán azonban a kifizetések nem a munkaszámok emelkedő sorrendjében történnek, hanem véletlenszerűen. A feladat egyik része ezért az, hogy a bizonylatok adatait a nap végén a munkaszámok szerint növekvő sorrendbe kell rendezni. Ahhoz, hogy ezt meg lehessen tenni, a bizonylatok adatait tárolni, és a nap végén az adatokat rendezni kell. A rendezett adatokat pedig ki kell írni.
A feladat számítógépes megoldásához az szükséges, hogy a pénztáros a kifizetések alkalmával ezek három adatát (munkaszám, összeg, bizonylatszám) beírja a számítógépbe, és a nap végéig megőrizze a gépen. Ekkor a kifizetésekhez tartozó adatokat munkaszámok szerint növekvő sorrendben össze kell rendezni, és ki kell ín egy kimutatásra. A kimutatásra az aznapi dátumot is fel kell írni, ezért a kiírás előtt valamikor ezt is be kell gépelni. A feladat elvileg megoldható, hiszen ezek a műveletek számítógéppel elvégezhetők.
Egy dolgot kell még megvizsgálni. Az aznapi bizonylati adatokat egész nap tárolni kell. Megoldható ez? Akkor igen, ha az adatok mennyisége nem lépi túl a gép adattárolási képességét. Esetünkben maximum 3x100 = 300 adatot kell tárolni. Egy numerikus adat tárolásához géptől függően 4-12 bájt szükséges. Ezek szerint legfeljebb 3600 (3,6 kbájt) szükséges az adatok tárolásához. Nem szabad elfelejteni, hogy a feladatot megoldó program is helyet foglal el. Azt azonban előre nem tudjuk megmondani, hogy mekkorát. Mégis azt mondhatjuk, hogy amelyik gépnek a tárkapacitása 8 kilobájt vagy e feletti, azzal a feladatot nagy valószínűséggel meg lehet oldani.
A feladat megoldásához nyomtatóra is szükség van, hogy a kimutatást el lehessen készíteni. A feladat tehát számítógépeinkkel megoldható.
Nézzük meg, milyen fontosabb részfeladatokat kell elvégezni a feladat megoldásához! A napi dátumot a nap kezdetén érdemes beolvasni. Egy részfeladat tehát a dátum beolvasása. Ezután következik a bizonylatonkénti három adat beolvasása, hogy a gép tárolni tudja az adatokat. A nap végén az adatokat sorrendbe kell szedni és ki kell írni.
Egy adatbeolvasás után így két dolog következhet:

Ezt a kiválasztást (döntés) a pénztárosnak kell megtennie. A beolvasások után ezért mindig ki kell írni egy menüt, hogy a pénztáros választhasson. A nap kezdetén, a dátum beolvasása után is ki kell írni ezt a menüt a képernyőre, hogy a műveletek egységesek legyenek (a nap kezdetén elég lenne rögtön az adatbevitelre rátérni).
Egy másik részfeladat a bemutatott menü kiírása. A menüből két további részfeladatot lehet hívni: az adatbeolvasást és a kimutatás készítését.

A program tervezése
Először vizsgáljuk meg, hogy lehet-e tovább bontani a részfeladatokat!
A dátum beolvasása egyszerű feladat, nem érdemes tovább bontani. A kifizetési adatok beolvasása három adat beolvasásából áll minden további művelet nélkül, ezért ez is lehet egy modul. A kimutatáskészítés két további feladatra bontható: először sorrendbe kell rendezni az adatokat, majd a rendezett adatokat ki kell írni. A kimutatás tehát két modulból fog állni:

A feladat modulszerkezetéhez tartozik a program vezérlési módjának meghatározása is. Ebben a feladatban a bemutatott programtervezési módszerünk szerint járunk el.
A dátumbeolvasás és a menükiírás műveleteit egy vezérlőmodul irányítja, ez lesz a feladatvezérlő modul. A menükiíró modul a kifizetési adatok beolvasását és a kimutatáskészítő modult fogja irányítani. Ez utóbbi maga is vezérlőmodul, amely előbb a rendezés, majd a kiírás végrehajtásáról gondoskodik.


29. ábra: A 7. feladat programterve

Ezzel a feladat modulszerkezete kialakult (29. ábra). A feladat egy programmal megoldható! Az (1) modul kivételével valamennyi modult szubrutinként fogjuk megvalósítani. Külön ki kell térni a feladatban tárolandó adatok tárolási módjára. A feladat megfogalmazásából nyilvánvaló, hogy a legfeljebb 100 kifizetési bizonylat munkaszám, összeg, bizonylatszám adatai összetartozó adatok. Az egyed itt a kifizetés, és három tulajdonságának értékeit kell megőrizni. A tulajdonságok:

Az adatok viszonylag alacsony száma miatt a programon belüli adattárolás megoldható. Az adatbeolvasás - mint látni fogjuk - a rendezés és a kiírás ciklus alkalmazásával elvégezhető, ezért az adatokat tömbben kell tárolni. Legyen a tömb neve K.
A K tömbön belül egy sorban egy egyed adatai helyezkednek el. Egy egyedről három adatot kell tárolni, és mondjuk azt, hogy munkaszám, kifizetett összeg, bizonylatszám sorrendben.
Ebből következően az adattárolásra 100 soros és 3 oszlopos tömböt kell felvenni. A tömb 1. sorában lesznek az 1. bizonylat, második sorában a 2. bizonylat - és így tovább - adatai.
Ha 100-nál kevesebb kifizetés van, akkor nem célszerű a teljes tömböt kezelni a rendezés és a kiírás során, csak annyit, amennyi adat van. Ezért vegyünk fel egy N változót, amely a kifizetések számát tartalmazza.

A modulok tervezése

(1) Feladatvezérlő
A modul vezérlő típusú. Bemeneti adata nincs. Kimenete a (2) és a (3) modul hívása. A program első moduljában kell definiálni a felhasznált tömböt, majd két szubrutinhívással végre kell hajtani a (2) és a (3) modult. Ezután a program befejeződik.

(2) Dátumbeolvasás
A modul eljárás típusú. Bemenete az aznapi dátum, és ez a modul kimenete is. A modulban be kell olvasni az évszámot, a hónapsorszámot és a nap számát.

(3) Menü
A modul vezérlést lát el. Bemenete a kiválasztott műveletnek megfelelő adat. A modul kimenete vagy a (4), vagy az (5) modul hívása.
A modul kezdetén törölni kell a képernyőt, majd ki kell írni a menüt, és be kell olvasni a döntésnek megfelelő adatot (D). Ezután D értékének megfelelően kell a két modul közül valamelyiket hívni. Ha

Az utóbbi esetben a modul befejeződik. Egyébként újra ki kell írni a menüt az újabb döntéshez.

(4) Kifizetési adatok
A modul adat típusú. Bemenete a kifizetés adatai: a munkaszám, a kifizetett összeg és a bizonylatszám, amelyeket a billentyűzetről kell beolvasni, és ezek a modul kimeneti adatai is.
A munkaszám mindig egy I sornak az 1., a kifizetett összeg a 2., a bizonylatszám a 3. eleme. Jelölésben:

A modulban előbb törölni kell a képernyőt, majd a munkaszám, a kifizetett összeg és a bizonylat sorszámát kell beolvasni.
A beolvasott adatokat a K tömbben kell tárolni. Hogy a beolvasott adatok ne vesszenek el, minden adathármast a tömb következő üres sorában kell elhelyezni. Ehhez fel kell venni egy változót (N), amelynek értéke biztosítja, hogy a begépelt adatok a következő üres sorba kerüljenek, és minden beolvasás után gondoskodni kell a növeléséről (felkészítés a következő beolvasásra).
Az első adat beolvasásakor N=1 legyen, majd minden újabb beolvasáskor az N-t eggyel meg kell növelni, hogy a következő adatok már a következő tömbsorba kerüljenek. A növelést célszerű a modul elejére tenni, mert így az index a beolvasott adatok sorszámát jelöli. A modul első hívásakor N=0 legyen (mert az N növelés után 1 lesz). A BASIC nyelvben ez automatikusan teljesül (kivéve a Spectrum-gépeken), tehát külön műveletet nem igényel.

(5) Kimutatásvezérlő
A modul vezérlő modul. Bemeneti adata nincs. Kimenete a (6) és a (7) modul hívása. A modul előbb a (6), majd a (7) modult hívja.

(6) Rendezés
A modul eljárást valósít meg. Bemenete az N kifizetésszám és a K tömb elemei. Ki menete a K tömb rendezett változata.
A rendezést csak az első N sorra kell elvégezni. Vizsgáljuk meg, hogy a kifizetések adatai milyen módszerrel rendezhetők! A rendezés szempontja a munkaszám. A sorba rendezést többféleképpen lehet végrehajtani. Ezek közül mutatunk be egy megoldást. A megoldás lényege a páronkénti vizsgálat és csere. Példaként tekintsük a 30. ábra bal oldali oszlopának két felső elemét. Tegyük fel, hogy a cél az oszlop (vektor) elemeinek növekvő sorrendű sorba rendezése.


30 ábra: példa a sorba rendezésre

Ha a két elem helyes sorrendben van (növekvő), akkor nem kell semmit sem tenni. Térjünk most át a 2. és 3. elemre (2. oszlop)! Ez a két elem nincs sorban, ezért fel kell cserélni őket (az eredmény a 3. oszlopban látható). Majd a 3. és 4. elemre térünk át. Azt látjuk, hogy itt is cserélni kell. A műveletet tovább folytatjuk, amíg el nem kezdjük elölről. Megint elkezdjük a szomszédos elemek összehasonlítását és szükség szerinti cseréjét.
A sorba rendezés akkor ér véget, ha a tömbön úgy mentünk végig, hogy nem kellett elemet cserélni. Hogy tudjuk, ez mikor következik be, fel kell venni pl. egy F változót, amelynek értéke megmondja, kellett-e elemet cserélni. Minden vizsgálatsorozat előtt adjunk F-nek nulla értéket. Ha a vizsgálatsorozatban nem kell cserét végrehajtani, akkor F=0 marad. Ha viszont egyetlen cserét is el kell végezni, akkor F értéke 1 legyen. Ez az 1 mutatja meg, hogy a sorba rendezés még nem ért véget.
Könnyen belátható, hogy a vizsgálatsorozat (páronkénti összehasonlítás és szűkség szerint csere a tömb elejétől a végéig) ciklikus művelet. Ugyanis minden vizsgálatnál az l-edik sorszámú elemet hasonlítjuk össze az l+1-edikkel, jelen esetben munkaszámot:

K(I,1)<=K(I+1,1)

Az első esetben I=1, ezért az 1. és a 2. munkaszámot kell összehasonlítani. Utána a 2. és 3. elemet kell vizsgálni, tehát I értékét 1-gyel növelni kell. Ezt folytatjuk egészen I = N-1-ig. A műveletet I=1-től kezdve l=N-1-ig kell végrehajtani úgy, hogy az I növekménye 1 lesz. Ez a ciklus a FOR, NEXT utasításpárral oldható meg legegyszerűbben.
Nézzük meg, hogy két szomszédos elem vizsgálatát hogyan kell elvégezni! Ha K(I,1)<=K(I+1,1) fennáll, akkor át kell térni a következő elempár vizsgálatára, vagyis az l-t eggyel meg kell növelni, és így kell a vizsgálatot megismételni. Ha a feltétel nem áll fenn, akkor végre kell hajtani az elemcserét. Ezt csak két lépésben lehet elvégezni, mert két értékadást kell végrehajtani:

K(I,1)=K(l+1,1)
K(I+1,1)=K(I,1)

Ha az első lépésben a K(l,1) felveszi a K(I+1,1) értékét, akkor a K(I,1) eredeti értéke elvész, és a második lépésben már nem történne semmi. Ezért mielőtt az első lépést végrehajtjuk, a K(I,1) értékét valahol meg kell őrizni. Legyen az SM változó:

SM=K(l,1)

Ha most végezzük el az első lépést:

K(I,1)=K(l+1,1)

akkor (l,1) értéke már nem vész el. A második lépésben a K(I+1,1) értékét az SM-mel kell egyenlővé tenni:

K(I+1,1)=SM

Ezt a cserét nemcsak a munkaszámoknál kell elvégezni, hanem a munkaszámokhoz tartozó másik két adatnál is. Itt hasonlóan kell eljárni. A kifizetett összegeknél az SF, a bizonylatszámnál az SB változót használjuk fel:

SF=K(I,2)
K(I,2)=K(I+1,2)
K(I+1,2)=SF

illetve

SB=K(I,3)
K(I,3)=K(I+1,3)
K(I+1,3)=SB

Ezzel a cserét végrehajtottuk. Ez egyben a ciklusművelet is, vagyis ezt kell az I=1 indextől N-1-szer végrehajtani. Ha cserét hajtunk végre, akkor az F=1 értékadást is el kell végezni. A vizsgálatot tartalmazó ciklust addig kell ismételni, amíg minden elem a helyén nincs. Ilyenkor a vizsgálatsorozat végén F=0 marad, és ez jelzi, hogy az adatok sorba rendezése megtörtént.
Észrevehetjük, hogy maga a vizsgálatsorozat is egy cikluson belül van. Ennek a ciklusnak a ciklusművelete egy egész vizsgálatsorozat. Ezt addig kell ismételni, amíg az F=0 feltétel nem áll fenn. Ez tehát egy hátul tesztelő ciklus lesz. A vizsgálatsorozatot ismétlő cikluson belül van az elemcserék ciklusa. Ezért ez a két ciklus egymásba ágyazott ciklust alkot. Ezek után a modul teljes folyamatát megterveztük.

(7) Kiírás
A modul eljárás típusú. Bemeneti adatai a K tömb sorba rendezett értékei, kimenetét is ezek az adatok képezik.
A modulban ki kell nyomtatni a K tömb első N sorának adatait a specifikáció szerinti formában. Először a fejlécet (dátum, cím és az oszlopok fejrovata), utána a K tömb rendezett elemeit kell kinyomtatni. Egy sorba három adatot kell kiírni, amelyek a K tömb egy sorát alkotják:

K(l,1)    K(l,2)    K(l,3)

Eddigi tapasztalataink alapján már tudjuk, hogy ezeket a sorokat is ciklusban lehet kiíratni.
A ciklusművelet egy sor kiírása. Ezt annyiszor kell ismételni, ahány érvényes sor (N) van a K tömbben. Erre is jól használható a FOR, NEXT utasításpárból felépített ciklus.

A modulok kódolása
A program tervezése során megállapítottuk, hogy az (1) modul kivételével minden modult szubrutinként kódolunk.
Az (1)-(5) modul kódolása eddigi ismereteink alapján mind a négy gépen elvégezhető. Különbség a képernyő törlésében és az INPUT utasítás formájában (vessző, illetve pontosvessző) van. A kiírást viszont gépenként kell megvizsgálni.
A Commodore-nál a nyomtató használatára külön utasítás van, a PRINT#. A gép a nyomtatót nem tekinti "természetes" tartozékának, ezért a használat előtt összeköttetést kell létrehozni a gép és a nyomtató között. Erre szolgál az OPEN utasítás:

x OPEN állományszám,4

ahol

Az állományszámnak akkor van jelentősége, ha több állományt használunk. Esetünkben válasszuk a 2-t állományszámként.
A megnyitás után következhetnek a kiírási utasítások a PRINT# alkalmazásával. A PRINT# utasítás használati módja megegyezik a PRINT utasításéval. De az utasítás formája az eszköz miatt eltér a már ismert PRINT utasítás formájától.

x PRINT #állományszám,adatelemek

ahol

Az állományszám itt az a szám, amellyel a sornyomtatót megnyitottuk (2). Az adatelemeket ugyanúgy kell megadni, mint a képernyőre írás esetén.
A kiírás végén a gép és sornyomtató közötti kapcsolatot meg kell szakítani a CLOSE utasítással.

x CLOSE állományszám

ahol

Ezután a kódot megírhatjuk. Azt kell még meghatározni, hogy az oszlopokat milyen eljárással kell kiírni. Ez esetben a TAB(n) függvényt használjuk fel a kimutatás oszlopainak kiírásához. Az oszlopok 10 szóköznyi távolságban legyenek egymástól.

A kimutatás adatelemeit a TAB függvény segítségével válasszuk el. Az egyes oszlopra 16 pozíciót hagyjunk ki.

10 REM ***** MSZK *****
20 REM *** FELADAT VEZ. ***
30 LET N=0
40 DIM K(100,3)
50 GO SUB 80
60 GO SUB 130
70 GO SUB 690
80 REM *** DATUM BEOLVASAS ***
90 INPUT "Ev: ";EV
100 INPUT "Ho: ";HO
110 INPUT "Nap: ";NA
120 RETURN
130 REM *** MENU ***
140 CLS
150 PRINT : PRINT
160 PRINT TAB 6;"Kifizetesi muveletek"
170 PRINT
180 PRINT " (1) Kifizetesi adatok beirasa"
190 PRINT " (2) Kimutatas keszites"
200 PRINT : PRINT
210 INPUT "Melyiket valasztja? ";D
220 IF D=1 THEN GO SUB 270
230 IF D=2 THEN GO SUB 340
240 IF D=2 THEN GO TO 260
250 GO TO 130
260 RETURN
270 REM *** KIFIZ. ADATOK ***
280 CLS
290 LET N=N+1
300 INPUT "Munkaszam: ";K(N,1)
310 INPUT "Osszeg: ";K(N,2)
320 INPUT "Bizonylat sorszam: ";K(N,3)
330 RETURN
340 REM *** KIMUTATAS VEZ. ***
350 GO SUB 380
360 GO SUB 570
370 RETURN
380 REM *** RENDEZES ***
390 LET SM=0: LET SF=0: LET SB=0
400 LET F=0
410 FOR I=1 TO N-1
420 IF K(I,1)<=K(I+1,1) THEN GO TO 550
430 REM * ELSE AG *
440 LET SM=K(I,1)
450 LET K(I,1)=K(I+1,1)
460 LET K(I+1,1)=SM
470 LET SF=K(I,2)
480 LET K(I,2)=K(I+1,2)
490 LET K(I+1,2)=SF
500 LET SB=K(I,3)
510 LET K(I,3)=K(I+1,3)
520 LET K(I+1,3)=SB
530 LET F=1
540 NEXT I
550 IF F=1 THEN GO TO 400
560 RETURN
570 REM *** KIIRAS ***
580 LPRINT "Napi kifizetesek"
590 LPRINT "----------------"
600 LPRINT
610 LPRINT "Kelt, ";EV;". ev ";HO;". ho ";NA;". nap"
620 LPRINT
630 LPRINT "Munka-";TAB 10;"Kifizetett";TAB 25;"Biz."
640 LPRINT " szam";TAB 12;"osszeg";TAB 24;"sorsz."
650 FOR I=1 TO N
660 LPRINT K(I,1);TAB 12;K(I,2);TAB 24;K(I,3)
670 NEXT I
680 RETURN
690 STOP

Ellenőrző kérdések és feladatok

  1. Mi a BASIC nyelvben használható tömb előnye az egyedi adatnevekkel szemben? (Próbálja megoldani a 6. feladatot egyedi adatnevekkel!)

  2. Rajzoljunk egy teljes szinuszgörbét a képernyőre! Az X tengely legyen függőleges, és a képernyő 16. oszlopán helyezkedjen el. Az X és Y tengely metszéspontja a képernyő tetején legyen. A rajzoláshoz 16 sort használjunk fel (1 sor = PI/16) a függvényértékeket 14-szeresre nagyítsuk fel. A függvénypontokat csillaggal jelöljük.

  3. Egészítsük ki a 6. feladatot azzal, hogy a kiírás végére kiírjuk a legkisebb és a legnagyobb mérési eredményt!

  4. Állítsa össze ismerősei, barátai névsorát! Jegyezze meg mindenkinek a nevét és a testmagasságát. Készítsen egy programot, amely a névsort egyrészt ábécésorrendbe rakja, és kiírja a barátok nevét, valamint testmagasságát, másrészt a személyek nevét testmagasság szerint növekvő (vagy csökkenő) sorrendbe rendezi, és kiírja a neveket, valamint a testmagasságot. (A megoldáshoz használjuk fel azt az elvet, hogy szöveges változók közül az a "kisebb", amelynek kezdőbetűje az ábécében előbb van, mint a másiké.)

  5. A 7. feladatot egészítsük ki azzal, hogy az azonos munkaszámokra való kifizetéseket összegezve írjuk ki. A kimutatás végén pedig a kifizetések összegét írjuk ki.

11. Játékok készítése
A képernyőre "rajzolás" alapjai, véletlenszámok generálása.
A 8. feladat megoldása.

A számítógépet nemcsak műszaki és gazdasági számítások vagy más adatfeldolgozási feladatok elvégzésére lehet felhasználni, hanem szórakoztató szerepet is játszhat. A számítógép mint "játszótárs" a kétszemélyes játékokban terjedt el. A mikroszámítógépek gyors térhódítása következtében a számítógépet mind nagyobb számban alkalmazták, és ez megnövelte a számítógéppel játszók táborát.
A játékokban interaktív használata miatt nagyszerepet kap a BASIC nyelv, és az is segíti a BASIC nyelvű játékok elterjedését, hogy nagyon sok "játékos kedvű" ember (egyetemi hallgató, kutató stb.) használja, aki napi feladatain kívül szívesen "elszórakozik" a számítógéppel. Énük köszönhető, hogy a számítógépes játékok programozása és a BASIC nyelv összetartozó fogalmak.
A számítógép alkalmas játszótárs, mert interaktív (kérdést ír ki, a játékos válaszol), a játékos akcióira (lépéseire) gyorsan válaszol, statisztikával értékeli a játékos eredményeit, és végül: nem csal.
Nagyon sok számítógépes játék van forgalomban, és számuk egyre bővül. Programozásuknak néhány egyedi sajátossága közül az egyik leglényegesebb a nagyfokú interaktivitás, vagyis számos kérdés és válasz A játékprogramok sok alternatívát kezelnek, és nagyon sok funkciót tartalmaznak, ami a program szerkezetét bonyolulttá teszi.

8. feladat
A közismert hadihajócsata-játék számítógépen játszható, módosított változatát kell elkészíteni. Most csak a számítógép jelölhet ki egy hajót egy 20x20 (a HT-nél és PRIMO-nál 12x12, a Sinclair-gépeknél 18x18) négyzetből álló háló valamelyik pontjára, amelyet a játékosnak el kell találnia.
A játék célja, hogy a játékos minél kevesebb, de legfeljebb 15 (a HT-nél és a PRIMO-nál 10, a Sinclairnél 12) lövéssel eltalálja a hajókat.
A játékszabályok:

A játék kezdetén ki kell írni a játékszabályokat a játékos számára:

Egy 20x20-as (illetve 12x12-es vagy 18x18-as) csatamezőben kell egy ismeretlen helyen lévő hajót eltalálni a célpont koordinátáinak megadásával. A program a becsapódás és a hajó távolságát közli: a hajóra legfeljebb 15 (illetve 10 vagy 12) lövedéket lőhet ki.

Ezután következik maga a vadászat. A játékos megadja az első becsapódás pontjának a koordinátáit az alábbi kérdésre: "AZ 1. LOVES KOORDINATAI (X, Y):"
Az X, Y koordináta-rendszer 0,0 pontja a játéktér bal alsó sarkában van.
Ezután a játékos begépeli a lövés X, Y koordinátáit. Az ennek megfelelő ponton a csatatérben egy csillag karaktert kell kiírni, majd a program kiírja a becsapódási pont és a hajó közötti távolságot a játéktér alsó szélétől egy sorral lejjebb: "A BECSAPODAS TAVOLSAGA: X"
Ha ez nulla, akkor a játékos eltalálta a hajót. Ezt külön is tudatni kell: "ON ELSULLYESZTETTE AZ ELLENSEG HAJOJAT."
A második lövés helye csak az első lövés valamelyik főirányú (fel, le, jobbra, balra) szomszédja lehet. Ugyanígy minden további lövés csak az előző lövés fő irányú szomszédja lehet. Minden lövés után továbbra is ki kell írni a becsapódás távolságát. Mivel az első lövés után nem koordinátákat kell megadni, hanem a lövés mozgási irányát, a mozgatásra gombokat használunk fel. Úgy célszerű a négy iránynak megfelelő négy billentyűt kiválasztani, hogy azok utaljanak a mozgás irányára is. Ezért a gépeken az alábbi billentyűket válasszuk ki a mozgatásra:

 
Commodore
HT
PRIMO
Sinclair
fel
P
P
Ö
I
balra
L
L
Á
J
jobbra
:
;
*
K
le
.
.
>
M

Ha a 15. (illetve 10. vagy 12.) lövés sem talált, akkor a csata sikertelen volt. Ezt a játékossal közölni kell: EZ NEM SIKERULT. A HAJO AZ X, Y KOORDINATAKON ALLT.

A feladat elemzése
Ez a játék csak akkor élvezhető, ha az "ellenfél" (a számítógép) lépései kiismerhettek, vagyis a játékos a korábbi játékok lefolyásából nem következtethet arra, hogy a program hol helyezi el a hajót a csatamezőben. A játékon belüli véletlenszerűség az RND véletlenszám-generáló függvénnyel érhető el.
A becsapódás helye és a hajó közötti távolság könnyen megállapítható, mivel minden pontot X és Y koordinátákkal adunk meg. Ügyelni kell azonban arra, hogy a program és a játékos is csak egész számmal jelölhet koordinátát. Ez különösen a találat érzékelésekor fontos.
A becsapódás és a lövés távolságát a koordináták segítségével lehet kiszámítani az alábbi ismert módszer alapján:

Az R-nek csak az egész részét szabad a játékossal közölni, mivel azonos egész részű R-ek esetében a törtrész értékéről az irányra lehet következtetni. Ha a törtrész 0, akkor vagy X1=X2, vagy Y1=Y2. Tehát valamelyik koordinátát eltalálta a játékos. Minél nagyobb a törtrész, annál biztosabb, hogy a két koordináta eltérése megegyezik.
A lövéseket számlálni kell, és a következő lövés sorszámát tájékoztatásul ki is kell mi. A 15. sikertelen lövés után a játékot be kell fejezni.
A lövés helyének megjelölése a képernyőn számítógéppel megoldható. A képernyő törlése után a helyőr a képernyő bal felső sarkában áll. Ha a játékos az X = 5, Y= 17 lövést adta meg, akkor ez azt jelenti, hogy a helyőrt a 3. sor 5. pozíciójába kell állítani és ott egy csillag karaktert kinyomtatni. Azért kell így eljárni, mivel a mi szemléletünk szerint a koordináta-rendszer origója a játéktér bal alsó sarkában van. A helyőr ilyen jellegű mozgatását meg lehet valósítani mind a négy gépen. A Commodore-gépen a helyőrt úgy tudjuk a képernyő egy megadott pozíciójára állítani és ott valamilyen jelet kinyomtatni, hogy a PRINT utasításban idézőjelek közé helyőrt mozgató karaktert írunk be. Mivel előre nem tudjuk, hová kell állítani a helyőrt, mind a vízszintes, mind a függőleges mozgatást lépésenként kell végrehajtani a játékos által megadott koordinátáknak megfelelően. A fenti példában a helyőrt 5 lépésben kell 1-1 pozícióval jobbra tolni, és 3 lépésben kell 1-1 sorral lejjebb tolni. Ez sugallja, hogy a mozgatásra egy függőleges és egy vízszintes ciklust kell kialakítani, amelyeket annyiszor kell végrehajtani, ahányadik pozícióba vagy sorba kell a helyőrt mozgatni.
A HT, a PRIMO és a Sinclair-gépeken a képernyő bármely pontjára közvetlen címzéssel tudunk kiírni. Ez azt jelenti, hogy egyetlen utasításban meg lehet adni annak a pontnak a koordinátáit, ahová írni akarunk valamit.

Felmerül a kérdés, hogy mi történjék akkor, ha a játékos bármely irányban eléri a játéktér szélét, és további lépést kísérel meg kifelé. Mivel a játéktér határai nem láthatók a képernyőn, nem tisztességes a kilépést megengedni vagy a lövésmódosítást letiltani. E helyett a "körben járást" végezzük el, vagyis ha a játékos bármely oldalon kilépne, akkor az ellenkező oldalon lépjen be ellenkező irányban a játéktérbe. Így a kilépés is hasznos lépés lehet.
A csillag kinyomtatása után a játéktér alatti 2. sorba kell menni, és ki kell írni a távolságot, majd még egy sorral lejjebb a következő lövés sorszámát.
A második lövéstől kezdve a játékos a megadott gombok valamelyikével lő. A lövés beolvasására az INPUT utasítás nem használható, mivel a beolvasott adat a képernyőn megjelenne, s ezzel a kialakított képet megzavarná. Helyette más lehetőséget kell használnunk.
Először is azt kell tudni, hogy minden billentyűhöz egy kód tartozik (0- 255 közötti szám), amely a billentyű lenyomásakor a tár meghatározott rekeszébe kerül, majd onnan a központi egységbe. A leütött billentyű kódját (jelentését) egy utasítással ki lehet olvasni. Ezzel a program számára meg lehet tudni, hogy a felhasználó melyik gombot nyomta be, és ezután mit kell tenni. A betűk és a speciális jelek gombjai esetében az elemzésben a kódot nem kell külön ismerni, elég csak a gombon levő karaktert megadni. Ha például azt kell figyelni, hogy a felhasználó A betűt ütött-e le, akkor meg kell vizsgálni, hogy a tár megfelelő helyén A betű van-e, és nem az A betűnek megfelelő kódszámot kell megadni (de azt is lehet). Erre a kiolvasásra használható a Commodore-nál a

GET

A HT gép, a PRIMO és a Sinclair-gépek esetében az

INKEY$

függvény. Az utasítás formája:

x GET A$

A HT gép, a PRIMO és Sinclair-gépek esetében

x LET A$=INKEY$

Az utasítás hatására A$ felveszi a legutolsónak leütött billentyű kódját, egyben törli (nullát ír be) a tárnak azt a rekeszét, amelyből kiolvasta a kódot.
A GET utasítás, illetve az INKEY$ függvény nem vár valamilyen billentyű leütésére, mint az INPUT utasítás, hanem az olvasás eredményétől függetlenül továbbmegy. Ha tehát azt akarjuk, hogy a program egy billentyű lenyomását megvárja a program egy adott pontján (pl. ez alapján kell eldönteni, hogy milyen műveletet kell a programnak végrehajtani), addig nem szabad továbbmenni, amíg ez meg nem történik. Ennek az a módja, hogy amíg nem ütünk le billentyűt, addig az olvasást meg kell ismételni:

20 GET A$
30 IF A$="" THEN 20

A HT, a PRIMO és Sinclair gépeknél:

20 LET A$=INKEY$
30 IF A$="" THEN GO TO 20

Vagyis a gép egy végtelen ciklust hajt végre mindaddig, amíg a beolvasott érték egy "üres" karakter, azaz nem nyomtunk le billentyűt. Ha bármelyik billentyűt lenyomjuk, a visszaugrás feltétele nem teljesül, ezért a program a következő utasítássoron folytatódik.
Példánk értelmében most azt kell megvizsgálni, hogy melyik gombot nyomta le a felhasználó, és ennek megfelelően melyik irányba kell mozgatni a kiírt karaktert. Mind a négy gépen azt kell vizsgálni, hogy melyik billentyű kódja jelenik meg az erre kijelölt A$ változóban. Ez pedig megegyezik a billentyűn levő jel (alsó állásban) kódjával, amit a jellel adhatunk meg. Eszerint a programnak az alábbi funkciói annak:

A program tervezése
Vizsgáljuk meg az egyes funkciókat részletesen! A kezdőműveletek lényegében két lépésből állnak: ki kell írni a megadott játékszabályokat, és el kell helyezni a hajót a játéktér valamelyik pontjára. Tehát ezt a funkciót célszerű 2 modulra bontani
A kezdőlövés két adat beolvasásából áll, ezért további bontása felesleges. Ezután és minden további lövés után a következő műveleteket kell elvégezni:

Az utolsó lépés után az elsőnek írt következik, és ez ismétlődik mindaddig, amíg a játékos vagy eltalálja a hajót, vagy leadta mind a 15 (illetve 10 vagy 12) lövést, Ezeket a lépéseket tehát ciklusban kell végrehajtani. A ciklus változója ezek szerint a lövésszám lenne. A ciklusváltozót a ciklusmag végén ellenőrizzük, tehát a ciklus hátul tesztelő lesz. A ciklus befejezési feltétele akkor teljesül, ha a lövésszám már 15-nél nagyobb. A ciklus előkészítő művelete az az első lövés leadása, amely induló értéket ad a lövési művelethez.
A ciklusból viszont akkor is ki kell lépni, ha találat következik be. Ezek szerint a ciklusmag végén nemcsak a lövésszámot kell ellenőrizni, hanem a találatot is. A ciklus befejezési feltétele tehát akkor teljesül, ha vagy minden lövést leadtunk, vagy találat következett be.
A további lövés részfeladatot ezzel négy modulra bontottuk. A (8), (9) és (10) modulok a lövési ciklus magját alkotják. A (13)-as modult csak akkor kell végrehajtani, ha nem a kezdőlövést adta le a játékos (vagylagos végrehajtás).
A befejezésben értékeljük a játékot. A következő sorba a találathoz tartozó vagy a sikertelen befejezés szövegét kell kiírni. A találat és a sikertelen vadászat kiírásait célszerű két külön modulba tárolni, és a (10) modulban elért eredménytől függőét valamelyiket hívni. Ezután a program befejeződik.
A programot a bemutatott programtervezési módszer szerint építjük fel (31 .ábra). A programban ezek szerint összesen öt vezérlőmodul van: az (1), (2), (4), (5) és (8) modul.


31. ábra: A 8. feladat modulszerkezete

A modulok tervezése

(1) Csatavezérlés
A modul vezérlést végez. Bemeneti adata nincs. Kimeneti adata a (2), (3), (4) és (5) modul hívása.
A modul a fenti négy modult szekvenciálisán hívja, utána a befejezésre tér át.

(2) Kezdőművelet
A modul vezérlő típusú. Bemeneti adata nincs, kimenete a (6) és (7) modul hívása. A modul a (6) és (7) modult hívja.

(3) Kezdőlövés
A modul eljárás típusú. Bemeneti adatai a játékos által begépelt X2, Y2 koordináták, és ezek képezik a modul kimenetét is.
A modul első művelete az X2 és Y2 beolvasása. Mindkettőt csak akkor lehet elfogadni, ha értékük az (1,20), HT-nél és a PRIMO-nál (1,12), a Sinclair-gépnél pedig az (1,18) intervallumba esik. Ezt ellenőrizni kell, és hiba esetén a hibás adat nevét ki kell írni. Ezután a beolvasást meg kell ismételni. A helyes értékű adatnak csak az egész értékét kell figyelembe venni, mert a találat nem lenne kimutatható, ha a játékos nem egész számot gépel be. Ebben a modulban kell a lövésszámlálást is elkezdeni az L=1 ráadással.

(4) További lövés
A modul vezérlő típusú. Bemeneti adata a lövésszám (2) és a találatjelző (T). Kimenete a (8), (9) és (10) modul hívása.
A modul a (8), (9) és (10) modult hívja mindaddig, amíg vagy találat nem következik be, vagy a játékos le nem adta az összes megengedett lövésszámot (Commodore-nál 15, HT-nél és PRIMO-nál 10, Sinclair-gépeknél 12). Mint a tervezés során már megállapítottuk, a (8), (9) és (10) modulok egy ciklust alkotnak, amelyet ez a modul irányít. A ciklus hátul tesztelő, azaz a három hívott modul után kell vizsgálni a befejezés feltételét.
A ciklus akkor fejeződik be, ha a lövésszám elérte a megengedett maximumot, vagy találat következett be (T=1). A (13) lövés modulban minden lövés után meg kell növelni a lövések számát eggyel. Emiatt a lövésszámváltozó (L) már a következő lövés sorszámát tartalmazza. (Az utolsó megengedhető lövés után pedig ennél eggyel nagyobb számot.) Ezért az egyik befejezési feltétel a lövések maximuma +1.

(5) Befejezés
Vezérlő típusú modul. Bemenete a T találatjelző értéke. Kimenete vagy a (11), vagy a (12) modul hívása. A modul a T=1 feltétel teljesülése esetén (találat következett be) a (11) modult, egyébként a (12) modult (nincs találat) hívja.

(6) Játékszabályok
A modul eljárás típusú. Kívülről nem kap adatot, kimenete a játékszabályok kiírása ábra.

(7) A hajó helyzete
A modul eljárás típusú. Bemenete két véletlenszám a hajó helyzetének meghatározásához, kimeneti adata a hajó helye a csatatér területén.
A hajó helyzetét a program az RND függvény segítségével véletlenszerűen úgy tudja kijelölni a játéktérben, hogy mind az X1, mind az Y1 koordinátát véletlenszám-generálással állítja elő. A Commodore-nál figyelembe kell venni, hogy az RND(0) utasítás csak a [0,1] intervallumba eső számot képes generálni. Ezért a kapott véletlenszámot meg kell szorozni 20-szal, és hozzá kell adni 1-et, hogy a kívánt intervallumba essen. Mindig csak egész számú koordinátákat veszünk figyelembe, ezért a kapott értéknek csak az az egész részét kell megtartani. Vagyis a koordináták kiszámítása:

X1=INT(20*RND(0))+1
Y1=INT(20*RND(0))+1

Ha csak ezt a két utasítást alkalmaznánk, akkor a gép minden bekapcsolás után ugyanazt a véletlenszám-sorozatot állítaná elő. így viszont a játék elveszítené érdekességét, mert megtanulható lenne. Ezért a koordináták meghatározása előtt egy

x RANDOM

utasítást kell megadni, amelynek eredményeként a gép minden alkalommal más véletlenszám-sorozatot állít elő egy játéksorozathoz.

A játék teljes véletlenszerűségét itt is a RANDOM utasítás alkalmazásával lehet elérni a HT gépen való megoldáshoz hasonlóan.

A teljes véletlenszerűséget ennél a gépnél a RANDOMIZE utasítás biztosítja.

(8) Lövésszám vizsgálat
A modul vezérlést lát el. Bemeneti adata a már leadott lövésszám (L). Kimenete a (13) modul hívása vagy nem hívása. Ha L>1, akkor a (13) modult kell hívni, egyébként nem.

(9) Csillagkiírás
A modul eljárás típusú. Bemeneti adatai az X2 és Y2 koordináták, amelyek megmutatják, hová kell kiírni a csillagot. A modul kimenete a csillag megjelenítése a képernyőn.
A modult minden lövés után végre kell hajtani, mivel a csillag helyzete csak úgy módosítható, ha az egész kiírási műveletet megismételjük a módosított adattal. A modul helyzetén a helyőrt a bal felső sarokba kell állítani, és a képernyőt torolni kell. Ezután a helyőrt a Commodore-nál:

Y3 = 20-Y2

Lépéiben a megfelelő sorba kell állítani (az 1. sorban Y=20, a 20. sorban Y=1). Ha Y2=20, akkor a helyőrt az első sorban kell hagyni. Ilyenkor a lefelé mozgató ciklus műveletit nem kell végrehajtani.
A sorbeállítás után a soron belüli helyzetet kell meghatározni. A helyőrt az adott soron belül az X3=X2 sorszámú oszlopba kell léptetni. Ehhez viszont csak X2-1 léptetést kell elvégezni, mivel a helyőr az 1. oszlopról indul. Ezt a műveletet is csak akkor kell végrehajtana X2>1.
Mindkét műveletet ciklusban kell végrehajtani. Mindkét ciklus magjában a helyőr egy-egy léptetése megy végbe. Magát a mozgatást a PRINT utasítás tárgyában levő helyőrmozgató karakterrel végezzük el.

Ezzel a csillagkarakter már kiírható.

alakú utasítással a képernyő tetszés szerinti sorába és oszlopába a megadott szöveget ki lehet íratni.
A sorszám 0-15 közötti érték a képernyőn felülről lefelé haladva. Az oszlopszám pedig 0-41 közötti érték a képernyő bal szélétől jobbra növekedve. A sorszám 12-Y2 kifejezéssel számítható ki, mivel az utasításban levő sorszám a felső sorban 0, alatta 1, és így tovább. A játék legalsó sora viszont a 12. sor. Ezért kell a fenti különbséget számolni. Az oszlopszám (soron belüli pozíciószámi eggyel kisebb, mint az X2 koordináta (nulláról indul). Ezek szerint az X2=10, Y2=6 lövéshez tartozó csillag az

x PRINT$ 2,5,"*"

utasítással írható ki.

A sorszám itt is 0-nál kezdődik, és 21-ig mehet. A 0 sorszámú a képernyő legfelső sorát jelenti. Az oszlopszám balról jobbra haladva 0-tól 31-ig nő. A lövés koordinátáit is hasonlóan lehet átszámítani sorszámmá és oszlop számmá. A sorszám a 18-Y2 különbségből számítható. Az oszlopszám pedig az X2-1 különbségből adódik. Mindezek figyelembevételével az Y2=13, X2=2 koordinátájú lövéshez a csillagot a következő tartalmú utasítással tudjuk kiíratni:

x PRINT AT 5,1;"*"

Megjegyezzük, hogy az AT függvény a TAB-hoz hasonlóan csak a PRINT utasítással együtt használható.

(10) Értékelés
A modul eljárás típusú. Bemeneti adatai a hajó koordinátái (X1, Y1) a (7) modulból, a lövés koordinátái (X2, Y2) a (3) vagy a (13) modulból. A modul kimenete a hajó és a becsapódás helye távolságának kiírása.
Ha R=0, akkora találatjelző értéke T=1 lesz, egyébként T=0 marad.
A távolság kiírása előtt az utolsó kiírás (csillag)

Y3=20-Y2+1

sorban volt. (Ne tévesszük össze a kiírási sor számát a léptetés számával!)
Ebből következik, hogy

S = 22-Y3 = 22-(20-Y2+1)-1 = Y2

üres sort kell nyomtatni a csillag után (ekkor érünk a játéktér alatti 2. sorba), mielőtt a távolságot kiírnánk. Az üres sorokat a már ismert ciklusos formában "írjuk ki". Itt kell növelni a lövések számát is (L=L+1), mivel ezt a modult minden lövés után végre kell hajtani. A távolság kiírása után a következő lövés sorszámát (L) is ki kell írni.

(11) Találat
A modul eljárás típusú. Bemeneti adata nincs. Kimenete a találat kiírása.
A modulban egyedül a találatot kell kiírni.

(12) Nem talált
A modul eljárás típusú. Bemeneti adatai a hajó helyzetének koordinátái (X1, Y1). Kimenete a sikertelenség kiírása.
A modulban csupán a sikertelen befejezés szövegét kell kiírni.

(13) Lövés
A modul eljárás típusú. Bemeneti adatai az előző lövés X2 és Y2 adata, valamint a játékos módosító lépése. Kimenete a módosított X2 és Y2 koordináta.
A modulban a játékos lépéseit kell várni. Műveletet csak akkor kell végrehajtani, ha a játékos lenyomja valamelyik lövésmódosító billentyűt. A billentyű lenyomásakor a billentyűtől függően más-más műveletet kell az alábbiak szerint elvégezni:

 
Commodore
HT
PRIMO
Sinclair
Módosító koordináta
fel
P
P
Ö
I
Y2 növelése (sorszámcsökkentés)
balra
L
L
Á
J
X2 csökkentése
jobbra
:
;
*
K
X2 növelése
le
.
.
>
M
Y2 csökkentése (sorszámnövelés)

Ebből következik, hogy a billentyűlenyomás figyelési ciklusában mind a négy nyomógombot külön kell érzékelni, ezért ez egy CASE szerkezetet fog alkotni. A CASE szerkezet műveleteiben a fentiek szerint eggyel módosítani kell a kiválasztott koordinátát. Ezenkívül figyelni kell azt is, hogy a lövés nem esik-e a játéktéren kívülre. Ha például X2=8 és Y2=1 (vagyis a csillag a játéktér legalsó sorában van), és a játékos a lefelé haladás gombját nyomja le (Y2-t tovább csökkenti, azaz a játékteret lefelé hagyná el), akkor a csillagnak a 8. oszlop tetején (1. sor) keli megjelennie, tehát Y2=20 (illetve 12 vagy 18) lesz.
A Commodore-nál, a PRIMO-nál és a Sinclair-gépeknél a lövési koordináták módosítása közvetlenül elvégezhető az X2 és Y2 eggyel való csökkentésével vagy növelésével, illetve a "túlsó oldali" koordináta értékének megadásával.

Kódolás

10 REM ***** CSATA *****
20 REM *** CSATA VEZ. ***
30 LET T=0
40 GO SUB 90
50 GO SUB 140
60 GO SUB 250
70 GO SUB 320
80 GO TO 1030
90 REM *** KEZDO MUV. ***
100 RANDOMIZE
110 GO SUB 370
120 GO SUB 500
130 RETURN
140 REM *** KEZDO LOVES ***
150 PRINT : PRINT
160 INPUT "Az elso loves koordinatai (X,Y) ";X2,Y2
170 IF X2<1 THEN PRINT "Az X<1 nem lehet!": GO TO 160
180 IF X2>18 THEN PRINT "Az X>18 nem lehet!": GO TO 160
190 IF Y2<1 THEN PRINT "Az Y<1 nem lehet!": GO TO 160
200 IF Y2>18 THEN PRINT "Az Y>18 nem lehet!": GO TO 160
210 REM * IF VEG *
220 LET X2=INT X2: LET Y2=INT Y2
230 LET L=1
240 RETURN
250 REM *** TOVABBI LOVES ***
260 GO SUB 540
270 GO SUB 570
280 GO SUB 610
290 IF (L>12) OR T=1 THEN GO TO 310
300 GO TO 260
310 RETURN
320 REM *** BEFEJEZES ***
330 IF T=1 THEN GO SUB 710: GO TO 680
340 GO SUB 760
350 REM * IF VEG *
360 RETURN
370 REM *** JATEKSZABALYOK ***
380 CLS
390 PRINT "Egy 18x18-as mezoben kell egy"
400 PRINT "ismeretlen helyen levo hajot"
410 PRINT "eltalalni a celpont koorina-"
420 PRINT "tainak megadasaval."
430 PRINT
440 PRINT "A program a becsapodas es a hajo"
450 PRINT "tavolsagat kozli."
460 PRINT
470 PRINT "A hajokra legfeljebb 12"
480 PRINT "lovedeket lohet ki."
490 RETURN
500 REM *** HALYO HELYZETE ***
510 LET X1=1+INT (RND*18)
520 LET Y1=1+INT (RND*18)
530 RETURN
540 REM *** LOVESSZAM VIZSGALAT ***
550 IF L>1 THEN GO SUB 800
560 RETURN
570 REM *** CSILLAG KIIRAS ***
580 CLS
590 PRINT AT 18-Y2,X2-1;"*"
600 RETURN
610 REM *** ERTEKELES ***
620 LET R=INT (SQR (ABS (X2-X1)^2+ABS (Y2-Y1)^2))
630 IF R=0 THEN LET T=1
640 FOR I=1 TO Y2
650 PRINT
660 NEXT I
670 LET L=L+1
680 PRINT "A becsapodas tavolsaga: ";R
690 PRINT "A(z) ";L;". loves kovetkezik."
700 RETURN
710 REM *** TALALAT ***
720 CLS
730 PRINT "On elsullyesztette az"
740 PRINT "ellenseg hajojat!"
750 RETURN
760 REM *** NEM TALALT ***
770 PRINT "Ez nem sikerult!"
780 PRINT "A hajo a ";X1;",";Y1;" koorinatakon alt!"
790 RETURN
800 REM *** LOVES ***
810 LET K$=INKEY$
820 IF K$="I" OR K$="i" THEN GO TO 870
830 IF K$="J" OR K$="j" THEN GO TO 910
840 IF K$="K" OR K$="k" THEN GO TO 950
850 IF K$="M" OR K$="m" THEN GO TO 990
860 GO TO 810
870 REM * I GOMB *
880 IF Y2=18 THEN LET Y2=1: GO TO 1020
890 LET Y2=Y2+1
900 GO TO 1020
910 REM * J GOMB *
920 IF X2=1 THEN LET X2=18: GO TO 1020
930 LET X2=X2-1
940 GO TO 1020
950 REM * K GOMB *
960 IF X2=18 THEN LET X2=1: GO TO 1020
970 LET X2=X2+1
980 GO TO 1020
990 REM * M GOMB *
1000 IF Y2=1 THEN LET Y2=18: GO TO 1020
1010 LET Y2=Y2-1
1020 RETURN
1030 PRINT "VEGE"
1040 STOP

Ellenőrző kérdések és feladatok

  1. Hogyan lehet még a csillagot kiírni a lövés helyére?

  2. Alakítsa át úgy a 8. feladatot, hogy ha a játékos eléri a csatatér szélét, és ki akarna lépni, akkor a kifelé mutató lövést ne fogadja el! (Még szebb a megoldás, ha a játékos valamilyen figyelmeztetést is kap erről.)

  3. Készítsen "fej vagy írás" (pénzdobálós) játékot úgy, hogy a gép "dobja fel" a pénzt! Lehessen fogadni is!

  4. Készítsen lottójátékot, amelyben a gép "húzza ki" az öt számot, és kiírja a képernyőre!

  5. Készítsen huszonegyező játékot, amelyben a gép a bankos (osztó), és az egyetlen játékos a felhasználó! Egyszerű változatában "pénz nélkül" (ütési lehetőség nélkül) játsszanak, de készítsünk olyan megoldást is, amelyben ütni is lehet!

12. Több programból álló szerkezetek
Miért kell egy feladatot több programmal megoldani?
Mi a feltétele a több programos szerkezetnek?
Néhány alapszerkezet

Egy feladat nem mindig oldható meg egyetlen programmal. Ennek egyik oka az lehet, hogy a feladat túl hosszú programot eredményezne, ezért inkább több különálló programból építjük fel. Egy másik ok pedig, hogy a feladat egy részére már van alkalmas kész program, így csak a hiányzó részekhez kell programo(ka)t írni.
Több programos szerkezet főleg csak lemezes tárolóval rendelkező gépnél valósítható meg, mivel a kazettáról való betöltés egy programnál nem jelent akadályt, de több program bemásolása már rendkívül nehézkessé tenné a programok használatát.
A több programos szerkezet jelentősen eltér az egyprogramos szerkezettől. Az egyprogramos megoldásnál a program teljes egészében a tárban van, így minden modul (vagy szubrutin) szabadon hívható. Több programos szerkezetnél viszont a programrendszernek mindig csak egyetlen programja - az aktuálisan futó program - tartózkodik a tárban. Így az sem lehetséges, hogy egy vezérlő-(fő-)program állandóan a tárban legyen, hogy a többi program futását irányítsa.
A programcserének az a következménye, hogy a bemásolás előtt a bent lévő program törlődik, és aztán csak az új marad bent a tárban. Az adatokat ilyenkor általában nem törli a gép, így a következő program elvileg használhatja az előző program adatait. Az előző program adatai akkor használhatók teljes biztonsággal, ha a második program rövidebb az elsőnél (kevesebb utasításból és adatterületből áll). Ez a feltétel viszont nem mindig teljesíthető.
De az sem jelent lényeges akadályt, ha a két program nem tud egymással kommunikálni a tárban tárolt adatok révén. Ilyenkor még mindig fennáll annak a lehetősége, hogy külső tárolóeszközön tároljuk a közösen használt adatokat.
Egy programból egy másik programot a Commodore-64 esetében a LOAD utasítással lehet hívni:

x LOAD "programnév",8

ahol

Az utasítás hatására a jelenleg futó program a tárból törlődik (tovább nem használható), a gép behívja a megadott nevű programot, és futtatni kezdi az első sortól kezdve. A felhasználó lényegében nem is veszi észre, hogy programcsere történt. Hogy elkerüljük az adatok megőrzésével kapcsolatos bizonytalanságot, a program bemásolása előtt, az előző program végén CLR utasítással törölni kell a változók tartalmát.
A törlőutasításnak nincs tárgya, de felesleges is, mivel valamennyi változó tartalmát nullázza. Így a programcsere kifogástalanul működik ugyan, de a programok közötti adatcsere megszűnik. Ez adott esetben a programrendszer működését is lehetetlenné teheti. A probléma szerencsére nem megoldhatatlan. Egy kis többletráfordítás árán átmenthetjük a változók értékeit a programcsere és a törlés ellenére. Ezekkel az eljárásokkal itt nem foglalkozunk.
Vigyázzunk! Több programos rendszerben hiba esetén ne felejtsük el megnézni, hogy melyik program futott éppen (pl. listázással)!
A több programos szerkezetek logikai felépítése ugyanolyan, mint más programoké, de a kódolásukban vannak eltérések. Nézzük meg a leggyakrabban előforduló szerkezeteket!

Szekvenciális programok
A legegyszerűbb eset. A programrendszerben lévő programok valamilyen sorrendben hívják egymást.
A programrendszer végrehajtása az 1. részfeladatot megvalósító programmal kezdődik, majd ez hívja a 2. részfeladatot megoldó programot. Ennek végrehajtása után a futás befejeződik. Kód szempontjából annyi az újdonság, hogy az 1. részfeladat programjának a végén egy LOAD utasítást kell elhelyezni.

Főprogramot tartalmazó szerkezetek
Vannak olyan feladatok, amelyekben több, egymástól többé-kevésbé független funkciót kell ellátni. Az olyan esetekben, amikor a funkciók eléggé összetettek ahhoz, hogy mindegyiket önálló programmal valósítsuk meg, vagy a funkciók hívási sorrendje nem kötött, hanem a felhasználón múlik, akkor szükségünk van egy olyan programra, amely egyes funkciók programjait hívja. Ez a főprogram. A főprogram vezérlési funkciót lát el. Valamilyen algoritmus szerint kiválasztja, hogy melyik programot kell behívni, majd ezt behívja. A program lefut, és ezzel feladatát befejezi. Ekkor a vezérlést vissza kell adni a főprogramnak, hogy az újabb funkciók végrehajtását vezérelhesse. Minden funkció programjának végén ezért el kell helyezni a főprogramot hívó LOAD utasítást.
A főprogram ismét lehetőséget kap, hogy újabb feladat végrehajtását vezérelje. Ez a fajta vezérlési szerkezet ott használatos, ahol a felhasználó dönti el, hogy milyen funkciót kell végrehajtani. Például egy raktári készletnyilvántartó rendszer funkciói az anyagbevételezés, az anyagkiadás, a készletkiírás stb. lehetnek. A részfeladatot a raktáros jelöli ki az igények alapján. Ilyenkor a főprogram egy "menüt" ír ki, hogy a felhasználó láthassa, milyen műveletek közül választhat. Látható, hogy a főprogram a főmodulhoz hasonló szerepet tölt be, de önálló programként.

13. Adatállományok és látrehozásuk
Az adatállományok jellemzői.

Nagy mennyiségű összetartozó adat tárolására két lehetőség van:

adattárolás. Az előző módszer szerint néhány száz egyed adatait lehet tárolni tömbben. A programon kívüli tárolás elvileg végtelen mennyiségű adat tárolására ad lehetőséget. Tényleges korlátot a rendelkezésre álló tárolóeszköz adattárolási kapacitása jelent.
Adatokat programtól függetlenül adatállományokban lehet tárolni. Az adatállomány valamilyen rendezettségben tárolt adatok összessége.
Az adatállomány egyik legfontosabb jellemzője, hogy a programtól függetlenül létezik. Ez azt jelenti, hogy meglévő adatállomány használatára bármikor készíthetünk újabb programokat, vagy már meglévőket törölhetünk. Mindezek a műveletek az adatállományt érintetlenül hagyják. Az adatállomány önálló létéből következik az is, hogy saját neve van. Ezt az adatállomány azonosítása teszi szükségessé. Ha ugyanis egy program egy adatállományt használni akar meg kell nevezni, hogy milyen adatokon kíván műveleteket elvégezni. A név azért is szükséges, hogy több adatállomány közül ki lehessen választani a szükségeset. Az adatállományok nevének felépítése gépenként különbözik. A Commodore-64 esetében az adatállomány-név 1-16 karakter, CP/M rendszereknél 8 karakter + 3 karakter kiterjesztés hosszúságú szöveges változó lehet.
Az adatállományok rekordokból épülnek fel. Egy rekord egy egyed tulajdonságainak értékeit tartalmazza egy mátrixsorhoz hasonlóan. A rekordon belüli adatok (egyedek tulajdonságainak értéke) neve itt a mező. Ezenkívül olyan mezőket is használunk, amelyek valamilyen adattárolási információt tartalmaznak, az egyedekhez pedig semmi közük. Ilyen adat például a rekord sorszáma. A mátrixos adattároláshoz hasonlóan a mezők sorrendje kötött a rekordon belül, hogy minden rekordot azonos elvek szerint lehessen feldolgozni.
Az adatállományok külső tárolóegységen kapnak helyet, vagyis a táron kívül vannak. Az adatállományok kezelésénél a számítástechnikában az a gyakorlat alakult ki, hogy az adatállományoknak csak egy vagy néhány rekordja van egy-egy alkalommal a gép tárjában, ha a rekordok adatai egymástól függetlenül feldolgozhatok. Ez a módszer azt eredményezi, hogy a feldolgozásban részt vevő adatok csak kevés helyet foglalnak el a tárban.
Mielőtt azonban egy adatállomány rekordjaival bármilyen műveletet elvégezhetnénk, a gép és az adatállomány között kapcsolatot kell létrehozni. Ezt a kapcsolatlétrehozást nevezzük az adatállomány megnyitásának. Csak ezután tudjuk a rekordokat a tárba beolvasni és adataival a műveleteket elvégezni. Az adatállomány feldolgozásának végén a gép és az állomány közötti kapcsolatot meg kell szüntetni, vagyis az adatállományt le kell zárni.
Az adatállományokkal kapcsolatos műveleteket három csoportra lehet felosztani:

Logikailag az első művelet az adatállomány létrehozása. Ennek során a tárban létrehozott rekordokat a gép a külső adattároló berendezésre másolja.
A feldolgozás során a rekordokban tárolt adatokat valamilyen műveletsorozat (például összesítés) elvégzésére használjuk fel. Ekkor a rekordokat a háttértárolóból be kell olvasni a gép tárjába, és ott kell elvégezni a feldolgozás lépéseit. A feldolgozás nem változtatja meg az adatállomány tartalmát.
A harmadik műveletcsoportba tartoznak az olyan műveletek, amelyek az adatállomány tartalmát megváltoztatják. Ilyen művelet az adatállomány kiegészítése, a rekordok törlése vagy a rekordok tartalmának megváltoztatása.
Az adatállományon belül a rekordok valamilyen szempont szerint sorba rendezhetők a feldolgozás egyszerűsítésére. A rendezett sorrend bizonyos szempontból megkönnyíti a feldolgozást. Ilyen rendezett esetekkel itt nem foglalkozunk. Az egyszerűség kedvéért csak olyan adatállomány-feldolgozási műveleteket fogunk megismerni, amelyekben a rekordok sorrendje tetszőleges. Ha a rekordok rendezetlenek, és csak a rekordok egy bizonyos csoportján kell valamilyen műveletet elvégezni, akkor is minden rekordot be kell olvasni, hogy megvizsgáljuk, el kell-e végezni a műveletet rajta. Az ilyen adatállományokat szekvenciális adatállományoknak nevezzük. Ezek legfőbb jellemzője, hogy feldolgozásuk esetén valamennyi rekordot be kell olvasni. Ez a tulajdonság nem jelent hátrányt akkor, ha valamennyi rekordot fel kell dolgozni. Például, ha az adatállomány egy vállalat dolgozóinak bérelszámolási adatait tartalmazza, és a hó végén valamennyi dolgozó adatait fel kell dolgozni a bérük meghatározásához. Ekkor a rekordok tárolási sorrendje közömbös. De ha az a feladat, hogy ugyanebben az adatállományban egyetlen dolgozó béradatát keressük meg, akkor a tárolás rendezettsége komoly segítséget jelenthet a kiválasztott rekord megtalálásában. A rendezetlenség sok felesleges beolvasást okozhat, ami időigényes.
Az adatállománynak még két fontos tulajdonsága: kezdete és vége van. Szekvenciális adatállományok feldolgozása az állomány elején (az első rekordnál) kezdődik, és az állomány utolsó rekordjánál fejeződik be.

Az adatállományok létrehozása
Az eddig leírtak értelmében adatállományok a következő lépésekben hozhatók létre:

Létrehozásnál mindig egy új adatállományt kell megnyitni írásra. Erre szolgál Commodore-64-en az OPEN utasítás:

x OPEN i,8,j,"0:név,S,W"

ahol

Az utasítás hatására a program megnyit egy új adatállományt, amelynek neve a megadott név lesz. Az adatállomány lemezen jön létre, mivel a 8 és 9 egységszám lemezegységet jelent. A program további részében az adatállományra nem a nevével, hanem a logikai hivatkozási számával (i) hivatkozunk. A logikai hivatkozási szám a változónévhez hasonlóan egyedi, több állományhoz különböző hivatkozási számokat kell megadni. Ez leegyszerűsíti az írási és a lezárási műveletet.
A csatornaszám tetszőlegesen 2-14 lehet. A mi szempontunkból egyszerű, ha a logikai hivatkozási számmal megegyező csatornaszámot használunk. Az ilyen utasítással létrehozott adatállományra csak írhatunk, más művelet nem végezhető.
A megnyitott adatállományra a következő utasítással írhatunk:

x PRINT #i, A;",";B; ...

Ez a már ismert PRINT# utasítás, amikor is az utasítás tárgyában lévő adatokat nem a képernyőre kell kiírni, hanem a # jel után megadott logikai hivatkozási számú adatállományra. Az utasítás tárgyában a rekord mezőit (a rekordot alkotó adatok) kell felsorolni, és közéjük a vesszőt (mező-elválasztójel) idézőjelbe írva kell az adatállományra kiírni. Egy utasítással egy rekordot lehet az adatállományra felírni. Az állomány létrehozása után az állományt a

x CLOSE i

utasítással le kell zárni. Ezután az adatállományon további művelet nem végezhető, csak egy újabb megnyitás esetén. Az utasításban szereplő i az adatállomány logikai hivatkozási száma.

Függelék

A könyvben szereplő fontosabb fogalmak magyarázatuk

Adat: Tények és elképzelések nem értelmezett, de értelmezhető formában való közlése. Az adat a feldolgozás tárgya és eredménye.

Adatállomány: Sok egyed tulajdonságainak értékeiből álló, valamilyen szempontból összetartozó adathalmaz.

Adatállomány-feldolgozás: A tárba beolvasott rekordokon valamilyen művelet végrehajtása a feldolgozás céljának megfelelően.

Adatállomány-létrehozás: A tárban létrehozott rekordok kimásolása a háttértárolón megnyitott adatállományba.

Adatállományok módosítása: Egy adatállományhoz új rekordok hozzáadása, meglevő rekordok törlése és a meglevő rekord adatainak módosítása.

Adatállomány-nyitás: Egy megadott nevű adatállomány és a gép közötti kapcsolat létrehozása.

Adatállomány-zárás: Egy megadott nevű adatállomány és a gép közötti kapcsolat megszüntetése.

Adatkezelés: Az adatokkal kapcsolatos műveletek összessége (beolvasás, ellenőrzés, rendszerezés, azonosítás, tárolás stb.).

Adatmodul: Adatok meghatározására (definiálás, beolvasás, kezdőértékadás) szolgál.

Algoritmus: Valamilyen feladat megoldását célzó műveletsorozat.

Állapotbájt: Adatállomány-olvasáskor az állomány állapotáról tartalmaz információt (az állományvég elérésekor értéke 1, egyébként 0).

Argumentum: A függvény bemeneti adata (vagy független változója), amelyből a függvény egy eredményadatot állít elő.

ASCII kód: A számítógépen használt jelekhez és a BASIC karaktereihez hozzárendelt bájttartalmak együttese.

Bájt: 8 bitből álló adattároló egység, melynek 256 különböző állapota van. Az állapotok tetszőleges karaktereknek feleltethetők meg valamilyen rendszer szerint (pl. ASCII kódrendszer).

Bemeneti adat: A feldolgozás kiinduló adatai, amelyekből az eredményadatok készülnek.

Betöltés: A külső tárolóeszközről a gép tárjába való programmásolás.

Billentyűzet: Egy számítógéphez tartozó billentyűk és nyomógombok.

Bit: Kétállapotú adattároló egység.

C helyőr (Sinclair-gépek): Az L helyőr alesete, amelyben csak nagybetűk írása lehetséges.

Ciklus: Különböző adatokkal ismételten végrehajtott műveletsorozat.

Ciklusfeltétel: A ciklus befejezését vagy folytatását meghatározó feltétel.

Ciklusmag: A ciklikusan végrehajtott műveletsor a ciklusban.

Ciklusváltozó: Az az adat, amelynek értéke meghatározza a ciklus folytatását vagy befejezését.

Cím: A tár egy bájtjához tartozó szám, amelynek megadásával tartalmát ki lehet olvasni, illetve adatot lehet beleírni.

CP/M: Mikroszámítógép operációs rendszere.

Csatorna: A számítógép és a perifériák között fizikai kapcsolatot valósít meg.

Egyed: Egy rendszernek olyan eleme, amelyet adatokkal kívánunk leírni.

Egykijáratúság: A modul végrehajtása mindig ugyanazon az utasításszámon kezdődik, és mindig ugyanazon a soron fejeződik be.

Egymásba ágyazott ciklus: Egy ciklus magjában egy másik ciklus helyezkedik el.

Egymásba ágyazott szubrutin: A program egy szubrutinból egy másikat is hív.

E helyőr (Sinclair-gépek): A CAPS SHIFT és SYMBOL SHIFT billentyű együttes lenyomásakor jelenik meg. Ekkor a billentyűk feletti zöld feliratok írhatók ki.

Elágazás: Valamilyen feltételtől függően egy vagy több művelet közül az egyik kiválasztása és végrehajtása.

Eljárásmódul: Tényleges műveletet végző modul.

Eredményadat: A feldolgozási folyamat terméke, valamilyen számérték vagy szöveg.

Érték: Egy egyed tulajdonságának konkrét megjelenése.

Feldolgozás: Valamilyen feladat megoldása végett adatokon végzett műveletek összessége.

Felhasználói függvény: A felhasználó által definiált függvény, amely egyetlen programban érvényes.

Feltételváltozó: Az a változó, amelynek értéke eldönti, hogy az elágazás melyik ága hajtódik végre.

Felülről lefelé haladás (top-down): A feladat lépésenkénti, egyre részletesebb felbontása részfeladatokra.

Folt (C64): Vízszintes irányban 24, függőleges irányban 21 pontból álló, a felhasználó által meghatározható formájú jel, amely a képernyő bármely részén megjeleníthető.

Folyamatábra: A program (modul) műveleteinek ábrázolása szabványos jelekkel.

Főág: A programnak az a része, amely nem tartalmaz szubrutint, és amely a szubrutinok végrehajtását vezérli.

Főprogram: Több programból álló szerkezet vezérlőprogramja.

Funkcionális billentyű: Lenyomásakor a számítógép valamilyen műveletet végez el.

Függvény: Egy független változó értékből (argumentumból) valamilyen szabály szerint egy eredményértéket számít ki.

G helyőr (Sinclair-gépek): A CAPS SHIFT és a 9 billentyű együttes lenyomása után jelenik meg. Ekkor a billentyűk grafikus jelei írhatók ki.

Gyűjtő: Hasonló feladatot betöltő változók összegét tartalmazó változó, amelynek tartalma (összeg) ciklusban alakul ki.

Helyőr: Egy (villogó) karakter, mely a következő kiírandó karakter helyét mutatja.

Kalkulátormód: Lásd közvetlen mód.

Karakter: Egy jel (betű, szám vagy speciális jel), amely a programozásban valamilyen funkciót lát el.

Kazettás tároló: A magnetofon elve szerint működő adatot tároló berendezés.

Képernyősor: A képernyő bal széle és jobb széle között megjelenített karaktersor.

Kétszeres pontosságú változó: A normál numerikus változónál nagyobb pontossággal tárolt változó. A kétszeres pontosságú változó tárolásához a gép több bájtot vesz igénybe, és több számjeggyel képes kiírni, mint a normál numerikus változókat.

K helyőr (Sinclair-gépek): Utasítássorszám vagy kulcsszó begépelését teszi lehetővé.

Kiíró: Számítógép által vezérelt elektronikus íróberendezés.

Kimentés: A program kimásolása a gép tárjából külső tárolóberendezésre.

Kódlap: Programkód írását segítő űrlap.

Kódolás: Az algoritmusban meghatározott műveletek megfogalmazása egy programozási nyelven.

Közvetlen mód: Egy utasítássorba írt sorszám nélküli utasítás(oka)t a gép azonnal végrehajt a sorzáró billentyű lenyomása után.

Kulcsszó: Valamilyen programozási nyelv által lefoglalt szó, amelyet csak a nyelv által előírt célra és módon lehet használni (pl. nem lehet adatnév).

Külső tároló: A számítógéphez hozzákapcsolt adattároló berendezés, amely adatok hosszú távú tárolására alkalmas.

L helyőr (Sinclair-gépek): A billentyűkön levő főjelek (betűknél kisbetűk) begépelését teszi lehetővé.

Logikai ÉS reláció: A reláció két feltétel egyidejű teljesülése esetén áll fenn.

Logikai hivatkozási szám: Egy adatállomány programon belüli azonosítója.

Logikai VAGY reláció: A reláció egyik vagy másik feltétel teljesülése esetén fennáll.

Mágneslemez: Lemez alakú, mágneses elven működő adattároló.

Menü: A programmal elvégezhető részfeladatok kiírása, amelyből a felhasználó valamelyiket kiválaszthatja.

Mező: A rekord egy önállóan értelmezett adata (egy egyed egy tulajdonságának értéke).

Modul: Az egész feladaton belül elkülönített részfeladat, amely önállóan is elkészíthető.

Moduláris programozás: A feladatot előbb modulokra kell bontani, ezeket önállóan kell elkészíteni, és belőlük kell összeállítani a programot.

Modulok közötti kapcsolat: A modulok végrehajtási sorrendjét meghatározó viszony.

Operációs rendszer: Programok összessége, amelyek a számítógéprendszer egészét irányítják, az elemek működését összehangolják, és a programozónak szolgáltatásokat nyújtanak.

Paraméterezés: Szubrutinok bemeneti adatainak beállítása a hívási rész követelményei szerint.

Parancs: Sorszám nélküli utasítás(ok), amelye(ke)t a gép a sorzáró gomb lenyomása után azonnal végrehajt. Vannak olyan kulcsszavak, amelyek parancsban nem használhatók (pl. INPUT), illetve vannak olyan kulcsszavak, amelyek csak parancsként használhatók (pl. AUTO).

Perifériák: A számítógéphez kapcsolt kiegészítő berendezések (nyomtató, háttértár, kijelző stb.).

Program: Utasítások sorozata, melyek megmondják a számítógépnek, hogy milyen műveleteket kell végrehajtani a feladat megoldása érdekében.

Programdokumentáció: A programról rendelkezésre álló írásos információ.

Programkódlista: A program egyes utasítássorai alkotják.

Programkönyvtár: Egy mágneses tárolón tárolt programok összessége.

Rekord: Az adatállomány része, amely egy egyed tulajdonságainak értékét tartalmazó adathalmaz.

Rendezés: Egy tömb vagy egy adatállomány adatcsoportjainak (pl. egy tömbsor vagy egy rekord) valamilyen szempont szerint csökkenő vagy növekvő rendben való összeállítása, ami lehetővé teszi az adatcsoportok megadott szempont szerinti rendezett kiolvasását.

Sorszám: Az utasítássor programon belüli végrehajtását meghatározó szám.

Sorzáró billentyű: A begépelés során egy sort fejez be.

Szekvencia: Két vagy több utasításból álló műveletsorozat, amelynek minden elemét végre kell hajtani.

Szekvenciális adatállomány: Bármilyen (teljes körű vagy csak egy rekordra vonatkozó) feldolgozás esetén a rekordokat az állomány elejétől a végéig be kell olvasni.

Szintaktikai hiba: A programozási nyelv szabályainak be nem tartása miatt fellépő formai hiba.

Szubrutin: A program tetszés szerinti helyéről hívható részfeladat, amely lehet egy modulrészlet, egy modul vagy több modul.

Tár: A számítógép adattároló egysége.

Tesztelés: A program kipróbálása.

Többszörös utasítás: Egy utasítássorba (egy sorszám után) írt és elválasztójellel (:) elválasztott utasítások.

Tömb: Egy n dimenziós mátrix, amelynek elemei valamilyen szempontból összetartozó adatok.

Tulajdonság: Az egyedek jellemzői, amelyekkel ezek leírhatók.

Utasítássor: Sorkezdettől a sorzáró karakter lenyomásáig begépelt jelek sorozata, amely több képernyősort is elfoglalhat.

Utasítás tárgya: Legtöbbször valamilyen adat vagy utasítássorszám. Bizonyos esetekben hiányzik.

Üzenet: Valamilyen művelet végrehajtása után vagy hiba esetén a gép által kiírt szöveg a képernyőre, a felhasználó tájékoztatására.

Változó: Szimbolikus névvel ellátott adat.

Vektor: Egy egydimenziós tömb.

Vezérlőmodul: Egy vagy több modul végrehajtását irányítja.

Véletlenszám-generálás: Egy adott tartományba eső szám vagy számsorozat előállítása, amelynek tagjai szabálytalanul követik egymást.

BASIC utasítások, parancsok és kulcsszavak

Kulcsszó Funkció Típus
C64
HT-1080Z
PRIMO
Spectrum
ABS(A) A abszolút érték számítása függvény
X
X
X
X
ACS A A arkusz koszinusza függvény      
X
AND Logikai ÉS kapcsolat szava kulcsszó
X
X
X
X
ASC(A$) A$ első karakterének ASCII kódja függvény
X
X
X
 
ASN A A arkusz szinusza függvény        
ATN(A) A arkusz tangense függvény
X
X
 
X
ATTR X,Y Az X sorban és Y oszlopban kiadott jel megjelenési módja függvény      
X
AUTO(A,B) Automatikus sorszámozás A-tól B lépésben parancs  
X
X
 
BEEP X,Y Y magasságú hangkiadás X-ig utasítás      
X
BIN Az utána írt számot binárisan olvassa függvény      
X
BORDER A Az A-nak megfelelő színre állítja a keretet utasítás      
X
BRIGHT A Az A-nak megfelelő fényességet állít be utasítás      
X
CALL(X) A X címen levő gépi kódú program hívása függvény    
X
 
CDBL(X) X szám kétszeres pontosságú változó függvény  
X
X
 
CHR$(A) Az A számnak megfelelő karaktert adja vissza függvény
X
X
X
X
CINT(A) A-t egész típusúra alakítja függvény  
X
X
 
CIRCLE(X,Y,Z) X, Y középpontú, Z sugarú kört rajzol függvény      
X
CLEAR(A) Az A számú bájtot és a változókat törli parancs  
X
X
X
CLOAD#-1,A Az A nevű programot betölti parancs  
X
   
CLOAD? A Az A nevű állományt összehasonlítja a tárban levővel parancs  
X
   
CLOSE A Lezárja az A logikai hivatkozási számú állományt utasítás
X
 
X
X
CLR A változókat törli utasítás
X
     
CLS Képernyőtörlés utasítás  
X
X
X
CMD A A kiírást az A logikai hivatkozási számú állományra irányítja utasítás
X
     
CODE A$ A szöveg első karakterének kódját adja függvény      
X
CONT A programot a leállás helyéről folytatja parancs
X
X
X
 
CONTINUE Ua., mint CONT parancs      
X
COPY Az első 22 sort kinyomtatja utasítás      
X
COS(A) A koszinusza függvény
X
X
X
X
CSAVE#-1,A A tárban levő programot A névvel kimásolja parancs  
X
   
CSNG(A) A-t valósra konvertálja függvény    
X
 
CREATE Állomány létrehozása utasítás    
X
 
DATA Adatokat helyez el utasítás
X
X
X
X
DEFDBL Az utána írt változók kétszeres pontosságúak utasítás  
X
X
 
DEF FN Felhasználói függvény definiálása utasítás
X
   
X
DEFINT Az utána írt változók egész típusúak utasítás  
X
X
 
DEFSNG Az utána írt változók numerikus változók utasítás  
X
X
 
DEFSTR Az utána írt változók szövegesek utasítás  
X
X
 
DELETE Az utána álló sorszámú utasítás(oka)t törli parancs  
X
X
 
DIM Tömböt definiál utasítás
X
X
X
X
DRAW X,Y A jelenlegi pont és X,Y között egyenest rajzol utasítás      
X
DRAW X,Y,Z A jelenlegi pont és X,Y között egyenest húz Z-vel elforgatja utasítás      
X
EDIT A A sorszámú programsor módosítása parancs  
X
X
X
ELSE Lásd az IF THEN ELSE-nél kulcsszó  
X
X
 
END Program vége utasítás
X
X
X
 
ERL A hibás sorszámot adja vissza függvény  
X
X
 
ERR A hibakód számát adja vissza függvény  
X
X
 
ERROR A Az A hibakódot állítja elő utasítás  
X
   
EXP(A) Az e A-adik hatványát adja vissza függvény
X
X
X
X
FLASH A A-nak megfelelően villogást ad utasítás      
X
FIX(X) X-ről leválasztja a törtrészt függvény  
X
X
 
FN név (A) Az FN név függvény A pontbeli értékét adja függvény
X
   
X
FOR TO STEP Ciklust hajt végre utasítás
X
X
X
X
FRE(0) A tárban a szabad hely mérete bájtban függvény
X
X
X
 
FRE(0$) A szöveges változók szabad tárolóhelye függvény    
X
 
GET A$ A lenyomott billentyű kódja A$-ba utasítás
X
     
GET#A Az A számú eszközről egy bájtot olvas utasítás
X
     
GOSUB A Szubrutint hív az A sorszámon utasítás
X
X
X
X
GOTO A A végrehajtás A sorszámon folytatódik utasítás
X
X
X
X
IF THEN Elágazási utasítás utasítás
X
X
X
X
IF THEN ELSE Elágazási utasítás utasítás  
X
   
INK A A képernyőre írás színét állítja be utasítás      
X
INKEY$ A lenyomott billentyű kódját adja vissza függvény  
X
X
X
INP(A) Az A kapuról egy bájtot beolvas függvény  
X
X
 
INPUT A billentyűzetről adatot olvas be utasítás
X
X
X
X
INPUT#A Az A logikai hivatkozási számú állományról egy rekordot olvas utasítás
X
 
X
 
INVERSE A A-nak megfelelően negatív írást ad ki utasítás      
X
INT(A) A-nál kisebb egész értéket ad függvény
X
X
X
X
LEFT$(A$,B) B sorszámú karakter az A$ bal oldaláról függvény
X
X
X
 
LEN(A$) A$ karakterszámát adja vissza függvény
X
X
X
X
LET Értékadás utasítás
X
X
X
X
LINE Szöveges változó beolvasása INPUT-tal utasítás      
X
LIST Programlistázás parancs
X
X
X
X
LLIST Programlistázás nyomtatóra parancs  
X
X
X
LOAD Programbetöltés parancs
X
X
X
X
LOG(X) X logaritmusát adja vissza függvény
X
 
X
 
LPRINT Kiírás nyomtatóra utasítás  
X
X
X
MEM A tárban nem használt bájtok száma függvény  
X
   
MERGE A betöltött és a bent levő programból egy újat hoz létre parancs      
X
MID$(A$,B,C) Az A$ szöveg B-edik és C-edik helyértéke közötti szöveget adja függvény
X
X
X
 
NEW A bent levő programot törli parancs
X
X
X
X
NEXT Cikluszárás utasítás
X
X
X
X
NOT Logikai tagadás utasítás
X
X
X
X
ON ERROR GOTO Hiba esetén elágazás utasítás  
X
X
 
ON A GOTO A-tól függően ágazik el utasítás
X
X
X
 
ON A GOSUB A-tól függően egy szubrutint hív utasítás
X
X
X
 
OPEN Megnyit egy perifériát utasítás
X
 
X
 
OR Logikai VAGY kapcsolatot jelöl utasítás
X
X
X
X
OUT(A,B) Az A kapun B számot ír ki utasítás  
X
X
X
OVER A A-nak megfelelő módon egy jelet átír utasítás      
X
PAPER A A-nak megfelelően alapszínt állít utasítás      
X
PAUSE A A végrehajtást leállítja A*1/50 mp-re utasítás      
X
PEEK(A) Az A címen levő bájt tartalma függvény
X
X
X
X
PI Pi értékét adja függvény      
X
PLOT A,X,Y A-nak megfelelő színű pontot rajzol az X,Y koordinátákba utasítás      
X
POINT(X,Y) Az X,Y koordinátájú pont állapotát vizsgálja utasítás  
X
X
 
POKE A,B Az A című bájtba B értékét írja utasítás
X
X
X
X
POS(0) A helyőr jelenlegi helye egy sorban függvény
X
X
   
PRINT Adatkiírás utasítás
X
X
X
X
PRINT#A Az A logikai hivatkozási számú állományra írás utasítás
X
     
RANDOM Véletlenszámsort véletlenszerűvé teszi utasítás  
X
X
 
RANDOMIZE Ua. mint a RANDOM utasítás      
X
RE(A,B) A-tól B lépésben újraszámozza az utasításokat parancs  
X
   
READ Adatolvasás a DATA-ból utasítás
X
X
X
X
REM Megjegyzés, magyarázat utasítás
X
X
X
X
RESET(X,Y) A X,Y koordinátájú pontot kikapcsolja utasítás  
X
X
 
RESTORE A DATA olvasást visszaállítja az első adatra utasítás
X
X
X
X
RESUME A hibakezelést befejezi, és visszatér a hibás utasításra utasítás    
X
 
RESUME A A hibakezelés után az A sorszámra adja a vezérlést utasítás  
X
   
RESUME NEXT A hibakezelést befejezi, és visszatér a hívás utáni utasításra utasítás    
X
 
RETURN Szubrutin-befejezés utasítás
X
X
X
X
RIGHT$(A$,B) Az A$ jobb oldaláról B karaktert vesz függvény
X
X
X
 
RND(A) A-tól függő véletlenszámot állít elő függvény
X
X
X
X
RUN Programvégrehajtás parancs
X
X
X
X
SET(X,Y) Az X,Y koordinátájú pontot kapcsolja utasítás  
X
X
 
SAVE A programot háttértárolóra másolja parancs
X
X
X
X
SAVE SCREEN A Képernyőmásolás az A nevű állományra parancs      
X
SCREEN$(X,Y) A képernyő X,Y koordinátájú pontját olvassa függvény      
X
SGN(A) Az A előjelétől függően -1, 0, +1 függvény
X
X
X
X
SIN(A) A szinusza függvény
X
X
X
X
SPC(A) A számú szóközt nyomtat függvény
X
     
SQR(A) A négyzetgyökét adja függvény
X
X
X
X
STATUS Az állomány helyzetét tartalmazza olvasásnál függvény
X
     
STEP Lásd a FOR TO STEP utasításnál kulcsszó
X
X
X
X
STOP A végrehajtást leállítja utasítás
X
X
X
X
STRING$(A,B) B-t A jelből álló szöveges adattá alakítja függvény  
X
X
 
STR$(A) A-t szöveges formájú adattá alakítja függvény
X
X
X
X
SYS(A) Az A tárcímtől gépi kódú programot hív utasítás
X
     
SYSTEM Gépi kódú üzemmódba kapcsol parancs  
X
   
TAB(A) PRINT utasításban A-adik pozícióra áll be függvény
X
X
X
X
TAN(A) A tangense függvény
X
X
X
X
TEST A tárban levő és a kazettán levő programot összehasonlítja parancs    
X
 
THEN Lásd az IF THEN és IF THEN ELSE utasításoknál kulcsszó
X
X
X
X
TI A belső órát olvassa függvény
X
     
TI$ A belső órát szöveges formában olvassa függvény
X
     
TO Lásd a FOR TO STEP utasításnál kulcsszó
X
X
X
X
TROFF Kikapcsolja a nyomkövetést parancs  
X
X
 
TRON A nyomkövetést bekapcsolja parancs  
X
X
 
USING Formátumkiírás kulcsszava PRINT utasításban kulcsszó    
X
 
USR(A) Az A tárcímtől gépi kódú szubrutint hív függvény
X
X
 
X
USR A$ Az A$ nevű felhasználói grafika kezdőcíme függvény      
X
VAL(A$) A$ numerikus értékét adja függvény
X
X
X
X
VARPTR A Az A címét adja meg függvény  
X
X
 
VARPTR(A$) Az A$ címét adja meg függvény    
X
 
VERIFY A tárban és a háttértáron levő programot hasonlítja össze parancs
X
     
WAIT Programleállítás egy eseményig utasítás
X
     

A függvények argumentumát a Sinclair-gépeken nem kell zárójelbe tenni.

Gyakrabban előforduló programhibák és javításuk
Bemutatunk néhány gyakrabban előforduló hibát és az ekkor megjelenő hibaüzenetet, valamint azt, hogy hogyan lehet a hibát kijavítani.
Leírásunk nem teljes körű, ezért azt ajánljuk az olvasónak, hogyha olyan hibaüzenetet ír ki a gépe, amit itt nem talál meg, azt a gép kézikönyvében keresse meg, és így derítse ki a hiba okát, vagy kérjen tanácsot egy szakértőtől.

Programsorok javítása

1. A Commodore-gép hibajavítási lehetősége
A tárban levő program sorait a képernyőn lehet javítani. Ezért először a hibás sort a LIST paranccsal ki kell íratni a képernyőre. Ezután a helyőrt a hibás sor elejére állítjuk a helyőrmozgató gombok segítségével:

Ezután tudunk hibát javítani.

Karakterek törlése
A helyőrt a törölni kívánt karaktersorozatból egy helyértékkel jobbra állítjuk, és annyiszor nyomjuk le a törlőgombot (INST/DEL), ahány jelből áll a törölni kívánt szövegrész. Törlés közben a helyőrtől jobbra eső szövegrész a helyőrrel balra mozog. Tegyük fel, hogy az alábbi utasításból ki akarjuk törölni a GOTO-t:

100 IF A=B THEN GOTO 500

A helyőrt az O és az 5 közé állítjuk, majd annyiszor lenyomjuk az INST/DEL gombot, hogy a GOTO eltűnjön. Ha a sor javítását befejeztük, nyomjuk le a RETURN gombot, mert csak így marad meg a módosítás.

Karakterek beszúrása
helyőrt arra a helyre állítjuk a programon belül, amely után valamiin szövegrészt be kell szúrni. Ezután a SHIFT és az INST/DEL gomb együttes lenyomásával a helyőrtől jobbra üres helyek keletkeznek, ahová a hiányzó szövegrészt begépelhetjük. Az üres helyek kitöltése után a javítást a RETURN gomb lenyomásával lehet befejezni.
Ha egy PRINT utasításban páratlan sorszámú idézőjelet írunk, akkor a helyőrmozgató gombok hatástalanná válnak. Ha ilyenkor egy helyőrmozgató gombot nyomunk le, akkor a gombnak megfelelő fordított karakter jelenik meg a képernyőn. Ez egyébként helyőrmozgatást fog végrehajtani a program futásakor. Ezért idézőjelbe tett szövegrészeken elül csak az INST/DEL gombbal lehet balra haladva törölni.

Szöveg átírás
A programsor szövegét más szöveg begépelésével módosíthatjuk. A módosítás után ne felejtsük el a RETURN gombot lenyomni, mert csak ezzel válik véglegessé a javítás. Ha több programsor van a képernyőn, és a javítás után a helyőr a következő sor elejére áll, de ezt nem kell javítani, akkor a RETURN gomb lenyomásával haladhatunk lefelé.

2. A HT gép hibajavítási lehetősége
(tárban levő program sorait az EDIT szövegszerkesztővel lehet módosítani. Az EDIT nagyon sok hibajavítási lehetőséget tartalmaz. Ezek közül a fontosabbakat mutatjuk be.
A javítani kívánt sort az EDIT sorszám paranccsal hívhatjuk be, például:

EDIT 200

Ezután el lehet kezdeni a javítást. Előtte azonban érdemes megjeleníteni keresett sort az L (listázás) paranccsal.

Karakterek törlése
A helyőrt a szóközbillentyű lenyomásával (jobbra mozgatás) és a gombbal (balra mozgatás) tudjuk a soron belül (pontosabban a sor alatt) mozgatni.
A törlést az nD paranccsal lehet végrehajtani. Hatására a helyőrtől jobbra álló karakter törlődik. A kiírásban a törölt szövegrész nem tűnik el, hanem két felkiáltójel között jelenik meg. A NEW LINE lenyomása után a törlés véglegesen megtörténik. Például a következő sorból töröljük ki a GOTO-t:

200 IF A>B THEN GOTO 500

A helyőrt állítsuk a G betűre, és adjuk ki az

5D

parancsot, melynek hatására az alábbi kiírás jelenik meg:

200 IF A>B THEN ! GOTO ! 500

A 2 felkiáltójel határolja a törölni kívánt szöveget. Ha meggondoltuk magunkat, vagy rosszul írtuk be a javítást, akkor A parancsot kell kiadni, amely visszaállítja a programsort az EDIT-be való belépéskor meglevő állapotába, és a módosítást elölről lehet kezdeni. A javítást a NEW LINE gombbal lehet véglegesíteni.

Karakter beszúrása
A helyőrt arra a pozícióra kell állítani, ahol a beszúrást el akarjuk kezdeni. Ekkor I parancsot adunk ki, és beírjuk a beszúrandó szöveget. A begépelés végén a SHIFT és a fel billentyű együttes lenyomásával befejezzük a beszúrást. Az L paranccsal kiírható a módosított utasítássor.

Karakter cseréje
A helyőrt állítsuk közvetlenül a kicserélni kívánt szövegrész elé. Ekkor itt egy nC parancsot adunk ki, amelyben n a kicserélendő karakterek számát jelöli. Ezután beírjuk az új szöveget. Például az alábbi sorban az AB változó nevet B2-re akarjuk javítani:

200 PRINT AB

A helyőrt az A-ra állítjuk, és kiadjuk a cserére vonatkozó parancsot:

2C

majd beírjuk az új szöveget: B2
Ezzel a módosítás megtörtént. A módosított sort az L paranccsal kilistázhatjuk.
Az EDIT szerkesztési műveletet a NEW LINE gomb lenyomásával fejezhetjük be.
Az EDIT nem teszi lehetővé a sorszám módosítását!

3. A PRIMO gép hibajavítási lehetősége
A tárban levő programot az

EDIT sorszám

panccsal lehet módosítani. A sorszám a programsor sorszáma. A módosítandó sort a ismételt lenyomásával lehet kiíratni. A sorból a gombbal lehet törölni. Ha a törölt szövegrész helyébe újat akarunk berni, akkor azt ilyenkor be lehet gépelni. A RETURN gomb lenyomásával a helyőrtől jobbra levő szövegrész törlődik, és a módosítás befejeződik.
Ha több részt kell módosítani, akkor az egyes részek módosítása után SHIFT és gomb együttes lenyomásával lehet a sor elejére állítani a helyőrt és folytatni a módosítást.
Ha nem akarunk javítani, vagy a javítást nem akarjuk átvezetni, akkor a le gombot nyomjuk le, és a sor visszaáll az EDIT-be lépés előtti formájára.
A módosítást a SHIFT és a gomb együttes lenyomásával zárhatjuk le.
Az EDIT-tel a sorszám is módosítható. Ilyenkor mind az eredeti, mind a módosított sor megmarad.

4. A Sinclair-gépek hibajavítási lehetősége
A Sinclair-gépeken az utasítássorok beírásakor is van lehetőség olyan hibajavításra, amely nem a törlésen és újraíráson alapul. A gomb segítségével a begépelt szövegben visszaléptethetjük a helyőrt a javítás helyére. Ekkor a helyőrtől jobbra levő szövegrész helyett újat írhatunk be, vagy a helyőrtől balra levő szövegrészt a DELETE gomb ismételt lenyomásával törölhetjük.
A tárban levő programsorokat az EDIT paranccsal lehet javítani. Előtte azonban a javítandó sort ki kell listázni. Ha több sor közül kell a javítandót kiválasztani, akkor a fel és le gombbal tudjuk mozgatni a > sormutató jelet, és ezzel választhatjuk ki azt a sort, amelyet javítani akarunk.
A kívánt sorra ráállunk, és lenyomjuk az EDIT gombot. Ekkor a sor megjelenik a képernyő alsó részén. A javítást ugyanúgy végezhetjük el, mint egy most begépelt sorban. A javítás befejeztével lenyomjuk az ENTER gombot, ekkor a javított sor kerül a képernyő felső részén levő régi sor helyébe.

Vissza