Više o Roster Softu
Sve usluge
Sva gotova rešenja
Svi članci

30. switch-case u C++ — izbor između više mogućnosti

U prethodnim lekcijama našeg serijala „Mala škola programiranja — C++“ naučili smo kako program donosi odluke pomoću naredbi if, if-else i else if. Videli smo da pomoću ovih naredbi možemo proveravati različite uslove, upoređivati brojeve, određivati ocene, obračunavati popuste i upravljati tokom izvršavanja programa. Međutim, zamislimo da pravimo aplikaciju sa glavnim menijem u kome korisnik […]

Mala škola C++Lekcija 30 od 30
U prethodnim lekcijama našeg serijala „Mala škola programiranja — C++“ naučili smo kako program donosi odluke pomoću naredbi if, if-else i else if. Videli smo da pomoću ovih naredbi možemo proveravati različite uslove, upoređivati brojeve, određivati ocene, obračunavati popuste i upravljati tokom izvršavanja programa. Međutim, zamislimo da pravimo aplikaciju sa glavnim menijem u kome korisnik bira jednu od nekoliko ponuđenih opcija:
===== GLAVNI MENI =====
1. Dodavanje korisnika
2. Pregled korisnika
3. Izmena podataka
4. Brisanje korisnika
0. Izlaz

Izaberite opciju:
Ovakav program mogli bismo napisati pomoću više else if uslova. Ipak, C++ nudi još jedan način za rešavanje sličnih problema — naredbu switch. Naredba switch posebno je korisna kada želimo da proverimo vrednost jednog izraza i na osnovu nje izaberemo odgovarajuću granu programa. Koristi se u kalkulatorima, konzolnim menijima, igrama, programima za upravljanje uređajima, obradi korisničkih komandi i brojnim poslovnim aplikacijama. U ovoj lekciji detaljno ćemo naučiti kako funkcioniše switch-case, čemu služe ključne reči case, break i default, koje tipove podataka možemo koristiti i kada je bolje izabrati switch, a kada if-else. Obradićemo i jednu od najvažnijih osobina ove naredbe — fall-through, odnosno nastavljanje izvršavanja kroz naredne grane kada izostavimo break. Na kraju ćemo napraviti funkcionalan kalkulator i mali konzolni sistem sa menijem, a zatim proveriti znanje kroz fakultetske zadatke i mini-test.

Šta ćemo naučiti u ovoj lekciji?

Nakon završetka lekcije znaćete da:
  • Objasnite šta predstavlja naredba switch.
  • Razumete razliku između switch i if-else strukture.
  • Pravilno koristite ključne reči switch, case, break i default.
  • Napišete program koji bira između više ponuđenih opcija.
  • Razumete kako funkcioniše fall-through.
  • Grupišete više case oznaka za istu operaciju.
  • Koristite switch sa celim brojevima, karakterima i enumeracijama.
  • Razumete zašto switch ne prihvata direktno double i std::string.
  • Koristite ugnježdene switch strukture.
  • Izbegnete česte sintaksne i logičke greške.
  • Rešavate tipične fakultetske zadatke.
  • Napravite praktičan program sa korisničkim menijem.

1. Šta je switch naredba?

Naredba switch predstavlja kontrolnu strukturu koja omogućava izbor između više različitih grana programa na osnovu vrednosti jednog izraza. Naziv switch možemo razumeti kao „prebacivanje“ ili „izbor“. Osnovna ideja je: Proveri vrednost izraza i izvrši odgovarajuću grupu naredbi. Na primer, korisnik unosi broj dana u nedelji. Ako unese 1, program prikazuje ponedeljak. Ako unese 2, prikazuje utorak. Ako unese 3, prikazuje sredu. I tako dalje. Primer:
switch (dan) {
    case 1:
        cout << "Ponedeljak";
        break;

    case 2:
        cout << "Utorak";
        break;

    case 3:
        cout << "Sreda";
        break;

    default:
        cout << "Nepoznat dan";
}
Ako promenljiva dan ima vrednost 2, izvršavanje počinje od grane:
case 2:
Program ispisuje:
Utorak
Naredba break zatim prekida izvršavanje switch strukture. Ako nijedna case oznaka ne odgovara vrednosti izraza, izvršavanje može preći na granu default.
Dijagram izbora jedne od više switch-case grana

2. Osnovna sintaksa switch-case strukture

Opšti oblik naredbe:
switch (izraz) {
    case vrednost1:
        // Naredbe za prvu vrednost
        break;

    case vrednost2:
        // Naredbe za drugu vrednost
        break;

    case vrednost3:
        // Naredbe za trecu vrednost
        break;

    default:
        // Naredbe kada nijedna
        // vrednost ne odgovara
}
Pogledajmo pojedinačne elemente.
Element Značenje
switch Ključna reč za višestruki izbor
(izraz) Izraz čija se vrednost proverava
case Oznaka određene vrednosti
: Razdvaja oznaku case od naredbi
break Prekida izvršavanje switch strukture
default Grana koja se bira ako nema odgovarajućeg case
{ } Telo switch strukture
Za razliku od if naredbe, koja proverava logički uslov, switch prvenstveno bira odgovarajuću granu na osnovu vrednosti izraza.

Prvi kompletan program

#include <iostream>
using namespace std;

