Professional Documents
Culture Documents
One su sastavni dio svakog programskog jezika, a ovisno o mjestu ispitivanja uvjeta mogu
se podijeliti na:
programske petlje s ispitivanjem uvjeta na početku i
petlje kod kojih se uvjet ponavljanja nalazi na kraju niza naredbi koje se ponavljaju.
Niz naredbi unutar programskih petlji for i while ne mora se izvršiti niti jednom, dok će niz
naredbi unutar do-while naredbe sigurno izvršiti barem jednom.
Programska petlja for
Naredba for najčešće se primjenjuje u zadacima u kojima je broj ponavljanja unaprijed
poznat. To je najopćenitija vrsta petlje i najčešće se koristi, a ima slijedeći oblik:
gdje:
inicijalizacija znači postavljanje kontrolne varijable (i/ili dodatnih varijabli) na početnu
vrijednost,
uvjet je uvjet koji kontrolna varijabla mora zadovoljiti da bi se izvršile naredbe u petlji (blok
naredbi), a
promjena_vrijednosti je dio u kojem se definira način promjene stanja kontrolne varijable.
Kontrolna varijabla kontrolira broj prolazaka petljom, a deklarira se kao i sve ostale
varijable koje se koriste u programu. Njezina se vrijednost automatski mijenja svakim
prolaskom kroz petlju kako je to definirano promjenom_vrijednosti. U ostalim programskim
jezicima kontrolna varijabla mora biti rednog tipa (obično cijeli broj) no u C-u ona može biti i
realan broj!
Dijelovi programske petlje for mogu se i izostaviti, ali da bi se zadovoljila sintaksa C-a
obavezno je napisati nul naredbu ;
1
Ako je vrijednost uvjeta neistina, blok naredbi se preskače i program se nastavlja prvom
naredbom iza bloka.
2
Dijagram tijeka for petlje :
Inicijalizacija / promjena
vrijednosti kontrolne varijable
NE
uvjet
DA
blok naredbi
Primjer 1: Petljom:
for (i=1;i<=10;i++)
printf("\n Danas je ponedjeljak.");
će se na zaslon 10 puta ispisati rečenica «Danas je ponedjeljak.», svaki put u novi red
/*zbog konstante \n ispred početka rečenice*/.
Zašto?
Varijabla i je kontrolna varijabla, čija se vrijednost najprije postavlja na 1. Nakon toga se
provjeri uvjet (i<=10). Obzirom da je zadani uvjet istinit (jer 1 je manji od 10), na zaslon se
ispiše zadana rečenica. Zatim se, zbog promjene vrijednosti kontrolne varijable (i++), ta
vrijednost poveća za 1 (postavi na 2) i izvođenje se vraća na početak. Naredba će se
zadnji put izvršiti kada se vrijednost kontrolne varijable postavi na 10. Nakon što se
vrijednost kontrolne varijable postavi na 11, uvjet neće biti ispunjen i program kreće s
izvršavanjem prve naredbe iza naredbe for.
Vitičaste zagrade za oznaku početka i kraja bloka nisu potrebne, jer se ponavlja samo jedna
naredba. One se koriste samo u slučajevima kada se treba ponavljati više naredbi (blok
naredbi).
Ako program od zahtjeva blok naredbi za ponavljanje, a oznake početka i kraja bloka ({ i })
se izostave program će dati pogrešan rezultat. U tom slučaju, C ponavlja samo prvu
naredbu iza for. Preostale naredbe iz bloka izvršavaju se izvan naredbe ponavljanja!
Primjer 2: Petljom
for(i=100;i<=110;i++)
printf("%d ",i);
će se na zaslon ispisati brojevi 100, 101, 102, 103, 104, 105, 106, 107, 108, 109 i 110, a
petljom
for(i=100;i<=110;i+=2)
printf("%d ",i);
3
Zadatak
U programu koji slijedi napravljene su tri pogreške. Pronađite ih bez korištenja računala!
#include <stdio.h>
int br;
float i,a,s,ars;
void main()
{
printf("\n Koliko imate ucenika? ");
scanf("%d",&br);
for(i=1,i<=br,i++);
{
printf("\n Upisite ocjenu %d. ucenika: ",i);
scanf("%f",&a);
if ((a<1)||(a>5))
i--;
else
s+=a;
}
ars=s/br;
printf("\n Srednja ocjena razreda je %.2f",ars);
}
Rješenje:
unutar for petlje, početna vrijednost i uvjet ponavljanja odvajaju se znakom ;
uvjet ponavljanja i promjena vrijednosti kontrolne varijable odvajaju se znakom ;
iza for naredbe ne smije se pisati ; jer se blok koji slijedi neće ponavljati u petlji
Petlje for mogu se i ugnježđivati, što znači pisati jedna unutar druge:
U tom slučaju, kada se jednom promjeni vrijednost kontrolne varijable vanjske petlje,
potpuno se izvrši unutarnja petlja (vrijednosti njezine kontrolne varijable promjene se od
početne do završne). Tek tada se ponovo promjeni vrijednost kontrolne varijable vanjske
petlje. Ako se vanjska petlja izvršava n puta, a unutarnja m, ugniježđene petlje izvršit će se
n*m puta
int i,j;
for(i=0;i<=6;i+=5)
for(j=1;i<=7;j+=3)
printf("\ni + j = %d",i, j);
4
0, 7
Tada unutarnja petlja (po j) staje, jer je uvjet lažan. Povećava se vrijednost kontrolne
varijable i (i= 5), pa se ponovo izvršava unutarnja petlja i poprima vrijednosti: 1, 4 i 7.
Ispis na zaslon:
1, 1
1, 4
1, 7
Slijedeće povećanje kontrolne varijable i je na 10 pa uvjet nije istinit što znači da prestaje
izvršavanje petlji.
Zadatak:
Napraviti program koji će na zaslon ispisati sve Pitagorine brojeve u intervalu od 2 do 50.
Osim tog podatka program treba ispisati i koliko Pitagorinih brojeva ima u danom intervalu.
/* Pitagorini brojevi su uređene trojke brojeva (a, b, c) za koje vrijedi da je a2 + b2 = c2) */
Rješenje:
#include <stdio.h>
#include <math.h>
void main (void)
{
int a,b,c,koliko=0;
for(a=2;a<=50;a++)
for(b=a;b<=50;b++)
for(c=b;c<=50;c++)
if (pow(a,2)+pow(b,2)==pow(c,2))
{
printf("\n %d, %d, %d", a,b,c);
koliko++;
}
printf("\n Ima ih %d", koliko);
}
Zadaci za vježbu:
1. Bez utipkavanja programa odgovorite na pitanje: Kada se slijedeći program izvrši, što će
se ispisati na zaslonu?
#include <stdio.h>
int i;
void main()
{
for(i=20;i<=30;i+=3)
printf("%d ",i);
}
a) }
#include <stdio.h>
void main ()
{
int n=5,i;
long int f=1;
for (i=2;i<=n;i++) f=f*i;
printf(" %d!=%d",n,f);
5
b) int a=2, x=3,y=1,i;
#include <stdio.h> for (i=1;i<=x;i++) y=a*y;
void main () printf(" rezultat je %d",y);
{ }
#include <stdio.h>
int i=1,br;
float a,s,ars;
void main()
{
printf("\n Koliko imate ucenika? ");
scanf("%d",&br);
for(i<=br)
{
printf("\n Upisite ocjenu %d. ucenika: ",i);
scanf("%f",&a);
if ((a<1)||(a>5)) i--;
else
{
s+=a;
i++;
}
}
ars=s/br;
printf("\n Srednja ocjena razreda je %.2f",ars);
}
Kada napravite ispravan program odgovorite na pitanje: Kako glasi tekst zadatka kojim bi se
zadao prethodni program?
#include <stdio.h>
void main()
{
int i=1;
for(;i<=7;i++)
printf("%d \n",i);
}
int i,j;
for(i=5,j=0;i<=10;i+=2,j++)
{
printf("\ni = %d j = %d",i,j);
}
6. Napravite program koji će na zaslon ispisati prvih 20 prirodnih brojeva, ali u obrnutom
redoslijedu (od 20 do 1)
7. Napraviti program koji će zbrojiti sve cijele brojeve između 500 i 600 koji su djeljivi sa 11.
Uz rezultat zbroja, program treba na zaslon ispisati i koliko ima takvih brojeva.
6
8. Napraviti program koji će tražiti unošenje prirodnog broja n (n<10) Program treba
izračunati i ispisati na zaslon n! ( n! 1 2 3 n )
3 5
32 3413
2. Napraviti program koji će tražiti unošenje prirodnog broja n i realnog broja x. Program
treba izračunati i ispisati na zaslon rezultat zbroja
x3 x5 x7 x 2 n 1
S x
3! 5! 7! (2n 1)!
Test primjeri:
5 10
1 1.57
0.89 1.16
3. Napravite program koji će od korisnika tražiti unošenje dva cijela broja. Program treba
pomnožiti zadane brojeve koristeći samo operaciju zbrajanja.
Testni primjeri:
3, 2 30, 50
6 600
a znači slijedeće:
Uvjet je aritmetički ili logički izraz. Blok naredbi u petlji se ponavlja sve dok je uvjet istinit
ili različit od 0. Kad uvjet postane lažan ili jednak 0 program nastavlja izvođenje prvom
naredbom iza while bloka. Obzirom da se uvjet ponavljanja ispituje na početku petlje, to
znači da blok naredbi unutar petlje ne mora nužno biti izvršen niti jednom.
NE
uvjet
DA
blok naredbi
Kao i kod ostalih složenih naredbi, tako i kod while vrijedi činjenica da oznake početka i
kraja bloka ({, }) nisu neophodne ako se unutar bloka nalazi samo jedna naredba!
Prilikom postavljanja uvjeta potrebno je voditi računa o tome da on mora u jednom
trenutku postati lažan. U protivnom će program ući u beskonačnu petlju!
Primjer: Koristeći while naredbu program na zaslon ispisuje prvih 10 prirodnih brojeva.
#include <stdio.h>
void main()
{
int i=1;
while(i<=10)
{
printf("%d ",i);
i++;
}
}
#include <stdio.h>
float s;
void main()
{
int p=1,i,n;
printf("\n Upisite jedan broj: ");
scanf("%d",&n);
8
while(i=1;i<=n;i+=2)
{
s+=(float)p/i;
p=-p;
}
printf("\n suma je %.3f",s);
}
Rješenje:
Konstrukcija (i=1;i<=n;i+=2) karakteristična je za for petlju, a ne za while.
Početna vrijednost kontrolne varijable postavlja se ispred while naredbe, a
promjena njezine vrijednosti događa se unutar while bloka.
#include <stdio.h>
float s;
void main()
{
int p=1,i=1,n;
printf("\n Upisite jedan broj: ");
scanf("%d",&n);
while(i<=n)
{
s+=(float)p/i;
i+=2;
p=-p;
}
printf("\n suma je %.3f",s);
}
1 1 1 1
S 1
To je program koji za učitani broj n računa zbroj: 2 3 4 n.
Zadatak: Bez utipkavanja programa odgovorite na pitanje: Kada se slijedeći program izvrši,
što će se ispisati na zaslonu?
#include <stdio.h>
void main()
{
int i=1,s=0;
while(i<=5)
{
s+=i;
i+=2;
}
printf("\n Trazeni zbroj je %d",s);
}
Zašto?
1. korak:
Vrijednost kontrolne varijable i je 1. Pri prvom ulasku u while petlju, provjerava se uvjet.
Obzirom da je uvjet istinit (vrijedi da je 1<5) izvršava se blok naredbi iza while naredbe.
Vrijednost varijable s uvećava se za 1 (1 je vrijednost varijable i) pa postaje 1. Nakon toga
vrijednost varijable i se uvećava za 2 i postaje 3.
9
2. korak:
Sada se program vraća na provjeravanje uvjeta. 3<5 i uvjet je zadovoljen. Vrijednost
varijable s postaje 4 (prethodna vrijednost varijable s (1) uvećana za vrijednost varijable i
(3)), a vrijednost varijable i ponovo se uvećava za 2 i postaje 5.
3. korak:
Kod ponovne provjere uvjeta, vrijednost kontrolne varijable je 5, pa je uvjet još uvijek istinit
(5=5). Izvršavanjem bloka naredbi iza while, vrijednost varijable s postaje 9 (5+4), a
vrijednost kontrolne varijable je 7 (5+2).
4. korak:
Povratkom na provjeru uvjeta, pokazuje se da uvjet više nije istinit (7>5) i izvršavanje
programa nastavlja se sa slijedećom naredbom iza while bloka. U ovom slučaju to je
naredba za ispis vrijednosti varijable s. Dakle na zaslon će se ispisati 9.
Zadaci za vježbu:
1. Bez utipkavanja programa odgovorite na pitanje: koliko puta će se izvršiti slijedeća
petlja?
int i=100,suma=0;
while(i)
{
suma+=--i;
i++;
}
a) b)
#include <stdio.h> #include <stdio.h>
void main() void main()
{ {
int s=0, n; int s=0, i=1, n, znam;
printf ("\n Upisite broj: "); printf ("\n Upisite broj: ");
scanf("%d",&n); scanf("%d",&n);
while (i=1;i<=n) while (n!=0)
{ {
s+=i; znam=n%10;
i+=3; s+=znam;
} }
printf("Zbroj je %d",s); n/=10;
} printf("Zbroj je %d",s);
}
Nakon ispravljenih pogreški odgovorite na pitanje: Kako glase tekstovi kojima bi se zadali
prethodni programi?
3. Bez utipkavanja programa odgovorite na pitanje: Kada se slijedeći program izvrši, što će
se ispisati na ekranu?
#include <stdio.h>
void main()
{
int i=1,f=1,n=6;
while(i<=n)
{
10
f*=i;i++;
}
printf("\n %d! = %d",n,f);
}
4. Napravite program koji će od korisnika tražiti upisivanje jednog prirodnog broja, Program
treba upisani broj rastaviti na proste faktore.
Test primjer:
12
12=1*2*2*3
1. Napraviti program koji, koristeći Euklidov algoritam za traženje najveće zajedničke mjere
dva broja, skraćuje uneseni razlomak (Unosi se posebno brojnik, a posebno nazivnik danog
razlomka).
Primjer:
veći manji
ostatak
18 12
6
2. Među neparnim brojevima mogu se izdvojiti samo oni kojima je svaka znamenka
neparna. Nazovimo ih "potpuno neparni brojevi". Napravite program koji će za uneseni cijeli
broj ispisati je li ili nije potpuno neparan.
Testni primjeri:
1325 3793
3. Napravite program
koji Nije potpuno Potpuno je omogućuje
unošenje neparan neparan cijelih brojeva sve
dok se ne unese 0. program
treba na zaslon ispisati koliko od unesenih brojeva ima barem jednu parnu znamenku.
Testni primjer:
11
5
4. Napravite program koji omogućuje unošenje cijelih brojeva sve dok se ne unese 0.
program treba na zaslon ispisati koliko od unesenih brojeva ima točno jednu neparnu
znamenku.
Testni primjer:
do
blok naredbi;
while (uvjet);
a znači slijedeće:
radi
{
ponavljaj naredbe unutar bloka
}sve dok je uvjet ispunjen
12
Dijagram tijeka naredbe do-while:
blok naredbi
NE
uvjet
DA
#include <stdio.h>
void main()
{
int i=1;
do
{
printf("%d ",i);
i++;
}while(i<=10);
}
#include <stdio.h>
void main()
{
int i=11;
do
{
printf("%d ",i);
i++;
}while(i<=10);
}
Zašto?
Početna vrijednost kontrolne varijable je 11 i ona ne zadovoljava dani uvjet, ali uvjet se
provjerava tek na kraju i sve naredbe koje se nalaze ispred provjere uvjeta će se izvršiti. Tek
13
kada se provjeri uvjet, program izlazi van iz petlje. Zbog toga treba biti izuzetno oprezan
prilikom korištenja petlje s provjerom uvjeta na kraju bloka naredbi.
Zadatak 1:
Koje od slijedećih do-while oblika nisu ispravni i zašto?
a) c)
i=1 i=1;
do (i<=10) do
{ {
printf("%d ",i); printf("%d ",i);
i++; } while(i<=10);
}while;
d)
b) i=1;
i=1 do
while {
{ printf("%d ",i);
printf("%d ",i); i+=2;
i++;
}do(i<=10); } while(i<=10);
Rješenje:
Oblik a) nije ispravan jer se uvjet ponavljanja u do-while petlji treba nalaziti na kraju
bloka naredbi koje se ponavljaju.
Oblik b) nije ispravan jer ključna riječ do mora biti na početku, a while na kraju bloka
naredbi
Oblik c) ima ispravnu sintaksu, ali ima logičku pogrešku. Kontrolna varijabla i nigdje ne
mijenja svoju vrijednost, cijelo vrijeme ostaje 1. Program će ući u beskonačnu petlju.
Oblik d) je ispravan i na zaslon će ispisati brojeve: 1, 3, 5, 7 i 9, jer se kontrolna varijabla
i povećava za 2 prilikom svake promjene vrijednosti.
Zadatak 2.
Kolika je vrijednost varijable a nakon izvođenja slijedećih naredbi:
int a=0;
do
a++;
while (a>10);
Zašto?
Rješenje:
Varijabla a=1, jer uvjet nije ispunjen. S obzirom da se uvjet ispituje na kraju, jednom se
izvrši naredba unutar petlje!
Zadatak 3.
Kolika je vrijednost varijabli a i b nakon izvođenja slijedećeg niza naredbi:
int a=10,b;
do
{
b=a/2;
a=pow(a,2);
} while (a<50);
Rješenje:
14
a=100, b=5
Zadaci za vježbu:
1. Što će se ispisati na zaslon monitora nakon izvođenja slijedećeg programa?
#include <stdio.h>
void main()
{
int i=1, s=0;
do
{
s+=i;
i++;
}while (i<=10);
printf("%d ",s);
}
2. Napraviti program koji će pomoću do-while petlje zbrojiti troznamenkaste brojeve djeljive
sa 19. Osim dobivenog zbroja, program treba na zaslon ispisati i koliko ima takvih brojeva.
Test primjer:
3. Napravite program koji će korisniku omogućiti učitavanje brojeva sve dok se ne unese
-1. Program treba ispisati na zaslon koliko je među unesenim brojevima onih koji su djeljivi s
5.
Testni primjeri:
13,2,1,7,6,28,-1 15,21,5,10,13,-1
0 3
4. Napravite program koji će omogućiti unošenje brojeva sve dok se ne unese broj koji je
djeljiv s 3. Program treba ispisati koliko je ukupno uneseno brojeva (uključujući i posljednji
unesen broj) i njihov zbroj.
Testni primjeri:
2,7,13,17,21 4,22,41,32,16,18
ima ih 5 ima ih 6
zbroj: 60 zbroj: 133
1. Napraviti program koji će tražiti unošenje prirodnog broja n. Program treba pronaći i
ispisati na zaslon najmanji prost broj koji je veći od n.
/* Prosti brojevi su prirodni brojevi koji su djeljivi samo sa 1 i sa samim sobom */
15
2. Napraviti program koji će od korisnika tražiti unošenje realnog broja x. Program treba na
S sin( x ) 0.0001
zaslon ispisati prirodni broj n za koji vrijedi da je , gdje je
x3 x5 x7 x 2 n 1
S x
3! 5! 7! (2n 1)! .
Primjer: Petlja
for (i=2;i<n/2;i++)
if(n%i) break;
printf("\n Broj %d nije prost",i);
Naredba continue omogućuje preskakanje dijela bloka naredbi unutar petlje. Kada se
nalazi unutar bloka naredbi petlje, naredbe iza nje se preskaču i program se vraća na
uvjetni izraz koji omogućuje nastavak izvršavanja naredbi u petlji.
Primjer: Petljom
for (i=1;i<=50;i++)
{
if(i%3) continue;
printf("\n Broj %d je djeljiv s 3",i);
}
će se na zaslon ispisati svi brojevi iz intervala od 1 do 50 koji su djeljivi s 3. Ukoliko broj nije
djeljiv s 3 (i%3 je različito od 0) naredba koja slijedi se preskače i izvršavanje se nastavlja
od uvjeta ponavljanja! Ukoliko je broj djeljiv s 3 izvršava se naredba printf!
Ponovimo
Naredbe ponavljanja koriste se kada se isti dijelovi programa trebaju više puta ponoviti.
Programski jezik C razlikuje tri naredbe za ponavljanje. To su:
for petlja, kod koje se uvjet ponavljanja provjerava na početku i sadrži kontrolnu varijablu
while petlja, kod koje ponavljanje ovisi o uvjetu koji se nalazi na početku bloka naredbi koje
se ponavljaju i
do-while petlja, kod koje ponavljanje također ovisi o uvjetu, ali se uvjet nalazi na kraju bloka
naredbi koje se ponavljaju.
Ovisno o problemu koji se rješava, programer sam odlučuje koja naredba ponavljanja je
najbolji izbor.
Opći oblici spomenutih naredbi su:
for (inicijalizacija; uvjet; promjena_vrijednosti)
{
blok naredbi;
}
16
}
do
blok naredbi;
while (uvjet);
za prijevremeni prekid izvršavanja naredbi u petlji koristi se naredba break
za preskakanje dijela naredbi u petlji koristi se naredba continue
Funkcije
Već je rečeno da se svi programi u C-u sastoje od jedne ili više funkcija i da je jedina
obavezna funkcija u programu funkcija main() (koja označava početak izvršavanja glavnog
dijela programa). Tijekom procesa programiranja često se neki dijelovi programa trebaju
više puta izvoditi, ali sa različitim vrijednostima varijabli.
A(x1, y1)
#include <stdio.h>
#include <math.h>
void main(void)
{
float x1,x2,x3,y1,y2,y3,d1,d2,d3,o,s,p;
printf("Uneste koordinate tocke A ");
scanf("%f,%f",&x1,&y1);
printf("\nUnesite koordinate tocke B ");
scanf("%f,%f",&x2,&y2);
printf("\nUnesite koordinate tocke C ");
scanf("%f,%f",&x3,&y3);
17
printf("\nDuljine stranica trokuta su %.2f, %.2f, %.2f",d1,d2,d3);
printf("\nOpseg je %.2f\nPovrsina je %.2f",o,p);
}
Lako se može uočiti da se za računanje udaljenosti među točkama zapravo koristi ista
formula, ali sa različitim vrijednostima. Takve dijelove programa praktično je izdvojiti u
zasebne cjeline, korisnički definirane funkcije i pozivati ih po potrebi.
Rješavamo li problem na takav način, možemo reći da se bavimo strukturnim
programiranjem.
zadatak
To znači da je funkcija u C-u isto što i funkcija, potprogram i procedura u ostalim višim
programskim jezicima. One omogućavaju razlaganje problema na jednostavnije i manje
cjeline, čime doprinose boljoj preglednost izvornog koda i jednostavnijem pronalaženju i
otklanjanju pogrešaka. Također, korištenjem funkcija dolazi do značajnih ušteda
memorijskog prostora.
Funkcije se ne moraju koristi samo da bi se izbjeglo višestruko pisanje određenih dijelova
programa, već su praktične i ako će se izvršiti samo jednom. U tom slučaju olakšavaju
razumijevanje programa, odnosno algoritma.
Drugi način razlikuje se od prvog po tome što se argumenti funkcije najavljuju izvan
zagrade.
tip_funkcije ime_funkcije(lista_argumenata)
najava liste_argumenata;
{
najava lokalnih varijabli;
naredbe;
return izlazna_vrijednost;
}
int pomnozi(x,y)
int x,y; /*najava liste argumenata*/
{
int rez; /*najava lokalne varijable*/
rez=x*y; /*naredbe u funkciji*/
return rez; /*izlazna vrijednost*/
}
Funkciju je dovoljno definirati samo jednom. Nakon toga moguće ju je pozvati iz bilo
kojeg dijela programa. Funkcije u C-u mogu vratiti u glavni program jednu ili niti jednu
vrijednost (što je određeno tipom funkcije). Za to se koristi naredba return koja prenosi
izlaznu vrijednost u nadređeni program. Funkcija se prestaje izvršavati nailaskom na prvu
return naredbu.
Funkciji koja ne vraća nikakvu vrijednost dodjeljuje se tip podataka void. Takve funkcije
služe za obavljanje niza radnji, recimo za ispis, i ne sadrže return naredbu.
Na primjer, funkcija proba ne prenosi nikakvu vrijednost u glavni program već samo
ispisuje navedeni tekst.
void proba()
{
printf("Ovo je funkcija");
}
19
Ako u glavni program treba vratiti niz vrijednosti onda se to radi preko argumenta funkcije
koji su najavljeni kao globalne varijable. Slijedeća funkcija će u glavni program vratiti dvije
vrijednosti.
#include <stdio.h>
int a,b; /*najava globalnih varijabli*/
/*funkcija zamjene*/
void zamjena ()
{
int t; /*lokalna varijabla*/
t=a; /*zamjena koristenjem globalnih varijabli*/
a=b;
b=t;
}
void main()
{
printf("Unesite dva cijela broja ");
scanf("%d,%d",&a,&b);
printf("\nUpisali ste a=%d i b=%d",a,b);
zamjena(); /*poziv funkcije sa globalnim varijablama*/
printf("\nNakon funkcije a=%d, b=%d",a,b);
}
int proba1(int x)
{
return(x*x);
}
proba1(int x)
{
return(x*x);
}
Formalni parametri funkcije
Po samoj definiciji funkcija, njihova je namjena različita. Neke ne zahtijevaju ulazne
podatke, pa lista_argumenata može ostati i prazna (kao kod ranije navedenih funkcija proba
i zamjena). Ako ulazni podaci postoje, za svaki od njih se navodi tip podatka i identifikator.
Međusobno se odvajaju zarezom (kao kod funkcije proba1).
U funkciji proba1 identifikator x je formalni parametar koji služi za rezerviranje memorijskog
prostora. Tek pozivom funkcije na mjesto formalnog parametra učitava se u memoriju
stvarna vrijednost navedena u pozivu.
Kao što je navedeno na početku, argument funkcije se, osim unutar zagrada, može
deklarirati i ovako:
int proba1(x)
int x;
{
return(x*x);
}
iako je češće u upotrebi deklaracija kod koje se i tip i ime svakog formalnog parametra
navode unutar zagrade.
20
Poziv funkcije
Funkcija se izvršava onog trena kad je pozvana iz glavnog programa ili neke druge
funkcije.
Za poziv funkcije dovoljno je navesti njeno ime i listu stvarnih argumenata onim
redoslijedom kako su navedeni u najavi funkcije:
ime_funkcije (stvarna lista_argumenata);
Lista argumenata može biti i prazna. Ako je lista prazna onda funkcija koristi globalne
varijable (kao u primjeru funkcije zamjena) . No obavezno je pisati zagrade (), jer one
označavaju da se kontrola tijeka programa prenosi iz nadređene u pozvanu funkciju.
Funkcije se mogu pozivati u izrazima, petljama, ili kao argumenti u pozivima drugih
funkcija.
Deklaracija funkcije
Svaka funkcija se prije poziva treba najaviti.
Najava omogućava pravilnu pretvorbu različitih tipova podataka, te provjeru tipova podataka
u listi argumenata i podataka iz glavnog programa koji se prenose u funkciju.
Ako se funkcija piše na kraju glavnog programa, najavljuje se navođenjem tipa, imena i
tipa podataka ulaznih argumenata (prototip funkcije), kao što je to učinjeno u slijedećem
primjeru funkcije za računanje udaljenosti između dvije točke u pravokutnom koordinatnom
sustavu:
#include <stdio.h>
#include <math.h>
/*najava funkcije za racunanje udaljenosti*/
float udaljenost(float,float,float,float) ; /*prototip funkcije*/
Test primjer:
21
0,0
3,0
Primjer:
#include <stdio.h>
#include <math.h>
/*funkcija za racunanje udaljenosti*/
float udaljenost(float a,float b,float c,float d)
{
float dulj;
dulj=sqrt(pow(c-a,2)+pow(d-b,2));
return dulj;
}
Osim navedenih načina, definicija funkcije može biti i u odvojenoj datoteci ili unutar neke
druge funkcije. No takve se najave rjeđe koriste. U tim slučajevima obavezno je najaviti
funkciju.
Funkcija se može pojaviti kao argument druge funkcije i broj ugniježđenih funkcija nije
ograničen.
22
Primjer: Nakon izvođenja slijedećeg programa:
#include <stdio.h>
void funkcija_3()
{
printf("\nFunkcija_3"); ZAPAMTITE:
} FUNKCIJA NE MOŽE BITI
POZVANA AKO PRIJE POZIVA
void funkcija_2() NIJE NAJAVLJENA!
{
printf("\nFunkcija_2"); Stoga Funkcija_3 mora biti
funkcija_3(); najavljena prije nego je pozvana.
printf("\nOpet funkcija_2"); Obzirom da se poziva u funkciji_2
} mora biti najavljena prije nje. Isto
tako funkcija_2 je najavljena prije
void funkcija_1() funkcije_1 jer se u njoj poziva!
{
printf("\nFunkcija_1");
funkcija_2();
printf("\nOpet funkcija_1");
}
void main()
{
printf("Glavni program");
funkcija_1();
printf("\nOpet glavni program");
}
Glavni program
Funkcija_1
Funkcija_2
Funkcija_3
Opet funkcija_2
Opet funkcija_1
Opet glavni program
Zadatak:
Napraviti program koji će, koristeći funkciju za udaljenost dvije točke, izračunati i ispisati
opseg i površinu trokuta zadanog koordinatama svojih točaka u pravokutnom koordinatnom
sustavu.
Rješenje:
#include <stdio.h>
#include <math.h>
float o;
float udaljenost(float a,float b,float c,float d)
{
float dulj;
dulj=sqrt(pow(c-a,2)+pow(d-b,2));
return dulj;
23
}
float opseg (float d1, float d2, float d3)
{
o=d1+d2+d3;
return o;
}
float povrsina (float d1, float d2, float d3)
{
float s,p;
s=o/2;
p=sqrt(s*(s-d1)*(s-d2)*(s-d3));
return p;
}
void main()
{
float x1,x2,x3,y1,y2,y3,d1,d2,d3,p;
printf("Upisite koordinate tocke A ");
scanf("%f,%f",&x1,&y1);
printf("\nUpisite koordinate tocke B ");
scanf("%f,%f",&x2,&y2);
printf("\nUpisite koordinate tocke C ");
scanf("%f,%f",&x3,&y3);
Test primjer:
0,0
3,0
0,4
Stranice trokuta su 3.00, 5.00, 4.00
Opseg je 12.00
Povrsina je 6.00
Top-down metoda
Za raščlambu problema na manje zadatke, kao šo smo to radili u prethodnim primjerima
postoji i naziv: top-down metoda rješavanja zadatka. Top-down je općenit postupak koji se
ne koristi samo u programiranju. Njime se dani problem raščlanjuje na manje zadatke –
module. Pojedini moduli tada se rješavaju ili, ako je potrebno, ponovo dijele na nove
module. To je metoda koju smo i do sada koristili u svim dosadašnjim zadacima, sa
iznimkom zadataka rješavanih goto naredbom
Primjer:
Rotiramo li pravokutni trokut oko njegovih kateta i hipotenuze, dobit ćemo 4 stošca (po
jedan rotacijom oko kateta i dva spojena rotacijom oko hipotenuze). Treba pronaći stožac
sa najmanjim volumenom!
24
R 2v
V
3
c
b
vc
problem
#include<stdio.h>
#include<math.h>
#define pi 3.14
/*funkcija koja provjerava je li ucitani trokut pravokutan*/
int provjera(float x, float y, float z)
{
int p=0;
if (pow(x,2)+pow(y,2)==pow(z,2)) p=1;
return p;
}
/*funkcija koja racuna obujam stozca*/
float obujam(float r, float v)
{
float o;
25
o=(pow(r,2)*pi*v)/3;
return o;
}
float pitagora(float z, float y)
{
float x;
x=sqrt(pow(z,2)-pow(y,2));
return x;
}
/*manji od dva broja*/
float manji (float x, float y)
{
float z;
if (x<y)z=x;
else z=y;
return z;
}
void main()
{
float a,b,c,p,o1,o2,o3,o4,vc,min;
int k=0;
do
{
printf("Upisite duljine kateta pravokutnog trokuta: ");
scanf("%f, %f", &a, &b);
printf("Upisite duljinu hipotenuze: ");
scanf("%f", &c);
k=provjera(a,b,c);
}while (k==0);
p=a*b/2;
vc=(2*p)/c;
o1=obujam(a,b);
o2=obujam(b,a);
o3=obujam(vc,pitagora(a,vc));
o4=obujam(vc,pitagora(b,vc));
min=o1;
min=manji(min,o2);
min=manji(min,o3);
min=manji(min,o4);
printf("\nNajmanji obujam je %.3f", min);
}
Prijenos podataka
Podaci iz nadređenih funkcija prenose se na dva načina:
pomoću vrijednosti (call by value) ili
pomoću adrese (call by reference)
#include <stdio.h>
int funkcija(x)
{
x*=2;
26
printf("\nx u funkciji je %d",x);
}
void main(void)
{
int x=5;
funkcija(x);
printf("\nVrijednost varijable x=%d",x);
}
na zaslon će se ispisati:
x u funkciji je 10
Vrijednost varijable x=5
Zašto?
Obzirom da je početna vrijednost varijable x=5, ta vrijednost prenosi se u funkciju. U
funkciji se ulazna varijabla množi sa 2 i dobivena vrijednost se opet sprema u varijablu x.
Ispisuje se vrijednost varijable x u funkciji. No, promjena vrijednosti varijable unutar funkcije
ne prenosi se u glavnu funkciju tako da je u glavnom programu x=5.
Za prijenos podataka preko adrese koriste se pokazivači i o tome će biti više riječi u
poglavlju o pokazivačima
Svi podaci, njihove vrijednosti ili adrese, prenose se preko STOGA (eng. stack). Stog je
dinamički dio memorije koji se upotrebljava za pohranjivanje podataka koji se privremeno
koriste u određenim djelovnima programa. Broj podataka na stogu je promjenljiv. Međutim,
količina memorije za stog je ograničena. Stog se puni i prazni prema principu «zadnji unutra
– prvi van» (eng. LIFO – last in – first out)
Zadaci za vježbu:
1. Ako je definirana funkcija na slijedeći način:
broj()
{
return(7.56);
return (2);
return(10);
}
#include <stdio.h>
proba(x)
int x;
{
x=2*x;
return x;
}
void main()
{
27
int x=10,y;
y=2*proba(x);
printf("\nx=%d\ny=%d",x,y);
}
Test primjer:
3,0
5,7
Povrsina je 35.00
Opseg je 24.00
4. Napraviti program koji će omogućiti unošenje duljine stranice kocke. Program treba,
koristeći funkcije, ovisno o želji korisnika izračunati i ispisati oplošje, volumen ili duljinu
prostorne dijagonale zadane kocke.
Test primjeri:
5
1
Oplosje je 150.00
5
2
Volumen je 125.00
5
3
2. Napraviti program koji će, koristeći funkciju, za zadani prirodan broj provjeriti je li prost.
Test primjeri:
256
17
28
Broj 17 JE prost broj
3. Napraviti program koji će za uneseni prirodan broj ispisati sve njegove djelitelje.
Test primjer:
256
2 4 8 16 32 64 128
17
Rekurzivna funkcija
Rekurzivna funkcija je funkcija koja poziva samu sebe. U pravilu, rekurzivna rješenja su
kraća, ali je za njihovo izvođenje potrebno više vremena i memorije.
Svaka rekurzija mora imati uvjet zaustavljanja koji će omogućiti izlazak iz rekurzije. U
protivnom rekurzivna funkcija će se izvoditi beskonačno. Također svaki poziv rekurzije mora
se približavati uvjetu zaustavljanja.
Svi podaci, njihove vrijednosti ili adrese, prenose se preko STOGA (eng. stack). Stog je
dinamički dio memorije koji se upotrebljava za pohranjivanje podataka koji se privremeno
koriste u određenim dijelovima programa. Broj podataka na stogu je promjenljiv. Međutim,
količina memorije za stog je ograničena. Stog se puni i prazni prema principu «zadnji unutra
– prvi van» (eng. LIFO – last in – first out). Za bolje razumijevanje stoga često se koristi
analogija s hrpom tanjura (npr. u restoranima): posljednji tanjur stavljen na hrpu se uzima
prvi.
Na stogu se koriste dvije operacije: push i pop. Operacija push šalje podatak na stog dok
operacija pop skida podatak sa stoga.
Za pohranjivanje rezultata i povratak iz rekurzije upotrebljava se STOG.
n ! 1 2 3 4 5 n 1 n ? n ! n 1 ! n
Dakle n! se može izračunati ako je poznat (n-1)!, a (n-1)! može se izračunati ako je
poznat (n-2)!, itd.
29
uvjet zaustavljanja je 1!=1,
a opći oblik će biti n! n ( n 1)! .
30
Kad rekurzivna funkcija dostigne uvjet zaustavljanja, stog se prazni po principu «prvi
unutra – zadnji van». Znači, prvo se izračunava vrijednost funkcije za n = 1.
Primjer: Za nenegativan cijeli broj e slijedeće rekurzivna funkcija računa potenciju be, /*b0 =
1*/
Zadatak: Napraviti program kojim se, za uneseni prirodan broj n računa zbroj:
x x 2 x3 x 4 xn
s
1! 2! 3! 4! n!
/*iskoristite prethodnu rekurzivnu funkciju za računanje faktorijela!*/
Rješenje:
#include <stdio.h>
/*rekurzivna funkcija za racunanje potencije+/
long int potencija(int b,int e)
{
if (e==0)
return 1;
else
return b*potencija(b,e-1);
}
/*rekurzivna funkcija za racunanje faktorijela*/
long int faktorijel(int n)
{
if (n==1)
return 1;
else
return faktorijel(n-1)*n;
}
void main(void)
31
{
int x,i,y;
float s;
printf("Upisite prirodan broj x i n ");
scanf("%d,%d",&x,&y);
if (y<=0)
printf("Broj mora biti prirodan");
else
{
for (i=1;i<=y;i++)
s+=(float)potencija(x,i)/faktorijel(i);
printf("Zbroj je %.2f ",s);
}
}
Zadaci za vježbu:
1. Što će se ispisati na zaslonu monitora nakon izvođenja slijedećeg programa ako se
prilikom unosa podataka upišu vrijednosti:
a) broj=15, baza=2
b) broj=15, baza=8?
#include <stdio.h>
int pretvori (int n, int b)
{
if (n>=b) pretvori(n/b, b);
printf("%d ",n%b);
}
void main (void)
{
int broj, baza;
printf("\n Upisite jedan prirodni broj => ");
scanf("%d",&broj);
printf("\n Upisite bazu => ");
scanf("%d",&baza);
if (baza>=10)
printf("\nBaza mora biti <10");
else
pretvori(broj,baza);
}
Test primjer:
f(1)=1
f(2)=1
f(3)=2
32
f(4)=3
f(5)=5
f(6)=8
f(7)=13
Potezi su slijedeći:
zeleni disk sa prvog na treći štapić,
smeđi disk sa prvog na drugi štapić,
zeleni disk sa trećeg na drugi štapić,
plavi disk sa prvog na treći štapić,
zeleni disk sa drugog na prvi štapić,
smeđi disk sa drugog na treći štapić, i konačno
zeleni disk sa prvog na treći štapić.
Dakle za n = 3 najmanji broj poteza je 7. Za n diskova najmanji broj poteza je 2n-1. Problem
se svodi na to da na pomoćni štap stavimo n -1 disk i nakon toga n disk prebacimo na treći
štap. Dalje n -1 disk sa pomoćnog štapa analogno prenosimo na treći štap.
3. Napišite program kojim će te uporabom rekurzivne funkcije podijeliti dva učitana prirodna
broja na zadani broj decimala.
Ponovimo
Funkcije su cjelovite skupine naredbi koje izvršavanjem ispunjavaju određene zahtjeve
Omogućavaju razlaganje problema na jednostavnije manje cjeline, čime doprinose boljoj
preglednost izvornog koda i jednostavnijem pronalaženju i otklanjanju pogrešaka
Funkcija se definira na slijedeći način:
tip_funkcije ime_funkcije(najava liste_argumenata)
{
33
najava lokalnih varijabli;
naredbe;
return izlazna_vrijednost;
}
funkcija u nadređeni program vraća jednu ili niti jednu vrijednost ovisno o tipu funkcije
Za prijenos vrijednosti u nadređeni program koristi se naredba return
Funkcija se poziva na slijedeći način:
ime_funkcije(stvarna lista_argumenata);
Funkcije se mogu pozivati u izrazima, petljama, ili kao argumenti u pozivima drugih funkcija
Svaka korištena funkcija se mora najaviti prije poziva
Podaci iz nadređenih funkcija prenose se na dva načina:
pomoću vrijednosti (call by value)
pomoću adrese (call by reference)
STOG je dinamički dio memorije koji se upotrebljava za pohranjivanje podataka koji se
privremeno koriste u određenim djelovnima programa
Stog se puni i prazni prema principu «zadnji unutra – prvi van» (eng. LIFO – last in – first
out)
Rekurzivna funkcija je funkcija koja poziva samu sebe
Svaka rekurzija mora imati uvjet zaustavljanja koji će joj omogućiti izlaz
Svaki poziv rekurzije mora se približavati uvjetu zaustavljanja
34