06. 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
megoldás
11. Írj programot, amely kiírja a 0, 5, 10, ..., 100 számokat (ötösével) hátultesztelős ciklussal!
megoldás
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!
megoldás
13. Írj programot, amely kiszámítja az 1 és 100 közötti egész számok összegét
megoldás
14. Írj programot, amely megadja az 1 és 1000 közötti, 7-tel osztható számok összegét!
megoldás
15. Írj programot, amely kiszámítja 1,13-nak a 113-adik hatványát (szorzásokkal)!
megoldás
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.)
megoldás
17. Írasd ki az 5-ös szorzótáblát: 1*5=5, 2*5=10, ..., 10*5=50!
megoldás
18. Írasd ki a teljes 10-es szorzótáblát 1*1-től 10*10-ig! (Tipp: egymásba ágyazott ciklusok.)
Comments