$$ \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} \renewcommand{\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{\mss}{\,\mathrm{\frac{m}{s^2}}} \newcommand{\mmin}{\,\mathrm{\frac{m}{min}}} \newcommand{\smin}{\,\mathrm{\frac{s}{min}}} $$

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

Upotreba funkcija

Do sada smo koristili "gotove" funkcije iz standardnih biblioteka. Sve ove funkcije smo pozivali iz glavne funkcije našeg programa, main funkcije, koja predstavlja specijalnu funkciju, jer izvršavanje programa počinje od nje i sve programe, bez obzira na njihovu dužinu, pisali smo u toj jednoj funkciji.

Pogledajmo ponovo primer iz lekcije "Unos podataka".

using namespace std;
#include <iostream>

void main()
{
    int zbir = 0; 
    float prosek; 
    const int brPredmeta = 11; 
    int ocena;

    cout << "Sta imas iz srpskog?\n"; 
    cin >> ocena; 
    zbir += ocena;

    cout << "Sta imas iz matematike?\n"; 
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz fizickog?\n";
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz engleskog?\n";
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz fizike?\n";
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz hemije?\n";
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz ruskog?\n";
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz muzickog?\n";
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz likovnog?\n";
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz kung-fu-a?\n";
    cin >> ocena;
    zbir += ocena;

    cout << "Sta imas iz kibernetike?\n";
    cin >> ocena; 
    zbir += ocena;
    
    prosek = (float) zbir / brPredmeta;
    cout << "Tvoj prosek je:" << prosek;
}

Kao što vidiš, dobili smo prilično dugačak program u kome ima dosta ponavljanja sličnih ili istih operacija i blokova naredbi. Ovaj program možemo da napišemo na kraći i jednostavniji način, koristeći funkciju. U primeru koji sledi pokazano je kako se piše i koristi jedna jednostavna funkcija. Ova funkcija nas podseća na main funkciju iz naših prethodnih programa.

using namespace std;
#include <iostream>
#include <string>

int StaImasIz(std::string imePredmeta)
{
    int ocena; 
    
    cout << "Sta imas iz " << imePredmeta << "?\n"; 
    cin >> ocena;

    return ocena;
}

void main()
{ 
    int zbir = 0; 
    float prosek; 
    const int brPredmeta = 11;

    zbir += StaImasIz("srpskog"); 
    zbir += StaImasIz("matematike");
    zbir += StaImasIz("fizickog");
    zbir += StaImasIz("engleskog");
    zbir += StaImasIz("fizike");
    zbir += StaImasIz("hemije");
    zbir += StaImasIz("ruskog");
    zbir += StaImasIz("muzickog");
    zbir += StaImasIz("likovnog");
    zbir += StaImasIz("kung-fu-a");
    zbir += StaImasIz("kibernetike"); 
    
    prosek = (float) zbir / brPredmeta;

    cout << "Tvoj prosek je:" << prosek;
}

Dobili smo značajno kraći i pregledniji program u kome smo deo programa stavili u odvojenu funkciju StaImasIz. Obično je telo funkcije veoma složeno, za razliku od ovog primera. Posle kreiranja funkcije, možemo je iz ostalog dela programa pozivati po imenu, a funkcije mogu da pozivaju i jedne druge. Funkcija može čak i da poziva samu sebe (to se koristi u rekurzivnim algoritmima). Za sada nemoj da pozivaš funkciju iz same sebe.

Nabrojaćemo sve razloge za upotrebu funkcija:

  • Kada imamo više ponavljanja istih blokova naredbi (operacija) u različitim delovima programa (time skraćujemo tekst programa).

  • Upotrebom funkcija, program se deli na odvojene blokove. Svaki blok radi određeni posao. Ovako olakšavamo čitljivost/razumevanje programa. Osmišljavanje, razumevanje i održavanje manjih blokova koda je lakše.

  • Kada se deo programa moze izvršiti sa različitim parametrima. Ovi parametri se prosleđuju funkciji kao argumenti funkcije.

Definisanje funkcije

Prikazana funkcija StaImasIz uzima kao argument (argumenti funkcije su varijable čije se vrednosti tokom pozivanja funkcije) tekstualni podatak koji predstavlja naziv predmeta, na primer "fizike", a kao rezultat vraća ocenu iz tog predmeta koja je ceo broj, pa je tip njenog rezultata int.

Uopšteno možemo svaku funkciju da definišemo na sledeći način:

TIP REZULTAT ime_funkcije(OPIS ARGUMENATA FUNKCIJE)
{
    TELO FUNKCIJE
}

Ovo je ilustrovano sledećim dijagramom.

Na početku se navodi TIP REZULTATA koji je neki od već poznatih tipova podataka i označava kakav je rezultat koji funkcija vraća.

Često se kaže i "tip funkcije", a tada se misli upravo na tip njenog rezultata. Funkcija ima svoje jedinstveno ime ime_funkcije.

Između zagrada se navodi OPIS ARGUMENATA FUNKCIJE koji je lista argumenata funkcije. Za svaki argument se navodi njegov tip i ime (identifikator). Na primer, funkcija Izracunaj(int a, char ch, float x) ima u listi upisana tri argumenta i to: a, ch i x čiji su tipovi podataka navedeni ispred.

Niz naredbi koje će se izvršiti kada se pozove funkcija čine TELO FUNKCIJE. Telo funkcije započinje nakon otvorene vitičaste zagrade, a završava zatvorenom vitičastom zagradom.

Naredba return rezultat; u telu funkcije služi za vraćanje rezultata koji funkcija daje.

Pozivanje funkcije

Funkcija se izvršava tako što se "poziva" u (glavnom) programu ili drugoj funkciji. Funkcija se poziva navođenjem njenog naziva i argumenata zapisanih u redosledu koji je zadan deklaracijom, kao u primeru StaImasIz("kung-fu-a") gde učenika pitamo koju ocenu ima iz Kung-Fu-a.

Povratna vrednost funkcije

U programskom jeziku C++ očekujemo da funkcija vrati neku vrednost. Ova povratna vrednost ima svoj tip kao i ostale vrednosti u C++, pa može biti tipa int, float, char ili bilo šta drugo. Vrednost funkcije vraćamo sa komandom return.

float Kvadriraj(float x)
{ 
    float rezultat;
    rezultat = x * x;
    return rezultat;
}

Funkcija iz gornjeg primera vraća vrednost promenljive "rezultat" kao povratnu vrednost funkcije. Takođe, možemo koristiti i izraz u return komandi. Na primer možemo da napišemo return (x * x); umesto poslednje dve linije funkcije. Ukoliko zaboravite povratnu vrednost u nekoj funkciji dobićete poruku upozorenja (eng. warning) od C++ kompajlera da funkcija mora da vrati vrednost. Upozorenja kompajlera ne zaustavljaju izvršavanje programa, ali greške zaustavljaju. Ipak, dobra je praksa obraćati pažnju i na ova upozorenja i popraviti kod tako da se prevodi bez upozorenja.

Funkcije koje ne vraćaju vrednost

Prema pravilima pisanja programa na jezicima C, C++ i C#, svaka funkcija ima tip. Ako nam nije potrebno da funkcija na mesto poziva vrati vrednost, deklarišemo (objavljujemo) da je tip funkcije, to jest njene povratne vrednosti, tip void (srpski: nevažeći, prazan).

void test()
{
    /* kod funkcije ali bez povratne vrednosti */
}

Tip void se ne može koristiti. Njegovom upotrebom u deklaraciji samo saopštavamo da funkcija ne vraća neki podatak, tj. vrednost. Zato se pozivi funkcija tipa void pišu u programu kao naredbe, a ne kao izrazi.

Funkcija tipa void ne mora, ali može, da sadrži naredbu return. Ukoliko je sadrži, onda je to bez ikakvog izraza. Pogledajmo kako to izgleda na primeru:

void ispisUpozorenja()
{
    cout << "Upozorenje!";
}

Poziv ove funkcije sa nekog drugog mesta u programu bi izgledao ovako:

ispisUpozorenja();

Deklaracija funkcije

Svaka funkcija se pre upotrebe u programu najavljuje (deklariše), kao što se deklarišu promenljive. Ako pri čitanju programa, u trenutku kad naiđemo na upotrebu nekog imena, do tada nije već najavljeno to ime i način njegove upotrebe, naš program ne može da se pripremi za izvršenje jer mu to ime nije poznato i u tom trenutku mu nije jasno šta treba da radi. U najavi je dovoljno navesti samo tipove podataka koje funkcija koristi kao argumente ili vraća kao rezultat. Možemo da pogledamo koji je redosled deklaracija funkcije ispravan kroz primere

  • Ovo je ispravno:
int StaImasIz(string imePredmeta)
{
    …
}

void main()
{
     …
     zbir += StaImasIz("mađioničarskih trikova");
     …
}
  • Ovo je takođe ispravno:
int StaImasIz(string imePredmeta);

void main()
{
    …
    zbir += StaImasIz("mađioničarskih trikova");
    …
}

int StaImasIz(string imePredmeta)
{
    …
} 
  • Sledeće, međutim, nije ispravno:
void main()
{
    …
    zbir += StaImasIz("mađioničarskih trikova");
    …
}

int StaImasIz(string imePredmeta)
{
    …
}

Ovo je neispravno zato što kad naiđemo na StaImasIz, ne znamo da li je to ime funkcije ili nešto drugo.

Argumenti funkcije

Funkcije mogu da prihvataju ulazne parametre u formi promenljivih i izraza i ove ulazne promenljive se mogu koristiti u telu funkcije.

Do sad su parametri služili da prenesu vrednost sa mesta poziva u funkciju i to su ulazni parametri, a moguće je preneti i vrednost iz funkcije (tako da parametri budu izlazni), ali o tome će biti reči u nekoj od narednih lekcija.