Basic ismertető - 2. rész

Most folytatjuk a Basic nyelv megismerését. Ami az előző részben volt:

1. A print parancs

2. A változók használata, na meg minden ronda művelet velük

3. Elágazások (döntések)

4. Számlálós ciklusok

5. Végtelen ciklusok

Ami most jön:

6. A GOTO parancs

A Basic (meg akármilyen más programnyelv) parancsértelmezője egymás utáni veszi a programsorokat. Ezt azonban különböző vezérlési szerkezetekkel tudjuk befolyásolni. Ami gyakran előfordul. Az elágazásokkal és a ciklusokkal már megismerkedtünk. Vannak még az ugrások és az alprogramok. Először a feltétel nélküli ugrásról beszélünk. Ő a GOTO parancs. Önmagában azonban semmire se jó, mert meg kell határozni, hova ugorjon a parancsértelmező. Ezt a régi basicekben (pl. C64 Basic - a Qbasicben is lehet, de nem kötelező) a programsorok számozásával adtuk meg. A DarkBasicben (meg minden többi basicben) címkéket helyezhetünk el a programban. A címke egy kis karaktersorozat, nem lehet benne ékezet, nem egyezhet meg egy utasítás nevével, és ami legfontosabb: a végén kettőspontnak kell lennie. Nem írhatunk utána más parancsot: egyedül kell állnia a sor elején. És hogy miért kell össze-vissza ugrálni a programban ok nélkül? Mindjárt kiderül.

Hozzunk össze egy programot, amivel másodfokú egyenletet lehet számolgatni!

`Az egyenlethez szükségünk van az a,b,c értékekre:

eleje:

input "Az A értéke:",a

input "A B értéke:",b

input "A C értéke:",c

`És átírjuk a megoldóképletet a basic nyelvére.

`Legelőször vizsgáljuk meg, hogy van-e valós gyök.

if ((b^2)-(4*a*c))<0 then print "Nincs valós gyök!" : goto vege

`Számolás! A két gyököt külön-külön kiszámítjuk.

x1=((0-b)+sqrt((b^2)-(4*a*c)))/(2*a)

x2=((0-b)-sqrt((b^2)-(4*a*c)))/(2*a)

`Majd kiírjuk.

print "X1= ";x1

print "X2= ";x2

vege:

print "Új számoláshoz nyomj egy billentyűt! ESC-kel kiléphetsz."

`Egy billentyű lenyomásáig felfüggesztjük a program futását.

`Esc amúgy is kilépés, nem kell vizsgálnunk.

suspend for key

cls

goto eleje

A goto-val ciklust is lehet csinálni, de a DO-LOOP szerkezet átláthatóbb. Példa erre egy ősrégi közismert C64 (QB) program:

10 PRINT "SZIA"

20 GOTO 10

Dark Basicben ez így néz ki: (Sajnos a DB nem scrollozza printnél a képernyőt. Csak a DBPro az 1.05-ös verziótól kezdődően. De az se olyan szép, mint a DOS képernyő-scrollja :-)

start:

PRINT "SZIA"

goto start

Ennek a programnak nem volt sok értelme, de jólesett bepötyögni :-)

7. A GOSUB alprogram

Sokszor előfordul az, hogy egy programrészt (nevezzük alprogramnak) sokszor szeretnénk felhasználni, több helyen egy programban. Ezt GOTO-val nem tehetjük meg; egy olyan vezérlési szerkezet kell, ami az alprogram lefutása után a parancssor-értelmezőt visszaállítja az alprogram meghívása utáni sorba. Ez a Gosub-Return szerkezet. A Gosub olyan mint egy Goto, a program a Gosub utáni cimkére ugrik. Fut tovább addig, amíg returnhoz nem ér. Ekkor visszaugrik a meghívás helyére. A DB-nek nem ért, ha gosub nélkül összetalálkozik egy returnnal, a többi Basic azonban harap erre. Íme egy példa a használatára.

a=8 : b=6

gosub szamol

a=10 : b=20

gosub szamol

a=4 : b=24

gosub szamol

end

szamol:

print "A érték:";a;" B érték:";b

print "Összeg:";a+b

print "Különbség:";a-b

print "Szorzat:";a*b

print "Hányados:";a/b

return

8. A Function alprogramok

Ezek a felhasználó által készített függvények. Hogy mi köze van a függvényeknek az alprogramokhoz?

A QBasicben az alprogramok lehettek Subok vagy Functionok. A DB összemosta a két tipus között a határt.

A programozásban a függvény egy olyan utasítás, aminek visszatérési értrke van. A functionnak LEHET visszatérési értéke. De nem KÖTELEZŐ, hogy legyen. Ugyanígy lehet paramétere (bemenő értéke) is. Sokkal önállóbb, mint a gosub.

Előnyei:

-Akár külön fájlban tárolható

-DBpro-ban "összecsukható"

-Úgy lehet használni, mint egy parancsot

-Nem kell címkékkel szenvedni

Hátrányai:

-Át kell adni neki a változókat

Ajánlom ennek a szerkezetnek a használatát, a gosubhoz csak végveszélyban nyúljunk, ha túl sok bemenő változót használnánk. A hátránya (át kell adni neki a változókat) előnnyé válhat, mert lokális változókat használ. A lokális változó azt jelenti, hogy csak a functionban létezik, a program többi részén nem. Tehát a főprogramban is lehet ugyanolyan nevű változó, nem fog megegyezni az értékük.

Most már nézzük meg, miről van szó! Az alprogram maga:

Function Funcnév

(parancsok)

....

...

....

...

endfunction

Úgy hívjuk meg, hogy a parancsok közé egyszeren beírjuk az alprogram nevét.A DBpro kötelezővé teszi, hogy a funkciónév után legyen két zárójel: () . Nem tudom ez miért kell, a sima DB megvan nélküle. Nézzünk egy egyszerű példát.

randomize timer()

do

    veletlenszoveg

loop

function veletlenszoveg

`Szín meghatározása

