2. Naredbe selekcije

Podeli svoje utiske o poglavlju na anketi OVDE.

Preduslovi za rad:

Poznavanje osnovne strukture C programa i funkcija za rad sa standardnim ulazom/izlazom.

Naredbe selekcije omogućuju da kontrolišemo tok izvršavanja programa. Ukoliko želimo da se određeni deo koda ne izvršava uvek, već samo pod određenim uslovima, koristimo naredbe selekcije. Deo koda koji je uslovljen naredbom selekcije će se izvršiti samo ukoliko je postavljeni uslov ispunjen.

Napomena:

U programskom jeziku C se kao tačno podrazumeva sve što je različito od 0, dok je sve sto ima vrednost 0 netačno.

2.1. if-else iskaz

Osnovna forma if-else iskaza je:

if(izraz)
  naredba_1
else
  naredba_2

Ukoliko je izraz u zagradi tačan, izvršiće se naredba_1. Ako je izraz netačan, izvršiće se naredba_2.

Dat je primer programa gde imamo promenljivu x čija je vrednost 5 i promenljivu y čija je vrednost 3. U if-u proveravamo da li je x veće od y. Ako jeste, ispisaćemo X je veće, a ako nije ispisaćemo Y je veće:

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int x = 5, y = 3;
 6
 7    if(x > y)
 8        printf("X je vece\n");
 9    else
10        printf("Y je vece\n");
11
12    return 0;
13}

Ispis ovog programa je:

X je vece

Pitanje:

Šta će se desiti u slučaju da x i y imaju istu vrednost?

Ispis ovog programa kada su x i y iste vrednosti je (u kodu smo prethodno promenili da su vrednosti i x i y 3):

Y je vece

Napomena:

Izraz if(x = 2) će uvek biti tačan zato što u ovom slučaju promenljivoj x dodeljujemo vrednost 2 i to je uvek moguće i tačno.
Kada zelimo da poredimo bilo koje 2 vrednosti, potrebno je da koristimo == operator. izraz if(x == 2) će biti tačan samo onda
kada je vrednost promenljive x postavljena na 2 pre ove provere.
Ako želimo da proverimo da li je vrednost x različita od 2, koristićemo != operator.

2.2. if-else-if iskaz

U primeru iznad smo videli da nije pokriven slučaj kada x i y imaju istu vrednost. Da bismo pokrili i njega, potrebno je da proširimo if-else iskaz. Proširena forma je if-else-if iskaz:

if(izraz_1)
  naredba_1
else if(izraz_2)
  naredba_2
else if(izraz_3)
  naredba_3
  ...
else
  naredba_n

Ukoliko je izraz_1 tačan, izvršiće se naredba_1, ukoliko je izraz_2 tačan, izvršiće se naredba_2, ukoliko je izraz_3 tačan, izvršiće se naredba_3 itd. Kod ovog iskaza možemo imati neograničen broj provera. Ukoliko nijedan izraz nije tačan, izvršiće se naredba_n koja je u else delu iskaza.

Dat je primer programa gde imamo promenljivu x čija je vrednost 6 i promenljivu y čija je vrednost 6. U if-u proveravamo da li je x veće od y. Ako jeste, ispisaćemo X je veće. U else-if-u proveravamo da li su jednaki. Ako jesu, ispisaćemo Jednaki su. Ukoliko x nije veće i nisu jednaki, znamo da je sigurno y veće. Else iskaz će biti ispis Y je veće.

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int x = 6, y = 6;
 6
 7    if(x > y)
 8        printf("X je vece\n");
 9    else if(x == y)
10        printf("Jednaki su\n");
11    else
12        printf("Y je vece\n");
13
14    return 0;
15}

Ispis ovog programa je:

Jednaki su

Napomena:

U slučaju if-else, kao i if-else-if iskaza, uvek će se izvršiti samo jedna naredba. Ukoliko je neki izraz tačan,
izvršiće se samo naredba u okviru tog izraza. Ukoliko nijedan izraz nije tačan, izvršiće se naredba u okviru
else iskaza, ako je on prisutan.

Ukoliko je potrebno izvršiti više naredbi u okviru bilo kog od ovih iskaza (if, else-if, else) potrebno je sve naredbe smestiti u vitičaste zagrade {}. U suprotnom, kompajler će prijaviti grešku ukoliko je dodatna naredba napisana nakon if naredbe. Ako je dodatna naredba napisana nakon else, program će se uredno kompajlirati. Zbog toga, preporuka je stavljati vitičaste zagrade i u slučaju jedne naredbe.

