You are on page 1of 94

Funkcije

Potprogrami:
• dekompozicija složenih problema
na jednostavnije
• procesna apstrakcija
• samo funkcije (nema procedura)
• funkcija - n-arni operator
najvišeg prioriteta
• vraća rezultat (preko imena) +
bočni efekti, oboje opciono
Definisanje funkcija
tip ime(argumenti) telo

ime funkcije
• identifikator
tip funkcije
• mogu svi standardni skalarni tipovi,
kao i korisnički definisani tipovi
• po starim verzijama može izostati i
onda se podrazumeva tip int
• void – funkcija ne vraća vrednost
Definisanje funkcija

tip funkcije
• ako stoji * ispred imena – vrednost
funkcije je pokazivač na objekat
navedenog tipa
• može i generički pokazivač (void *),
pokazivač na pokazivač, ...
• vrednost mora da bude
samo jedan objekat
(zato tip ne može biti niz)
ali može biti pokazivač
Definisanje funkcija
argumenti funkcije
• formalni (u definiciji) – parametri
• stvarni (u pozivu) - argumenti
• može bez parametara – f() ili f(void)
• unošenje vrednosti i
iznošenje rezultata
• proizvoljan broj argumenata
razdvojenih sa ,
• definišu se kao i promenljive,
ali tip i kvalifikator za svaki posebno
(npr. double x, double y)
Definisanje funkcija

argumenti funkcije
• argument može da bude niz
zadatog tipa ili
pokazivač na dati tip (int *a)
• za 1-D niz ne mora dužina, samo []
(int a[])
• za n-D moraju se navesti dužine za
sve dimenzije osim za prvu
(int b[][5])
Definisanje funkcija

kvalifikatori ispred oznake argumenta


tipa pokazivača ili niza
• const – funkcija neće da promeni
vrednost objekta na koji pokazuje
argument
• volatile – pokazivani objekt
može da promeni vrednost
mimo kontrole programa
nema efekta za druge tipove
Definisanje funkcija
telo funkcije
• blok: deklaracije + naredbe
(oboje opciono)
• promenljive lokalne za funkciju
• oblast važenja -
od mesta definicije do kraja funkcije
• inicijalizacija –
izrazi koji, osim konstanti,
mogu da sadrže i formalne
argumente
Prenos argumenata

• formalni argumenti se smatraju


lokalnim promenljivima

• inicijalizuju se vrednostima
stvarnih argumenata

• vrednosti stvarnih argumenata


se ne mogu promeniti u funkciji
(prenos po vrednosti – by value)
Prenos argumenata

• iznošenje rezultata preko


argumenata pokazivačkog tipa

• pokazivač se ne menja

• menja se vrednost pokazanog


objekta (bočni efekat)

• indirektan pristup
Prenos argumenata

• skalarni - po vrednosti

• nizovi - po referenci (adresi)


(ne prenose se vrednosti niza!)

• kako je indeksiranje praktično


indirektno adresiranje
nije potrebna posebna notacija
za pristup komponentama
Prenos argumenata

• nizovi sa ili bez navođenja dužine


• čak i ako se navede po prvoj dimenziji
konkretna vrednost dužine, pri pozivu
dužina može biti proizvoljna
• za ostale dužine provera slaganja je
moguća ako su nepromenljive
• u slučaju neslaganja dimenzija (osim
prve) nepredvidljive posledice
Prenos argumenata

int f1(int a[5]) {…}


int f2(int n, int a[n]) {…};
int f3(int a[3][5]) {…}
int f4(int m, int n, int a[m][n]) {…}
int main(){
int i, t[5], u[3][5];
i=f1(t); i=f2(5, t);
i=f3(u); i=f4(3,5,u);
i=f1(u[2]); i=f2(5, u[2]);
}
Prenos argumenata
int f1(int a[5]) {…}
int f2(int *a) {…};
int f3(int a[][8]) {…}
int f4(int (*a)[8]) {…}
int f5 (int *a[5]) {…}
int f6 (int **a) {…}
int f7(int n, int a[][n]) {…}
int f8(int n, int (*a)[n]) {…}
int main(){
int i, t[5], u[3][8], *v[5];
i=f1(t)+f2(t); i=f3(u)+f4(u);
i=f5(v)+f6(v); i=f7(8,u)+f8(8,u);
}
Ograničeni parametri

• Za funkcije čiji pokazivački parametri