int main() {
    int opcija;

    cout << "Izaberite opciju (1-3): ";
    cin >> opcija;

    switch (opcija) {
        case 1:
            cout << "Izabrali ste opciju 1.";
            break;

        case 2:
            cout << "Izabrali ste opciju 2.";
            break;

        case 3:
            cout << "Izabrali ste opciju 3.";
            break;

        default:
            cout << "Nepostojeca opcija.";
    }

    return 0;
}
Primer izvršavanja:
Izaberite opciju (1-3): 2
Izabrali ste opciju 2.
Ako korisnik unese 8:
Izaberite opciju (1-3): 8
Nepostojeca opcija.
Ovo je osnovni obrazac koji ćemo koristiti u većini narednih primera.

3. Kako računar izvršava switch?

Posmatrajmo sledeći program:
#include <iostream>
using namespace std;

int main() {
    int broj = 3;

    switch (broj) {
        case 1:
            cout << "Jedan";
            break;

        case 2:
            cout << "Dva";
            break;

        case 3:
            cout << "Tri";
            break;

        default:
            cout << "Nepoznat broj";
    }

    cout << "nKraj programa.";

    return 0;
}
Rezultat:
Tri
Kraj programa.

Korak po korak

Prvi korak: Program definiše promenljivu broj i dodeljuje joj vrednost 3. Drugi korak: Izračunava se izraz unutar switch zagrada. Treći korak: Program pronalazi odgovarajuću oznaku:
case 3:
Četvrti korak: Izvršava se naredba:
cout << "Tri";
Peti korak: Naredba break prekida izvršavanje switch strukture. Šesti korak: Program nastavlja od naredbe nakon zatvaranja switch bloka. Zato se ispisuje i:
Kraj programa.
Važno je razumeti da break u ovom primeru ne završava ceo program. On prekida samo najbližu odgovarajuću strukturu koju može da prekine, ovde switch.
Tok izvršavanja case 3 i naredbe break u C++

4. Ključna reč case

Ključna reč case predstavlja oznaku određene vrednosti. Na primer:
case 1:
znači da izvršavanje može započeti na toj oznaci kada vrednost izraza odgovara broju 1. Iza oznake pišemo naredbe koje želimo da izvršimo.
case 1:
    cout << "Prva opcija";
    break;

Važno pravilo

Vrednosti navedene uz case moraju biti odgovarajući konstantni izrazi koji se mogu izračunati tokom kompajliranja. Dozvoljeno:
case 1:
case 10:
case 'A':
Možemo koristiti i imenovane konstante:
constexpr int DODAVANJE = 1;

switch (opcija) {
    case DODAVANJE:
        cout << "Dodavanje";
        break;
}
Nije dozvoljeno koristiti običnu promenljivu čija vrednost nije poznata tokom kompajliranja kao oznaku case. Pogrešno:
int x = 5;

switch (broj) {
    case x:
        cout << "Pet";
        break;
}
U ovom obliku x nije konstantni izraz.

Jedinstvenost vrednosti

Dve case oznake u istoj switch strukturi ne smeju imati istu vrednost nakon odgovarajućih konverzija. Pogrešno:
switch (broj) {
    case 1:
        cout << "A";
        break;

    case 1:
        cout << "B";
        break;
}
Kompajler će prijaviti grešku zbog duplirane oznake.

5. Ključna reč break

Jedna od najvažnijih stvari koje početnik treba da nauči jeste pravilna upotreba naredbe break. Ona omogućava izlazak iz switch strukture. Pogledajmo:
switch (opcija) {
    case 1:
        cout << "Dodavanje";
        break;

    case 2:
        cout << "Brisanje";
        break;
}
Ako je opcija jednaka 1, program ispisuje „Dodavanje“, a zatim napušta switch.

Šta ako izostavimo break?

Pogledajmo sledeći primer:
#include <iostream>
using namespace std;

int main() {
    int broj = 2;

    switch (broj) {
        case 1:
            cout << "A";

        case 2:
            cout << "B";

        case 3:
            cout << "C";

        default:
            cout << "D";
    }

    return 0;
}
Šta će program ispisati? Rezultat:
BCD
Zašto? Program pronalazi oznaku case 2 i odatle započinje izvršavanje. Pošto nema break, nastavlja kroz naredbe koje slede, uključujući naredbe ispod case 3 i default. Ovakvo ponašanje naziva se fall-through.

Šta je fall-through?

Fall-through označava nastavak izvršavanja kroz naredne case oznake, bez automatskog prekidanja nakon završetka jedne grane. To nije nužno greška. Ponekad se koristi namerno, ali ako želimo da se izvrši samo određena grana, najčešće ćemo koristiti break.

Primer sa break

#include <iostream>
using namespace std;

int main() {
    int broj = 2;

    switch (broj) {
        case 1:
            cout << "A";
            break;

        case 2:
            cout << "B";
            break;

        case 3:
            cout << "C";
            break;

        default:
            cout << "D";
    }

    return 0;
}
Rezultat:
B
Poređenje switch-case strukture sa break i bez break naredbe

6. Interaktivni simulator — kako break menja rezultat?

Pomoću sledećeg primera možete proveriti razliku između switch strukture sa break naredbama i one bez njih.
Koristi break nakon svake case grane
Primer kodaswitch (broj) { case 1: cout << „A“; break; case 2: cout << „B“; break; case 3: cout << „C“; break; default: cout << „D“; }
Rezultat izvršavanja

