3. Naredbe ciklusa

Podeli svoje utiske o poglavlju na anketi OVDE.

Ako je potrebno ponavljati jednu ili više naredbi koriste se ciklusi, tj. petlje. Broj ponavljanja može biti unapred poznat, ili određen nekim uslovom.

3.1. While ciklus

Osnovna forma while ciklusa je:

while(izraz)
{
  naredbe
}

Naredbe koje se nalaze u bloku ponavljaju se dok je izraz logički tačan. Ako se vrednosti promenljivih unutar izraza ne menjaju naredbama u bloku, može doći do "beskonačne petlje", koja će dovesti do toga da se program nikada ne izvrši do kraja.

Napomena:

U slučaju da program neće sam da se završi, moguće ga je prekinuti koristeći kombinaciju
tastera Ctrl+C.

Dat je primer programa gde korisnik unese deljenik i delilac čije deljenje je implementirano oduzimanjem. Od deljenika se oduzima delilac i uvećava količnik za jedan. Kada deljenik postane manji od delilaca, ostatak deljenja će se nalaziti u deljeniku, broj oduzimanja će predstavljati količnik:

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int p,q,r = 0;
 6
 7    printf("Unesite deljenik i delilac!\n");
 8    scanf("%d %d", &p, &q);
 9
10    while(p >= q) 
11    {
12        p -= q;
13        r++;
14    }
15    printf("kolicnik je %d, a ostatak %d\n", r, p);
16
17    return 0;
18}

Ako je deljenik manji od delioca, petlja se preskače jer uslov nije ispunjen pri ulasku u petlju, te će količnik biti 0. Ispis ovog programa je:

Unesite deljenik i delilac!
17 5
kolicnik je 3, a ostatak 2

3.2. For ciklus

Kada je unapred poznat broj iteracija (broj ponavljanja naredbi unutar bloka ciklusa), često je komotnije koristiti for ciklus, koji se zapisuje u obliku:

for (inicijalizacija; uslov; korak)
{
  naredbe
}

Za ciklus se vezuje promenljiva, koja služi da broji ponavljanja naredbi. Inicijalizacija je naredba kojom se definiše početna vrednost te promenljive pre ulaska u ciklus, korak definiše promenu te promenljive nakon svakog izvršenja naredbi, koje će se izvršavati dokle god je ispunjen uslov (odgovarajući izraz logički tačan). Ispod je dat primer petlje za ispisivanje svih cifara (brojeva od 0 do 9):

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int i;
 6    for(i = 0; i < 10; i++) 
 7    {
 8        printf("%d ", i);
 9    }
10    printf("\n");
11    
12    return 0;
13}
14

U datom primeru se deklariše nova promenljiva za kontrolu petlje i inicijalizuje na 0. Potom, kako je uslov ispunjen za vrednost promenljive 0, izvršava se funkcija printf. U sledećem ponavljanju, promenljiva se pomera za korak - kako je korak i++, uvećava se za jedan. Ispis se ponavlja sve dok promenljiva ne dostigne vrednost 10, kada uslov nije više ispunjen, i izlazi se iz petlje. Ispis ovog programa je:

0 1 2 3 4 5 6 7 8 9

Moguće je definisati proizvoljan korak. U sledećem primeru ispisuju se prvih n parnih brojeva:

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int i,n;
 6    printf("Koliko je brojeva potrebno ispisati?\n");
 7    scanf("%d", &n);
 8
 9    for(i = 2; i <= 2*n; i += 2) 
10    {
11        printf("%d ", i);
12    }
13    printf("\n");
14    
15    return 0;
16}
17

Početna vrednost promenljive je 2, i uvećava se za 2 sve dok je ispunjen uslov. Ispis programa je:

2 4 6 8 10

3.3. Do-while ciklus

Često je potrebno izvršiti bar jednom naredbe u while ciklusu. Za to se koristi do while, čija forma je:

do
{
  naredbe
} while(izraz);

Za razliku od ostalih ciklusa, do-while se završava sa ; Primena ove petlje je najčešće provera unosa. Ako je potrebno npr. osigurati da je uneti broj prirodan, to se može uraditi na sledeći način:

 1#include <stdio.h>
 2
 3int main() 
 4{
 5    int n;
 6
 7    do 
 8    {
 9        printf("Uneti prirodan broj: ");
10        scanf("%d", &n);
11    } while(n <= 0);
12
13    printf("Uspesno unet prirodan broj.\n");
14}
15

Kada se proverava unos, proverava se logički suprotan izraz željenom, u prethodnom primeru broj mora biti veći od 0 da bi bio prirodan, te se proverava da li je manji ili jednak 0, ako jeste ponavlja se unos. Primer pokretanja programa je:

Uneti prirodan broj: 0
Uneti prirodan broj: -1
Uneti prirodan broj: 1
Uspesno unet prirodan broj.

Dat je primer programa gde korisnik pogađa broj, koji je unapred postavljen u programu:

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int b, a = 2024;
 6
 7    printf("Pogodi broj!\n");
 8    do 
 9    {
10        scanf("%d", &b);
11        if (a > b) 
12        {
13            printf("Pokusaj ponovo, trazeni broj je veci od unetog!\n");
14        } 
15        else if (a < b)
16        {
17            printf("Pokusaj ponovo, trazeni broj je manji od unetog!\n");
18        }
19    } while(a != b);
20
21    printf("Cestitam! Trazeni broj je %d.\n", a);
22    return 0;
23}

