Materijali/Čas 04

Čas 04 · else if, logički operatori i switch

Više uslova i više mogućih putanja

Program sada može da razlikuje više od dva slučaja. Gradimo else-if lanac, spajamo uslove operatorima &&, || i !, proveravamo neispravan ulaz i koristimo switch kada biramo između tačno određenih vrednosti.

MAPA ČASA

Ulaz → provera podataka → prvi tačan uslov → jedna grana → rezultat

1
ulaz
2
provera
3
uslovi redom
4
prva tačna grana
5
rezultat

Na kraju je dovoljno da:

  • Napiši else-if lanac u kojem se izvršava samo prva tačna grana.
  • Sastavi opseg pomoću && i više dozvoljenih slučajeva pomoću ||.
  • Proveri da li je ulaz ispravan pre nego što ga razvrstaš.
  • Izaberi između if/else-if i switch grananja prema vrsti problema.
  • Nacrtaj dijagram toka sa više odluka i prevedi ga u C program.

01 · KORAK

else if dodaje treću i naredne putanje

if/else razdvaja program na dva slučaja. Kada problem ima tri ili više međusobno isključivih ishoda, između početnog if-a i završnog else-a dodajemo jednu ili više else if grana.

Uslovi se proveravaju odozgo nadole. Čim je jedan uslov tačan, njegova grana se izvršava, a sve preostale grane istog lanca se preskaču.

if (temperatura < 0) {
    printf("Ispod nule\n");
} else if (temperatura <= 20) {
    printf("Od 0 do 20\n");
} else {
    printf("Iznad 20\n");
}
Prati ceo lanacZa -4, 0, 20 i 21 zapiši koji se uslovi proveravaju i gde se lanac zaustavlja. Posebno proveri obe granice.
Samo jedna granaelse-if lanac nije isto što i više nezavisnih if naredbi. U lancu se izvršava najviše jedna grana; kod nezavisnih if naredbi može da se izvrši više tela.

02 · KORAK

Redosled uslova je deo algoritma

Kada se opsezi preklapaju, na vrh stavljamo posebniji ili stroži slučaj. Na primer, kod ocena prvo proveravamo najviši prag, zatim sledeći, sve do završnog else-a.

Ako prvo proverimo poeni >= 51, tada će i 95 zadovoljiti prvi uslov i program nikada neće stići do grane za najvišu ocenu.

if (poeni >= 91) {
    ocena = 10;
} else if (poeni >= 81) {
    ocena = 9;
} else if (poeni >= 71) {
    ocena = 8;
} else if (poeni >= 61) {
    ocena = 7;
} else if (poeni >= 51) {
    ocena = 6;
} else {
    ocena = 5;
}
Dokaži redosled testomPrati program za 50, 51, 71, 81 i 95. Zatim zamisli da je uslov poeni >= 51 prvi i objasni koji bi rezultat dobio ulaz 95.
Ne mora svaki opseg da ima dve graniceU dobro poređanom lancu prethodne netačne provere već su isključile više opsege. Kada stignemo do poeni >= 71, već znamo da poeni nisu 81 ili više.

03 · KORAK

Operator && zahteva da oba dela budu tačna

Uslov x >= 10 && x <= 20 proverava da li je x istovremeno najmanje 10 i najviše 20. To je zatvoren interval od 10 do 20.

Svaki deo složenog uslova napiši kao potpuno poređenje. Matematički zapis 10 <= x <= 20 nije ispravan način provere opsega u C-u.

if (x >= 10 && x <= 20) {
    printf("U opsegu\n");
}
Promeni granice namernoNapiši uslove za otvoren interval (10, 20), poluotvoren interval [10, 20) i vrednosti izvan zatvorenog intervala [10, 20].
Čitaj && kao „i“Za ceo uslov sa && dovoljan je jedan netačan deo da rezultat bude netačan. Zato testiraj obe granice i po jedan podatak izvan njih.

04 · KORAK

Operator || prihvata bar jedan slučaj, a ! menja odgovor

Uslov dan == 6 || dan == 7 tačan je za subotu ili nedelju. Kod || je dovoljno da jedan deo bude tačan.

Operator ! menja tačno u netačno i netačno u tačno. Koristan je kada je negativan oblik jasniji, ali često je čitljivije direktno napisati suprotan operator poređenja, na primer broj != 0.

if (dan == 6 || dan == 7) {
    printf("Vikend\n");
}

if (!(broj >= 1 && broj <= 9)) {
    printf("Nije jednocifren pozitivan broj\n");
}
Napiši bez dvosmislenostiNapiši uslov za broj deljiv sa 3 ili sa 5, zatim uslov za broj koji nije u intervalu od 1 do 100.
Pazi na svako poređenjeNe pišemo dan == 6 || 7. Desna strana operatora || mora da bude novi uslov: dan == 7.

05 · KORAK

Neispravan ulaz proveravamo pre razvrstavanja

Ako su dozvoljeni poeni od 0 do 100, program najpre odbacuje vrednosti izvan tog opsega. Tek zatim određuje rezultat za ispravan podatak.