B

Izvršava se odgovarajuća grana, a break prekida switch.

7. Ključna reč default

Grana default predstavlja podrazumevani slučaj. Izvršavanje započinje od nje kada vrednost izraza ne odgovara nijednoj case oznaci. Na primer:
switch (opcija) {
    case 1:
        cout << "Dodavanje";
        break;

    case 2:
        cout << "Izmena";
        break;

    default:
        cout << "Nepoznata opcija";
}
Ako korisnik unese 5, ispisuje se:
Nepoznata opcija

Da li je default obavezan?

Nije. Sledeći kod je ispravan:
switch (broj) {
    case 1:
        cout << "Jedan";
        break;

    case 2:
        cout << "Dva";
        break;
}
Ako broj nije 1 ili 2, nijedna grana neće biti izvršena. Ipak, u programima sa korisničkim menijima preporučuje se upotreba default grane radi obrade nepoznatih opcija.

Da li default mora biti poslednji?

Ne mora. Međutim, najčešće se postavlja na kraj zbog preglednosti. Ako se nalazi pre drugih oznaka, potrebno je voditi računa o fall-through ponašanju. Zato ćemo u našim primerima koristiti default na kraju, osim kada posebno objašnjavamo drugačije ponašanje.

8. Grupisanje više case oznaka

Ponekad više različitih vrednosti treba da pokrene istu operaciju. Na primer, želimo da odredimo da li je uneti dan radni dan ili vikend. Možemo napisati:
#include <iostream>
using namespace std;

int main() {
    int dan;

    cout << "Unesite dan (1-7): ";
    cin >> dan;

    switch (dan) {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
            cout << "Radni dan.";
            break;

        case 6:
        case 7:
            cout << "Vikend.";
            break;

        default:
            cout << "Nepostojeci dan.";
    }

    return 0;
}
Primer:
Unesite dan (1-7): 6
Vikend.

Kako ovo funkcioniše?

Ako je dan jednak 3, izvršavanje počinje na:
case 3:
Ispod te oznake nema posebnih naredbi. Program nastavlja kroz naredne oznake do zajedničke naredbe:
cout << "Radni dan.";
Zatim break prekida switch. Ovo je primer namernog i korisnog fall-through ponašanja.

Kada koristiti grupisanje?

Kada više različitih vrednosti treba da izazove potpuno istu reakciju. Na primer:
  • Više opcija koje pripadaju istoj kategoriji.
  • Više karaktera koji predstavljaju istu komandu.
  • Dani u nedelji.
  • Meseci sa istim brojem dana.
  • Različiti statusni kodovi koji zahtevaju istu obradu.

9. Koje tipove podataka možemo koristiti u switch naredbi?

Ovo je veoma važno pitanje koje se često pojavljuje na fakultetskim ispitima. Izraz unutar switch mora imati odgovarajući celobrojni ili enumeracioni tip. Tipični primeri:
Tip Može u switch?
int Da
char Da
short Da
long Da
bool Da
enum Da
double Ne
float Ne
std::string Ne

Primer sa char

#include <iostream>
using namespace std;

int main() {
    char slovo;

    cout << "Unesite slovo A, B ili C: ";
    cin >> slovo;

    switch (slovo) {
        case 'A':
            cout << "Izabrano je A.";
            break;

        case 'B':
            cout << "Izabrano je B.";
            break;

        case 'C':
            cout << "Izabrano je C.";
            break;

        default:
            cout << "Nepoznato slovo.";
    }

    return 0;
}

Važno: velika i mala slova

Karakteri 'A' i 'a' nisu jednaki. Ako želimo da prihvatimo oba oblika, možemo grupisati oznake:
switch (slovo) {
    case 'A':
    case 'a':
        cout << "Uneli ste slovo A.";
        break;

    case 'B':
    case 'b':
        cout << "Uneli ste slovo B.";
        break;

    default:
        cout << "Nepoznato slovo.";
}

Zašto ne možemo koristiti double?

Vrednosti tipa double predstavljaju brojeve sa pokretnim zarezom, a switch ne podržava direktno grananje prema takvom tipu izraza. Pogrešno:
double broj = 2.5;

switch (broj) {
    case 2:
        cout << "Dva";
        break;
}
Kompajler će prijaviti grešku. Za poređenje decimalnih vrednosti koristimo druge pristupe, najčešće odgovarajuće if-else uslove.

Zašto ne možemo direktno koristiti string?

Pogrešno:
#include <string>
using namespace std;

string komanda = "start";

switch (komanda) {
    case "start":
        break;
}
Standardni C++ ne dozvoljava ovakav switch. Za poređenje tekstualnih vrednosti možemo koristiti if-else:
if (komanda == "start") {
    cout << "Pokretanje";
} else if (komanda == "stop") {
    cout << "Zaustavljanje";
} else {
    cout << "Nepoznata komanda";
}
Podržani i nepodržani tipovi podataka u switch naredbi

10. switch ili if-else — šta je bolje?

Obe strukture omogućavaju grananje programa, ali nisu potpuno iste.

if-else je pogodniji kada:

  • Proveravamo intervale.
  • Koristimo složene logičke izraze.
  • Poredimo različite promenljive.
  • Proveravamo decimalne vrednosti.
  • Donosimo odluke na osnovu više nezavisnih kriterijuma.