Ciklus se, u slučaju da je korisnik odmah pogodio, preskače. Ako je uneti broj različit od traženog, ispisuje se poruka i poredi uneti broj sa traženim. Korisnik ponovo unosi broj, sve dok ne pogodi traženi, čime će uslov:

a != b

postati netačan, te će program izaći iz ciklusa. Primer ispisa programa za unete brojeve 1000, 3000 pa 2024 je:

Pogodi broj!
1000
Pokusaj ponovo, trazeni broj je veci od unetog!
3000
Pokusaj ponovo, trazeni broj je manji od unetog!
2024
Cestitam! Trazeni broj je 2024.

U programu je korišćen do while ciklus jer nije unapred poznato koliko puta će korisnik promašiti broj.

3.4. Break i continue

Za kontrolu petlji postoje dve naredbe, break i continue. Break uzrokuje da program odmah izađe iz ciklusa, dok continue naredbom prelazi se na sledeću iteraciju.

Primer koji sadrži obe naredbe:

 1#include <stdio.h>
 2
 3int main() 
 4{
 5    for(int i = 0; i < 10; i++) 
 6    {
 7        if (i == 2 || i == 4) 
 8        {
 9            continue;
10        }
11        if (i == 7) 
12        {
13            break;
14        }
15        printf("%d ", i);
16    }
17
18    printf("\n");
19    return 0;
20}
21

U iteracijama gde je vrednost promenljive 2 ili 4, preskače se ispis jer se continue izvrši pre ispisa, dok se u iteraciji gde je vrednost promenljive 7 izlazi se iz petlje. Ispis programa je tada:

0 1 3 5 6

3.5. Proveri svoje znanje

## Razlika između naredbi selekcije i naredbi ciklusa je? 1. [x] Kod naredbi selekcije će biti izabran deo koda koji će se izvršiti, dok naredbe ciklusa imaju mogućnost izvršavanja određenog koda više puta 1. [ ] Naredbe selekcije biraju kod koji se izvršava, dok naredbe ciklusa ne utiču na redosled naredbi tokom izvršavanja programa 1. [ ] Naredbe ciklusa biraju kod koji se izvršava, dok naredbe selekcije izvršavaju određeni kod više puta 1. [ ] Razlika je isključivo u korišćenim ključnim rečima, u ponašanju nema znatnih razlika ## Kako bi glasila naredba u programskom jeziku C "dok je vrednost a veća od 0 i vrednost suma je manja od 50"? 1. [x] ``while (a > 0 && suma < 50)`` > while -> "dok", a > 0 -> "vrednost a veća od 0", && -> logičko "I", suma < 50 -> "suma je manja od 50" 1. [ ] ``if (a > 0 && suma < 50)`` > Iako je sintaksno tačno, ne zadovoljava rečenicu jer ona ukazuje na potrebno ponavljanje u naredbi. 1. [ ] ``for (a = 0; a > 0 || suma < 50; a++)`` > Ova naredba nije dobra iz više razloga. Prvi je zato što a počinje od 0, što znači da odmah ne bi bila tačna i ciklus se ne bi nijednom izvršio, da je ostatak napisan kako treba. Drugi problem je što je napisano logičko "ILI" umesto "I" u izrazu. 1. [ ] ``switch (a > 0 && suma < 50)`` > Sintaksno nije tačno, izraz u switch naredbi mora biti konstantan. Switch takođe nije naredba ciklusa, nego selekcije. ## Koja će biti vrednost promenljive broj ako je početna 16, odnosno 12? ```c #include <stdio.h> int main() { int broj; printf("Unesite broj: "); scanf("%d", &broj); while(broj / 2 != 0) { if(broj % 3 == 0) { break; } broj /= 2; } printf("Broj%d\n", broj); return 0; } ``` 1. [x] ``1 i 12`` > Za broj 16, ``while`` ciklus će se izvršavati dokle god je deljivo sa 2 (8, 4, 2), a za 12 će odmah ispasti iz ``while`` ciklusa, jer je deljivo sa 3 1. [ ] ``16 i 12`` 1. [ ] ``1 i 1`` 1. [ ] ``1 i 6`` ## Koji izraz je potrebno da do-while naredba sadrži kako bi korisnik morao isključivo da unese neparan broj deljiv sa 7? ```c #include <stdio.h> int main() { int broj; do { printf("Unesite broj: "); scanf("%d", &broj); } while(<izraz>); return 0; } ``` 1. [x] ``broj % 2 == 0 || broj % 7 != 0`` 1. [ ] ``broj % 2 == 0 && broj % 7 != 0`` > Ovaj izraz će pustiti korisnika za svaki neparan broj koji nije deljiv sa 7 (3, 5, 9 itd.), što ne bi smelo da se desi. 1. [ ] ``broj % 2 != 0 && broj % 7 == 0`` > Ovaj izraz će vratiti korisnika za brojeve 14, 28 itd, odnosno parne deljive sa 7, ali će pustiti za 7 i 21 itd, odnosno neparne deljive sa 7, jer će u tom slučaju izraz biti logički netačan. 1. [ ] ``broj % 2 != 0 || broj % 7 != 0`` > Ovaj izraz će pustiti korisnika ukoliko je broj paran i deljiv sa 7, što nije ono što je traženo.