Ponavljanja

Poleg sekvence in vejitev, so ponavljanja (zanke) zadnji izmed pomembnejših osnovnih elementov programa. Ponavljanja običajno nastopajo v programih iz preprostega razloga : programiranje je v svojem bistvu modeliranje procesov, dogodkov realnega sveta. V realnem svetu so dogodki pogosto ali ponovljivi ali pa taki, da se s časom počasi spreminjajo. Pri opisovanju takih dogodkov v programih nujno nastopajo ponavljanja.

Primeri, kjer uporabljamo ponavljanja so npr. :

Pri računalniškem modeliranju so primeri še bolj izraziti tudi zaradi pomnenja podatkov, ki je ponavadi organizirano v strukture zaporedne narave. Obdelava tako organiziranih podatkov ponavadi temelji na ponavljajočih se postopkih (npr. isto operacijo izvedemo na večjem številu podatkov) .

Stavki ki jih javanski programski jezik namenja ponovitvam so:

Vse tri oblike zank (ponavlja) so zgrajene iz dveh blokov :

Telo zanke predstavljajo vsi programski stavki, ki jih želimo ponavljati. Telo zanke lahko vsebuje nič, enega ali več programskih stavkov. V primeru, da želimo ponavljati več kot en stavek, morajo biti vsi ti stavki ograjeni v programski blok stavkov (deločata ga { in } ).

Kontrolni blok zanke (včasih tudi glava zanke) zagotavlja pogoj za ponavljanje. Poenostavljeno rečeno določa, koliko časa oz. kolikokrat se bo telo zanke ponovilo (izvedlo).

Glede na to, kje stoji kontrolni blok zanke, pred telesom ali za njim, ločimo 2 obliki ponavljanj :

Oglejmo si posamezne primere.

stavek while

je primer zanke s pogojem za ponavljam na začetku zanke. Zagotavlja ponavljanje telesa zanke, dokler je izpolnjen logični pogoj. V primeru, da pogoj za ponavljanje ni izpolnjen, se ne izvede noben izmed stavkov telesa zanke.

sintaksa :

while (pogoj) ukaz;

ali (desna slika)

	  while ( pogoj) {
      ukaz_1; 
      ukaz_2:
      ukaz_N;
    }
Pogoj je pri tem vedno logičnega tipa.

Značilnosti while zanke :

Primer 1 :

// izpis celih števil iz intervala [1,10]

int x=1;

while (x <=10) {
   System.out.println(x);
   x++;
}

V zgonjem primer spremenljivka x določa, kolikokrat se bo izpis ponovil. Dejansko s tem kontrolira izvajanje zanke, zato o taki spremenljivki ponavadi govorimo kot o kontrolni spremenljivki zanke.

Primer 2 :

// izpis deliteljev števila n

int n=99, x;
x=1;

while(x<=n){if (n % x == 0)
 System.out.println(x);
 x+=1;
}
 

Primer 3 :

class Gcd {
   public static void main(String[] arg){
   
    int x = Integer.valueOf(arg[0]);
    int y = Integer.valueOf(arg[1]);
   
    while (x != y){
      if (x>y)
         x=x-y;
      else
        y=y-x;
    } 
    System.out.println("Največji skupni delitelj je "+x); 
   }
 } 
 

Zgornji program naj bi določil največji skupni delitelj dveh števil. Ugotovite, ali to res počne in skušajte prepisati program tako, da bo namesto uporabljenega uporabil Euklidov algoritem z deljenjem!

 

stavek do-while

je primer zanke s pogojem za ponavljam na koncu zanke. Zagotavlja ponavljanje telesa zanke, dokler je izpolnjen logični pogoj. V primeru, da pogoj za ponavljanje ni izpolnjen, se pred tem vsaj enkrat izvrši celotno telo zanke.

sintaksa :

 
	  do  {
      ukaz_1; 
      ukaz_2:
      ukaz_N;
    } while(pogoj);
Pogoj je pri tem vedno logičnega tipa.

Značilnosti do-while zanke :

Primer 1 :

// izpis celih števil iz intervala [1,10]
int x=1;
do  {
   System.out.println(x);
   x++;
} while(x<=10);

Primer je skoraj identičen primeru, kjer smo uporabili while obliko ponavljanja.

Primer 2 :

// izpis deliteljev števila n
int n=99, x;
x=1;

do{
   if (n % x == 0)
      System.out.println(x);
   x+=1;
} while(x<=n);

Primer 3 :

class Gcd2 {


   public static void main(String[] arg){


    int x = Integer.valueOf(arg[0]);
    int y = Integer.valueOf(arg[1]); 
  

    if (x!=y) 
    do {
      if (x>y)
         x=x-y;
      else
        y=y-x;
    } while (x != y);
    System.out.println("Največji skupni delitelj je "+x); 
   }

 } 
 