Primer:
if (poeni >= 91) {
    cout << "Ocena 10";
} else if (poeni >= 81) {
    cout << "Ocena 9";
} else {
    cout << "Niza ocena";
}

switch je pogodan kada:

  • Biramo između više konkretnih celobrojnih vrednosti.
  • Obrađujemo opcije korisničkog menija.
  • Proveravamo pojedinačne karaktere.
  • Obrađujemo enumeracije.
  • Više vrednosti treba da pokrene istu operaciju.
Primer:
switch (opcija) {
    case 1:
        cout << "Dodavanje";
        break;

    case 2:
        cout << "Izmena";
        break;

    case 3:
        cout << "Brisanje";
        break;

    default:
        cout << "Nepoznata opcija";
}

Uporedna tabela

Osobina if-else switch
Provera konkretne vrednosti Da Da
Provera intervala Da Ne direktno
Logički operatori u uslovu Da Ne na isti način
Podrška za double poređenja Da Ne direktno
Direktno poređenje string vrednosti Da Ne
Obrada menija sa numeričkim opcijama Da Da, često preglednije
Grupisanje više vrednosti Pomoću logičkih izraza Pomoću više case oznaka
Potreban break za sprečavanje fall-through Ne Obično da

Da li je switch uvek brži?

Ne postoji univerzalno pravilo. Kompajler može optimizovati i switch i if-else na različite načine. Za mali broj opcija razlika u brzini često nije značajna. Zato je za početnike važnije da izaberu konstrukciju koja najjasnije izražava logiku programa.

11. Tipični fakultetski zadaci

Zadatak 1 — naziv dana u nedelji

Napisati program koji učitava broj od 1 do 7 i ispisuje odgovarajući naziv dana.
#include <iostream>
using namespace std;

int main() {
    int dan;

    cout << "Unesite broj dana (1-7): ";
    cin >> dan;

    switch (dan) {
        case 1:
            cout << "Ponedeljak";
            break;

        case 2:
            cout << "Utorak";
            break;

        case 3:
            cout << "Sreda";
            break;

        case 4:
            cout << "Cetvrtak";
            break;

        case 5:
            cout << "Petak";
            break;

        case 6:
            cout << "Subota";
            break;

        case 7:
            cout << "Nedelja";
            break;

        default:
            cout << "Neispravan broj dana";
    }

    return 0;
}
Primer:
Unesite broj dana (1-7): 4
Cetvrtak

Zadatak 2 — naziv meseca

Napisati program koji na osnovu broja od 1 do 12 ispisuje naziv meseca.
#include <iostream>
using namespace std;

int main() {
    int mesec;

    cout << "Unesite broj meseca: ";
    cin >> mesec;

    switch (mesec) {
        case 1:
            cout << "Januar";
            break;

        case 2:
            cout << "Februar";
            break;

        case 3:
            cout << "Mart";
            break;

        case 4:
            cout << "April";
            break;

        case 5:
            cout << "Maj";
            break;

        case 6:
            cout << "Jun";
            break;

        case 7:
            cout << "Jul";
            break;

        case 8:
            cout << "Avgust";
            break;

        case 9:
            cout << "Septembar";
            break;

        case 10:
            cout << "Oktobar";
            break;

        case 11:
            cout << "Novembar";
            break;

        case 12:
            cout << "Decembar";
            break;

        default:
            cout << "Nepostojeci mesec";
    }

    return 0;
}
Ovo je klasičan primer u kome switch može biti pregledniji od dugog else if lanca.

Zadatak 3 — godišnje doba

Napisati program koji na osnovu broja meseca određuje godišnje doba prema pojednostavljenoj meteorološkoj podeli.
#include <iostream>
using namespace std;

int main() {
    int mesec;

    cout << "Unesite mesec (1-12): ";
    cin >> mesec;

    switch (mesec) {
        case 12:
        case 1:
        case 2:
            cout << "Zima";
            break;

        case 3:
        case 4:
        case 5:
            cout << "Prolece";
            break;

        case 6:
        case 7:
        case 8:
            cout << "Leto";
            break;

        case 9:
        case 10:
        case 11:
            cout << "Jesen";
            break;

        default:
            cout << "Nepostojeci mesec";
    }

    return 0;
}
Ovaj primer posebno je koristan za razumevanje grupisanja više case oznaka.

Zadatak 4 — broj dana u mesecu

Napisati program koji učitava broj meseca i godinu, a zatim određuje broj dana u tom mesecu. Program treba pravilno da obradi i prestupne godine.
#include <iostream>
using namespace std;

int main() {
    int mesec, godina;
    int brojDana = 0;

    cout << "Unesite mesec (1-12): ";
    cin >> mesec;

    cout << "Unesite godinu: ";
    cin >> godina;

    if (!cin || godina <= 0) {
        cout << "Neispravan unos.";
        return 1;
    }

    switch (mesec) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            brojDana = 31;
            break;

        case 4:
        case 6:
        case 9:
        case 11:
            brojDana = 30;
            break;

        case 2:
            if (godina % 400 == 0 ||
                (godina % 4 == 0 &&
                 godina % 100 != 0)) {
                brojDana = 29;
            } else {
                brojDana = 28;
            }
            break;

        default:
            cout << "Nepostojeci mesec.";
            return 1;
    }

    cout << "Mesec ima "
         << brojDana << " dana.";

    return 0;
}
Primer:
Unesite mesec (1-12): 2
Unesite godinu: 2024
Mesec ima 29 dana.
Ovde smo kombinovali switch i if-else, što je veoma česta praksa.

