Alapvető vezérlési szerkezetek |
|||
Ebben a fejezetben az Object Pascal (későbbiekben OP) nyelv
legalapvetőbb vezérlőegységeivel ismerkedhetünk meg. Ezeknek az
egységeknek a pontos megtanulása, megértése és egyértelmű alkalmazása
nagyon fontos, hiszen egy komolyabb program felépítésében mindezek
felhasználása nélkülözhetetlen. A következő részekben teljes egészében
tárgyalom a következőket: 1.
Feltételes elágazás (if) 2.
Többágú szelekció (case) 3.
Ciklusok (for, while, repeat) 4.
A break és a continue utasítások 5. A with utasítás 6. A goto utasítás |
|||
Feltételes elágazás |
|||
Egy program végrehajtása
során a gép az elemi utasításokat sorban, egymás után hajtja végre. Ennek során
számos esetben előfordulhat olyan eset, amikor valamilyen döntést kell hozni,
hogy az alapján elágaztassuk a programunkat egy vagy több irányban. Ilyen
esetekben nem mindegy, hogy melyik rész kerül végrehajtásra. Az ilyen,
feltételes elágaztatásra találták ki a Pascalban az if utasítást, melynek
általános formája a következő: if feltétel then utasítás1 else utasítás2; Az if utasítás megvizsgálja
az őt követő feltétel-t (mely egy logikai
kifejezés), s ennek eredményeképpen hoz döntést. Ha a kifejezés
kiértékelésének eredménye igaz, akkor a then ág utáni utasítás1,
egyébként az else ág
utáni utasítás2 kerül végrehajtásra. Fontos,
hogy az else szó
előtt ne legyen pontosvessző (;), mert akkor azt a fordító az if utasítás rövidített
változatának tekinti, s mivel az else szó önmagában semmire sem használható, ezért a fordítás
hibaüzenettel leállna. A rövidített változat abban különbözik az
előzőtől, hogy feltétel vizsgálat után csak akkor van elágazás
a programban, ha a feltételvizsgálat eredménye igaz, egyébként az
eredeti folytatódik tovább. if feltétel then utasítás; Ugyancsak
fontos még, hogy ha az if
utasítás után még újabb utasításokat szeretnénk elhelyezni, akkor azokat
programblokkba (begin … end)
tegyük. Megjegyzem, hogy az if
utasítások egymásba is ágyazhatók. Az 1.
és 2. ábrán az if
általános, illetve rövid formájának folyamatábrája látható:
Az
elmondottakra vonatkozóan nézzünk meg egy konkrét feladatot! A program kérjen
be egy egész számot a felhasználótól, majd állapítsa meg róla, hogy páros-e
vagy páratlan. program
Vizsgal; {$APPTYPE
CONSOLE} const v
= ’A megadott szam ’; var szam
: Integer; begin Writeln (’Szam
viszgalata’); Writeln; Write (’Kerek egy szamot: ’); Readln (szam); if szam mod
2 = 0 then Writeln
(v + ’paros!’) else Writeln
(v + ’paratlan!’); Readln; end. |
|||
Többágú szelekció |
|||
A többágú szelekciót akkor
használjuk, amikor egy adott kifejezés eredményét elemezzük ki, amelynek
során több lehetséges értéket kívánunk megvizsgálni, amelyek száma akár több
száz is lehet. A feladatot megoldhatjuk az előző részben
ismertetett if
utasítással is, de a szelekciós változat jobb, kényelmesebb megoldást
biztosít. case kifejezés of érték1 :
utasítás1; érték2 :
utasítás2; ... értékN : utasításN; else egyébként_utasítás; end; A case szó
után álló kifejezés egy sorszámozott típus lehet.
Ez alapján dönti el a fordító, hogy az érték1, érték2, …, értékN a
vizsgált kifejezés-sel
megegyezik-e. Ha igen, akkor az azt követő kettőspont (:) után álló
utasítást hajtja végre. Ha pedig nem, akkor az else résznél lévő utasítások kerülnek (egyébként_utasítás)
végrehajtásra, amennyiben van ilyen. Ennél az utasításnál az else elé muszáj pontosvesszőt rakni (mivel az else rész
elhagyható), valamint az utasítást az end–del kell lezárni! A 3. ábrán
látható a case
utasításnak a folyamatábrája. Feladat:
írjunk egy kalkulátort, mely a case szekvenciát használja a művelet eldöntésére! program
Kalkulator; {$APPTYPE
CONSOLE} var a,
b, e : Extended; muv : Char; begin e := 0.0; Writeln (’Kalkulator’); Writeln; Write (’1. adat: ’); Readln (a); Write (’2. adat: ’); Readln (b); Write (’Muveleti
jel: ’); Readln (muv); case
muv of ’+’ : e := a + b; ’-’ : e := a – b; ’*’ : e := a * b; ’/’ : if b <> 0 then e := a / b else begin Writeln
(’Hiba, az oszto nulla!’); Halt; end; else Writeln
(’Ervenytelen muveleti
jel!’); Halt; end; Writeln; Writeln (’Az eredmeny: ’, e : 8 : 2); Readln; end.
|
|||
Ciklusok |
|||
Ebben a részben tárgyaljuk a
ciklusokat, vagy más néven az iterációkat. Ciklusokat akkor szokás alkalmazni,
amikor ugyanazt a programrészt többször kell végrehajtani. Az OP nyelv három
ciklus használatát teszi lehetővé. Ebből az egyik a számláló ciklus
(for), a
másik kettő az úgynevezett „tesztelős” ciklus (while, repeat). Az
utolsó két ciklus neve onnan ered, hogy valamilyen feltételtől
függően működnek. A továbbiakban tekintsük át ezeket
részletesebben! A for ciklus
Ezt a
ciklust akkor használjuk, amikor pontosan meg tudjuk nevezni az ismétlések
számát. Remek példa erre a tömbök kezelése. A for, while, repeat ciklusban lévő végrehajtandó utasításokat
szokták a ciklus magjának is nevezni. Két fajtája létezik, mégpedig a
következők: for ciklusváltozó :=
kezdőérték to
végérték do utasítás; for ciklusváltozó :=
kezdőérték downto
végérték do utasítás; Ezek a
ciklusok úgy működnek, hogy először a ciklusváltozó
fölveszi a kezdőérték – et , majd
ha a kezdőérték ≤ végérték (1.
ciklus), vagy kezdőérték ≥
végérték (2. cikus), akkor a
ciklus magjában lévő utasítások kerülnek végrehajtásra, ami után a
ciklusváltozó 1-gyel nő (1. eset) vagy csökken (2. eset). Fontos, hogy a
ciklusváltozó, a kezdőérték és a végérték is sorszámozott
típusú legyen. A ciklusváltozót a ciklusmagon belül és kívül egyaránt fel lehet
használni. A 4. ábrán látható ennek folyamatábrája. 1
feladat: deklaráljunk egy 20 elemű egész vektortömböt, majd töltsük azt
fel véletlen-számokkal! A feltöltés után adjuk össze a tömb elemeit, majd
jelenítsük meg azt a képernyőn! program
Tomb; {$APPTYPE
CONSOLE} var t :
array [0..19] of Word; ossz : LongInt; i :
Integer; begin Randomize; ossz := 0; Writeln (’Tomb
feltoltese veletlenszeru szamokkal’); Writeln; for
i := 0 to
19 do begin t[i] := Random (High (Word)) + 1; Writeln
(i + 1, ’. elem: ’, t[i]); Inc (ossz, t[i]); end; Writeln; Writeln (’Az osszeg: ’, ossz); Readln; end. 2
feladat: Írjuk ki a képernyőre egymás alá az ASCII kódtáblázat elemeit
90-től 70-ig! program
ASCII; {$APPTYPE
CONSOLE} var i : Integer; begin for
i := 90 downto
70 do Writeln
(Chr (i)); Readln; end.
A while ciklus
A while
ciklust akkor használjuk, amikor nem tudjuk pontosan megadni az ismétlődések
számát, vagy a ciklus végrehajtásának száma egy feltételtől függ. A while
ciklust előltesztelőnek nevezzük, mivel a
ciklus lefutása előtt egy feltétel alapján dől el, hogy a ciklusmag
lefusson-e vagy sem. Szerkezete: while feltétel do utasítás; A feltétel (mint
az if
utasításnál is) egy logikai kifejezés. Ha ennek a kiértékelésének az
eredménye hamis, akkor a ciklus egyszer sem fog lefutni. Igaz érték esetén
mindaddig fut, amíg hamissá nem válik. Vigyázzunk, mert ha a ciklus nem
tartalmaz olyan utasítást, amely a feltétel kiértékelési eredményét
megváltoztatná, akkor úgynevezett végtelen ciklust kapunk. Folyamatábráját az
5. ábra mutatja. Általánosságban elmondható az is, hogy a for
ciklusok while
ciklusokká írhatók át. Feladat:
készítsünk egy olyan programot, ami addig kéri a felhasználótól a jelszót,
amíg el nem találja! program
Jelszo; {$APPTYPE
CONSOLE} const j
= ’Object Pascal’; var jsz
: string; begin Writeln (’Jelszo
megadasa’); Writeln; jsz
:= ’’; while
jsz <> j do begin Write (’Kerem a jelszot: ’); Readln (jsz); if
jsz <> j then Writeln
(’Hibas jelszo!’); end; Writeln (’Eltalaltad!’); Readln; end.
A repeat ciklus
Erről
a ciklusról is ugyanaz mondható el, mint a while ciklusról. A kettő közötti különbség csak
az, hogy ez nem elől-, hanem hátultesztelős,
vagyis a feltétel vizsgálata a ciklus legvégén van. Ebből az következik,
hogy a ciklus legalább 1-szer le fog futni. A következő szerkezettel
látták el: repeat utasítás; until
feltétel; Működése
is majdnem megegyezik az előző cikluséval. Lényeges eltérés, hogy a
ciklus addig fut, amíg a feltétel igazzá nem válik. A
ciklusmagban szereplő utasításokat nem kötelező programblokkba
helyezni. Folyamatábráját a 6. ábra szemlélteti. Feladat:
a program addig kérjen be adatokat a felhasználótól, míg az
0 és 1000 közé nem esik! program
Ellenoriz; {$APPTYPE
CONSOLE} var szam
: LongInt; begin Writeln (’Kerek egy szamot 0 es 1000 kozott!’); Writeln; repeat Write (’Szam: ’); Readln (szam); until
(szam
> 0) and
(szam < 1000); Writeln; Writeln (’Na
Vegre!’); Readln; end.
|
|||
A break
és a continue utasítások |
|||
Számos olyan helyzet állhat elő, amikor egy ciklusból valamilyen ok miatt ki kell lépni, vagy esetleg ki kell hagyni a hátralévő utasításokat. Ilyen esetekre kiváló megoldást kínál a break és a continue utasítás. A break utasítás kiléptet az aktuális
ciklusból és a program végrehajtása a ciklus utáni következő utasításra
tér. A continue utasítás hatására a program
átugorja a ciklusmag további utasításait (amennyiben van ilyen). 1.
feladat: a continue
utasítást használva írjuk ki a képernyőre 1-től 20-ig a páratlan
számokat! program
Paratlan; {$APPTYPE
CONSOLE} var i : Integer; begin Writeln (’1-20-ig a paratlan szamok:’); Writeln; for
i := 1 to
20 do begin if
i mod 2 = 0 then continue; Writeln
(i); end; Readln; end. 2.
feladat: egy felhasználó által megadott szövegből (maximum 255 karakter)
a program addig írja vissza a képernyőre ugyanazt a szöveget, addig, amíg
számjegyet nem talál! program
Ir; {$APPTYPE
CONSOLE} var s : string; i : Integer; begin Writeln (’Szoveg
megadasa’); Writeln; Write (’Kerem
a szoveget: ’); Readln
(s); Writeln; Write (’A
beirt szoveg az elso szamjegy elofordulasaig: ’); for
i := 1 to
Length (s) do begin if
(s[i] >= ’0’) and (s[i] <= ’9’) then break; Write (s[i]); end; Writeln; Readln; end. |
|||
A with
utasítás |
|||
A rekordok mezőihez
hozzáférni mindig a rekord_változó.mező
utasítással tudunk. Több mezővel rendelkező rekord
esetén ez a felírási mód igencsak fárasztó és hosszadalmas. Ennek
kiküszöbölésére találták ki a with utasítást, melynek formája: with rekord_változó
do utasítás; Használatakor
a rekord mezői közvetlenül érhetőek el a rekord_változó kirakása
nélkül is. Objektumok, osztályok esetében is megállja a helyét. Feladat:
a felhasználó által bevitt adatok egy ’szemely’ nevű rekordba kerüljenek, a with
utasítás felhasználásával! A megadott adatok íródjanak az ’Adat.dat’ nevű állományba! program
WithPelda; {$APPTYPE
CONSOLE} uses SysUtils; type RSzem = record nev : string; kor : Integer; nem : 0..1; //0 – férfi,
1 - nő end; var szemely : RSzem; F :
TextFile; begin Writeln (’Szemely
adatainak megadasa’); Writeln; AssignFile (F, ’Adat.dat’); if FileExists (’Adat.dat’)
then Append (F) else ReWrite
(F); with
szemely do begin Write (’Neve : ’); Readln (nev); Writeln (F, nev); Write (’Kora : ’); Readln (kor); Writeln (F, kor); Write (’Neme : ’); Readln (nem); Writeln (F, nem); end; Readln; CloseFile (F); end. |
|||
A goto
utasítás |
|||
A goto utasítás segítségével
egy címkével kijelölt területre ugorhatunk, átlépve a soron következő
utasítást, vagy visszatérve az előző utasítás(ok)ra (a címkét felhasználása előtt deklarálni kell): goto
utasításcímke; Ez az
utasítás lehetővé teszi a belső blokkból a külsőbe való
ugrást, de fordítottan ez nem lehetséges. Eljárásokból, függvényekből
(közös néven alprogramokból) nem ugorhatunk ki, de
be sem! Az
alábbi példa illusztrálja a goto
működését: program
GotoPelda; {$APPTYPE
CONSOLE} label ide,
oda, amoda; begin Writeln (’1. blokk’); begin Writeln
(’2. blokk’); begin Writeln
(’3. blokk’); goto
ide; Writeln
(’Ez az uzenet soha nem fog megjelenni!’); end; Writeln
(’Ez is!’); ide: Writeln
(’2. blokk kozepe’); goto
amoda; end; amoda: Writeln (’1. blokk vege!’); Readln; end. Ezekben
a részekben megtanulhattuk az OP nyelv legalapvetőbb vezérlési
szerkezeteit, példákkal illusztrálva azokat. A későbbiekben is sikeres
programozást, és jó munkát kívánok! |
|||
Veres Ádám |