$$ \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} \newcommand{\mod}{\,\mathrm{mod}\,} \renewcommand{\div}{\,\mathrm{div}\,} \newcommand{\metar}{\,\mathrm{m}} \newcommand{\cm}{\,\mathrm{cm}} \newcommand{\dm}{\,\mathrm{dm}} \newcommand{\litar}{\,\mathrm{l}} \newcommand{\km}{\,\mathrm{km}} \newcommand{\s}{\,\mathrm{s}} \newcommand{\h}{\,\mathrm{h}} \newcommand{\minut}{\,\mathrm{min}} \newcommand{\kmh}{\,\mathrm{\frac{km}{h}}} \newcommand{\ms}{\,\mathrm{\frac{m}{s}}} \newcommand{\mmin}{\,\mathrm{\frac{m}{min}}} \newcommand{\smin}{\,\mathrm{\frac{s}{min}}} $$
Priručnik za početnike (C++) / Kombinovanje uslovnih naredbi

Kombinovanje uslovnih naredbi

  • Dozvoljeno polaganje
  • Lekcije
  • Nema
  • Filip Zivkovic
  • 7/31/2015

Kada budemo pisali složene programe često moramo da kombinujemo uslovne naredbe da bismo dobili rezultat koji želimo. Pogledajmo jednostavan primer programa koji treba da proveri da li je broj A deljiv brojem B (oba broja se unose sa tastature). Program treba da ispiše DELJIV odnosno NEDELJIV u odgovarajućem slučaju. Bitno je da primetimo da neko može, slučajno ili namerno, da unese vrednost 0 za broj B. Kako deljenje nulom nije dozvoljeno, ako probamo da izračunamo ostatak pri deljenju sa 0, program se neće izvršavati kako treba! Zbog toga moramo prvo da proverimo da li je drugi broj različit od nule i da samo u tom slučaju radimo i proveru deljivosti. Kod kojim ovo realizujemo je sledeći:

#include <iostream>

int main()

{

int broj_a, broj_b;

std::cin >> broj_a >> broj_b;

if (broj_b != 0)

{

// ovo se izvrsava samo ako broj_b nije nula

if (broj_a % broj_b == 0)

{

std::cout << "DELJIV";

}

else

{

std::cout << "NEDELJIV";

}

}

else

{

std::cout << "Drugi broj je 0 pa nema smisla traziti ostatak pri deljenju! ";

}

}

Dijagram toka programa

Unesite nekoliko različitih vrednosti i izvršite program nekoliko puta da biste videli kako se ponaša u raznim slučajevima. Kada je B nula, provera deljivosti se neće ni razmatrati. Naravno, ako je potrebno, svako od ovih grananja može se dalje granati.

Evo primera jednog dijagrama sa dosta grananja

Hajde da probamo da rešimo sledeći problem:

U dalekoj budućnosti, robot koji leti Rokolet se sprema za let. Rokolet leti isključivo na baterije i u zavisnosti od dužine leta želi da ponese samo onoliko energije koliko mu je neophodno da obavi let - odnosno želi da mu što manje energije pretekne. Rokolet ima na raspolaganju dve različite baterije - sa prvom može da leti 4 a sa drugom 7 sati. Da li Rokolet može da obavi let za koji mu je potrebno X sati? Ukoliko može, koje baterije treba da ponese? Koliko mu pretekne energije u tom slučaju? Rokolet može istovremeno da ponese obe baterije ili samo jednu ali ne sme poneti manje od X.

Prvi deo zadatka je jednostavan - ako je za let potrebno manje ili jednako 4+7 sati sigurno ga može obaviti. Ako može da obavi let i let traje više ili jednako 7 sati znači da mora da nosi bateriju od 7 sati leta.
Ako mu je ostalo još više ili jednako 4 sata leta (bez obzira da li je leteo 7 ili 0 sati pre toga) onda mora da ponese bateriju od 4 sata.

Posmatrajmo dijagram toka koji odgovara ovom problemu i program koji odgovara.

#include <iostream>
int main()
{

int X;

std::cin >> X;

int ima_baterija = 0;

int ostalo_da_preleti = X - ima_baterija;

bool nosi_4 = false, nosi_7 = false;

// na pocetku ima da preleti jos X i ne nosi ni jednu bateriju

if (ostalo_da_preleti > 4)

{

// ako mu je ostalo vise od onoga sto moze sa manjom baterijom mora da ponese vecu, od 7 sati leta

nosi_7 = true;

ima_baterija = ima_baterija + 7;

}

ostalo_da_preleti = X - ima_baterija; // jos ovoliko moramo da preletimo sa  4

// za sledeci uslov je nebitno da li nosi bateriju od 7 ili ne - ono sto je ostalo prelecemo koristeci bateriju od 4

if (ostalo_da_preleti > 0)

{

nosi_4 = true;

ima_baterija = ima_baterija + 4;

}

ostalo_da_preleti = X - ima_baterija;

if (ostalo_da_preleti > 0)

{

std::cout << "Nema dovoljno baterija za " << X << " sati leta" << std::endl;

}

else

{

std::cout<<"Moze da preleti" << std::endl;

if (nosi_7)

{

std::cout<<"Mora da ponese bateriju od 7 sati" << std::endl;

}

if (nosi_4)

{

std::cout<<"Mora da ponese bateriju od 4 sata" << std::endl;

}

if (ima_baterija > X)

{

std::cout<<"Pretice mu " << ima_baterija - X << " sati leta" << std::endl;

}

else

{

std::cout<<"Ne pretice mu vreme za letenje" << std::endl;

}

}

}


Dijagram toka programa

Probajte da izvršavate ovaj program postepeno, sa različitim ulazima, da bi lakše uočili kada se šta izvršava.


Da bi lakše razumeli grananja možemo da zamislimo naš program kao put. Kad god pokrenemo program naši ulazni podaci počnu da se kreću kroz program, od početka programa ka kraju. Grananja možemo da zamislimo kao raskrsnice gde postoje dva puta (koja se kasnije spoje) a uslov kao putokaz koji kaže ko gde treba da ide. Može se desiti da se jedna grana puta dalje deli - ali to nikako ne utiče na slučaj kada smo na drugoj grani... Ako se putevi posle prve raskrsnice sretnu i spoje na svakoj sledećoj raskrsnici je nebitno da li su podaci prošli levom ili desnom, if ili else granom. Razlika je što je drugom slučaju druga raskrsnica tek pošto se deonica na kojoj su putevi razdvojeni završi a u provom slučaju je raskrsnica unutar te deonice...

Tako je i sa našim programima - kao na raskrsnici, prolazimo ili if ili else granom (ako ima else grane). Ako unutar jedne grane imamo grananje to utiče samo na tu granu. Ako posle jednog grananja imamo drugo to utiče na sve podatke jer se tokovi programa spoje pre drugog grananja.

U slučaju našeg Rokoleta vidimo primer uslova iza uslova u prvom delu zadatka - kada jednom zaključimo da li je mora da nosi 7 ili ne izračunamo koliko je