Deo iskaza else nije obavezan i može da se desi da postoji if, kao i if else bez else iskaza, ali obrnuto ne važi.

Dat je primer gde imamo promenljivu godine i promenljivu plata, gde se od korisnika traži da unesu njihove vrednosti. Proveravamo za unete godine i platu kreditnu sposobnost:

  • Ukoliko je vrednost godina do 20 ili je plata do 70 000, moguće je podići kredit do 100 000

  • Ukoliko je vrednost godina do 50 ili je plata do 120 000, moguće je podići kredit do 180 000

  • Ukoliko je vrednost godina preko 50, ne može se podići kredit zbog starosne granice

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int godine, plata;
 6
 7    printf("Unesite godine: ");
 8    scanf("%d", &godine);
 9    printf("Unesite platu: ");
10    scanf("%d", &plata);
11
12    if(godine <= 20 || plata <= 70000)
13    {
14        printf("Moguce je podici kredit do 100000\n");
15    }
16    else if(godine <= 50 || plata <= 120000)
17    {
18        printf("Moguce je podici kredit do 180000\n");
19    }
20    else if(godine > 50)
21    {
22        printf("Ne moze se podici kredit zbog starosne granice\n");
23    }
24
25    return 0;
26}

Ispis ovog programa je:

Unesite godine: 25
Unesite platu: 50000
Moguce je podici kredit do 100000

U ovom primeru će uslov prvog if iskaza biti zadovoljen. Godine su 25 i uslov za godine za prvi if nije zadovoljen, ali kod ovog if iskaza mi imamo proveru 2 uslova gde nam je dovoljno da je samo jedan uslov tačan kako bi ceo izraz bio tačan. Drugi deo uslova kaže da plata mora biti manja manja od 70 000, što se uklapa sa zadatom vrednošću plate koja je 50 000, pa je zato ispis u ovom primeru Moguce je podici kredit do 100000.

Ispis ovog programa u slučaju kad je broj godina veći od 50:

Unesite godine: 55
Unesite platu: 130000
Ne moze se podici kredit zbog starosne granice

Pitanje:

Kako bismo ispravili ovaj program da onemogućimo korisniku da unese broj godina manji od 18?

Napomena:

U prethodnom primeru korišćen je logički operator "ILI", koji se u programskom jeziku C predstavlja preko ||.
Njegovo ponašanje isto je kao i kod matematičkog operatora, odnosno, ukoliko je jedan od operanada tačan,
izraz će biti logički tačan. Takođe, postoji i logički operator "I". On se navodi sa &&. Negacija se navodi kao !.

2.3. Ternarni operator

Funkcioniše isto kao if-else iskaz, zapisan u jednoj liniji. Osnovna forma je:

izraz ? naredba_1 : naredba_2

Ukoliko je izraz tačan, izvršiće se naredba_1. Ako je izraz netačan, izvršiće se naredba_2.

Dat je primer programa gde imamo promenljivu x čija je vrednost 3 i promenljivu y čija je vrednost 5. U izrazu proveravamo da li je x veće od y. Ispisaćemo veći od ta dva broja:

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int x = 3, y = 5, veci;
 6
 7    veci = x > y ? x : y;
 8
 9    printf("Veci je %d\n", veci);
10
11    return 0;
12}

Ispis ovog programa je:

Veci je 5

Napomena:

Ovaj primer je mogao biti urađen preko if-else iskaza. Ternarni operator pogodan je u situacijama kada postoji promenljiva
koja treba da dobije vrednost na osnovu nekog uslova. Da je ovo bilo napisano preko if-else, rešenje bi imalo barem 3 linije
više. Ternarni izraz je u tim situacijama koncizniji.

2.4. Switch iskaz

Switch iskaz proverava dati izraz i u zavisnosti od vrednosti izraza izvršava naredbe onog case bloka čija je vrednost jednaka vrednosti izraza. Ovaj iskaz je veoma sličan if-else-if iskazu i može se koristiti kao njegova zamena kada je potrebno porediti neku vrednost ili izraz sa više celobrojnih vrednosti. Osnovna forma je:

switch(izraz)
{
case vrednost_1:
  naredbe_1
case vrednost_2:
  naredbe_2
...
default:
  naredbe_n
}

Napomena:

Vrednost u ovom iskazu mora biti celobrojna (int ili char). Može postojati 1 ili više case iskaza. Vrednost svakog
case-a mora biti jedinstvena. default sekcija je opciona.