Prva grana čuva ostatak programa od besmislenog podatka. Zbog toga su testovi -1, 0, 100 i 101 važniji od nekoliko nasumičnih vrednosti iz sredine.

if (poeni < 0 || poeni > 100) {
    printf("Neispravan unos\n");
} else if (poeni >= 51) {
    printf("Polozen\n");
} else {
    printf("Nije polozen\n");
}
Razdvoji proveru i klasifikacijuProširi program tako da za ispravan ulaz određuje ocenu 5–10. Neispravan ulaz ne sme da dobije ocenu.
Granice imaju dva poslaKod programa sa validacijom proveravaš granice dozvoljenog ulaza i granice između kategorija. To nisu isti testovi.

06 · KORAK

Uslov unutar grane rešava odluku u dva koraka

Neke odluke prirodno imaju redosled. Najpre proverimo da li je korisničko ime tačno, pa tek unutar te grane proverimo PIN. To je ugnježdeni if.

Ako su obe provere ravnopravne i vode istom ishodu, možemo ih spojiti sa &&. Ako želimo različitu poruku za svaku grešku, ugnježdeno grananje čuva više informacija.

if (korisnik == 17) {
    if (pin == 2468) {
        printf("Pristup odobren\n");
    } else {
        printf("Pogresan PIN\n");
    }
} else {
    printf("Nepoznat korisnik\n");
}
Uporedi dva rešenjaNapiši verziju sa jednim uslovom korisnik == 17 && pin == 2468. Objasni koju informaciju ta kraća verzija više ne može da prikaže.
Uvlačenje pokazuje pripadnostUnutrašnji else pripada najbližem if-u. Vitičaste zagrade i dosledno uvlačenje uklanjaju sumnju.

07 · KORAK

switch bira prema jednoj tačnoj vrednosti

switch je pregledan kada jednu promenljivu poredimo sa tačno određenim celobrojnim vrednostima, na primer brojem opcije u meniju. Nije namenjen opsezima kao što je poeni >= 51.

case označava jednu vrednost, break završava izabranu granu, a default obrađuje sve vrednosti koje nisu navedene. Bez break-a izvršavanje nastavlja u sledeći case.

switch (opcija) {
    case 1:
        printf("Stanje\n");
        break;
    case 2:
        printf("Uplata\n");
        break;
    case 3:
        printf("Isplata\n");
        break;
    default:
        printf("Nepoznata opcija\n");
}
Prati bez i sa break-omOdredi ispis za opcije 2 i 8. Zatim ukloni break iz case 2 i objasni šta bi se dodatno izvršilo za opciju 2.
Više case oznaka može deliti kodKod meseci, case 4, case 6, case 9 i case 11 mogu da vode do istog ispisa za 30 dana, uz jedan break posle zajedničkog koda.

08 · KORAK

Složeno grananje proveravamo sistematski

Najpre pročitaj svako poređenje, zatim način povezivanja uslova, pa redosled grana. Kod switch-a proveri vrednosti case oznaka, break i default.

Česte greške su obrnut redosled else-if pragova, && umesto ||, nepotpuno drugo poređenje, zapis a < x < b i izostavljen break.

if (0 <= poeni <= 100) {
    if (poeni >= 51 && prisustvo >= 75) {
        printf("Ispunjen uslov\n");
    }
}
Popravi ideju, ne samo znakPrepiši proveru opsega u ispravnom C obliku. Zatim napiši testove koji posebno proveravaju donju granicu, gornju granicu i uslov prisustva.
Jedan uspešan test nije dokazProgram sa više uslova mora da se proveri tako da svaki deo složenog uslova bar jednom bude razlog za prolaz i bar jednom razlog za odbijanje.

09 · KORAK

Vežbaonica proširuje iste obrasce na nove probleme

Zadaci Časa 04 uključuju validaciju, opsege, prestupnu godinu, trougao, najveći od tri broja i switch sa mesecima. Rešenje prvo napiši na papiru, pa ga unesi na sajt samo radi provere.

Nisu svi zadaci istog tipa. Pre koda odluči da li problem traži else-if lanac, više nezavisnih provera, ugnježdeni if ili switch.

Rad na časuNa času uradi zadatke 1, 5 i 8. Ako ostane vremena, pređi na zadatak 10. Posle časa završi sve zadatke Časa 04 koje nisi uradila.
Najpre odredi putanjePre pisanja C sintakse nabroj moguće ishode i napiši uslov koji vodi do svakog od njih. Tako se lakše vidi da li neki slučaj nedostaje ili se dve grane preklapaju.

ZATVARANJE

Završna provera bez gledanja

  1. Zašto redosled else-if uslova može da promeni rezultat?
  2. Kako zapisuješ da x pripada zatvorenom intervalu od 10 do 20?
  3. Kada koristiš &&, a kada ||?
  4. Zašto zapis 0 <= x <= 100 ne proverava opseg u C-u?
  5. Kada je switch prirodniji od else-if lanca i čemu služe break i default?
  6. Kako biraš probne ulaze za program sa više granica?