Zadatak 5 — jednostavan kalkulator

Napisati program koji učitava dva broja i operator +, -, * ili /.
#include <iostream>
using namespace std;

int main() {
    double a, b;
    char operacija;

    cout << "Unesite prvi broj: ";
    cin >> a;

    cout << "Unesite operaciju (+, -, *, /): ";
    cin >> operacija;

    cout << "Unesite drugi broj: ";
    cin >> b;

    if (!cin) {
        cout << "Neispravan unos.";
        return 1;
    }

    switch (operacija) {
        case '+':
            cout << "Rezultat: " << a + b;
            break;

        case '-':
            cout << "Rezultat: " << a - b;
            break;

        case '*':
            cout << "Rezultat: " << a * b;
            break;

        case '/':
            if (b != 0) {
                cout << "Rezultat: " << a / b;
            } else {
                cout << "Greska: deljenje nulom.";
            }
            break;

        default:
            cout << "Nepoznata operacija.";
    }

    return 0;
}
Primer:
Unesite prvi broj: 20
Unesite operaciju (+, -, *, /): *
Unesite drugi broj: 5
Rezultat: 100
Ovo je jedan od najčešćih zadataka za vežbanje switch naredbe.
Vežba izrade kalkulatora pomoću switch-case naredbe

12. Ugnježdene switch naredbe

Kao što možemo ugnježđavati if naredbe, možemo koristiti i jednu switch strukturu unutar druge. Na primer, prvo biramo kategoriju proizvoda, a zatim proizvod unutar kategorije.
#include <iostream>
using namespace std;

int main() {
    int kategorija;
    int proizvod;

    cout << "1. Racunarin";
    cout << "2. Telefonin";
    cout << "Izaberite kategoriju: ";
    cin >> kategorija;

    if (!cin) {
        cout << "Neispravan unos.";
        return 1;
    }

    switch (kategorija) {
        case 1:
            cout << "n1. Laptopn";
            cout << "2. Desktop racunarn";
            cout << "Izaberite proizvod: ";
            cin >> proizvod;

            if (!cin) {
                cout << "Neispravan unos.";
                return 1;
            }

            switch (proizvod) {
                case 1:
                    cout << "Izabrali ste laptop.";
                    break;

                case 2:
                    cout << "Izabrali ste desktop racunar.";
                    break;

                default:
                    cout << "Nepoznat proizvod.";
            }
            break;

        case 2:
            cout << "n1. Android telefonn";
            cout << "2. iPhonen";
            cout << "Izaberite proizvod: ";
            cin >> proizvod;

            if (!cin) {
                cout << "Neispravan unos.";
                return 1;
            }

            switch (proizvod) {
                case 1:
                    cout << "Izabrali ste Android telefon.";
                    break;

                case 2:
                    cout << "Izabrali ste iPhone.";
                    break;

                default:
                    cout << "Nepoznat proizvod.";
            }
            break;

        default:
            cout << "Nepoznata kategorija.";
    }

    return 0;
}

Važno pravilo

Kada se break nalazi unutar unutrašnjeg switch, prekida samo taj unutrašnji switch. Ne prekida automatski i spoljašnji. Zato u prethodnom primeru postoje posebne break naredbe za spoljašnje grane.

Da li je ugnježđavanje uvek najbolje rešenje?

Ne. Kod velikog broja nivoa, program može postati nepregledan. U većim aplikacijama složene operacije obično izdvajamo u funkcije ili druge organizacione celine, što ćemo učiti u narednim lekcijama.

13. switch i enumeracije (enum)

Enumeracija je tip podataka koji omogućava definisanje skupa imenovanih vrednosti. Na primer, možemo definisati statuse porudžbine.
enum Status {
    NOVA,
    U_OBRADI,
    POSLATA,
    ISPORUCENA
};
Zatim koristiti switch:
#include <iostream>
using namespace std;

enum Status {
    NOVA,
    U_OBRADI,
    POSLATA,
    ISPORUCENA
};

int main() {
    Status status = POSLATA;

    switch (status) {
        case NOVA:
            cout << "Nova porudzbina.";
            break;

        case U_OBRADI:
            cout << "Porudzbina je u obradi.";
            break;

        case POSLATA:
            cout << "Porudzbina je poslata.";
            break;

        case ISPORUCENA:
            cout << "Porudzbina je isporucena.";
            break;
    }

    return 0;
}
Rezultat:
Porudzbina je poslata.
Ovaj primer pokazuje kako switch može da se koristi u realnim poslovnim sistemima. Enumeracije ćemo detaljnije obrađivati u posebnoj lekciji, a za sada je dovoljno da razumete da predstavljaju imenovane vrednosti koje možemo koristiti pri grananju.

14. Praktični projekat — konzolni sistem sa glavnim menijem