Napomena:

Na kraju svakog case-a, treba staviti naredbu break.
Ova naredba služi da se izađe iz switch-case iskaza kada se izvrši neki case. Ukoliko se naredba break ne stavi,
izvršavaće se naredbe u okviru preostalih case iskaza.

Dat je primer programa gde imamo promenljivu dan čiju vrednost korisnik unosi preko tastature (standardnog ulaza). U switch deo postavljamo promenljivu dan čiju ćemo vrednost proveravati. Ukoliko je vrednost promenljive dan 1, ispisaće se Ponedeljak, ukoliko je 2 Utorak, itd. Ukoliko vrednost promenljive nije između 1 i 7, neće se biti izabran nijedan case, već će se izvršiti sekcija default.

 1#include <stdio.h>
 2
 3int main()
 4{
 5    int dan;
 6
 7    printf("Uneti dan: ");
 8    scanf("%d", &dan);
 9
10    switch(dan) 
11    {
12    case 1:
13        printf("Ponedeljak\n");
14        break;
15    case 2:
16        printf("Utorak\n");
17        break;
18    case 3:
19        printf("Sreda\n");
20        break;
21    case 4:
22        printf("Cetvrtak\n");
23        break;
24    case 5:
25        printf("Petak\n");
26        break;
27    case 6:
28        printf("Subota\n");
29        break;
30    case 7:
31        printf("Nedelja\n");
32        break;
33    default:
34        printf("Vrednost dana moze biti izmedju 1 i 7");
35    }
36
37    return 0;
38}

Ispis ovog programa je:

Uneti dan: 3
Sreda

2.5. Proveri svoje znanje

## Koji će biti ispis sledećeg programa? ```c #include <stdio.h> int main() { int a = 3, b = 5, c = a / b; if(a > b) { printf("Kolo srece"); } else { printf("Ipak"); } if(c) { printf(" se okrece!\n"); } return 0; } ``` 1. [x] Ipak > ``a > b`` je netačno za zadate vrednosti 3 i 5, tako da će se ići u else i ispisati "Ipak". a / b će izvršiti celobrojno deljenje brojeva 3 i 5, pritom dajući rezultat 0, što se smatra logički netačnom vrednošću u programskom jeziku C. Zato neće biti dodatnog ispisa. 1. [ ] Kolo sreće se okrece > 3 nije manje od 5, stoga izraz u ``if`` naredbi neće biti zadovoljen. U tom slučaju, izvršiće se ``else`` naredba. Drugi deo ispisa se neće dogoditi zbog rezultata celobrojnog deljenja broja 3 i 5, što će dati rezultat 0, što je logički netačno. 1. [ ] Ipak se okrece > Iako je prvi deo odgovora tačan, drugi deo se neće ispisati usled celobrojnog deljenja broja 3 i 5, što će dati rezultat 0, što je logički netačno. 1. [ ] Ništa neće biti ispisano > Ovo ne može biti ni za jedan par vrednosti a i b tačno, jer imamo barem jednu if-else naredbu, gde se mora ispisati barem nešto. ## Koju vrednost će ispisati sledeći program za unete vrednosti 6 i 9? ```c #include <stdio.h> int main() { int vr, rez; printf("Unesite vrednost: "); scanf("%d", &vr); switch(vr) { case 10: rez = 95; break; case 9: rez = 85; break; case 8: rez = 75; break; case 7: rez = 65; break; case 6: rez = 55; default: rez = 45; } printf("Rezultat: %d\n", rez); return 0; } ``` 1. [x] 45 i 85 1. [ ] 55 i 85 > Fali ``break`` naredba kod ``case 6`` naredbe, izvršiće se i ``default`` naredba zbog toga. 1. [ ] 45 i 95 > 45 je tačno, ali 95 se neće ispisati, jer bi to bilo za slučaj da je uneta vrednost 10. 1. [ ] 45 i 45 > Prvo 45 je tačno, ali u slučaju vrednosti 9, neće se dobiti rezultat 45, zbog postojanja break naredbi. ## Koju vrednost će imati promenljiva rez na kraju programa? ```c #include <stdio.h> int main() { int a = 2, b = 4, rez; rez = a != 0 ? b : a; return 0; } ``` 1. [x] 4 > Pošto je ``a`` različito od 0 (ima vrednost 2), onda će se uzeti vrednost nakon ? i pre :, a to je vrednost promenljive b (4). 1. [ ] 2 1. [ ] 6 1. [ ] 8