treba da pokazuju na različite nizove
• Kada je pokazivač, restrict kao
modifikator, a kada je niz, onda u
prvim [], ispred eventualne dužine
• Informacija za prevodilac i
programera, na kome je odgovornost
• Ako ipak ne važi restrikcija,
posledice nepredvidljive
Ograničeni parametri

void kopiraj(const int *restrict izv,


int odr[restrict], int n) {
for (int i=0; i<n; i++)odr[i] = izv[i];
}
int main() {
int a[10], b[20];

kopiraj(a,b,10);
kopiraj(b,b+10,10);
kopiraj(b, b+5, 10); //preklapanje!
}
Definisanje funkcija

povratak iz funkcije

• naredba return

• argument – izraz
koji predstavlja vrednost funkcije

• ako je potrebno, konverzija tipa


Definisanje funkcija

povratak iz funkcije

• ako je funkcija tipa void,


return ne sme da ima izraz

• return može da se izostavi,


ako je poslednja naredba

• u funkciji može više naredbi return


Definisanje funkcija

mesto definisanja funkcije:

• ista ili druga datoteka

• ispred ili iza poziva

• ne može u okviru funkcije


Pozivanje funkcija

• ime funkcije (stvarni argumenti)

• može i adresni izraz


čija je vrednost adresa funkcije
(preko pokazivača)

• operator najvišeg prioriteta (16)


Pozivanje funkcija

poziv se vrši

• u okviru izraza
• ako funkcija ne vraća vrednost ili ona
nije potrebna =>
poziv može i kao posebna naredba
• još može i u nizu izraza, kao i u
ternarnom izrazu kao izraz2 ili izraz3
Pozivanje funkcija

stvarni argumenti pri pozivu

• izrazi proizvoljne složenosti i tipa


čija vrednost inicijalizuje
formalne argumente

• izračunavaju se proizvoljnim
redosledom pre pozivanja funkcije
Pozivanje funkcija
stvarni argumenti pri pozivu

• treba da se slažu po broju,


tipu i poretku sa formalnim

• po potrebi se konvertuju
u tip fomalnih

• mogu biti i adresni izrazi


(npr. ime niza i adresa)
Pozivanje funkcija

stvarni argumenti pri pozivu

• ako je stvarni argument niz izraza,


mora se staviti u zagrade
(zbog zareza)

 na primer f(a,b,c) i f(a,(b,c))


Primer definisanja

/* izračunavanje skalarnog proizvoda */

#include <stdio.h>

double skal_pro(double a[], double b[], int n) {


double zbir = 0;
int i;

for (i=0; i<n; i++)


zbir += a[i] * b[i];

return zbir;
}

Primer pozivanja

/* izračunavanje skalarnog proizvoda */

main () {

double x[100], y[100];


int i, k;

printf ("Duzina vektora:");


scanf ("%d", &k);


Pozivanje funkcija

/* izračunavanje skalarnog proizvoda */

printf ("Komponente vektora X:");


for (i=0; i<k; i++)
scanf ("%lf", x+i);

printf ("Komponente vektora y:");


for (i=0; i<k; i++)
scanf ("%lf", y+i);

printf ("skalarni proizvod X*Y:%g\n",


skal_pro(x,y,k));
}
Primer definisanja

/* izračunavanje polarnih koordinata */

#include <stdio.h>
#include <math.h>

void polar (double x, double y, double *pr, double *pfi)


{
*pr = sqrt(x*x + y*y);
*pfi = (x==0 && y==0)? 0 : atan2(y,x);
}
...
Primer pozivanja

/* izračunavanje polarnih koordinata */

int main () {
double x, y, r, fi;

while (printf("x, y :"),


scanf("%lf%lf",&x,&y)!=1E38) {
polar(x,y,&r,&fi);
printf ("r, fi: %g,%g\n",r,fi);
}
}
Ugrađene funkcije

• Prevod tela funkcije se ugrađuje u kod na mestu


svakog poziva
• Modifikator inline sugeriše prevodiocu da ugrađuje
prevod (što ne mora biti i urađeno)