Sada ćemo napraviti mali program koji simulira osnovni informacioni sistem. Korisnik treba da vidi glavni meni i izabere željenu operaciju. Program će podržavati:
  • Prikaz informacija o aplikaciji.
  • Prikaz trenutnog broja korisnika.
  • Dodavanje jednog korisnika.
  • Brisanje jednog korisnika.
  • Izlaz iz programa.
Za potrebe ove lekcije koristićemo jednostavnu promenljivu koja čuva broj korisnika. Nećemo još čuvati pojedinačne podatke o korisnicima niti koristiti bazu podataka.

Zašto nam je potrebna petlja?

Do sada smo uglavnom pisali programe koji se izvrše jednom i završe. Međutim, pravi meni treba da omogući korisniku da izabere više operacija pre izlaska. Zato ćemo ovde prvi put upotrebiti jednostavnu do-while petlju. Njenu detaljnu sintaksu i način rada obradićemo u narednim lekcijama o petljama. Za sada je dovoljno da znamo da će ponavljati prikaz menija dok korisnik ne izabere opciju 0.

Kompletan program

#include <iostream>
using namespace std;

int main() {
    int opcija;
    int brojKorisnika = 5;

    do {
        cout << "n=========================n";
        cout << "     ROSTER SISTEMn";
        cout << "=========================n";

        cout << "1. Informacije o programun";
        cout << "2. Broj korisnikan";
        cout << "3. Dodavanje korisnikan";
        cout << "4. Brisanje korisnikan";
        cout << "0. Izlazn";

        cout << "nIzaberite opciju: ";

        if (!(cin >> opcija)) {
            cout << "Greska: unesite ceo broj.n";
            return 1;
        }

        switch (opcija) {
            case 1:
                cout << "nROSTER SISTEM v1.0n";
                cout << "Primer konzolne aplikacije.n";
                break;

            case 2:
                cout << "nTrenutni broj korisnika: "
                     << brojKorisnika << endl;
                break;

            case 3:
                brojKorisnika++;

                cout << "nKorisnik je dodat.n";
                cout << "Ukupno korisnika: "
                     << brojKorisnika << endl;
                break;

            case 4:
                if (brojKorisnika > 0) {
                    brojKorisnika--;

                    cout << "nKorisnik je obrisan.n";
                    cout << "Ukupno korisnika: "
                         << brojKorisnika << endl;
                } else {
                    cout << "nNema korisnika za brisanje.n";
                }
                break;

            case 0:
                cout << "nIzlaz iz programa.n";
                break;

            default:
                cout << "nNepostojeca opcija.n";
        }

    } while (opcija != 0);

    return 0;
}

Primer izvršavanja

=========================
     ROSTER SISTEM
=========================
1. Informacije o programu
2. Broj korisnika
3. Dodavanje korisnika
4. Brisanje korisnika
0. Izlaz

Izaberite opciju: 2

Trenutni broj korisnika: 5
Program zatim ponovo prikazuje meni. Ako korisnik izabere 3:
Izaberite opciju: 3

Korisnik je dodat.
Ukupno korisnika: 6
Ako zatim izabere 0:
Izaberite opciju: 0

Izlaz iz programa.

Šta smo naučili kroz ovaj projekat?

Povezali smo više prethodno naučenih oblasti:
  • Promenljive i tipove podataka.
  • Unos pomoću cin.
  • Ispis pomoću cout.
  • Aritmetičke operatore.
  • Kombinovane i inkrement operatore.
  • if-else proveru.
  • switch-case grananje.
  • break i default.
  • Osnovni princip ponavljanja pomoću petlje.
Ovo je jednostavan, ali koristan primer načina na koji se organizuju konzolne aplikacije.
Konzolni meni za upravljanje korisnicima pomoću switch-case naredbe

15. Najčešće greške početnika

Greška 1 — zaboravljen break

Pogrešno kada ne želimo fall-through:
switch (broj) {
    case 1:
        cout << "Jedan";

    case 2:
        cout << "Dva";
}
Ako je broj jednak 1, ispisuje se:
JedanDva
Ispravno:
switch (broj) {
    case 1:
        cout << "Jedan";
        break;

    case 2:
        cout << "Dva";
        break;
}

Greška 2 — korišćenje tačke-zareza umesto dvotačke

Pogrešno:
case 1;
Ispravno:
case 1:
Oznaka case završava se dvotačkom.

Greška 3 — korišćenje promenljive kao case vrednosti

Pogrešno:
int x = 5;

switch (broj) {
    case x:
        cout << "Pet";
        break;
}
Ispravno:
constexpr int X = 5;

switch (broj) {
    case X:
        cout << "Pet";
        break;
}

Greška 4 — duplirane case vrednosti

Pogrešno:
switch (broj) {
    case 2:
        cout << "A";
        break;

    case 2:
        cout << "B";
        break;
}
Svaka case vrednost mora biti jedinstvena unutar iste switch strukture.

Greška 5 — korišćenje double izraza

Pogrešno:
double broj = 2.5;

switch (broj) {
    case 2:
        cout << "Dva";
}
switch ne prihvata direktno izraz tipa double.

Greška 6 — pokušaj korišćenja intervala u case

Pogrešno:
case broj > 10:
Ovo ne predstavlja proveru intervala. case zahteva konstantni izraz odgovarajućeg tipa. Za intervale koristimo if-else.

Greška 7 — očekivanje da default uvek mora da se izvrši

