FUNKCIJE U C PROGRAMSKOM JEZIKU
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
- Deklaracija funkcija
- Definisanje funkcija
- Pozivanje funkcija
Deklaracija funkcija
povratni_tip ime_funkcije(tip_argumenta1 argument1, tip_argumenta2 argument2, ...);
// Deklaracija funkcije koja računa zbir dva broja
int zbir(int a, int b);
int main() {
printf("Zbir je: %d\n", rezultat); // Ispis rezultata na ekran
return 0; // Kraj programa
// Definicija funkcije zbir koja vraća zbir dva broja
int zbir(int a, int b) {
Definisanje funkcija
- Naredbe funkcije
- zaglavlje funkcije
- telo 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.
Pozivanje funkcija
Jedina funkcija koja se automatski pozove prilikom startovanja aplikacije je main funkcija.
Naredbe u main se izvršavaju redom, odozdo na dole, i kada se završi poslednja naredba, program se završava. Ako u projektu imamo definisano još funkcija, one se neće izvršiti same od sebe. Da bi program iz main nastavio izvršenje u nekoj drugoj funkciji, jedna od naredbi u main mora biti poziv te funkcije.
U primeru na slici 3 poziva se funkcija max:
printf("Veći broj je %d\n", max(A, B));
Deklaracija poziva funkcije, u opštem slučaju, izgleda:
naziv_funkcije(parametar1, parametar2, ...);
Parametri koji se prosleđuju funkciji se kopiraju redom u parametre definisane u funkciji (vidi sliku 2). U definiciji funkcije, ispred naziva parametra stavlja se 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: Odeđivanje maksimuma dva broja-rešenje u jeziku c
Učitati dva cela broja i odrediti njihov maksimum koristeći prethodno definisanu funkciju.
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:
// Deklaracija funkcije koja menja vrednost lokalno
void promeni_vr(int x);
int main() {
int broj = 20;
printf("Početna vrednost: %d\n", broj);
// Poziv funkcije koja menja vrednost lokalno
promeni_vr(broj);
printf("Nakon promene u main: %d\n", broj);
return 0; // Završetak programa
// Definicija funkcije koja menja vrednost lokalno
void promeni_vr(int x) {
x = 200;
printf("Vrednost unutar funkcije: %d\n", x);
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 pokazivaču.
Prenos parametara funkcije po pokazivaču
Više o pokazivačima vidi u lekciji Pokazivači u jeziku C.
Prethodni primer sada izgleda kao na slici 10:
Primeri funkcija sa različitim tipovima povratnih vrednosti i argumentima
Primer:
void pozdrav() {
int main() {
return 0;
Objašnjenje:
- Funkcija pozdrav nema povratnu vrednost jer koristi povratni tip void.
- Izvodi samo jednu akciju - ispisuje poruku.
2. Funkcija sa povratnom vrednošću tipa int
Kod:
int zbir(int a, int b) {
int main() {
printf("Zbir je: %d\n", rezultat);
return 0;
Funkcija zbir uzima dva argumenta (a i b) i vraća njihov zbir kao rezultat.
3. Funkcija sa povratnom vrednošću tipa double
Kod:
double povrsinaKruga(double r) {
int main() {
double povrsina = povrsinaKruga(r);
printf("Površina kruga je: %.2lf\n", povrsina);
return 0;
4. Funkcija sa povratnom vrednošću tipa string
void pozdravPoruka(char ime[], char rezultat[]) {
int main() {
char rezultat[50]; // Prostor za rezultat
pozdravPoruka(ime, rezultat);
printf("%s\n", rezultat);
return 0;
- 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.
Primeri sa funkcijama
Primer 1: Štampanje niza
Napišite program u C jeziku koji koristi funkciju za ispis članova niza.
Kreirajte funkciju stampaj_niz koja prima ceo niz i njegovu dužinu, i
ispisuje elemente niza u jednom redu. U main funkciji:
- Pročitajte ceo broj n (veličina niza) sa ulaza.
- Napravite niz dužine n i popunite ga unosom od korisnika.
- Pozovite funkciju
stampaj_nizda prikažete unesene elemente.
Kratko objašnjenje zadatka:
Cilj je da praktično primenite deklarišanje i definisanje funkcije, način prosleđivanja niza u C (pogled na argument A[])
i poziv funkcije iz main. Obratite pažnju na redosled operacija: prvo unos veličine, zatim unos elemenata,
pa poziv funkcije za ispis.
#include <stdio.h> #include <stdlib.h> /* Funkcija koja prima niz i njegovu duzinu i ispisuje elemente */ void stampaj_niz(int A[], int n) {// Ispis zaglavlja radi preglednosti printf("stampaj_niz:\n"); // štampa naslov // Prolazimo kroz sve elemente niza i štampamo ih for(int i = 0; i < n; i++){} int main() {printf("%d ", A[i]);} printf("\n"); // prelaz u novi red nakon ispisaint n; // Ucitavanje velicine niza scanf("%d", &n); // Dinamicki alociran lokalni niz: VAZNO: u standardnom C-u pre C99 ovaj nacin nije podrzan; pri C99 i kasnije VLAs su dozvoljeni int niz[n]; // Unos elemenata niza for(int i = 0; i < n; i++){}printf("Unesi %d. element niza\n", (i+1)); // Pitamo za element (i+1) radi citljivosti scanf("%d", &niz[i]); // Citamo vrednost u niz[i]} // Poziv funkcije koja ispisuje niz stampaj_niz(niz, n); return 0; // Signal da je program uspešno završen
Objašnjenje (nastavak)
- prima parametre int A[] i int n (niz i njegova dužina). Napomena: u C-u A[] u deklaraciji zapravo postaje pokazivač na prvi element, tj. A je ekvivalentno int *.
- ne vraća vrednost (zato je tip void) — njena jedina svrha je da prikaže (ispisuje) podatke na standardni izlaz.
- Šta znači "%d"? — to je mesto u format stringu gde će printf ubaciti vrednost celobrojnog tipa (integer) koja je navedena kao sledeći argument.
- Šta znači A[i]? — to je i-ti element niza; u semantičkom smislu A[i] je isto što i *(A + i) (aritmetika pokazivača).
- Obavezno proslediti dužinu niza — funkcija ne može sama da sazna koliko je elemenata u nizu.
- Bezbednost: uvek vodite računa da n bude validna (npr. nenegativna) pre nego što pristupate A[i], kako biste izbegli pristup van granica niza.
- Alternativa za starije C standarde: ako ne koristite VLA (variable length arrays), umesto int niz[n]; koristite dinamičku alokaciju (malloc) ili fiksni maksimalni niz.
- Mogućno proširenje zadatka: napišite dodatne funkcije, npr. int suma(int A[], int n) ili int max(int A[], int n), i testirajte ih iz main.
Primer 2 Pomeri elemente niza ulevo (rotacija)
Napišite funkciju u C jeziku koja pomera sve elemente niza za jedno mesto ulevo (ciklična rotacija). Funkcija treba da modifikuje niz in-place i pri tome poslednji element treba da postane prethodno prvi element.
- Kreirajte funkciju
ciklus_levokoja prima parametreint A[]iint n. - U main funkciji: pročitajte veličinu n, unesite n elemenata niza, pozovite
ciklus_levoi zatim prikažite rezultat pozivom pomoćne funkcijestampaj_niz. - Obratite pažnju na ivične slučajeve: n <= 1 (niz se ne menja).
Kratko objašnjenje zadatka:
Cilj je da demonstrirate kako se niz menja direktno u funkciji (prosleđivanjem pokazivača na prvi element) i da razumete jednostavnu algoritamsku operaciju pomeranja elemenata (O(n) vremenska složenost).
#include <stdio.h> #include <stdlib.h> /* Funkcija ciklicnog pomeranja niza ulevo za jedno mesto */ void ciklus_levo(int A[], int n) {// Ako je n manje ili jednako 1 nema sta da se pomera if (n <= 1) {} void stampaj_niz(int A[], int n) {return;} // Sacuvamo prvi element u privremenu promenljivu int b = A[0]; // Pomeramo svaki element ulevo: A[i-1] = A[i] for (int i = 1; i < n; i++) {A[i - 1] = A[i];} // Na kraj stavljamo sacuvani prvi element A[n - 1] = b;printf("stampaj_niz:\n"); for (int i = 0; i < n; i++) {} int main() {printf("%d ", A[i]);} printf("\n");int n; // Ucitavanje velicine niza scanf("%d", &n); // Napomena: koristi se VLA (C99). Ako trebate kompatibilnost sa starijim standardima, koristite malloc. int niz[n]; for (int i = 0; i < n; i++) {}printf("Unesi %d. element niza\n", (i + 1)); scanf("%d", &niz[i]);} // Poziv funkcije za pomeranje ulevo ciklus_levo(niz, n); // Ispis rezultata stampaj_niz(niz, n); return 0;
Objašnjenje rešenja
-
Funkcija
ciklus_levoje tipa void — ne vraća vrednost, već menja sadržaj niza koji je prosleđen (u C-u se niz prosleđuje kao pokazivač na prvi element). - Prvo proveravamo if (n <= 1) — kod nizova dužine 0 ili 1 nema pomeranja i odmah izlazimo.
-
Sačuvamo prvi element u promenljivu
b, jer će on biti prepisan prilikom pomeranja ostalih elemenata. -
for petljom prolazimo od indeksa 1 do n-1 i dodeljujemo
A[i-1] = A[i]— time pomeramo svaki element ulevo za jedno mesto. -
Nakon petlje, na poslednju poziciju
A[n-1]postavljamo prethodno sačuvani prvi elementb, čime je rotacija kompletirana. -
Algoritam radi u mestu (in-place), koristi konstantnu dodatnu memoriju (samo jednu promenljivu
b) i ima vremensku složenost O(n). -
Bezbednosne napomene: uvek proverite validnost
npre pristupa elementima (da nije negativan), i kod produkcijskih rešenja razmislite o upotrebi dinamičke alokacije umesto VLA ako vam je potrebna kompatibilnost sa starijim C standardima.
Proširenje zadatka (opciono): Napišite funkciju ciklus_desno koja pomera elemente niza ciklično udesno za jedno mesto, ili generičku funkciju
rotate(int A[], int n, int k) koja rotira niz za k pozicija (pozitivno ulevo, negativno udesno).
Primer 3: Funkcija za brojanje karaktera u C stringu
Napišite funkciju u C jeziku koja prima C-style string (niz tipa char) i vraća broj karaktera u tom nizu (bez završnog null znaka).
Funkcija treba da prebroji znakove i vrati tu vrednost kao int.
U main-u pročitajte string sa ulaza, pozovite funkciju i ispišite rezultat.
- Kreirajte funkciju
duzinasa potpisomint duzina(const char s[]). - U main-u učitajte liniju teksta (koristeći fgets) i uklonite mogući završni newline prije poziva funkcije.
- Testirajte za prazan string (treba vratiti 0) i za niz sa razmacima.
Kratko objašnjenje zadatka:
Cilj je pokazati kako u C-u funkcija prima niz (koji je u funkciji zapravo pokazivač na prvi element),
kako se stringovi završavaju sa posebim znakom '\0' i kako iteracijom prebrojavamo elemente do prvog null znaka.
#include <stdio.h> #include <stdlib.h> /* Funkcija koja prebrojava karaktere u C-stringu (bez '\\0') */ int duzina(const char s[]) {int i = 0; while (s[i] != '\0') {} int main() {i++;} return i;char s[256]; // Učitaj liniju sa standardnog ulaza (do 255 karaktera + '\\0') if (fgets(s, sizeof(s), stdin) == NULL) {}return 0;} // Uklanjamo eventualni '\\n' koji dodaje fgets int j = 0; while (s[j] != '\0') {if (s[j] == '\n') {} // Poziv funkcije koja vraća dužinu int len = duzina(s); printf("Length: %d\n", len); return 0;s[j] = '\0'; break;} j++;
Objašnjenje rešenja
-
Funkcija
duzinaprima parametarconst char s[]. U deklaraciji to je ekvivalentnoconst char * s— dakle, u funkciji radimo sa pokazivačem na prvi karakter niza. -
String u C-u je niz karaktera koji se završava nul-znakom
'\0'. Funkcija prebrojava elemente dok ne naiđe na taj terminator. SvakoA[i](ovdes[i]) predstavlja pojedinačni karakter. -
U main-u koristimo fgets da bismo bezbedno pročitali liniju (umesto scanf sa
%s, koji prestaje na prvom razmaku). Pošto fgets uključuje znak novog reda ako ga ima, uklanjamo ga pre pozivaduzinada bismo dobili broj korisnih karaktera. - Funkcija vraća int koji predstavlja broj karaktera (0 za prazan string). Algoritamski vremenska složenost je O(n), gde je n dužina stringa.
-
Važno: ne pokušavajte da koristite
sizeofu funkciji da biste odredili dužinu stringa —sizeof(s)u funkciji će vratiti veličinu pokazivača, ne dužinu niza. Zato je neophodno iterativno prebrojavanje ili korišćenje standardne strlen funkcije iz <string.h>. - Edge cases: Ako je ulazna linija prazna (samo enter), funkcija vraća 0. Ako je string duži od bafera (255 znakova), fgets će učitati samo početni deo — za potpunu podršku koristite dinamičku alokaciju i loop za čitanje.
Proširenje (opciono): Implementirajte varijantu koja vraća size_t i koristi const unsigned char * za ispravno brojanje byte/karaktera kod proširenih ASCII/UTF-8 scenarioa, ili jednostavno pozovite strlen iz <string.h>.
Više o radu sa tekstom u C jeziku pročitajte u članku: Stringovi u C jeziku
Naprednije funkcije
1. Funkcija koja vraća pokazivač
#include <stdio.h>
#include <stdlib.h>
int* kreirajNiz(int n) {
if (niz == NULL) {
return NULL;
for (int i = 0; i < n; i++) {
return niz;
int main() {
int* niz = kreirajNiz(n);
if (niz != NULL) {
for (int i = 0; i < n; i++) {
printf("\n");
free(niz); // Oslobađanje memorije
return 0;
- Funkcija kreirajNiz dinamički alocira niz i vraća pokazivač na prvi element.
- main funkcija koristi ovaj pokazivač da bi pristupila i ispisala vrednosti u nizu.
- Nakon korišćenja, memorija se oslobađa pomoću free(niz).
2. Korišćenje funkcijskih pokazivača
// Deklaracija funkcije koja sabira dva broja
int saberi(int a, int b) {
// Funkcija koja oduzima dva broja
int oduzmi(int a, int b) {
// Funkcija koja prima pokazivač na funkciju
int obradi(int x, int y, int (*operacija)(int, int)) {
int main() {
printf("Sabiranje: %d\n", obradi(a, b, saberi));
printf("Oduzimanje: %d\n", obradi(a, b, oduzmi));
return 0;
- Definisane su dve funkcije: saberi i oduzmi.
- obradi funkcija prima pokazivač na funkciju kao argument i poziva odgovarajuću operaciju.
- U main funkciji se poziva obradi sa različitim operacijama.
3. Funkcija koja sortira niz pomoću pokazivača na funkciju
// Funkcija za poređenje rastućeg reda
int rastuce(int a, int b) {
// Funkcija za poređenje opadajućeg reda
int opadajuce(int a, int b) {
// Implementacija bubble sort algoritma sa pokazivačem na funkciju
void bubbleSort(int arr[], int n, int (*compare)(int, int)) {
arr[j] = arr[j + 1];
arr[j + 1] = temp;
// Ispis niza
void prikaziNiz(int arr[], int n) {
printf("\n");
int main() {
int n = sizeof(niz) / sizeof(niz[0]);
printf("Originalni niz: ");
prikaziNiz(niz, n);
bubbleSort(niz, n, rastuce);
printf("Sortiran rastuće: ");
prikaziNiz(niz, n);
bubbleSort(niz, n, opadajuce);
printf("Sortiran opadajuće: ");
prikaziNiz(niz, n);
return 0;
- bubbleSort funkcija prima pokazivač na funkciju compare, što omogućava menjanje kriterijuma sortiranja bez menjanja koda sortiranja.
- U main funkciji se niz sortira prvo rastuće, a zatim opadajuće.
Primeri sa funkcijama i njihova memorijska organizacija
1. Osnovni primer funkcije sa objašnjenjem memorijske organizacije
Pogledaćemo kako se podaci prenose u memoriji.
// Funkcija koja prima dva cela broja i vraća njihov zbir
int saberi(int a, int b) {
return rezultat; // Povratna vrednost se skladišti u registar (ili stek u zavisnosti od arhitekture)
int main() {
int zbir = saberi(x, y); // Poziv funkcije - argumenti se stavljaju na stek ili u registre
printf("Zbir: %d\n", zbir);
return 0;
Šta se dešava u memoriji prilikom poziva saberi(x, y)?
Alokacija memorije na steku
- x i y su promenljive u main funkciji i čuvaju se na steku.
- Kada se pozove saberi(x, y), vrednosti x i y se stavljaju na stek ili prosleđuju putem registara (zavisi od kompajlera).
Izvršavanje funkcije
- Funkcija saberi dobija kopije vrednosti x i y.
- Nova promenljiva rezultat se kreira na steku i dodeljuje joj se zbir a + b.
Vraćanje rezultata
- Povratna vrednost funkcije se skladišti u posebnom registru procesora (npr. EAX u x86 arhitekturi) ili na steku.
- Nakon povratka iz funkcije, zbir u main funkciji dobija ovu vrednost.
Čišćenje steka
- Memorija zauzeta parametrima i promenljivom rezultat se oslobađa kada funkcija završi.
2. Funkcija sa pokazivačima i promene u memoriji
// Funkcija koja menja vrednosti preko pokazivača
void zameni(int* a, int* b) {
*a = *b; // Menja vrednost na adresi a
*b = temp; // Menja vrednost na adresi b
int main() {
printf("Pre zamene: x = %d, y = %d\n", x, y);
zameni(&x, &y); // Prosleđujemo adrese promenljivih
printf("Posle zamene: x = %d, y = %d\n", x, y);
return 0;
Šta se dešava u memoriji prilikom zameni(&x, &y)?
Alokacija memorije na steku
x i y su promenljive smeštene na steku main funkcije.
Kada pozovemo zameni(&x, &y), u stek funkcije zameni se smeštaju pokazivači na x i y.
Manipulacija podacima kroz pokazivače
*a pokazuje na vrednost x, a *b na y.
Zamena se odvija direktno u memoriji, tako da se x i y u main funkciji menjaju.
Povratak iz funkcije
Po završetku zameni, memorija zauzeta parametrima i temp promenljivom se oslobađa.
Pošto su vrednosti x i y promenjene na originalnim adresama, rezultat je trajna promena.
3. Funkcija sa dinamičkom alokacijom memorije
#include <stdlib.h>
// Funkcija koja kreira dinamički niz i vraća pokazivač na njega
int* kreirajNiz(int n) {
if (niz == NULL) {
return NULL;
for (int i = 0; i < n; i++) {
return niz; // Vraćamo pokazivač na prvi element
int main() {
int* niz = kreirajNiz(n);
if (niz != NULL) {
for (int i = 0; i < n; i++) {
printf("\n");
free(niz); // Oslobađanje memorije
return 0;
Šta se dešava u memoriji?
Poziv kreirajNiz(5)
- Alocira se memorija na HEAP-u za
ncelih brojeva. - Pokazivač
nizukreirajNizpokazuje na početak tog bloka memorije.
Vraćanje pokazivača
- Pokazivač
nizse prenosi nazad umain, gde se koristi za ispis vrednosti.
Oslobađanje memorije (free(niz))
- Memorija na HEAP-u ostaje zauzeta sve dok eksplicitno ne pozovemo
free(niz). - Bez
free, imali bismo curenje memorije (memory leak).
Povezivanje sa srodnim temama
Da biste stekli dublje razumevanje funkcija u C jeziku, preporučujemo da pogledate sledeće srodne teme:
- Pokazivači u C jeziku – Osnovni koncepti pokazivača, njihova uloga u funkcijama i rad sa dinamičkom memorijom.
- Dinamički nizovi u C – Objašnjenje alokacije i dealokacije memorije pomoću
malloc,freei drugih funkcija. - Rekurzija u C – Kako funkcije mogu pozivati same sebe i kada je rekurzija korisna.
- Nizovi u C jeziku – Prolazak nizova kroz funkcije i razlike između prolaza vrednošću i referencom.
Ove teme su usko povezane sa funkcijama i omogućavaju bolje razumevanje kako funkcije upravljaju podacima i memorijom u C jeziku.