inline int max(int i, int j) {


return ( (i>j) ? i : j; ) }
Naredbe c = max(a, b);
d = max(a++, b++);
Prevode se kao:
c = (a>b) ? a : b;
a++; b++; d = (a>b) ? a : b;
Ugrađene funkcije
• Navođenjem prototipa sa modifikatorom extern, može
se učiniti da funkcija bude sa spoljašnjim
povezivanjem
• Tada u datoteci postoji i uobičajeni prevod funkcije
koja se može pozvati iz iste i iz drugih datoteka
• Od prevodioca zavisi da li prilikom poziva u istoj
datoteci vrši ugrađivanje ili koristi neugrađenu
varijantu
inline void zameni(int *i, int *j) {
int k=*I; *i=*j; *j=k; }
extern void zameni (int *, int *);
• Isti extern protiotip navodi se u drugoj datoteci, gde se
funkcija može pozivati, i tada se uvek koristi
neugrađena varijanta
Funkcije koje se ne vraćaju

• Ove funkcije nikada se ne vraćaju na mesto sa koga su


pozvane, npr. zato što prekidaju rad programa
• Modifikator _Noreturn sugeriše prevodiocu da je u
pitanju takva funkcija
• Ukoliko u funkciji postoji return generiše se greška ili
upozorenje
• Prekidanje rada programa: pozivom bibliotečke
funkcije exit iz <stdlib.h> čiji je prototip:
_Noreturn exit(int status);
• Za status se koristi imenovana konstanta
EXIT_SUCESS (za uspešan završetak) ili EXIT_FAILURE
za neuspešan završetak, definisane u <stdlib.h>
Obrada programskog sistema

• čitav programski sistem


se sastoji od proizvoljnog broja
funkcija

• glavni program –
funkcija int main() koju poziva OS
Obrada programskog sistema

• može u više datoteka,


ali jedna funkcija mora
u celini unutar datoteke

• poredak smeštanja funkcije


proizvoljan
Obrada programskog sistema

prevođenje

• svaka datoteka odvojeno i


nezavisno

• svaki objekt mora biti


unapred deklarisan
po poretku linija izvornog teksta
Obrada programskog sistema

prevođenje

• ako je funkcija kasnije definisana


(ili izvan datoteke), pre poziva
se mora navesti prototip (potpis)
funkcije
Obrada programskog sistema

prototip

• praktično zaglavlje funkcije


(bez bloka)

• navodi spolja vidljive osobine


funkcije (tip kao i argumente),
ali ne i sadržaj
Obrada programskog sistema

prototip

• ne rezerviše prostor

• jednom naredbom može


više funkcija
sa istim osnovnim tipom
Obrada programskog sistema

prototip

• argumenti mogu da se navode i


bez imena
(služe samo da sugerišu namenu)

• provera broja i tipova argumenata


nije obavezna po standardu
Obrada programskog sistema

• Prototipski doseg: u nizu


parametara identifikatori vidljivi do
kraja deklaracije funkcije

• Kod nekih prevodilaca:


 prototip može biti nepotpun
(bez argumenata)
 može i da izostane
(predpostavlja se int)
Obrada programskog sistema

prototip

• ako se piše u deklarativnom delu


funkcije, onda vidljiv samo u njoj

• može izvan tela drugih funkcija


(tada vidljiv za sve u nastavku)
Lokalne i globalne
promenljive

lokalne

• promenljive definisane
na početku tela funkcije
• važe samo unutar funkcije,
nevidljive za druge funkcije
• mogu ista imena u različitim
funkcijama - različite promenljive
Lokalne i globalne
promenljive

globalne

• definišu se izvan funkcija

• oblast važenja –
od mesta definicije
do kraja datoteke
Lokalne i globalne
promenljive

globalne

• zajedničke za sve funkcije


samo između mesta definicije
i kraja datoteke

• mogu služiti za prenos podataka


između funkcija
Lokalne i globalne
promenljive

korišćenje globalne promenljive


u funkciji gde nije automatski vidljiva

• obavezna deklaracija
(samo osobine)
• nema dodele prostora
i inicijalizacije
• koristi se službena reč extern
ispred
Lokalne i globalne
promenljive

korišćenje globalne promenljive


u funkciji gde nije automatski vidljiva

• kod nizova dovoljne samo zagrade,


ne moraju dimenzije
• ako je deklaracija u nekoj funkciji,
važi samo unutar funkcije
Lokalne i globalne
promenljive

korišćenje globalne promenljive


u funkciji gde nije automatski vidljiva

• ako je izvan funkcije


važi do kraja datoteke
• redundantne deklaracije dozvoljene
(na početku datoteke i u funkciji)
Lokalne i globalne
promenljive

globalni identifikatori – spoljašnji


(po standardu bar 6 značajnih slova)

kad lokalna i globalna imaju isto ime


važi lokalna u funkciji
Lokalne i globalne
promenljive

prenos podataka
preko globalnih promenljivih