default se ne izvršava automatski nakon svake druge grane. Ako postoji odgovarajući case sa break, default se preskače. Ipak, bez break izvršavanje može nastaviti i kroz default oznaku.

Greška 8 — deklarisanje promenljivih neposredno ispod case

Pogledajmo problematičan primer:
switch (opcija) {
    case 1:
        int rezultat = 10;
        cout << rezultat;
        break;

    case 2:
        cout << "Druga opcija";
        break;
}
Ovakav kod može izazvati grešku pri kompajliranju jer se prelaskom na drugu case oznaku može preskočiti inicijalizacija lokalne promenljive čiji opseg obuhvata naredne oznake. Preporučeni način je da koristimo poseban blok:
switch (opcija) {
    case 1: {
        int rezultat = 10;
        cout << rezultat;
        break;
    }

    case 2:
        cout << "Druga opcija";
        break;
}
Na taj način promenljiva ima jasno ograničen opseg.

Greška 9 — mešanje break i return

break prekida switch. return završava izvršavanje funkcije i, po potrebi, vraća rezultat pozivaocu. U funkciji main, return 0; završava program i označava uspešan završetak. Zato ne treba automatski zamenjivati break naredbu sa return.

Greška 10 — neproveravanje unosa

Ako korisnik umesto broja unese tekst, cin može preći u stanje greške. Za jednostavnu proveru koristimo:
if (!(cin >> opcija)) {
    cout << "Neispravan unos.";
    return 1;
}

16. Kako rešavati fakultetske zadatke sa switch naredbom?

Kada dobijete zadatak koji zahteva izbor između više mogućnosti, preporučujemo sledeći postupak:
  1. Pročitajte zadatak i odredite šta korisnik unosi.
  2. Proverite da li se izbor zasniva na konkretnim vrednostima jednog izraza.
  3. Izaberite odgovarajući tip podataka.
  4. Napišite switch strukturu.
  5. Definišite sve potrebne case oznake.
  6. Za svaku opciju napišite odgovarajuće naredbe.
  7. Dodajte break tamo gde ne želite nastavak izvršavanja.
  8. Dodajte default za nepoznate vrednosti kada je to potrebno.
  9. Testirajte svaku opciju.
  10. Testirajte i vrednosti koje nisu predviđene.

Primer testiranja menija

Ako program podržava opcije 1, 2, 3 i 0, proverite:
Ulaz Očekivano ponašanje
1 Prva operacija
2 Druga operacija
3 Treća operacija
0 Izlaz
5 Nepoznata opcija
-1 Nepoznata opcija
Slovo Obrada neispravnog unosa
Ovakvo testiranje pomoći će vam da uočite nedostajuće break naredbe, pogrešne case vrednosti i probleme sa unosom.

17. Zaključak

U ovoj lekciji naučili smo kako funkcioniše naredba switch-case u programskom jeziku C++. Najvažnije je zapamtiti:
  • switch omogućava izbor između više mogućnosti na osnovu vrednosti izraza.
  • case označava pojedinačnu vrednost.
  • break prekida izvršavanje switch strukture.
  • default obrađuje slučajeve kada nijedna oznaka ne odgovara vrednosti izraza.
  • Ako izostavimo break, izvršavanje može nastaviti kroz naredne grane.
  • Više case oznaka može deliti isti blok naredbi.
  • switch podržava odgovarajuće celobrojne i enumeracione tipove.
  • double, float i std::string ne mogu se direktno koristiti kao switch izrazi.
  • if-else je pogodniji za intervale i složene logičke uslove.
  • switch je često pregledniji za numeričke menije i izbor između konkretnih vrednosti.
Naredba switch predstavlja važan alat za organizovanje programa koji imaju više jasno definisanih opcija. Kada se pravilno koristi, omogućava pregledan kod i jednostavnije održavanje aplikacije.

18. Mini-test — proverite svoje znanje

Pokušajte da odgovorite bez pokretanja programa. Pitanje 1. Čemu služi naredba switch? a) Za ponavljanje naredbi. b) Za izbor između više mogućnosti na osnovu vrednosti izraza. c) Za deklarisanje promenljivih. Pitanje 2. Koja ključna reč označava pojedinačnu vrednost? a) case b) if c) while Pitanje 3. Čemu služi break u switch strukturi? a) Završava ceo program. b) Prekida izvršavanje switch strukture. c) Deklariše promenljivu. Pitanje 4. Šta će ispisati program?
int x = 2;

switch (x) {
    case 1:
        cout << "A";
        break;

    case 2:
        cout << "B";
        break;

    default:
        cout << "C";
}
a) A b) B c) C Pitanje 5. Šta će ispisati program?
int x = 1;

switch (x) {
    case 1:
        cout << "A";

    case 2:
        cout << "B";

    default:
        cout << "C";
}
a) A b) AB c) ABC Pitanje 6. Da li je default obavezan? a) Da. b) Ne. c) Samo kod karaktera. Pitanje 7. Koji tip ne može direktno biti izraz u switch naredbi? a) int b) char c) double Pitanje 8. Koji zapis je ispravan? a) case 1; b) case 1: c) case = 1: Pitanje 9. Šta predstavlja fall-through? a) Automatsko završavanje programa. b) Nastavljanje izvršavanja kroz naredne grane bez prekidanja. c) Grešku pri unosu podataka. Pitanje 10. Kada je if-else pogodniji od switch? a) Kada proveravamo intervale i složene logičke uslove. b) Kada imamo numerički meni. c) Kada biramo između nekoliko karaktera.

