FUNKCIJE U C++ PROGRAMSKOM JEZIKU
Sadržaj lekcije: Funkcije u C++
Dobrodošli na lekciju o funkcijama u jeziku C++! Funkcije su osnovni građevinski blok svakog programa i omogućavaju organizaciju koda u manje, lako razumljive delove. U ovoj lekciji ćemo objasniti kako funkcije rade, kako ih definišemo i koristimo, kao i koje su njihove prednosti. Pokrićemo različite tipove funkcija, uključujući funkcije sa i bez povratne vrednosti, funkcije sa parametrima, preklapanje funkcija i rekurziju.
Programi u programskom jeziku C++ mogu da imaju veliki broj naredbi i ako bi one bile napisane jedna za drugom u jednom fajlu, programeri bi se teško snalazili u takvom kodu, tj. bilo bi ga teško održavati. S druge strane, često se dešava da se jedan algoritam, deo naredbi koje rešavaju jedan mali ili veliki problem unutar aplikacije, ponavlja više puta.
Može se zaključiti da bi bilo mnogo bolje taj skup naredbi (deo programa) izdvojiti kao jednu celinu samo jednom kao podprogram ili funkciju i onda se po potrebi ta funkcija pozivala svaki put kada je potrebno. Potprogrami su mehanizam razbijanja složenih problema na potprobleme.
Programski jezik C poznaje samo jednu vrstu potprograma koje se nazivaju funkcijama.
Primere iz funkcija možete naći na sledećoj web strani: Funkcije u C/C++ jeziku - primeri
Treba razlikovati tri stvari vezano za funkcije:
- Deklaracija funkcija
- Definisanje funkcija
- Pozivanje funkcija
Deklaracija funkcija
Deklaracija funkcije (poznata i kao prototip funkcije) je način da se kompajler unapred obavesti o postojanju funkcije, njenom povratnom tipu i argumentima. Ovo je korisno kada funkcija nije implementirana pre njenog poziva u kodu.
Pod deklaracijom podatka ili funkcije u programiranju naziva se određivanje identifikatora i opisivanje osobina podataka ili funkcije, bez dodeljivanja memorijskog prostora za smeštanje podataka ili funkcije. U slučaju funkcije određuje se tip vrednosti funkcije i broj i tipovi argumenata. U opštem slučaju deklaracija izgleda:
Deklaracija funkcije još se naziva i prototip funkcije, kao i potpis funkcije.
Ako se funkcija nalazi u fajlu iznad main
funkcije, kao u prethodnim primerima, onda nije potrebno posebno navesti deklaraciju. U suprotnom, deklaraciju je potrebno napisati iznad main
funkcije. Npr. prototip funkcije max
bi bio:
ili samo
Prototip funkcije promeni_ref
izgleda:
Primer koda sa deklaracijom funkcije
using namespace std;
// Deklaracija funkcije koja računa zbir dva broja
int zbir(int a, int b);
int main() {
cout << "Zbir je: " << rezultat << endl;
return 0; // Kraj programa
// Definicija funkcije zbir koja vraća zbir dva broja
int zbir(int a, int b) {
Definisanje funkcija
Primer definicije funkcije
int proizvod(int x, int y) {
- Naredbe funkcije
- zaglavlje funkcije
- telo funkcije
Primer 1: Određivanje maksimuma dva cela broja
- Zaglavlje funkcije sadrži povratni tip, ime funkcije i listu argumenata.
- Telo funkcije sadrži logiku funkcije.
Prva, u ovom slučaju int, predstavlja tip podatka povratne vrednosti. Ova metoda koja računa veći broj između dva cela broja, vraća taj broj čiji je tip int. To je tip povratne vrednosti.
Druga, predstavlja naziv metode, koji programer bira sam i koji treba da sugeriše svrhu metode.
Telo metode se predstavlja vitičastim zagradama. U telu se nalaze naredbe funkcije.
U zaglavlju funkcije(metode) se, posle naziva, unutar običnih zagrada pišu parametri(argumenti) funkcije. To su podaci koje treba dostaviti funkciji da bi ona mogla da završi postavljen zadatak. U prethodnom primeru zadatak koji funkcija treba da izvrši je određivanje maksimuma između dva cela broja, a podaci koje funkciji preko parametra treba dostaviti su ta dva broja, u ovom slučaju označena kao a i b. Na sledećoj slici je prikazana detaljnije ova metoda.
Ukoliko metoda ne vraća vrednost, neće imati u telu naredbu return podatak, ali može imati samo return. kao tip povratne vrednosti se u tom slučaju piše reč void.
U programu mora postojati najmanje jedna funkcija i to je funkcija main(glavna). Primer main funkcije iz prethodnog primera prikazana je na slici ispod.
Poziv funkcija
- Unutar funkcije main().
- Unutar drugih funkcija.
Primer poziva funkcije u main():
using namespace std;
// Deklaracija funkcije koja računa kvadrat broja
int kvadrat(int broj);
int main() {
cout << "Kvadrat broja " << broj << " je: " << kvadrat(broj) << endl;
return 0;
// Definicija funkcije koja računa kvadrat broja
int kvadrat(int broj) {
- Deklaracija funkcije: kvadrat prima jedan ceo broj i vraća njegov kvadrat.
- Glavna funkcija (main): Učitava broj 4, poziva funkciju kvadrat i ispisuje rezultat.
- Definicija funkcije: kvadrat računa proizvod broja sa samim sobom, što predstavlja kvadrat tog broja.
Pozivanje funkcija unutar drugih funkcija:
using namespace std;
// Deklaracije funkcija
int zbir(int a, int b);
int kvadrat_zbira(int a, int b);
int main() {
cout << "Kvadrat zbira je: " << rezultat << endl;
return 0;
// Definicija funkcije koja računa zbir dva broja
int zbir(int a, int b) {
// Definicija funkcije koja računa kvadrat zbira dva broja
int kvadrat_zbira(int a, int b) {
return z * z;
- Deklaracije funkcija: Funkcija zbir računa zbir dva broja, dok kvadrat_zbira računa kvadrat zbira dva broja.
- Glavna funkcija (main): Poziva funkciju kvadrat_zbira sa brojevima 3 i 4, a rezultat ispisuje na ekranu.
- Definicija funkcija:
- zbir vraća zbir dva broja.
- kvadrat_zbira koristi funkciju zbir da izračuna zbir, a zatim vraća kvadrat tog zbira.
Testirajte svoj kod u editoru ispod!
Detaljnije objašnjenje pozivanja funkcija u primeru "Određivanje maksimuma dva broja". Nastavak zadatka
U primeru na slici 3 poziva se funkcija max:
cout<<"Veći broj je "<<max(A,B);
Deklaracija poziva metode, u opštem slučaju izgleda:
naziv_funkcije(parametar1,parametar2,....);
Parametri koji se prosleđuju funkciji, se kopiraju redom u parametre definisane u definisanoj metodi(vidi sliku 2). U definiciji metode se ispred naziva parametra stavlja tip podatka.
int max(int a, int b)
Ovde se zapravo rezerviše nova memorija označena sa a i b koja prima kopije vrednosti parametara iz poziva funkcije:
max(A , B);
U pozivu se ispred parametra ne stavlja tip podatka.
Kopiranje parametra je prikazano na slici 5.
Primer 1-nastavak: Odeđivanje maksimuma dva broja-kod
Učitati dva cela broja i odrediti njihov maksimum koristeći prethodno definisanu funkciju.
using namespace std;
// Funkcija koja određuje maksimum između dva broja
int maksimum(int a, int b) {
int main() {
cout << "Unesite prvi broj: ";
cin >> broj1;
cout << "Unesite drugi broj: ";
cin >> broj2;
cout << "Veći broj je: " << maksimum(broj1, broj2) << endl;
return 0; // Kraj programa
Prosleđivanje parametra po vrednosti i po referenci
Ovo možemo ilustrovati kroz sledeći primer:
Primer 2: Zamena vrednosti podatku
Napravimo funkciju koja će promeniti vrednost poslatom podatku:
Ova vrednost se jeste promenila unutar funkcije promeni_vr, ali se ova promena ne odražava na podatke u glavnoj funkciji.
Da bi ovo bilo ispravno, parametri se moraju preneti po referenci.
Prenos parametara funkcije po referenci
Izmenimo prethodni primer zamenom funkcije koja sada prosleđuje parametre po referenci. Parametri sada zapravo nisu podaci nego pokazivači na te podatke.
Više o pokazivačima vidi u lekciji Pokazivači u C++
Prenos parametara funkcije po pokazivaču
Umesto referenci, mogu se koristiti i pokazivači na podatke. Efekat je sličan prosleđivanju po referenci, što znači da će se promene nastale unutar te funkcije nad podacima, kojima se pristupa preko pokazivača, odraziti na originalne podatke definisane u glavnoj funkciji. To je zbog toga što pokazivači pokazuju originalni podatak, a ne na neki novi, koji samo ima istu vrednost kao originalni.
Više o pokazivačima vidi u lekciji Pokazivači u C++.
Primer koda:
using namespace std; // Koristi std prostor imena
/*
void promeni_vr(int pr){
pr = 200; // Ova funkcija ne menja originalnu promenljivu jer se parametar prosleđuje po vrednosti
}
*/void promeni_po_pokazivacu(int *pr){ // Funkcija prima pokazivač na int
cout << "U funkciji: " << (*pr) << endl; // Prikaz nove vrednosti u funkciji
int main() { // Glavna funkcija programa
x = 30; // Postavljamo pocetnu vrednost
cout << x << endl; // Prikaz originalne vrednosti
// promeni_vr(x); // Ovaj poziv bi ostavio x nepromenjen
promeni_po_pokazivacu(&x); // Prosleđujemo adresu x funkciji
cout << x << endl; // Prikaz nove vrednosti x nakon poziva funkcije
return 0; // Kraj programa
Izlaz:
U funkciji: 200
200
Primeri funkcija sa različitim tipovima povratnih vrednosti i argumentima
1. Funkcija bez povratne vrednosti (void)
Funkcije koje ne vraćaju vrednost koriste povratni tip void
. Koriste se za izvršavanje akcija, kao što je ispis na ekran.
Primer:
int main() {
return 0;
Objašnjenje:
- Funkcija
pozdrav
nema povratnu vrednost jer koristi povratni tipvoid
. - Izvodi samo jednu akciju - ispisuje poruku.
2. Funkcija sa povratnom vrednošću tipa int
Funkcija može vraćati numeričke vrednosti koje se koriste u daljem toku programa.
Kod:
int main() {
cout << "Zbir je: " << rezultat << endl;
return 0;
Objašnjenje:
- Funkcija
zbir
uzima dva argumenta (a
ib
) i vraća njihov zbir kao rezultat.
3. Funkcija sa povratnom vrednošću tipa double
Koristi se kada su potrebni decimalni brojevi, npr. za matematičke proračune.
Kod:
int main() {
double povrsina = povrsinaKruga(r);
cout << "Površina kruga je: " << povrsina << endl;
return 0;
Objašnjenje:
- Funkcija
povrsinaKruga
računa površinu kruga pomoću formuleπ · r²
i vraća rezultat tipadouble
.
4. Funkcija sa povratnom vrednošću tipa string
Omogućava rad sa tekstualnim vrednostima.
Kod:
int main() {
cout << pozdravPoruka(ime) << endl;
return 0;
Objašnjenje:
- Funkcija
pozdravPoruka
prihvata tekstualni argument i vraća personalizovanu poruku.
Rekurzivne funkcije
Rekurzivne funkcije su funkcije koje pozivaju same sebe, direktno ili indirektno. Ovaj pristup omogućava rešavanje problema koji se prirodno mogu podeliti na manje podprobleme.
Za detaljnije objašnjenje i praktične primere, posetite našu stranicu: Rekurzivni algoritmi.
Video lekcija: Funkcije u jeziku C++
Najčešće greške i saveti
U radu sa funkcijama u C++ jeziku često dolazi do određenih grešaka. Evo nekoliko primera sa savetima kako ih izbeći:
Najčešće greške pri radu sa funkcijama
-
Zaboravljena deklaracija funkcije: Ako funkcija nije deklarisana pre njenog poziva, kompajler neće prepoznati funkciju.
Savet: Uvek deklarišite funkcije pre glavne funkcije main() ili koristite zaglavlja. -
Nepodudaranje tipova argumenata: Prosleđivanje argumenata pogrešnog tipa može izazvati greške.
Savet: Proverite tipove argumenata i uskladite ih sa deklaracijom funkcije. -
Nepostojanje povratne vrednosti: Deklarisali ste funkciju da vraća vrednost, ali ste zaboravili
return
.
Savet: Uvek proverite da li funkcija vraća vrednost ako je tip povratne vrednosti različit odvoid
. -
Rekurzija bez osnovnog uslova: Ako funkcija nema uslov koji zaustavlja rekurziju, doći će do beskonačnog poziva.
Savet: Uvek definišite osnovni slučaj (terminirajući uslov) za rekurzivne funkcije.
Povezivanje sa objektno-orijentisanim konceptima
U objektno-orijentisanom programiranju (OOP), funkcije igraju ključnu ulogu kao deo klasa i objekata:
Funkcije i OOP u C++
U okviru klasa, funkcije se nazivaju metodama. One omogućavaju objektima da izvršavaju zadatke i manipulišu svojim podacima.
Primer:
using namespace std;
class Krug {
double poluprecnik;
public:
// Konstruktor za inicijalizaciju poluprečnika
Krug(double r) {
// Metoda za izračunavanje površine
double povrsina() {
int main() {
Krug k(5.0);
// Poziv metode
cout << "Površina kruga je: " << k.povrsina() << endl;
return 0;
Metode kao što je povrsina()
omogućavaju enkapsulaciju logike u klase, čineći kod modularnijim i čitljivijim.
Klasa Krug: Definiše privatni podatak poluprecnik
i javnu metodu povrsina()
, koja izračunava površinu kruga.
Konstruktor: Inicijalizuje poluprecnik
prilikom kreiranja objekta.
Metoda povrsina(): Vraća površinu kruga koristeći formulu π r2.
Glavna funkcija (main): Kreira objekat klase Krug
, poziva metodu povrsina()
i ispisuje rezultat.
Napredne teme u korišćenju funkcija
Lambda izrazi
Lambda izrazi su anonimne funkcije koje se mogu koristiti kao argumenti ili kao povratne vrednosti iz drugih funkcija. Omogućavaju koncizno definisanje funkcija unutar koda, bez potrebe za zasebnom definicijom.
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> brojevi = {1, 2, 3, 4, 5};
int faktor = 2;
std::for_each(brojevi.begin(), brojevi.end(), [&faktor](int &n) { n *= faktor; });
for (int n : brojevi) {
std::cout << n << std::endl;
}
return 0;
}
Ovaj kod koristi lambda izraz da pomnoži svaki broj u vektoru sa zadatim faktorom. Lambda funkcija prima referencu na svaki element i množi ga sa faktorom.
Funkcijski pokazivači
Funkcijski pokazivači omogućavaju prosleđivanje funkcija kao argumenata drugim funkcijama, čime se postiže veća fleksibilnost koda i omogućava dinamička promena ponašanja programa.
#include <iostream>
void prikaziPoruku() {
std::cout << "Zdravo, svet!" << std::endl;
}
void izvrsiFunkciju(void (*f)()) {
f(); // Poziv prosleđene funkcije
}
int main() {
izvrsiFunkciju(prikaziPoruku);
return 0;
}
Ovaj primer pokazuje kako koristiti funkcijske pokazivače za prosleđivanje funkcije kao argument. Funkcija izvrsiFunkciju
prihvata pokazivač na funkciju i poziva je unutar svog tela.
Preopterećenje funkcija
Preopterećenje funkcija omogućava definisanje više funkcija sa istim imenom, ali sa različitim brojem ili tipovima parametara. Na taj način se omogućava fleksibilnije pozivanje funkcija sa različitim vrstama podataka.
#include <iostream>
void ispisi(int broj) {
std::cout << "Broj: " << broj << std::endl;
}
void ispisi(std::string tekst) {
std::cout << "Tekst: " << tekst << std::endl;
}
int main() {
ispisi(42);
ispisi("Programiranje u C++");
return 0;
}
U ovom primeru, funkcija ispisi
je preopterećena i može da radi sa različitim tipovima podataka – celim brojevima i stringovima. Preopterećenje omogućava intuitivniji i čitljiviji kod.
Dodatne napredne teme: Šabloni i Lambda funkcije
Pored gore navedenih tema, moderni C++ (C++11 i noviji) uvodi moćne karakteristike kao što su lambda funkcije i šabloni. Lambda funkcije omogućavaju definisanje funkcija direktno unutar izraza, dok šabloni omogućavaju pisanje generičkih funkcija koje rade sa različitim tipovima podataka.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <typename T >
T maksimalniElement(T a, T b) {
return (a > b) ? a : b;
}
int main() {
// Primer lambda funkcije: sabiranje elemenata vektora
vector<int> brojevi = {1, 2, 3, 4, 5};
int suma = 0;
for_each(brojevi.begin(), brojevi.end(), [&suma](int n) {
// Dodaj svaki element na sumu
suma += n;
});
cout << "Suma: " << suma << endl;
// Primer funkcije sa šablonom za pronalaženje maksimuma
cout << "Maksimum od 3 i 7: " << maksimalniElement(3, 7) << endl;
cout << "Maksimum od 3.5 i 2.1: " << maksimalniElement(3.5, 2.1) << endl;
return 0;
}
Objašnjenje poslednjeg primera:
U gornjem primeru, šablonska funkcija maksimalniElement
je definisana za pronalaženje maksimuma od dve vrednosti. Ova funkcija radi sa bilo kojim tipom podataka koji podržava operator >
. Takođe, lambda funkcija korišćena u std::for_each
iterira kroz vektor celih brojeva i sabira njegove elemente. Upotreba lambda izraza i šablona je karakteristična za moderni C++ (C++11 i noviji), što omogućava fleksibilniji i generički kod.
Preklapanje funkcija
Preklapanje funkcija omogućava definisanje više funkcija sa istim imenom, ali sa različitim brojem ili tipovima parametara. Ovo omogućava intuitivnije pozivanje funkcija sa različitim vrstama podataka.
#include <iostream>
using namespace std;
void ispisi(int broj) {
cout << "Celobrojna vrednost: " << broj << endl;
}
void ispisi(std::string tekst) {
cout << "Tekstualna vrednost: " << tekst << endl;
}
int main() {
ispisi(42);
ispisi("Pozdrav");
return 0;
}
Inline funkcije
Inline funkcije su one koje se umesto poziva u kodu ekspandiraju direktno, što može poboljšati performanse za vrlo male funkcije. One se definišu korišćenjem ključne reči inline
.
#include <iostream>
using namespace std;
inline int saberi(int a, int b) {
return a + b;
}
int main() {
int rezultat = saberi(3, 4);
cout << "Rezultat: " << rezultat << endl;
return 0;
}
Ugnježdene funkcije (Lambda izrazi)
C++ ne podržava ugnježdene funkcije u tradicionalnom smislu, ali lambda izrazi omogućavaju definisanje funkcija unutar drugih funkcija. Ovo se često koristi za kratke operacije koje se izvršavaju u okviru funkcije.
#include <iostream>
using namespace std;
int main() {
// Lambda funkcija za sabiranje dva broja
auto saberi = [](int a, int b) -> int {
return a + b;
};
int rezultat = saberi(10, 20);
cout << "Rezultat lambda funkcije: " << rezultat << endl;
return 0;
}
Objašnjenje:
Preklapanje funkcija: U gornjem primeru, funkcija ispisi
je preopterećena tako da može da obradi i celobrojne i tekstualne vrednosti. Ovo omogućava fleksibilnije korišćenje iste funkcije za različite tipove podataka.
Inline funkcije: Funkcija saberi
je deklarisana kao inline, što znači da se njen kod ubacuje direktno na mesto poziva, smanjujući overhead poziva funkcije, što je korisno za jednostavne operacije.
Ugnježdene funkcije (Lambda izrazi): Iako C++ ne podržava tradicionalno ugnježdene funkcije, lambda izrazi omogućavaju definisanje funkcija unutar funkcije. U gornjem primeru, lambda funkcija saberi
se definiše unutar funkcije main
i koristi se za sabiranje dva broja.
Primer upotrebe funkcija u većim projektima
U većim projektima, funkcije se koriste za organizaciju koda, poboljšanje čitljivosti i omogućavanje lakšeg održavanja. Na primer, razmotrimo simulaciju sistema za upravljanje studentskim podacima.
Struktura projekta
- main.cpp – Glavni fajl koji pokreće program
- student.hpp / student.cpp – Klase i funkcije za rad sa studentima
- bazaPodataka.hpp / bazaPodataka.cpp – Funkcije za manipulaciju bazom podataka
Implementacija
U nastavku je prikazan pojednostavljeni primer kako se funkcije koriste za organizaciju rada sa studentima.
student.hpp (Definicija strukture studenta)
#ifndef STUDENT_HPP
#define STUDENT_HPP
#include <iostream>
#include <string>
struct Student {
std::string ime;
std::string prezime;
int indeks;
void prikaziPodatke();
};
#endif
student.cpp (Implementacija metoda)
#include "student.hpp"
void Student::prikaziPodatke() {
std::cout << "Student: " << ime << " " << prezime << ", Indeks: " << indeks << std::endl;
}
bazaPodataka.hpp (Deklaracija funkcija za upravljanje studentima)
#ifndef BAZA_PODATAKA_HPP
#define BAZA_PODATAKA_HPP
#include "student.hpp"
#include <vector>
class BazaPodataka {
private:
std::vector<Student> studenti;
public:
void dodajStudenta(const Student& s);
void prikaziSveStudente();
};
#endif
bazaPodataka.cpp (Implementacija funkcija)
#include "bazaPodataka.hpp"
#include <iostream>
void BazaPodataka::dodajStudenta(const Student& s) {
studenti.push_back(s);
}
void BazaPodataka::prikaziSveStudente() {
for (const auto& s : studenti) {
s.prikaziPodatke();
}
}
main.cpp (Glavni program)
#include "bazaPodataka.hpp"
int main() {
BazaPodataka bp;
Student s1 = {"Marko", "Marković", 202301};
Student s2 = {"Ana", "Anić", 202302};
bp.dodajStudenta(s1);
bp.dodajStudenta(s2);
bp.prikaziSveStudente();
return 0;
}
Objašnjenje
- Korišćenjem posebnih fajlova za različite komponente, kod postaje modularan i lakši za održavanje.
- Klasa BazaPodataka omogućava rad sa kolekcijom studenata, dok se manipulacija pojedinačnim studentima obavlja kroz klasu Student.
- Funkcije pomažu da se izdvoje pojedinačne operacije, čime se povećava ponovna upotrebljivost koda.
Dodatni resursi
-
cppreference.com - Functions
Detaljna dokumentacija sa primerima o funkcijama u C++. -
GeeksforGeeks - Functions in C++
Praktični primeri i objašnjenja funkcija u C++ jeziku. -
LearnCpp - Functions
Sveobuhvatan vodič za učenje funkcija i drugih koncepata C++ jezika. -
Svet Programiranja - Glavna stranica
Lokalni resursi na srpskom jeziku za programere. -
Rekurzivni algoritmi u C++
Stranica posvećena rekurziji i njenoj primeni u programiranju.
Za dodatna pitanja i objašnjenja, kontaktirajte nas putem formi za kontakt.