Včasih je potrebno določen postopek prepisati tako, da uporablja le eno izmed doslej omenjenih oblik ponavljanj. Pri pretvorbi si lahko pomagamo z naslednjima slikama :



stavek for

Stavek for je tako kot stavek while oblika ponavljanja s pogojem ponavljanja na zečetku. Kot smo že opazili pri stavku while, se pri takih zankah telo zanke ne izvrši, če pogoj pre vstopom v zanko ni izpolnjen. Za osvežitev si še enkrat oglejmo diagramski prikaz zanke s pogojem na začetku :

Struktura stavka for je kompleksnejša od strukture stavka while. Glavo (kontrolni del zanke) sestavljajo trije bloki :

Primer izpisa prvih desetih naravnih števil :

for (int i=1; i<=10; i++)
  System.out.println(i);   

Opazimo lahko, da je bila v tem primeru deklaracija in inicializacija kontrolen spremenljivke izvedena v inicializacijskem bloku, prav tako je spremeba vrednosti kontrolne spremenljivke določena v zadnjem bloku glave zanke.

Tipično bi lahko samo izvajanje pojasnili na primeru, izvedenem z while zanko :

a) deklaracija in inicializacija kontrolne spremenljivke se izvrši pred vstopom v zanko :

int i=1;

b) pred izvajanjem se preveri pogoj za vstop v telo zanke

while (i<=10)

c) izvedba telesa zanke (za vse i <= 10)

System.out.println(i);

d) za zadnjim stavkom telesa se izvede korekcija vrednosti kontrolen spremenljivke:

i++;

e) nadaljujemo izvajanje s kontrolo pogoja za ponavljanje v glave zanke

Še analogija celotnega programa z uporabo while stavka :

int i=1;


while (i<=10) {
   System.out.println(i);
   i++;
}

Iz danega primera je razvidno, da sta si obe omenjeni obliki ponavljanja popolnoma enakovredni. Obstaja pa malenkostna razlika: stavek while ne omejuje uporabljanega tipa kontrolne spremenljivke, dokler z njeno rabo lahko ustvari pogoj, ki je logičnega tipa. In tu imate domačo nalogo : skušajte ugotoviti, kateri izmed primitivnih javaskih tipov lahko nastopajo kot tip kontrolne spremenljivke pri zanki for !

 

Vsak izmed blokov glave zanke (razen pogoja za ponavljanje, ki mora biti logičnega tipa) je lahko sestavljen iz nič, enega ali večih stavkov. V primeru večih stavkov v posameznem bloku, so stavki (neobičajno) ločeni z vejico, kajti podpičja, ki po pravilu zaključujejo stavke v tem primeru ločujejo bloke kontrolnega dela zanke :

primer zanke s praznimi bloki (pazite, izvajanje take zanke lahko povzroči nemalo preglavic pri njeni zaustavitvi. Taka zanka izvaja nič stavkov v telesu in se izvaja v neskončnost. Ker je telo izredno kratko, jo boste težko nasilno prekinili s CTRL-C oz. BREAK oz. CTRL-Break):

for ( ; ; );

prazen pogoj pri taki zanki se smatra za izpolnjen pogoj ponavljanja.

Naslednji primer prikazuje uporabo večih stavkov znotraj blokov kontrolnega dela zanke. Postopek izračuna in izpiše vsoto števil od 1 do 33 :

int a,b;


for (a=1, b=33, vsota=0; a < b; vsota+=a+b, a++, b--);
    System.out.println(vsota);

 

Ponavljanja-vaje za utrjevanje

 

Vprašanje 1
Kateri izmed naštetih omogočajo ponavljanje stavkov ?
do-while
printf
for
while
if
   
Vprašanje 2
Katere izmed navedenih sintaks odgovarjajo while stavku v Java?
 
ponavljaj stavek, dokler ni pogoj izpolnjen
while Pogoj do Stavek;
while Pogoj Stavek;
while (Pogoj) Stavek;
   
Vprašanje 3
Čemu je namenjen stavek while (zanka) ?
Izberi najprimernejši odgovor.
vejitvi izvajanja programa v dve ali več vej
izpisu želene vrednosti
ponavljanju programskega stavka ali bloka stavkov
izbiri med dvema ali večimi možnostmi
   
Vprašanje 4
Katere razlike nastopajo med zankama while in do-while ?
v glavi zanke while je pogoj za ponavljanje, pri do-while pa je oklepaju pogoj za prekinitev ponavljanja.
neizpolnjen pogoj zanke while telo zanke izvrši natanko enkrat.
zanka while ima pogoj za ponavljanje po koncu, do-while pa pred telesom zanke.
obe zanki sta popolnoma enaki, uporabimo tisto, ki jo raje uporabljamo.
telo zanke do-while se vsaj enkrat izvrši, pri while to ni nujno.
   