ink rgb(rnd(255),rnd(255),rnd(255)),0

`Hely meghatározása

set cursor rnd(640),rnd(480)

print "Ez a véletlen!"

endfunction

A program egy szöveget ír ki a képernyőre véletlen színnel a véletlenszerűen megadott koordinátákra. Ami új, az a véletlenszám számítása.

Véletlen számot az RND() függvény ad, a szám 0 és a zárójelek között megadott maximális érték között lesz. A probléma az, hogy minden futáskor ugyanazokat a "véletlen" számokat számolja ki a DB. Ezért a véletlenszám-generátor kezdőértékét kell változtatni. Ezt a Randomize paranccsal tehetjük meg. Utána írjuk kezdőértéknek a Timer() függvényt, ami az időt adja vissza ezredmásodpercekben. Így már tényleg véletlen számokat kapunk. A set cursor-ral a kiírás helyét állítjuk be, képpontokban.

A másik újdonság a function. Láthatjuk, az alprogram nevét úgy használjuk, mintha egy DB-s parancs lenne. De ha változót is kell használni?

x=100 : y=100

kiir

suspend for key

end

function kiir

set cursor x,y

print x;";";y

endfunction

Ha futtatjuk a programot, azt írja ki, hogy 0;0. Az x és y változót át kell adni az alprogramnak. Mert most az történik, hogy:

1, Az x és y felveszi a 100 értéket.

2, A kiir alprogram nem törődik a főprogram változóival. Ő is létrehoz egy x és egy y változót 0 értékkel. A főprogram változóinak értéke ettől 0 marad!

3, Ezek után az alprogram kiírja a változóit. Nem a főprograméit.

A megoldás: át kell adni az alprogramnak az x és y változót: (az alprogramban megváltoztattam a változóneveket az áttekinthetőség kedvéért)

x=100 : y=100

kiir(x,y)

suspend for key

end

function kiir(xhely,yhely)

set cursor xhely,yhely

print xhely;";";yhely

endfunction

Az alprogram meghívásánál (2.sor) átadjuk a két változó értékét az alprogramnak. Hogy ezek az értékek milyen néven kerülnek be az alprogramba, azt a funkció-deklaráció (function kiir(xhely,yhely) sor) után adjuk meg.

És ha az a szerencsétlen alprogram függvény szeretne lenni, mit kell csinálni?

egyik=10

masik=30

print kulonbseg(egyik,masik)

end

function kulonbseg(a,b)

c=a-b

endfunction c

Ehhez nem kell sok komment. A visszaadandó változót az endfunction után írjuk, és alprogramunkat függvénynek nevezhetjük.

A functionokat - mint már írtam - ki lehet exportálni külön dba-kba. Meghívásukhoz az #include parancs kell.

Használata: #include "fájlnév" Ezután használhatjuk a megadott fájlban lévő functionokat. A DBpro támogatja a több fájlra bontott forráskódot, ott nem kell "includeolni" azokat a fájlokat, amik a project managerben a "files" pontnál megjelennek (azaz már benne vannak a projectben).

Az end nem véletlenül van benne a programban. Ha a program meghívás nélkül szembetalálkozik egy functionnal, runtime error-t (futásközbeni hibát) kapunk.

Apropó, hibák. Hibákból 3 fajta van:

1, elírási hibák, hiányzó ciklusvégek vagy paraméterek, stb.: Ezeket a DB futtatás előtt kiszűri, amikor leellenőrzi a kódot

2, futásközbeni hibák: Ők futás közben jönnek elő, amikor egy parancsnak rossz értékeket adtunk, vagy mondjuk egy fájl nem létezik. Legalább a DB szól, hogy léteznek.

3, bugok: Ez az ősmagyar szó az olyan hibát jelöli, amit a DB nem vesz hibának, csak mi. Nem azt kapjuk, amit várunk. Ők a legalattomosabbak. Jó esetben hamar kiderül, mi okozza őket.

A hibajavítás külön művészet. A programozás leghálátlanabb feladata: nem veszi senki észre, ha kijavítjuk a programhibákat, de az mindenkinek feltűnik, hogyha benne marad a programban.

Vége ennek a kis kitérőnek, nézzünk valami mást:

9. Összetett változók: a tömbök

Gyakran elő fog fordulni, hogy programunknak sok adattal kell dolgoznia. Ezt a sok adatot tárolni kell valahol. Mindhez külön változónév kellene, és szerintem senki se kezdene 1000 változó értékét pl. egyenként megnövelni. Sok adat együttes kezelésére találták ki a tömböket. Míg az egyszerű változókat nem kell deklarálni (megadni a típusukat a parancsértelmezőnek a program elején), addig a tömböket kell. Ezt a DIM paranccsal végezhetjük el.

dim szamok(10)

vagy

dim tortek#(10)

vagy

dim szovegek$(10)

Többdimenziós is lehet egy tömb:

kétdimenziós:

dim szamok(10,10)

háromdimenziós:

dim szamok(10,10,10)

négydimenziós:

dim szamok(10,10,10,10)

ötdimenziós:

dim szamok(10,10,10,10,10)

(Ez a maximum - a dimenziót persze nem fizikailag/matematikailag kell értelmezni)

A típus-előjelekről (#,$) itt se kell megfeledkeznünk. A fent leírt parancsok egy 11 elemű tömböt készítettek. (Tipp: Érdemes a tömb 0. elemét szabadon hagyni, és ideinformációkat írogatni magáról a tömbről - pl. azt, hogy hány elemben van adat) Adat kiolvasása: változó=szamok(5) Ez a sor a számok tömb 5-ös elemének az értékét teszi változóba. Egy tömb kiválasztott elemével mindent meg lehet csinálni, amit egy egyszerű változóval. Adatok beleírása is egyszerű: szamok(5)=34534. El lehet játszadozni az egymásba pakolgatásukkal, pl. szamok(maximum(x,1),10)=minimum(0,x) Így is lehet értéket adni...

Nézzünk egy példaprogramot:

randomize timer()

dim adatok(10,10)

`feltöltés adatokkal

