6. fejezet: Ciklusok
A program többször végrehajtódó részét ciklusnak nevezzük. A ciklusfeltétel adja meg, mikor kell a ciklusmagot ismét végrehajtani.
Elöltesztelős ciklus
A következő program megkeresi a legkisebb 15-nél nagyobb, 7-tel osztható páros számot. Az oszthatóságot a mod művelet segítségével ellenőrizzük.
Var a:integer; BEGIN a:=16; while (a mod 7>0) or (a mod 2>0) do a:=a+1; writeln(a); readln; END.
A ciklus felépítése: while
feltétel do
utasítás;
Azért elöltesztelős, mert először vizsgálja a feltételt és utána hajtja végre a ciklusmagot, ha a feltétel igaz. Lehet, hogy egyszer sem fut le (ha a feltétel már kezdetben hamis).
A fenti program úgy működik, hogy addig növeli a értékét, amíg nem felel meg a feladat feltételének (vagyis amíg nem osztható 7-tel vagy nem osztható 2-vel). Ezért ha leáll, akkor azért áll le, mert a osztható 7-tel és osztható 2-vel is.
A do
után csak egy utasítás állhat, ezért több utasításból álló ciklusmagot begin
és end
közé kell írni.
Hátultesztelős ciklus
A hátultesztelős ciklus először hajtja végre a ciklusmagot és utána vizsgálja a feltételt – ezért a ciklusmag legalább egyszer lefut.
Var a:integer; BEGIN repeat write('Adj meg egy egész számot, 0-ra kilép: '); readln(a); if a mod 11=0 then writeln('osztható 11-gyel.') else writeln('nem osztható 11-gyel.'); until a=0; END.
Ennél a ciklusnál repeat
és until
közé több utasítást is be lehet írni, az until
után pedig a leállás feltételét kell megadni.
Most nem tettünk a program végére readln
-t, mert a felhasználó 0 beírásával már jelezte, hogy ki akar lépni.
Számlálós ciklus
Gyakori feladat, hogy egy változóval egyesével számolunk:
Var i:integer; BEGIN i:=1; while i<=10 do begin writeln(i:2,' négyzete=',sqr(i):3); i:=i+1; end; readln; END.
Itt a :2 azt jelzi a kiírásnál, hogy az egész számot hány karakter szélességben kell jobbra igazítva kiírni (balról szóközökkel kiegészítve); így a megfelelő helyiértékek egymás alá kerülnek. Így jobban néz ki.
A számlálós (vagy for-) ciklus pont ezt csinálja:
Var i:integer; BEGIN for i:=1 to 10 do writeln(i:2,' négyzete=',sqr(i):3); readln; END.
A ciklus így néz ki: for
változó:=kezdőérték to
végérték do
utasítás;
ahol a változót egyesével növeli a kezdőértéktől a végértékig, és minden lépésben végrehajtja az utasítást.
Mivel a ciklus elöltesztelős, ha a kezdőérték nagyobb a végértéknél, egyszer sem fut le. Ilyenkor viszont to
helyett downto
-t használva visszafelé számol.
Mivel ennek a ciklusnak a beírása nagyon rövid, gyakran a nem egyesével számláló feladatokat is így csináljuk meg. A következő program páratlan számokat ír ki:
Var i:integer; BEGIN for i:=1 to 10 do writeln(2*i-1); readln; END.
Használhatjuk akkor is, ha egyszerűen csak valahányszor meg akarunk csinálni valamit.
Var fokozat,i:integer; BEGIN write('Mennyire szépen kérjem? '); readln(fokozat); for i:=1 to fokozat do write('nagyon '); writeln('szépen kérem!'); readln; END.
Példa ciklusra és elágazásra
Ez egy számkitalálós játék, ahol a gondolt számot a gép a random
függvénnyel állítja elő. Pl. random(4)
eredménye egy 0 és 3 közötti véletlenszerűen választott egész szám. Természetesen a gép igazi véletlen eseményt nem tud létrehozni (nem dobhat kockával), és ezeket a számokat meghatározott algoritmus alapján állítja elő. Ha a programban kiadjuk a randomize
parancsot, minden futtatáskor más véletlen sorozatot kapunk.
VAR g,t,c:integer; BEGIN randomize; g:=random(100)+1; c:=0; repeat write('Gondoltam egy számot 1 és 100 között. Találgass: '); readln(t); if g<t then writeln('Kisebbre gondoltam!'); if g>t then writeln('Nagyobbra gondoltam!'); c:=c+1; until g=t; writeln('Eltaláltad ',c,' lépésben!'); writeln('Nyomj entert'); readln; END.
Egymásba ágyazott ciklusok
Ciklusban ciklus is lehet. Ha a külső ciklus n-szer fut le, a belső pedig m-szer, akkor a belső ciklus ciklusmagja összesen n·m alkalommal fog lefutni. A következő példa belső ciklusa 15 db. '*' karaktert ír ki egy sorba, amit a külső ciklus 10-szer ismétel. Az eredmény egy 150 *-ból álló téglalap.
Var i,j:integer; BEGIN for i:=1 to 10 do begin for j:=1 to 15 do write('*'); writeln; end; writeln('Nyomj entert'); readln; END.
Feladatok
10. Írj programot, amely kiírja a 0, 5, 10, ..., 100 számokat (ötösével) elöltesztelős ciklussal
11. Írj programot, amely kiírja a 0, 5, 10, ..., 100 számokat (ötösével) hátultesztelős ciklussal!
12. Írj programot, amely a következő idétlen játékot játssza a felhasználóval mindaddig, amíg az a "nem" szót beírja. A felhasználó által beírt dolgokat vastagítva jelzem.
Írj be egy számot!
6
7! Nyertem! Még egy játék?
igen
Írj be egy számot!
2000
2001! Nyertem! Még egy játék?
nem
Kösz a játékot!
13. Írj programot, amely kiszámítja az 1 és 100 közötti egész számok összegét!
14. Írj programot, amely megadja az 1 és 1000 közötti, 7-tel osztható számok összegét!
15. Írj programot, amely kiszámítja 1,13-nak a 113-adik hatványát (szorzásokkal)!
16. Írasd ki (FOR-ciklussal) 1 és 1000 között a 7-tel osztható, páratlan számokat! (Tipp: egyesével számolunk, de csak a feltételnek megfelelő számokat írjuk ki.)
17. Írasd ki az 5-ös szorzótáblát: 1*5=5, 2*5=10, ..., 10*5=50!
18. Írasd ki a teljes 10-es szorzótáblát 1*1-től 10*10-ig! (Tipp: egymásba ágyazott ciklusok.)