Vprašanje 5
Sestavite pogoj, da se bo zanka while izvršila natanko 3 krat.


i=1;
while(>i) i=i+1;
 
Vprašanje 6
Katere izmed možnosti teoretično izpisujejo znak B v neskončnost ?
Izberi vse možnosti.
i=1;
while (i > 0){
  println("B"); 
  i+=1;
}
while (false)
   println("B");
while (true)
  println("B");
  i=1;
  while(i-- > 0)
    println("B");
   
Vprašanje 7
Telo naslednje zanke bi želeli izvesti 3x. Kaj smo storili narobe ?
while (i<3){
   System.out.println(i++);
}
Vrednost kontrolne spremenljivke se povečuje, namesto da bi se zmanjševala.
Vrednost kontrolne spremenljivke se ne spreminja.
Nismo inicializirali kontrolne spremenljivke.
Nič. Vse je prav.
   
Vprašanje 8
Kaj izpiše naslednji del programa ? (a)
int i=2,j=7;
while (i++ < j){
    System.out.println(i); 
j-=0.5;
}
345
34
3456
2345
   
Vprašanje 9
Kaj izpiše naslednji del programa ? (b)
int i=2; float j=7;
while (i < j){
   i++;
   System.out.println( i) ;
   j -= 0.5;
}
345
3456
2345
234
   
Vprašanje 10
Izberite tiste stavke, ki stavek S nikoli ne ponovijo in so sintaktično pravilni
while (true) S;
i=10;
while (i<=10){
 S;
 i++;
}
i=2;
for (;i<3;i++) S; 
i=0;
do {
  S;
} while(i<1);
for (i=0;++i<1;) S;
   
Vprašanje 11
Izberite vse bloke kode, ki izpišejo prvih 10 naravnih števil
for(i=1;i<10;i++) 
  System.out.print(i);
i=1;
while (i<11) 
  System.out.print(i++);
i=1;
while (i<10) 
  System.out.print(++i);
i=1;
do {
 System.out.print(i);
 i++;
} while (i<=10);
i=11;
do {
 System.out.print(++i - 11);
} while (i<21);
   
Vprašanje 12
Kaj izpiše naslednji blok kode ?

int j=1,i;
do{
i=1;
do {
System.out.print( i );
i++;
} while (i <= 3);
j+=1;
}while (j <= 3);

123
123234345
123
123
123
123123123
nič od predhodno naštetega
   
Vprašanje 13
Koliko vrstic izpisa je posledica izvajanja naslednje kode ?


for (int i=1; i<4; i++){
if (i%4==0)
System.out.println();
for(int j=1; j<4; j++)
System.out.print(j);
System.out.println();

}

5
4
3
2
1
   
Vprašanje 14
Povežite zanko z njenim številom izvajanj.
(več zank ima lahko enako število ponavljanj)
1 for (int i=2; i<4; i++);       A. 1
2 for (int i=0; i++<5; );       B. 2
3 int i=4, j=6; while ( i < j-- );       C. 9
4 for (int i=4, j=6; i < j; i++, j-- );       D. 5
  E. 0
  F. sintaktična napaka!
   
Vprašanje 15
Katera števila bi bilo potrebno vpisati v naznačena mesta, da bi se na zaslon izpisala vsa cela števila med 20 in 39 ?

for (int i=;i<4;i++)
for (int j=0;j<;j++)
System.out.println(i*10+j);

Rešite naslednje programske probleme

 

Prve štiri ( 4) naloge rešite izključno s stavkom while.

 

 

Naloga 1

Napišite javanski program, ki vrednost N na zaslon izpiše N-krat. N naj bo pri tem vhodni parameter programa. Izvedba programa s parametrom 6:

>java V4n1 6

666666

 

Naloga 2

Napišite javanski program, ki na zaslon izriše kvadrat vrednosti N s stranico N. Npr.:

>java V4n2 5

55555
55555
55555
55555
55555 

 

Naloga 3

Napišite javanski program ki na zaslon izriše podano obliko. Za boljšo ponazoritev sta podana dva izrisa:

>java V4n3 5 
54321
4321
321
21
1 
>java V4n3 3
321
21
1 

Naloga 4

Program naj razstavi s parametrom vneseno število na posamezne števke. Vsako števko podanega števila naj izpiše v drugi vrstici. Npr.:

>java V4n4 2319

2
3
1
9 

 

Naloga 5

Zgornje 4 primere rešite z uporabo stavka do-while.

 

Naloga 6

Naloge od 1 do 4 rešite z uporabo stavka for.