for i=1 to 10

                for j=1 to 10

                               adatok(j,i)=rnd(9)

                next j

next i

`Kiolvasás

for i=1 to 10

                `A számokat egy stringgé alakítjuk, amit az a$ változó tárol.

                for j=1 to 10

                               a$=a$+str$(adatok(j,i))

                               `Két szám közé + jel, az utolsó után =

                               if j<10 then a$=a$+" + " else a$=a$+" = "

                               `Nem csak stringként fűzzük egybe a számokat, össze is adjuk őket

                               a=a+adatok(j,i)

                next j

                `Az összeadás eredményét az a$ változó végére írjuk

                a$=a$+str$(a)

                `Kiírjuk

                print a$

                `Az összeget eltároljuk a dimben

                adatok(0,i)=a

                `Lenullázzuk a két változó értékét

                a$="" : a=0

next i

`üres sor

print " "

`Most az előbb letárolt ösdszegeket adjuk össze

for i=1 to 10

                `a$-be mennek a szöveggé alakított számok...

                a$=a$+str$(adatok(0,i))

                `...a-ba az összeg

                a=a+adatok(0,i)

                if i<10 then a$=a$+" + " else a$=a$+" = "

next i

`kiírjuk

a$=a$+str$(a)

print a$

Amint láthatjuk, a tömbök igen alkalmasak műveletek végzésére. És mivel ez egy játékírásra kifejlesztett basic, sok helyen fogjuk őket használni, pl. mátrix magasságának tárolása, ellenségek életerejének tárolása, stb...

Ezzel véget is ért a Basic-okítás, Úgy gondolom, ez az előző résszel együtt elég erős alapot ad arra, hogy belkezdj te is egy saját játék írásába. Azaz - előtte olvasd el a Dark Basic "Dark" részével (most csak a basicet tárgyaltuk) foglalkozó írást. De ez nem azt jelenti, hogy evvel vége a BASIC nyelv ismertetésének - sok minden maradt! Szóval következő hónapban még mélyebbre ássuk magunkat a Basic rejtelmeiben!

Várkonyi Tibor - vtibor3@freemail.hu