Rešenja mini-testa

Proverite odgovore nakon što završite test. Pitanje Tačan odgovor 1b — switch bira odgovarajuću granu prema vrednosti izraza. 2a — case označava pojedinačnu vrednost. 3b — break prekida izvršavanje switch strukture. 4b — Vrednost x je 2, pa se izvršava case 2. 5c — Bez break naredbi izvršavanje se nastavlja kroz naredne grane. 6b — default nije obavezan. 7c — double nije dozvoljen kao direktan switch izraz. 8b — case oznaka završava se dvotačkom. 9b — Fall-through predstavlja nastavak izvršavanja kroz naredne case grane. 10a — if-else je pogodniji za intervale i složene logičke izraze.

19. Zadaci za samostalnu vežbu

Zadatak 1 — dan u nedelji Napisati program koji na osnovu broja od 1 do 7 ispisuje naziv dana. Zadatak 2 — naziv meseca Napisati program koji na osnovu broja od 1 do 12 ispisuje naziv meseca. Zadatak 3 — godišnje doba Napisati program koji na osnovu broja meseca određuje godišnje doba. Zadatak 4 — kalkulator Napisati program koji podržava operacije +, -, * i / pomoću switch naredbe. Zadatak 5 — ocena slovom Napisati program koji učitava karakter A, B, C, D ili F i ispisuje odgovarajući opis uspeha. Zadatak 6 — broj dana u mesecu Napisati program koji određuje broj dana u mesecu, uključujući prestupne godine. Zadatak 7 — jednostavan meni Napraviti meni sa opcijama za prikaz informacija, podešavanja i izlaz. Zadatak 8 — kategorija proizvoda Napisati program koji na osnovu broja kategorije ispisuje naziv: računari, telefoni, televizori ili dodatna oprema. Zadatak 9 — upravljanje uređajem Napisati program koji prihvata karaktere U, I i R za uključivanje, isključivanje i restart uređaja. Zadatak 10 — analiza fall-through ponašanja Napisati tri primera switch strukture sa različitim rasporedom break naredbi i unapred predvideti njihov izlaz.

20. Domaći zadatak — mini POS sistem za prodavnicu

Napraviti jednostavan konzolni program koji simulira rad prodajne kase. Program treba da ima sledeći meni:
================================
       MINI POS SISTEM
================================
1. Kafa           180 RSD
2. Sok            220 RSD
3. Voda           100 RSD
4. Sendvic        350 RSD
5. Kolac          280 RSD
0. Zavrsi kupovinu

Izaberite proizvod:

Zahtevi zadatka

Program treba da:
  1. Prikaže meni proizvoda.
  2. Omogući korisniku izbor proizvoda.
  3. Za izabrani proizvod zatraži količinu.
  4. Izračuna vrednost izabrane stavke.
  5. Doda vrednost stavke na ukupan račun.
  6. Omogući dodavanje više različitih proizvoda.
  7. Prijavi nepostojeću opciju.
  8. Završi kupovinu kada korisnik unese 0.
  9. Prikaže konačan iznos računa.

Dodatni uslovi

Ako ukupan račun iznosi najmanje 2.000 dinara, kupac ostvaruje popust od 5%. Ako je račun manji od 2.000 dinara, popust se ne obračunava.

Primer izvršavanja

Izaberite proizvod: 1
Unesite kolicinu: 2
Dodato: Kafa x 2 = 360 RSD

Izaberite proizvod: 4
Unesite kolicinu: 3
Dodato: Sendvic x 3 = 1050 RSD

Izaberite proizvod: 5
Unesite kolicinu: 3
Dodato: Kolac x 3 = 840 RSD

Izaberite proizvod: 0

================================
          RACUN
================================
Ukupno pre popusta: 2250 RSD
Popust 5%: 112.50 RSD
Za placanje: 2137.50 RSD
================================

Dodatni izazov

Proširite program tako da:
  • Ne prihvata negativne i nulte količine.
  • Evidentira ukupan broj prodatih artikala.
  • Prikazuje broj različitih proizvoda koji su kupljeni.
  • Prikazuje najprodavaniji proizvod po količini.
  • Omogućava ponovno pokretanje nove kupovine.
Za rešavanje ovog zadatka biće vam potrebna i petlja, koju smo kratko upoznali u praktičnom projektu ove lekcije. Njenu detaljnu upotrebu naučićemo u narednim temama.

Najava naredne lekcije

U sledećoj lekciji nastavljamo sa kontrolom toka programa, ali prelazimo na veoma važnu programersku konstrukciju koja omogućava ponavljanje naredbi. Tema 31 — while petlja u C++: ponavljanje naredbi dok je uslov ispunjen Naučićemo kako funkcioniše while, kako se proverava uslov ponavljanja, kako nastaju beskonačne petlje i kako da napravimo programe koji izvršavaju određene operacije više puta bez nepotrebnog ponavljanja koda.
Vaša privatnost nam je važna

Koristimo neophodne kolačiće da bi sajt i forme za upit ispravno radili, a uz vašu dozvolu i opcionalne kolačiće za analitiku, personalizaciju i marketing. Saznajte više.