• efikasniji nego preko argumenata

• manje fleksibilan
(svaki poziv obrađuje iste
promenljive)
Lokalne i globalne
promenljive
/* primer prenosa podataka preko globalnih promenljivih */
/* jedna datoteka, 1 deo */

#include <stdio.h>
#include <math.h>

double x, y, r, fi;

void polar (void) {


extern double x, y, r, fi; /* redudantno */
r = sqrt(x*x+y*y);
fi = (x==0 && y==0)? 0 : atan2(y,x);
}
...
Lokalne i globalne
promenljive
/* primer prenosa podataka preko globalnih promenljivih */
/* jedna datoteka, 2 deo */

int main () {

extern double x, y, r, fi; /* redudantno */

while (printf("x, y :"),


scanf("%lf%lf",&x,&y), x!=1e38) {
polar();
printf ("r, fi: %g,%g\n",r,fi);
}
}
Lokalne i globalne
promenljive
/* primer prenosa podataka preko globalnih promenljivih */
/* dve datoteka; prva datoteka */

#include <math.h>

extern double x, y, r, fi;

void polar (void) {


extern double x, y, r, fi; /* redudantno */

r = sqrt(x*x+y*y);
fi = (x==0 && y==0) ? 0 : atan2(y,x);
}
...
Lokalne i globalne
promenljive
/* primer prenosa podataka preko globalnih promenljivih */
/* dve datoteka; druga datoteka */

#include <stdio.h>

double x, y, r, fi;
void polar (void);

int main () {
extern double x,y,r,fi;

while (printf("x, y :"),scanf("%lf%lf",&x,&y),x!=1e38) {


polar();
printf ("r, fi: %g,%g\n", r, fi);
}
}
Blokovska struktura
programa

svaka sekvenca se smatra blokom

može i da definiše promenljive

 lokalne za blok i nevidljive izvan njega

 važe od mesta definicije do kraja bloka


Blokovska struktura
programa

može i da definiše promenljive

 ako je ime isto sa globalnom


promenljivom ova je nedostupna za blok

 globalna za sve blokove unutar tog bloka

 promenljive u obuhvatajućim blokovima


globalne za njega
Blokovska struktura
programa
#include <...>

int i, j, k; // int i, j, k;

char pp1 (...) {


float a, b, i; // int j, k; float a, b, i;
if (...) {
int j, a, x; // int j, k, a, x; float b, i;
for (..;..;..){
double a, j; // int k, x; float b, i; double a, j;
...
}
} else {
char j; // int k; float a, b, i; char j;
...
}
}
int e, h; // int i, j, k, e, h; char pp1;
...
Blokovska struktura
programa
...
int e, h; // int i, j, k, e, h; char pp1;

double pp2 (char k, ...) { // int i, j, e, h; char pp1, k;


char a, x, i; // int j, e, h; char pp1, i, k, a, x;
{
int h; // int j, e, h; char pp1, i, k, a, x;
...
}
{
long h; // int j, e; char pp1, i, k, a, x; long h;
...
}
}
// int i, j, k, e, h; char pp1; double pp2;
int main () {
float x, y, z, i; // int j, k, e, h; char pp1; double pp2; float x, y, z, i;
...
}
Kategorije promenljivih

prema načinu korišćenja

 globalne
 statičke
 automatske
 registri

određuju se prefiksom u naredbi


za definiciju promenljive
Kategorije promenljivih

globalne promenljive

• definišu se izvan funkcija

• njihova imena postaju jedinstvena


za čitavi programski sistem

• ako je izvorni program u više datoteka,


globalna promenljiva se:
 definiše samo u jednoj datoteci
 definiše sa extern u ostalim
Kategorije promenljivih

globalne promenljive

• postoje za čitavo vreme izvršavanja

• mogu se inicijalizovati početnim


vrednostima kao konstantnim izrazima

• ako se ne inicijalizuju, podrazumeva se 0


Kategorije promenljivih

statičke promenljive:

• definišu se ili deklarišu sa static na


početku

• postoje do kraja programa


(vrednosti se čuvaju između
poziva)
Kategorije promenljivih

statičke promenljive:

• statičke definisane izvan funkcija su


lokalne za datoteku (vide se samo u njoj)

• statičke definisane unutar funkcije su


lokalne za funkciju
 formiraju se na početku izvršavanja
 inicijalizuju se eksplicitno ili se smatra 0
Kategorije promenljivih

automatske promenljive

• definišu se samo unutar funkcija ili


