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.)