blokova

• default za promenljive koje ne navode


prefiks (extern, static ili register)

• eksplicitno sa auto
Kategorije promenljivih

automatske promenljive

• pri svakom pozivu se ponovo formiraju

• inicijalizacija
 izrazima koji mogu da sadrže promenljive,
ali sa definisanim vrednostima
 ako nema eksplicitne početne vrednosti,
onda slučajno
Kategorije promenljivih

registri

• automatske promenljive za koje se želi


alokacija u registrima

• ne garantuje se stvarna alokacija registara

• prefiks register

• nedozvoljena primena adresnog operatora


Pretprocesor jezika C

• vrši pripremnu obradu izvornog


teksta programa

• posebne naredbe u posebnim


redovima i počinju sa #
Pretprocesor jezika C

vrši transformacije izvornog programa

• umetanje sadržaja tekstualne datoteke


na određeno mesto

• zamena leksičkih simbola


novim nizovima simbola

• uslovno uključivanje ili izostavljanje


delova teksta
Pretprocesor jezika C

umetanje sadržaja datoteke

• naredba #include sa zadatim imenom


datoteke

• ako je ime između "" datoteka se trazi u


istom katalogu kao i izvorni program

• ako se ne nađe ili je između <>, traži se u


sistemskim katalozima
Pretprocesor jezika C

umetanje sadržaja datoteke

• koristi se za duže sekvence


deklarativnih naredbi

• npr. deklaracije bibliotečkih


funkcija (zaglavlja - prototipovi) iz
sistemskog kataloga
Pretprocesor jezika C

zamena leksičkih simbola

• naredba #define zamenjuje


svako pojavljivanje identifikatora
zadatim nizom simbola

• naredba #undef identifikator poništava


efekt odgovarajuće #define naredbe
Pretprocesor jezika C

za definiciju makroa

• iza identifikatora u zagradama može da


bude niz argumenata odvojenih zarezima

• kao formalni argumenti koji se javljaju u


nizu iza zagrada

• stvarni argumenti u daljem tekstu -


proizvoljni nizovi simbola
Pretprocesor jezika C

#define se može produžiti


u naredni red ako se na kraj stavi \

#define MAX_DUZ 1000


#define ZAUVEK for(;;)
#define MAX(A,B) ((A)>(B)?(A):(B))
Pretprocesor jezika C

preporučuje se stavljanje zagrada


oko svakog formiranog argumenta
u makrou, jer stvarni argument
može da sadrži operatore viših prioriteta

npr. zamena pri pojavi:


x=MAX(p+q, r+s);
Pretprocesor jezika C

uslovno prevođenje:
#if izraz
prevodi do #else ili #endif ako je izraz tačan
#ifdef ime
prevodi ako je ime prethodno def. sa #define
#ifndef ime
prevodi ako ime nije prethodno def. sa #define
#else
početak alternativnog bloka
#endif
kraj uslovnog bloka
Rekurzivne funkcije

Funkcije koje indirektno ili direktno


pozivaju same sebe

• svode se na rešavanje istog problema


sa promenljivim parametrima

• da bi konvergirao, postoje neke


specijalne nerekurzivne vrednosti
funkcije
Rekurzivne funkcije

• pogodno za inherentno rekurzivne


algoritme (npr. faktorijel,
Fibonaccijevi brojevi, ...)

• manje efikasna od iterativnih


(po utrošku vremena ili memorije)

• otkrivanje grešaka
teže nego kod iterativnih
Rekurzivne funkcije

Rekurzivno izračunavanje faktorijela

• int fakt(int n) {
return (n>0) ? (n*fakt(n-1)):1;}

• N+1 puta se
 poziva funkcija
 inicijalizuje formalni argument
 ispituje vrednost argumenta,
 oduzima i množi, uključući čuvanje i
obnavljanje steka
Rekurzivne funkcije

Iterativno izračunavanje faktorijela

• int fakt (int n) {


int i, f;
for (i=f=1; i<=n; f*=i++);
return f;
}
• mnogo efikasnije (nema poziva)
Pokazivači na funkcije

• funkcije su objekti
na koje se može pokazivati

• sve uobičajene operacije su


dozvoljene nad takvim pokazivačima
Pokazivači na funkcije

standardne naredbe za
definiciju promenljivih, npr.

• double (*pf)(float, int);


pokazivač pf na funkciju tipa double
sa argumentima tipa float i int

• double *f(float, int);


prototip funkcije čija je vrednost
pokazivač na objekte tipa double
Pokazivači na funkcije

pri pozivu

• *f(x, n)
prvo se poziva funkcija
(zbog višeg prioriteta),
a zatim indirektno adresiranje

• (*pf)(x, n)
prvo indirektno adresiranje na pokazivač pf,
a zatim poziv funkcije
Pokazivači na funkcije

identifikator funkcije sam za sebe (slično nizu)


predstavlja pokazivač na tu funkciju

• npr. :

 ako je double fct(float, int);


 nakon pf = fct, pf pokazuje na funkciju fct
 pa (*pf)(x,n) poziva funkciju fct()
Pokazivači na funkcije

Primer:

/* program za tabeliranje realne funkcije realnog arg. */

#include <stdio.h>

void tabela (double (*pf)(double),


double x1, double x2, double dx) {
double x;
printf ("\n x f(x) \n");
for (x=x1; x<=x2; x+=dx)
printf("%20.10lf%20.10lf\n", x, (*pf)(x));
}
...
Pokazivači na funkcije

/* glavni program za prikaz rada potrpograma */

int main() {

double x1, x2, dx, oscilac(double);

printf("x1, x2, dx:");


scanf("%lf%lf%lf", &x1, &x2, &dx);
tabela (oscilac, x1, x2, dx);
}
...
Pokazivači na funkcije

/* primer funkcije za tabeliranje */

#include <math.h>

double oscilac (double x)


{
return exp(-0.1*x)*sin(x);
}

Prvi argument potrpograma tabela –


pokazivač pf na funkciju koja se tabelira
njen poziv sa (*pf)(x)
Argumenti glavnog programa

• pri startovanju C programa,


u istoj komandi OS
mogu se predati parametri
glavnom programu

• glavni program se iz OS-a


poziva kao funkcija
sa dva argumenta
Argumenti glavnog programa

int main (int argc, const char * argv[])

• argc - broj parametara u komandi


uključujući i samu komandu

• argv - niz pokazivača dužine argc+1


na znakovne nizove (reči iz komande)
poslednji pokazivač argv[argc] = NULL
Argumenti glavnog programa

Npr. komanda echo

/* program ia ispisivanje poruke na ekranu */

#include <stdio.h>

int main (int argc, const char * argv[]) {


int i;
for (i=1; i<argc; i++)
printf ("%s%c",argv[i],
(i<argc-1)?(' '):('\n'));
}
Argumenti glavnog programa

Pisanje funkcija po staroj notaciji

 unutar zagrada samo imena argumenata


 tipovi argumenata ispred tela
u posebnim naredbama
 za funkcije bez argumenata se ne piše void
 prototip samo tip (ne i argumente)
i piše se izvan funkcija
Funkcije sa promenljivim brojem
argumenata

• Pozvana funkcija sama mora otkriti


broj i tipove prosleđenih
argumenata
• Primer: scanf, printf mogu na
osnovu formata prebrojati
konverzije koje počinju sa %
• Dakle, obavezni argument mora
sadržati informaciju koliko ima
neobaveznih
Funkcije sa promenljivim brojem
argumenata

• Postoji alat za bezbedno


dohvatanje neobaveznih
argumenata
• Da bi se koristio, mora:
#include <stdarg.h>
• Sadrži makroe:
va_list, va_start, va_arg i va_end
Funkcije sa promenljivim brojem
argumenata

• Prvo se definiše pokazivač na prvi


neobavezni argument:
va_list pok_arg;
• Zatim se postavi početna vrednost
pokazivača navođenjem imena
pokazivača i imena poslednjeg
obaveznog argumenta:
va_start (pok_arg, posl_arg);
Funkcije sa promenljivim brojem
argumenata

• Uzastopni neobavezni argumenti se


dohvataju pozivajući:
va_arg (pok_arg, tip);
gde se za svaki navodi tip argumenta
• Završetak dohvatanja argumenta se
označava naredbom:
va_end (pok_arg);
Primer: zbir promenljivog broja
argumenata

#include <stdarg.h>
int zbir (int n, ...) {
int s,i; va_list pa; va_start (pa,n);
for (s=i=0; i<n; i++)
s+=va_arg(pa, int);
va_end(pa);
return s;
}
Primer: zbir promenljivog broja
argumenata

#include <stdio.h>
int main() {
printf (“1+2= %d\n”, zbir(2,1,2));
printf (“1+2+3= %d\n”,
zbir(3,1,2,3));
}

You might also like