You are on page 1of 353

1

1
1. . P PO OG GL LA AV VL LJ J E E



F FU UN NK KC CI I J J E E
























2



1.1. POJAM I DEFINICIJA FUNKCIJE


Sloeniji problemi se reavaju dekompozicijom u vei broj manjih problema.
Potprogrami predstavljaju mehanizam koji direktno podrava funkcionalnu
dekompoziciju kao jednu od osnovnih metoda strukturnog programiranja.

Definicija potprograma:

Potprogrami su sastavni segmenti programskog koda koji se pozivaju radi
obavljanja konkretno specificiranog zadatka.

Potprogrami u razvoju programa se koriste iz tri razloga:
1) Segmenti programa se mogu vie puta pojavljivati u okviru istog ili u okviru
razliitih programa (iscrtavanje table igrice se pojavljuju na vie mesta u
okviru programa, ili sortiranje niza koje nam treba ne samo u jednom ve i u
vie razliitih programa). Korienje potprograma u takvim situacijama pre
svega omoguava da jednom napisan potprogram bude neogranieno puta
pozivan. Sa druge strane ovakav pristup je prevencija od mogunosti
pravljenja greaka prilikom kopiranja programskog koda sa jednog mesta na
drugo u okviru istog ili u okviru razliitih programa.

2) Programi predstavljaju logike jedinice dekomponovanih programa. ak i
da se programski kod izvrava samo jednom, veoma je korisno odvojiti
programski kod sa jasno definisanim ciljem zbog dekomponovanosti,
itljivosti i potreba testiranja celokupnog reenja. Ispred svakog
potprograma postoji dokumentacija: opis potprograma i datum poslednje
izmene. Poeljno je da telo main() -na bude prikazan (stane) na ekran radi
preglednosti i itljivosti programa.


3) Potprogrami predstavljaju i fiziku jedinicu programske dekompozicije, koji
se posmatra kao jedinini kod u postupku prevoenja. Programski jezik C
koristi module (datoteke) u kojima se nalaze deklaracija promenljivih i
deklaracija potprograma kao jedinice fizike dekompozicije. Vie programa
moe koristiti isti potprogram koji se nalazi u posebnom modulu.

U veini programskih jezika se jasno razlikuju potprogrami koji vraaju vrednost
(funkcije), od onih koji to ne ine (procedure). Programski jezik C poznaje samo funkcije
kao tip potprograma, ali se u okviru ovakvog pristupa procedure formalno zamenjuju
funkcijama koje ne vraaju nikakvu vrednost.
Sa pojmom funkcija sreemo se u matematici gde se na osnovu argumenta funkcije
(nezavisna promenljiva x) dobija vrednost rezultata funkcije (zavisna promenljiva y).
3

Na primer: 5 4
2 3
+ + =
+
x e y
x


Definicija funkcije:

Funkcije su potprogrami koji na osnovu izvesnog broja argumenata daju
jedan rezultat koji se naziva vrednost funkcije.

Osobine funkcija:

- Vrednost funkcije moe da se koristi ugraivanjem poziva funkcije u izraze.
Poziv funkcije se, u stvari, smatra operatorom kao i svi ostali operatori.
- Funkcije kontroliu pristup do vanih podataka i uvaju ih od neovlaenih
promena.
- Funkcija skriva detalje naina obavljanja odreenog zadatka. Ovaj princip
se zasniva na ideji da onoga ko poziva funkciju ne mora interesovati kako
odreena funkcija reava odabrani problem koji je rezultat funkcionalne
dekompozicije.




























4



1.2. DEFINISANJE FUNKCIJE


Definisanje funkcije
Funkcija se definie naredbom za definisanje funkcije:

tip naziv_funkcije(lista _argumenata)
{
telo_ funkcije
}

tip - predstavlja osnovni tip vrednosti funkcije (svi standardni prosti tipovi).
Vrednost funkcije moe da bude samo jedan podatak. Za tip vrednosti
funkcije ne moe da bude niz. Za funkcije koje ne stvaraju vrednost funkcije
kao oznaka tipa treba da se koristi slubena re void. Ako se izostavi oznaka
tipa podrazumeva se tip int.

naziv_funkcije - sastoji se od indentifikatora funkcije, koji je istovetan sa bilo
kojom vrstom indentifikatora.

lista_argumenata - predstavljaju argumente funkcije pomou kojih se vri
unoenje poetnih vrednosti funkcije. Vrednost funkcije se izraunava na
osnovu tih poetnih podataka. Argumenti se u listi argumenata razdvajaju sa
zarezom. Pojedini argumenti definiu se na isti nain kao i podaci: tip naziv.
Za razliku od naredbi za definisanje podataka ovde se za svaki argument mora
zasebno navesti oznaka tipa. U sluaju vektora dovoljno je da se samo parom
zagrada oznai da se radi o vektoru. Argumenti koji se pominju prilikom
definisanja funkcije nazivaju se i formalnim argumentima. Oni nisu stvarni
podaci koji se obrauju u toku izvravanja funkcije.Formalni argumenti koji
se pominju prilikom pozivanja funkcije zamenjuju vrednostima odgovarajuih
stvarnih argumenata koje se onda obrauju.

telo_funkcije - predstavlja sadraj funkcije koja se definie. Ona je po formi blok
(nalazi se izmeu vitiastih zagrada), to znai da moe da sadri deklarativne
i izvrne naredbe. Ako funkcija kao rezultat svog rada vraa neku vrednost u
okviru tela funkcije mora se nalaziti naredba return.
Opti oblik naredbe return je:
return izraz;
ili return;
I zraz mora da se po tipu slae sa predvienim tipom vrednosti
funkcije.Naredba return se koristi kada je potrebno izvriti povratak u glavni
program (u okviru funkcije na vie mesta se moe nalaziti naredba return).
Znai osim to moe da vrati vrednost u glavni program, omoguava i
5
prekidanje izvravanja programskog toka u funkciji, bez obzira na kom mestu
se nalazi u telu funkcije. Kod funkcija tipa void naredba return ne sme da
sadri izraz.

Tip vrednosti funkcije, naziv funkcije i lista argumenata predstavljaju zaglavlje
funkcije.

Primer 1:
Definisati C funkciju hipotenuza koja na osnovu kateta a i b izraunava hipotenuzu
pravouglog trougla.

Reenje

prvi nain:

float hipotenuza(float a, float b)
{
return sqrt(a*a+b*b);
}


drugi nain:

float hipotenuza(float a, float b)
{
float c; /* Deklarativna naredba */

sqrt(a*a+b*b);

return c;
}

Primer 2:
Definisati C funkciju slika koja na osnovu neparnog broja zvezdica n iscrtava sliku
sledeeg izgleda:

*
* * *
* * * * *
* * * * * * * Za n = 7 napravljena je ova slika
* * * * * * gde je n neparan broj i predstavlja
* * * * * gornju katetu trougla zvezdica.
* * * *
* * *
* *
*


6

Reenje

void slika(int n)
{
unsigned i, j;

printf("\n\n");
for(i=1;i<=n/2+1;i++)
{
for(j=1;j<=n/2-i+1;j++) printf(" ");
for(j=1;j<=2*i-1;j++) printf("* ");
printf("\n");
}
for(i=1;i<=n-1;i++)
{
for(j=1;j<=i;j++) printf(" ");
for(j=1;j<=n-i;j++) printf("* ");
printf("\n");
}
}



























7



1.3. POZIVANJE FUNKCIJA


Pozivanje funkcija u jeziku C smatra se binarnim operatorom i obeleava se sa ().
Za razliku od ostalih binarnih operatora ovaj operator se ne pie izmeu svojih operanada
ve "oko" drugog operanda. Prvi operand je funkcija koja se poziva, a drugi operand je
niz stvarnih argumenata:

funkcija(izraz1, izraz2, izraz3,...,izrazn)

funkcija - oznaava funkciju ije se izvravanje trai. Ona je u veini sluajeva
indentifikator funkcije koja se poziva, ali moe da bude i adresni izraz
ija je vrednost adresa eljene funkcije.

izrazi - predstavljaju stvarne argumente funkcije ije vrednosti slue za
inicijalizaciju formalnih argumenata funkcije pre obrade tela funkcije.
Stvarni argumenti mogu biti: promenljive, konstante ili izrazi i moraju
imati u potpunosti definisanu vrednost u momentu prosleivanja
(predaje) funkciji Izrazi koji predstavljaju stvarne argumente funkcije
izraunavaju se po proizvoljnom redosledu, neposredno pre pozivanja
funkcije.

Izraz za pozivanje funkcije moe se koristiti kao operand u sloenijem izrazu, tada
se vrednost funkcije koristi u izraunavanju tog izraza. Kako je operator poziva funkcije
() visokog prioriteta, to obezbeuje da se izraunavanje vrednosti funkcije (pozivanje
funkcije) izvri pre bilo kog susednog operatora u izrazu. Ukoliko funkcija nema svoju
vrednost (tip void) moe da se koristi samo kao drugi operand operatora zarez ili kao
drugi ili trei operand trinarnog operatora. Funkcija koja nema svoju vrednost najee se
koristi kao operand izraza u prostoj naredbi fun(...);


Primer 1:
Napisati C program koji na osnovu unetih kateta pravouglog trougla a i b
izraunava duinu hipotenuze. Duinu hipotenuze raunati funkcijom hipotenuza ija je
sintaksa: float hipotenuza(float a, float b);

Reenje

prvi nain:

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

8
float hipotenuza(float a, float b)
{
return sqrt(a*a+b*b);
}

void main()
{
float a,b;

printf("\n\n\t HIPOTENUZA \n\t\ta = ");
printf("\n\n\tUNESITE KATETU A PRAVOUGLOG TROUGLA:\n\t\ta = ");
scanf("%f",&a);
printf("\n\n\tUNESITE KATETU B PRAVOUGLOG TROUGLA:\n\t\ta = ");
printf("\t\tb = ");
scanf("%f",&b);

printf("\n\n\n\n\n\n\n");
printf("\n\n\n\n\n\n\n\tHIPOTENUZA C PRAVOUGLOG TROUGLA JE:\n\t\t");
printf("c = %.3f",hipotenuza(a,b));


}

drugi nain:

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

float hipotenuza(float a, float b)
{
return sqrt(a*a+b*b);
}

void main( )
{
float a,b,c;

printf("\n\n\HIPOTENUZA:\n\t\ta = ");
printf("\n\n\tUNESITE KATETE PRAVOUGLOG TROUGLA:\n\t\ta = ");
scanf("%f",&a);
printf("\t\tb = ");
scanf("%f",&b);

c = hipotenuza(a,b); /* Prilikom poziva funkcije pored stvarnih argumenata pogresno je
stavljati tip podatka, tj nije dobro pisati c=hipotenuza(int a, int
b); */


printf("\n\n\n\n\n\n\n");
printf("\n\n\n\n\n\n\n\tHIPOTENUZA C PRAVOUGLOG TROUGLAJE:\n\t\t");
printf("c = %.3f",c);
9



}



Primer 2:
Napisati C program koji korienjem unetog neparnog prirodnog broja n, pozivom
funkcije slika prikazuje na ekranu sliku od zvezdica sledeeg izgleda:


*
* * *
* * * * *
* * * * * * * Za n = 7 napravljena je ova slika
* * * * * * gde je n neparan broj i predstavlja
* * * * * gornju katetu trougla zvezdica.
* * * *
* * *
* *
*


Reenje

#include <stdio.h>
#include <conio.h>

void slika(int n)
{
unsigned i, j;

printf("\n\n");
for(i=1;i<=n/2+1;i++)
{
for(j=1;j<=n/2-i+1;j++) printf(" ");
for(j=1;j<=2*i-1;j++) printf("* ");
printf("\n");
}

for(i=1;i<=n-1;i++)
{
for(j=1;j<=i;j++) printf(" ");
for(j=1;j<=n-i;j++) printf("* ");
printf("\n");
}
}

10
void main(void)
{
unsigned xn,yn;
int n;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\n\tN = ");
xn=wherex(), yn=wherey();
do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0||n%2==0);

slika(n); /* Poziv funkcije koja nema svoju vrednost (tip void). */

gotoxy(1,25);
getch();
}

Test primer programa:












11
1.4. PREDAJA PARAMETARA


Prilikom pozivanja funkcije tipine su sledee akcije:
- Prosleivanje stvarnih argumenata,
- Alokacija i inicijalizacija lokalnih promenljivih funkcije,
- Prenos kontrole na funkciju, ali tek kada se na neki nain zapamti adresa,
to jest pozivajuu celinu koja se nalazi odmah iza mesta poziva funkcije.


Pri povratku iz funkcije redosled akcija je obrnut. Prvo se restaurira pozivajua
adresa u pozivajuu rutinu, oslobaa se prostor za lokalne promenljive i vri bezuslovni
skok na povratnu adresu. Formalni argumenti, lokalne promenljive i povratna adresa
predstavljaju jednu celinu oblika strukture pod nazivom aktivizacioni zapis, koji se
zapisuje na stek-u prilikom pozivanja funkcije. Prilikom zavretka funkcije aktivizacioni
zapis se uklanja sa steka.

Jedna bitna akcija prilikom pozivanja funkcije je prosleivanje vrednosti
stvarnih argumenata formalnim argumentima funkcije, ili predaja parametara.
Vrednosti stvarnih argumenata funkcije slue za inicijalizaciju formalnih
argumenata funkcije pre obrade tela funkcije.
Predaja parametara moe biti: predaja parametara po vrednost i predaja
parametara po referenci.
Prilikom predaje parametara po vrednosti kopija vrednosti promenljive se
prosleuje funkciji, odnosno formalnim parametrima funkcije.


Primer 1:
Napisati C program koji na osnovu duine stranice kvadrata izraunava obim i
povrinu kvadrata. Za izraunavanje obima kvadrata koristiti funkciju obim, a povrine
kvadrata funkciju povrsina.

Reenje

U ovom primeru koristi se predaja parametara po vrednosti.

#include <stdio.h>
#include <conio.h>

/* Funkcija za izracunavanje obima kvadrata. */
double obim(double a)
{
return 4*a;
}
/* Funkcija izracunava povrsinu kvadrata. */
double povrsina(double x)
{
12
double p; /* Promenljiva p je lokalna promenljiva i ima doseg do kraja funnkcije gde je i
deklarisana. */
p=x*x;

return p;
}

void main(void)
{
double a,o;
unsigned xa,ya;



printf("\n\ta = ");
xa=wherex();
ya=wherey();
do{
gotoxy(xa,ya);
printf(" ");
gotoxy(xa,ya);
scanf("%lf",&a);
}while(a<=0);

o=obim(a);

/* Prilikom startovanja programa operativni sistem rezervie pet zona memorije, koji
su delovi RAM memorije. Za sada posmatraemo dve zone memorije: Zona podataka i stek
memorija. Prilikom poziva funkcije a je stvarni argument funkcije i nalaze se u ZONI
PODATAKA. Vrednost promenljive a predaje se formalnom parametru koji u ovom
primeru ima isto ime. Formalni parametar a se nalazi na STEK-u te fiziki nije ista
memorijska lokacija kao stvarni argument, koji se nalazi u ZONI PODATAKA. */

printf("\n\n\n\tO = %.3f\n\tP = %.3f",o,povrsina(a));

/* U ovom pozivu funkcija se poziva u okviru druge funkcije. Vrednost stvarnog
parametar a iz ZONE PODATAKA se predaje formalnom parametru x sa STEK-a.
Kaemo da je time izvrena inicijalizacija parametra x koji sada ima vrednost parametra a.
Parametar x moe menjati svoju vrednost u okviru tela funkcije, ali nakon zavrsetka
funkcije promenljiva a iz ZONE PODATAKA imace istu vrednost kao i pre poziva
funkcije. */

gotoxy(1,25);
getch();
}
Primer 2:
Napisati C program koji korienjem funkcije suma izraunava zbir prvih n
lanova beskonanog periodinog niza periode p (p>4).
Beskonani niz ima sledei oblik:

13
1, 1, 2, 2, 4, 8, 12, 96, ...,1, 1, 2, 2, 4, 8, 12, 96,..., 1, 1, 2, 2, 4, 8, 12, 96, ...

U funkciji suma koristiti funkciju zbir koja moe na osnovu unetog broja k da
sabira celu periodu (ako je k=p) ili deo periode (ako je k<p) beskonanog niza.
Zadatak reiti bez korienja nizova.

Reenje

#include <stdio.h>
#include <conio.h>

/* Omogucava unos pozitivnog broja na zadatoj poziciji. Koristi se kao funkcija jer se
posebno mora uneti podatak kolika je perioda i podatak koliko elemenata treba sabrati. */

int unesi(int xpoz, int ypoz)
{
int br;

do{
gotoxy(xpoz,ypoz);
printf(" ");
gotoxy(xpoz,ypoz);
scanf("%d",&br);
}while(br<=0);

return br;
}

/* Funkcija zbirdeo je u stanju da izracuna zbir cele periode ili dela periode. Parametar k
opisuje koliko clanova niza treba sabrati, a da su manji ili jednaki od duzine periode. */
int zbirdeo(int k)
{
int i,p,q,pom,s;

if(k==1) return 1;
if(k==2) return 2;

p=1,q=1,s=2;
for(i=3;i<=k;i++)
{
/* Parnost je ispitivana pomocu bita parnosti. */
if(i&0x1) pom=q, q=p+q, p=pom;
else pom=q, q=p*q, p=pom;
s+=q;
}
return s;
}

/* Funkcija zbir izracuvava trazeni zbir pozivajuci funkciju zbirdeo. Funkcija zbirdeo je
sposobna da izracuna deo ili celu periodu. Nema nikakvih problema prilikom poziva jedne u
14
okviru druge funkcije. Promenljive koje ;ine deo izraza od stvarnih argumenata funkcije moraju
biti lokalne promenljive funkcije u okviru koje se vrsi poziv, ili promenljive koje su prosledjene
funkciji u okviru koje se vrsi poziv druge funkcije.
U ovom slucaju su promenljive n i p formalni parametri funkcije zbir a kao takvi mogu
ucestvovati u izrazima koji pretstavljaju stvarne parametre funkcije zbirdeo.*/

int zbir(int n, int p)
{
int s=0;

/* Na osnovu n i p moze se zakljuciti da ima n/p celih perioda i mozda jedan deo ostatka
periode koji ima n%p clanova. */

if(n%p!=0) s+=(n/p)*zbirdeo(p)+zbirdeo(n%p);
else s+=(n/p)*zbirdeo(p);

return s;
}


void main(void)
{
int p, n;
unsigned xn=-1, yn=-1, xp=-1, yp=-1;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\n\n\tPerioda je: ");
xp=wherex(), yp=wherey();
p=unesi(xp,yp);

printf("\n\n\tKoliko clanova treba sabrati: ");
xn=wherex(), yn=wherey();
n=unesi(xn,yn);
printf("\n\n\n\n\tTrazeni zbir je: %d",zbir(n,p));

gotoxy(1,25);
getch();
}








15
1.5. PROTOTIPOVI FUNKCIJA

Prototip funkcije pretstavlja deklaraciju funkcije i nastaje navoenjem prazne
naredbe umesto tela funkcije.

tip naziv_funkcije(lista _argumenata);

Prototipovi funkcija mogu da se piu u datotekom ili blokovskom dosegu, to
odreuje deo programa u kojem je prototip u vanosti. Prototipovi se najee piu u
datotekom dosegu. U glavnom programu nalazi se iznad main funkcije. Uloga prototipa
je samo da prevodiocu ukae na namenu njihovih argumenata.
Na primer:
int zbir(int n, int p);

Ovaj prototip ukazuje prevodiocu da e se kasnije koristiti funkcija zbir koja vraa
podatak tipa int i da funkcija zbir ima dva argumenta tipa int. Njega uopte ne zanimaju
promenljive n i p. Iz tih razloga dozvoljeno je pisanje prototipa funkcije i u sledeem
obliku.
int zbir( int, int );

Posmatraemo primer 2 sa asa 6. Ako bismo izvrili zamene mesta definisanja
funkcija zbir i zbirdeo program bi imao greaka, jer se u funkciji zbir poziva funkcija
zbirdeo koju prevodilac ne poznaje. Korienjem prototipova funkcija ne moramo
voditi rauna o rasporedu definicija funkcija, a definisanje funkcija se izvode u
proizvoljnom poretku ispod tela main funkcije.

Primer:
Napisati C program koji korienjem funkcije suma izraunava zbir prvih n
lanova beskonanog periodinog niza periode p (p>4).
Beskonani niz ima sledei oblik:

1, 1, 2, 2, 4, 8, 12, 96, ...,1, 1, 2, 2, 4, 8, 12, 96,..., 1, 1, 2, 2, 4, 8, 12, 96, ...

U funkciji suma koristiti funkciju zbir koja moe na osnovu unetog broja k da
sabira celu periodu (ako je k=p) ili deo periode (ako je k<p) beskonanog niza.
Zadatak reiti bez korienja nizova.

Reenje

#include <stdio.h>
#include <conio.h>

/* Prototipovi funkcija koje se koriste u programu. */
int unesi(int xpoz, int ypoz);
int zbir(int n, int p);
int zbirdeo(int k);
void main(void)
16
{
int p, n;
unsigned xn=-1, yn=-1, xp=-1, yp=-1;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\n\n\tPerioda je: ");
xp=wherex(), yp=wherey();
p=unesi(xp,yp);

printf("\n\n\tKoliko clanova treba sabrati: ");
xn=wherex(), yn=wherey();
n=unesi(xn,yn);
printf("\n\n\n\n\tTrazeni zbir je: %d",zbir(n,p));

gotoxy(1,25);
getch();
}

/* Omogucava unos pozitivnog broja na zadatoj poyiciji. Koristi se kao funkcija jer se
posebno mora uneti podatak kolika je perioda i podatak koliko elemenata treba sabrati. */
int unesi(int xpoz, int ypoz)
{
int br;

do{
gotoxy(xpoz,ypoz);
printf(" ");
gotoxy(xpoz,ypoz);
scanf("%d",&br);
}while(br<=0);

return br;
}

/* Funkcija zbir izracunava trazeni zbir pozivajuci funkciju zbirdeo. *
int zbir(int n, int p)
{
int s=0;

/* Na osnovu n i p moze se zakljuciti da ima n/p celih perioda i mozda jedan deo
ostatka periode koji ima n%p clanova. */

if(n%p!=0) s+=(n/p)*zbirdeo(p)+zbirdeo(n%p);
else s+=(n/p)*zbirdeo(p);
return s;
}
17
/* Funkcija zbirdeo je u stanju da izracuna zbir cele periode ili dela periode. Parametar k
opisuje koliko clanova niza treba sabrati, a da su manji ili jednaki od duzine periode. */

int zbirdeo(int k)
{
int i,p,q,pom,s;

if(k==1) return 1;
if(k==2) return 2;

p=1,q=1,s=2;
for(i=3;i<=k;i++)
{
/* Parnost je ispitivana pomocu bita parnosti. */
if(i&0x1) pom=q, q=p+q, p=pom;
else pom=q, q=p*q, p=pom;
s+=q;
}

return s;
}

Test primer programa:















18

1.6. REKURZIVNE FUNKCIJE

Algoritamske strukture u optem sluaju mogu biti rekurzivne ili iterativne.
Programski jezik C podrava reavanje oba tipa algoritama koristei iterativne i
rekurzivne funkcije.
Osnovna ideja rekurzije ukljuuje dva aspekta:
- Da se poznati problem redukuje na jednostavnije.
- Da se u reavanju problema svakim rekurzivnim korakom pribliavamo
eljenom reenju izmenom parametara prvobitnog problema.

Definicija rekurzivne funkcije:
Rekurzivne funkcije su funkcije koje neposredno ili posredno pozivaju same
sebe.
Rekurzivna reenja su po pravilu manje efikasna od iterativnih reenja istih
problema. Deava se da rekurzivna reenja traju neprihvatljivo dugo, ili se trai
dosta operativne memorije na steku za uvanje meustanja izmeu rekurzija.

Princip funkcionisanja rekurzije objasnie se najlake na primeru.

Primer 1:
Napisati C program koji pozivanjem rekurzivne funkcije prikaz na ekranu na
osnovu unetog prirodnog broja n prikazuje ispis brojeva: 1 2 3 n n 3 2 1.

Reenje

#include <stdio.h>

/*Prototip rekurzivne funkcije. */
void prikaz(int k, int n);

void main(void)
{
int n, xn, yn;



/*Unos prirodnog broja n. */
printf("\n\tN = ");
xn=wherex(), yn=wherey();

do{
printf(" ");
scanf("%d",&n);
}while(n<=0);

/*Pozivanje rekurzivne funkcije. */
prikaz(1, n);
19
getch();
}

/*Definisanje rekurzivne funkcije. */
void prikaz(int k, int n)
{
printf("%d\t",k);

/*U ovom redu se vidi da je prikaz rekurzivna funkcija jer u okviru svog tela
poziva sama sebe. */
if(k<n) prikaz(k+1);

printf("%d\t",k);
}

Analiziraemo program na pretpostavku da je korisnik programa uneo da je n=3.
Nakon poziva funkcije formalni parametar k dobija stvarnu vrednost 1 i formalni
parametri se u obliku aktivacionog zapisa upisuju na stek, a pokaziva steka se poveava
za 1 na sledeu lokaciju.

STEK

Aktivaciono Aktivacioni zapis 1.
Pok na stek






Funkcija prikaz poziva sama sebe, ali sa promenjenim parametrom (to je i odlika
rekurzije). Kako se funkcija pozvala na steku se formira njen aktivacioni zapis sa novim
vrednostima parametara i pokaziva steka se poveava za 1 na sledeu lokaciju.

STEK
Aktivaciono Aktivacioni zapis 1.

Aktivacioni zapis 2.
Pok na stek





Na ekranu se tampa broj 2 i ponovno poziva rekurzivna funkcija prikaz sa
promenjenim parametrom k. Na steku se stvara novi aktivacioni zapis.

STEK
k: 1, n: 3
k: 1, n: 3
k: 2, n: 3
20

Aktivaciono Aktivacioni zapis 1.

Aktivacioni zapis 2.

Aktivacioni zapis 3.
Pok na stek


Na ekranu se ispisuje broj 3, uslov nije ispunjen u if selekciji, te se ponovno ispisuje
broj 3 na ekranu. Kako se dolo do kraja funkcije unitava se aktivacioni zapis 3,
pokaziva na stek se smanjuje za 1.

STEK

Aktivaciono Aktivacioni zapis 1.

Aktivacioni zapis 2.
Pok na stek




Izvrava se na prva sledea naredba iz funkcije prikaz koja odgovara aktivacionom
zapisu 2, tj tampae se ponovno broj 2. Dolazi se do kraja funkcije te se sa steka
unitava aktivacioni zapis 2, a pokaziva steka se smanjuje za 1. Ponovno se izvrava
prva sledea naredba iz funkcije prikaz sa parametrima koji odgovaraju tom
aktivacionom zapisu.

STEK

Aktivaciono Aktivacioni zapis 1.
Pok na stek







Nakon zavretka funkcije prikaz sa parametrima koji odgovaraju aktivacionom
zapisu 1 vraamo se u glavni program.

Iz navedenog principa funkcionisanja rekurzivnih funkcija mogu se uoiti sledee
osobine:
k: 1, n: 3
k: 2, n: 3
k: 3, n: 3
k: 1, n: 3
k: 2, n: 3
k: 1, n: 3
21
- Prilikom rada sa rekurzivnim funkcijama potrebno je da rekurzivna funkcija
ima to manje argumenata i da po pravilu nema lokalnih promenljivih, jer se
na taj nain nee bespotrebno optereivati stek.
- Programer ne upravlja mehanizmom uvanja stanja funkcije na steku pre
rekurzivnog stanja i obnavljanja stanja po povratku iz rekurzivnog poziva,
jer se to deava automatski.
- U okviru funkcije neki od parametara se mora porediti sa nekom
konstantnom vrednou kako bi se iz rekurzije moglo izai, u suprotnom
program bi se beskonano dugo izvravao.
- Ako se koristi rekurzija prethodno se problem mora prikazati u rekurzivnom
duhu.


Primer 2:
Napisati C program koji korienjem rekurzivne funkcije suma izraunava zbir
elemenata niza A od n lanova n<31.

Reenje

Prvo se mora definisati rekurzivna zakonitost.
Zbir elemenata niza = prvi element + zbir ostalih elemenata.

#include <stdio.h>

#define MAX_NIZ 30

/*Prototip rekurzibne funkcije. */
int suma(int a[], int n);

void main(void)
{
int a[MAX_NIZ], n, pom;
unsigned i, xn, yn, xu, yu;

/*Inicijalizacija niza. */
for(i=0;i<MAX_NIZ;i++) x[i]=0;


printf("Broj elemenata niza je:\n\tN = ");
xn=wherex(), yn=wherey();

do{
printf(" ");
scanf("%d",&n);
}while(n<=0||n>MAX_NIZ);


printf("Unesite elemente niza X:\n");
xu=wherex(), yu=wherey();
22


/* Niz se unosi pomocu ciklusa. */
for(j=0,i=0;i<n;i++)
{
if(j==16)
{
j=j%16;
yu++;
xu=1;
}
gotoxy(xu+5*j,yu);
scanf("%4d",&x[i]);
j++;
}

printf("\n\nZbir = %d", zbir(a, n));
getch();
}

/*Definisanje rekurzivne funkcije. */
int zbir(int a[], int n)
{
return (n>0) ? a[0] + zbir(a+1, n-1) : 0;
}























23

2
2. . P PO OG GL LA AV VL LJ J E E



P PO OK KA AZ ZI IV VA A I I
24


2.1. POKAZIVAI

Definicija pokazivaa:
Pokaziva je promenljiva koja sadri adresu druge promenljive ili funkcije.

Kada se zapone program operativni sistem priprema razliita podruja
memorije, bazirajui se na zahtevima vaeg kompajlera. Program raspolae sa
sledeim podrujima memorije: zona podataka, registarska memorija, zona za kod,
stek i hip.

Pored direktnog i indeksnog adresiranja koristi se i indirektno adresiranje.
Pokazivai koriste indirektan pristup vrednostima programskih promenljivih korienjem
njihovih memorijskih adresa. Pokazivai obino zauzimaju 2 ili 4 bajta. Broj bajtova koje
zauzima pokaziva zavisi od mogueg opsega adresa na datom raunaru, a ne od broja
bajtova koliko zauzima pokazivani podatak. Kada neki podatak sadri vie bajtova, pod
adresom podatka podrazumeva se bajt sa najmanjim rednim brojem.
U neposrednoj vezi sa pokazivaima su dva specijalna operatora programskog
jezika C:
- Adresni operator & koji daje memorijsku adresu promenljive na koga je
primenjen.
- Operator diferenciranja * omoguava deklarisanje pokazivake promenljive
i indirektan pristup do vrednosti za koje su koriene pokazivake
promenljive.

Deklaracija pokazivake promenljive:

tip *pok;

Ovom deklaracijom pok je pokazivaka promenljiva koja je u stanju da pokazuje
(sadri adresu) promenljive tipa tip. U deklaraciji se vidi da je pok pokazivaka
promenljiva jer se ispred nje nalazi operator *.

Inicijalizacija pokazivake promenljive:
Inicijalizacija pokazivake promenljive vri se operatorom dodele gde se
pokazivakoj promenljivoj dodeljuje NULL.

pok =NULL;

NULL je simbolika konstanta koja se nalazi u biblioteci stdio.h i ima
vrednost 0.

Inicijalizacija pokazivake promenljive moe se izvriti i prilikom deklaracije.

tip *pok=NULL;
25
Pokazivaka promenljiva pokazivae na drugu promenljivu ako sadri njenu adresu.
To se postie na sledei nain.

pok =&prom;

U ovom sluaju pokazivaka promenljiva pok mora prethodno biti deklarisana tako
da pokazuje na promenljive tipa tip, a da je i promenljiva prom takoe tipa tip.


Na primer:
int *pok=NULL, a, b;

a=10, b=15;
pok = &a; /* pok sadrzi adresu od promenljive a. */
*pok=b; /* Podatak na koji pokazuje pokazivac pok dobija vrednost promenljive b,
a time i promenljiva a nema vise vrednost 10 vec 15. */
a++; /* vrednost promenljive a je sada 16. */
*pok+=5; /* vrednost promenljive a je sada 21. */


Primer 1:
Objasniti ta se deava sa memorijskim lokacijama gde su smetene promenljive a i
b (tokom itavog koda).

#include <stdio.h>
#include <conio.h>

void main(void)
{
int a=10, b=2, *p1, *p2;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

p1=&a, p2=&b; /* p1 sadrzi adresu promenljive a, a p2 sadrzi adresu promenljive b. */
(*p1)++;
(*p2)--;
*p1+=a;
*p2-=*p1;
(*p2)--;
a+=*p2;
b=*p1;

printf("A = %d\tB = %d",a,b);
getch();
}

26
Reenje

#include <stdio.h>
#include <conio.h>

void main(void)
{
int a=10, b=2, *p1, *p2; /* p1 i p2 su pokazivaci na promenljive tipa int. */

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

p1=&a, p2=&b; /* p1 sadrzi adresu promenljive a, a p2 sadrzi adresu promenljive b. */
(*p1)++; /* a = 11 */
(*p2)--; /* b = 1 */
*p1+=a; /* a = 22 */
*p2-=*p1; /* b = -21 */
(*p2)--; /* b = -22 */
a+=*p2; /* a = 0 */
b=*p1; /* b = 0 */

printf("A = %d\tB = %d",a,b); /* Stampanje vrednosti promenljivih a i b. */
getch();
}

a: 10, 11, 22, 0 b: 2, 1, -21, -22, 0

Adresna aritmetika sa pokazivaima:
- Dodela vrednosti jednog pokazivaa drugom,
- Dodavanje celobrojnog podatka na vrednost pokazivaa i oduzimanje
celobrojnog podatka od vrednosti pokazivaa,
- Oduzimanje i uporeivanje dva pokazivaa,
- Uporeivanje pokazivaa sa nulom ili sa NULL, i
- Indentifikator niza je konstantan pokaziva (ne smete mu promeniti
adresu na koju pokazuje), na poetak niza,
- Veza izmeu niza i pokazivaa moe se pretstaviti pomou formule

x[i] *(x + i)


Primer 2:
Napisati C program koji iskljuivo korienjem pokazivaa izraunava zbir
pozitivnih elemenata niza X od n elemenata n<31.

Reenje

27
#include <stdio.h>
#include <conio.h>

#define MAX 30

void main(void)
{

int n,x[MAX], *pok=NULL;
unsigned xn,yn, br;

/*Inicijalizacija niza pomocu pokazivaca. */
pok=x;
while(pok-x<MAX) *pok=0, pok++;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("Broj elemenata niza je:\n\tN = ");
xn=wherex(), yn=wherey();
do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0||n>MAX);

printf("Unesite elemente niza X:\n");

/* Niz se unosi pomocu ciklusa, pri cemu ovde razlika pokazivaca pok-x pretstavlja
indeks niza Kako pok sadrzi adresu gde treba odgovarajuceg clana niza to nam u
funkciji scanf ne treba adresni operator. */

pok=x;
while(pok-x<n)
{
scanf("%d",pok);
pok++;
}

br=0;
pok=x;
while(pok-x<n)
{
if(*pok>0) br++;
pok++;
}
printf("Niz sadrzi %d pozitivnih elemenata.",br);

28
gotoxy(1,25);
getch();
}

Generiki pokazivai:
Pored pokazivaa na podatke poznatih tipova, postoje i generiki pokazivai
kod kojih nije odreen tip pokazivakih podataka. Deklaracija generikog
pokazivaa vri se stavljanjem rezervisane rei void umesto opisa tipa pokazivakih
podataka.
void *pok;
Da bi se pomou generikog pokazivaa pristupilo podacima potrebno je prethodno
izvriti njegovu konverziju u poznati tip podatka.

Na primer:
int x, y, *pok1=NULL, *pok2=NULL;
void *pok3=NULL;

x=0;
y=5;

pok1=&x; /* pok1 sadrzi adresu promenljive x. */
*pok1++; /* Prvo ce se povecati adresa na koju pokazuje pokazivac pok za 1, a time
pok1 nece vise pokazivati na promenljivu x i pitanje je ciji smo to
podatak promenili. Znaci potrebno je pisati (*pok)++; */
pok2=&y; /* pok2 sadrzi adresu promenljive y. */
y++; /* povecava se vrednost promenljive y za 1. */
pok3=pok2, /* Sada i pokazivac pok3 sadrzi adresu promenljive y. */
*pok3=*pok3+4, /* Ovde je GRESKA jer genericki pokazivac ne moze promeniti
vrednost podatka na koji pokazuje pre nego sto se izvrsi
konverzija, a sto je ucinjeno u sledecem redu. */
*((int *)pok3)+=4;
















29

2.2. PREDAJA PARAMETARA PO REFERENCI
BONI EFEKTI

Prenos parametara po referenci najlake moemo objasniti kroz jedan prost zadatak.

Primer 1:
Napisati C program koji korienjem funkcije zameni vri zamenu vrednosti dve
promenljive. Prototip funkcije zameni je void zameni(int a, int b);

Reenje

#include <stdio.h>
#include <conio.h>

/* Prototip funkcije. */
void zameni(int a, int b);

void main(void)
{
int a, b;

printf("\n\tUnesite podatke:\n");
printf("\ta = ");
scanf("%d",&a);
printf("\tb = ");
scanf("%d",&b);

/* Poziv funkcije */
zameni(a,b);

printf("\n\n\tNakon zamene je:\n");
printf("\ta = %d",a);
printf("\n\tb = %d",b);


}

void zameni(int a, int b)
{
int pom;

pom=a;
a=b;
b=pom;
}

Ako istestiramo ovaj program videemo da program ne radi ispravno. Ispisae iste
vrednosti kao i pre poziva funkcije zameni. Problem lei u tome to formalni parametri a
30
i b respektivno pozivom funkcije zameni dobijaju stvarne vrednosti promenljivih a i b.
Formalni parametri nalaze se na steku i vie nikakve veze nemaju sa promenljivama a i b
iz ZONE PODATAKA. Zamena e biti izvrena izmeu formalnih promenljivih a i b.
Posle zavretka funkcije sadraj steka se brie, a time i sadraj formalnih parametara.
Podaci a i b iz zone podataka ostali su nepromenjeni.

Problem moemo reiti samo ako bismo pristupali promenljivama iz ZONE
PODATAKA u okviru funkcije zameni. Problem se reava korienjem pokazivaa koji
sadre adrese (reference) promenljivih a i b iz zone podataka. Na taj nain moemo u
okviru funkcije indirektno (diferenciranjem) menjati njihov sadraj.

Reenje pomou prenosa parametara po referenci.

#include <stdio.h>
#include <conio.h>

/*Prototip funkcije. Kako su formalni argumenti pokazivaci radi se znaci o prenosu
parametara po referenci. */

void zameni(int *a, int *b);

void main(void)
{
int a, b;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

printf("\n\tUnesite podatke:\n");
printf("\ta = ");
scanf("%d",&a);
printf("\tb = ");
scanf("%d",&b);

/*Kada se poziva funkcija tamo gde se u prototipu funkcije nalazi pokazivac mora se
proslediti adresa promenljive uz pomoc adresnog operatora &. */

zameni(&a,&b);

printf("\n\n\tNakon zamene je:\n");
printf("\ta = %d",a);
printf("\n\tb = %d",b);

gotoxy(1,25);
getch();

}

31
/*Definisanje funkcije. */
void zameni(int *a, int *b)
{
/* Promenljiva pom je lokalna promenljiva. */
int pom;

pom=*a; /*Promenljiva pom dobija vrednost podatka ciju adresu sadrzi formalni
parametar a, a to je vrednost promenljive a iz zone podataka. */

*a=*b; /*Promenljiva a iz zone podataka dobija vrednost promenljive b iz zone podataka.
*/

*b=pom; /*Promenljiva b iz zone podataka dobija vrednost lokalne promenljive pom. */
}

Startovanjem programa vidi se da e promenljive a i b zameniti vrednosti.

Funkcija moe da vrati samo jednu vrednost. Nekada je to dovoljno, meutim
uglavnom je potrebno da funkcija uradi vie stvari. Funkcija moe uraditi vie stvari na
osnovu prenosa parametara po referenci.

Funkciji se prosledi adresa promenljive iz zone podataka, i nakon zavretka
funkcije u njoj se nalazi jedan od rezultata, dok se jedan rezultat prosledio preko naredbe
return. Ako funkcija prenosom parametara po referenci zapamti reenje drugog problema,
kae se da je funkcija reila taj problem bonim efektom.

Najee se funkcije tako i realizuju da se u povratnoj vrednosti vraa neka
vrednost koja ukazuje da li je funkcija obavila uspeno zadatak, ili ta je obavila, dok
se bonim efektima funkcija obavlja jedan ili vie zadataka..


Primer 2:
Napisati ta radi sledei program i objasniti ta radi funkcija pronadji.

#include <stdio.h>
#include <conio.h>

#define MAX 50

void pronadji(int x[], int a, int k);


void main(void)
{
int i,j,k,n,x[MAX];
unsigned xu, yu;

textmode(3);
textbackground(0);
32
textcolor(15);
clrscr();

printf("\n\n\tN = ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0||n>50);

for(i=0;i<n;i++) x[i]=i+1;

printf("\nNiz nakon formiranja:\n");
for(i=0;i<n;i++) printf("%5d",x[i]);

for(i=0;i<n-1;i++) pronadji(x,0,n-i-1);

printf("\n\nNiz nakon izvrsene modifikacije funkcijom:\n");
for(i=0;i<n;i++) printf("%5d",x[i]);
getch();
}

void pronadji(int x[], int a, int k)
{
int pom, i;

pom=*(x+a);
for(i=a;i<k;i++) *(x+i)=*(x+i+1);
*(x+k)=pom;
}

Reenje

Program na osnovu unetog broja n formira niz od n elemenata iji lanovi imaju
vrednost jednaku rednom broju lana niza. Korienjem funkcije pronai niz se
modifikuje tako da postaje zapisan u inverznom poretku i takav se ponovno tampa na
ekranu.
Funkcija pronadji vri rotaciju niza X izmeu indeksa a i k za jedno mesto u levo.



Primer 3:
Napisati ta radi sledei program i objasniti ta radi funkcija utvrdi.

#include <stdio.h>
#include <conio.h>

33
#define MAX 50

void uradi(int x[], int *a, int k);

void main(void)
{
int i,j,k,n,x[MAX],a=0;
unsigned xu, yu;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

printf("\n\n\tN = ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0||n>50);

for(i=0;i<n;i++) x[i]=i+1;

printf("\nNiz nakon formiranja:\n");
for(i=0;i<n;i++) printf("%5d",x[i]);

for(i=0;i<n;i++) uradi(x,&a,i);
uradi(x,&a,0);

printf("\n\nNiz nakon izvrsene modifikacije funkcijom:\n");
for(i=0;i<n;i++) printf("%5d",x[i]);
getch();
}

void uradi(int x[], int *a, int k)
{
int pom;

pom=*a;
*a=*(x+k);
*(x+k)=pom;
}
Reenje

Program na osnovu unetog broja n formira niz od n elemenata iji lanovi imaju
vrednost jednaku rednom broju lana niza. Korienjem funkcije uradi niz se modifikuje
tako da postaje zarotiran za jedno mesto u desno i takav se ponovno tampa na ekranu.
34
Funkcija uradi vri zamenu vrednosti elementa niza X na k-toj poziciji sa vrednosti
promenljive a.

Primer 4:
Napisati C program koji proverava da li elementi datog niza X od n lanov n< 51
obrazuju:

a) aritmetiku, ili
b) geometrijsku progresiju

Za odreivanje da li niz obrazuje aritmetiku ili geometrijsku progresiju koristiti
funkciju utvrdi, koja vraa -1 ako je niz aritmetiki, -2 ako je niz geometrijski ili 0 ako
niz nije aritmetiki ni geometrijski.
Prenosom podataka po referenci funkcija utvruje d ako je niz aritmetiki i q ako
je niz geometrijski.

Reenje

#include <stdio.h>
#include <conio.h>

#define MAX 50

/*Prototip funkcije. */
int utvrdi(int x[], int n, int *d, float *q);

void main(void)
{
int n,d,x[MAX];
unsigned xn,yn,xu,yu,i,j;
float q;

/*Inicijalizacija niza. */
for(i=0;i<MAX;i++) x[i]=0;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("Broj elemenata niza je:\n\tN = ");
xn=wherex(), yn=wherey();
do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0||n>MAX);

35
printf("Unesite elemente niza X:\n");
xu=wherex(), yu=wherey();

/* Niz se unosi pomocu ciklusa. */
for(j=0,i=0;i<n;i++)
{
if(j==16)
{
j=j%16;
yu++, xu=1;
}
gotoxy(xu+5*j,yu);
scanf("%4d",&x[i]);
j++;
}


/*Kako funkcija vraca jednu od tri vrednost sta je zakljucila koristicemo switch
strukturu. */

switch(utvrdi(x,n,&d,&q))
{
case -1: printf("\nNiz je aritmeticki!!\n\n\td = %d",d);
break;
case -2: printf("\nNiz je geometrijski!!\n\n\tq = %.2f",q);
break;
default: printf("\nNiz nije aritmeticki ni geometrijski!!");
}

gotoxy(1,25);
getch();
}

/*Definisanje funkcije. */
int utvrdi(int x[], int n, int *d, float *q)
{
unsigned i;

/*Prvo utvrdjujemo da li je niz aritmeticki. */
*d=x[1]-x[0];
i=1;
while(i<n&&x[i]-x[i-1]==*d) i++;
if(i==n) return -1;

/*Niz nije geometrijski ako je vrednost prvog clana niza 0. */
if(x[0]==0) return 0;
/*Utvrdjujemo da li je niz geometrijski. */
*q=x[1]/x[0];
i=1;
while(i<n&&x[i]==x[i-1] * (*q)) i++;
if(i==n) return -2;
36

return 0;
}

Test primer programa:



Primer 5:
Zadati su celobrojni nizovi A od n elemenata i B od m elemenata. Napisati C
program koji na osnovu nizova A i B formira niz C po sledeim pravilima.
- Niz C imae isti broj elemenata kao i niz B,
- I-ti element niza C dobija se sabiranjem odgovarajuih elemenata niza A (redom
sleva na desno ili sa desna na levo), koliko je po apsolutnoj vretnosti vrednost i-tog
elementa niza B,
- Ako je vrednost i-tog elementa niza B pozitivna sa sabiranjem se kree sa leva na
desno, a ako je negativna sa desna na levo,
- Ako je vrednost elementa niza B nula, tada je odgovarajua vrednost elementa
niza C jednaka vrednosti elementa niza A na kojoj se trenutno u nizu A nalazimo,
- Prvi element niza C dobija se sa sabiranjem poev od prvog elementa iz niza A,
dok se ostali dobijaju sabiranjem od trenutne pozicije gde se sa sabiranjem zavrilo
prilikom dobijanja predhodnog elementa, i
- Ako se doe do kraja ili poetka niza sa sabiranjem se nastavlja u suprotnom
smeru.
Za sabiranje elemenata sa leva na desno koristiti funkciju sabdesno, a za sabiranje
elemenata sa desna na levo koristiti funkciju sablevo.

Test primer: A = 3 5 7 3 1 8 4 2 7 9
B = 4 15 -12 0 -3

Niz C imae sledei izgled C = 18 75 55 7 13
Reenje

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

#define MAX_NIZ 30

/*Prototipovi funkcija. */
unsigned sabdesno(int *s,int n,int a[],unsigned *k,unsigned *j);
unsigned sablevo(int *s,int a[],unsigned *k,unsigned *j);

void main(void)
{
int s,n=10,a[MAX_NIZ], m=5,b[MAX_NIZ],c[MAX_NIZ];
unsigned i,j,p,k,xn,yn,xm,ym,xu,yu;
for(i=0;i<MAX_NIZ;i++) a[i]=b[i]=c[i]=0;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("Broj elemenata niza A je:\n\tN = ");
xn=wherex(), yn=wherey();

do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0||n>MAX_NIZ);

printf("Unesite elemente niza A:\n");
xu=wherex(), yu=wherey();

/* Niz se unosi pomocu ciklusa. */
for(j=0,i=0;i<n;i++)
{
if(j==16) j=0, yu++, xu=1;

gotoxy(xu+5*j,yu);
scanf("%4d",&a[i]);
j++;
}

printf("\n\nBroj elemenata niza B je:\n\tM = ");
xm=wherex(), ym=wherey();
do{
gotoxy(xm,ym);
printf(" ");
gotoxy(xm,ym);
scanf("%d",&m);
}while(m<=0||m>MAX_NIZ);

printf("Unesite elemente niza B:\n");
38
xu=wherex(), yu=wherey();

/* Niz se unosi pomocu ciklusa. */
for(j=0,i=0;i<m;i++)
{
if(j==16) j=0, yu++, xu=1;

gotoxy(xu+5*j,yu);
scanf("%4d",&b[i]);
j++;
}

j=0; /* Sa indeksom j krecemo se kroz niz A, a sa indeksom i kroz niz B. */
for(i=0;i<m;i++)
{
k=abs(b[i]); /* Sa k promenljivom utvrdjujemo koliko elemenata niza A treba
sabrati. */

/* Promenljiva p govori u kom smeru se vrsi prolazak kroz niz A. Ako je p
pozitivno vrsi se sa leva na desno, ako je negativno sa desna na levo, a ako je
jednako nuli ne vrsi se sabiranje. */

if(b[i]<0) p=-1;
else{
if(b[i]>0) p=1;
else p=0;
}

/* Ako je p jednako 0 zbir je jednak elementu niza A gde se trenutno nalazimo u
nizu A a to nam govori indeks j. */
if(p!=0) s=0;
else s=a[j];

/* Sabiranje se vrsi sve dok je p razlicito od nule. Prenosom po referenci
prosledjuje se zbir s, jer se sa sabiranjem nastavlja i ako se promeni smer
kretanja, indeks j kojim se prolazi kroz niz A, jer se on stalno menja, i
promenljivu k koja nam stalno ukazuje koliko jos elemenata iz niza A treba
sabrati. */

while(p!=0)
{
if(p==1) p=sabdesno(&s,n,a,&k,&j);
else p=sablevo(&s,a,&k,&j);
}
c[i]=s;
}
/* Niz C ima isti broj elemenata kao i niz B. */
printf("\n\n\n\nNiz C je:\n");
for(i=0;i<m;i++) printf("%d ",c[i]);

gotoxy(1,25);
39
getch();
}

/*Funkcija sabdesno sabira prolazeci kroz niz A sa leva na desno. */
unsigned sabdesno(int *s,int n,int a[],unsigned *k, unsigned *j)
{
unsigned i, p;

/* Prvo je potrebno ustanoviti da li ce se u ovom prolasku zavrsiti sa sabiranjem, te ako
jeste promenljiva p dobija vrednost nula, a ako ne promenljiva p dobija vrednost -1 koji
oznacava da ce se sa sabiranjem nastaviti u suprotnom smeru sdesna na levo. U tom
slucaju je potrebno odrediti koliko je jos elemenata ostalo za sabiranje u suprotnom
smeru I tu vrednost proslediti promenljivoj k. */

if(*k>n-(*j))
{
(*k)-=n-(*j);
for(i=*j;i<n;i++) *s+=a[i];
*j=n-1;
p=-1;
}else{
for(i=1;i<=*k;i++) *s+=a[*j],(*j)++;
(*j)--;
p=0;
}

/* Funkcija vraca vrednost koja odredjuje da li je sa sabiranjem zavrseno ili je potrebno
nastaviti u suprotnom smeru. */

return p;
}

/*Funkcija sabdesno sabira prolazeci kroz niz A sa desna na levo. */
unsigned sablevo(int *s,int a[],unsigned *k,unsigned *j)
{
unsigned i, p;

if(*k>(*j)+1)
{
(*k)-=(*j)+1;
p=(*j)+1;
for(i=1;i<=p;i++)
{
*s+=a[*j];
(*j)--;
}
*j=0;
p=1;
}else{
for(i=1;i<=*k;i++) *s+=a[*j],(*j)--;
(*j)++;
40
p=0;
}

return p;
}

Test primer programa:





























41
2.3. FUNKCIJE KOJE VRAAJU POKAZIVAE
POKAZIVAI NA FUNKCIJE

Funkcija i pokazivai omoguavaju etiri razliita naina povezivanja:
1) tip fun(); - Deklarie funkciju koja vraa vrednost tipa tip.
2) tip *fun(); Deklarie funkciju koja vraa pokaziva na vrednost tipa
tip.
3) tip (*pokf)(); - Deklarie pokaziva na funkciju koja vraa vrednost
tipa tip.
4) tip *(*pok)(); - Deklarie pokaziva na funkciju koja vraa pokaziva
na vrednost tipa tip.

Funkcije koje vraaju pokazivae
Funkcije mogu naredbom return da vrate samo jednu vrednost. Osim vrednosti
rezultat moe pretstavljati pokaziva (adresa neke memorijske lokacije). Pokaziva koji
se vraa mora odgovarati tipu povratne vrednosti.

Primer 1:
Napisati C program koji omoguava izbacivanje iz niza X od n elemenata (n<51),
sve one elemente koje imaju odreenu vrednost. Izbacivanje elemenata vriti funkcijom
izbaciizniza koja vraa broj izbaenih elemenata. U funkciji izbaciizniza koristiti
funkciju trazi koja utvruje da li u nizu ima elementa koga treba izbaciti i vraa adresu
elementa niza gde je pronaen ili NULL u suprotnom. Na ekranu tampati saeti niz ili
poruku da je niz ostao nepromenjen.

Reenje

#include <stdio.h>
#include <conio.h>

#define MAX 50

/* Prototipovi funkcija. */
unsigned izbaciizniza(int x[], int *n, int izbaci);
int *trazi(int izbaci, int x[], int n);

void main(void)
{
int izbaci,n,x[MAX];
unsigned xn,yn,xu,yu,i,j,k;

/* Inicijalizacija niza. */
for(i=0;i<MAX;i++) x[i]=0;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();
42

printf("Broj elemenata niza je:\n\tN = ");
xn=wherex(), yn=wherey();
do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0||n>MAX);

printf("Unesite elemente niza X:\n");
xu=wherex(), yu=wherey();
for(j=0,i=0;i<n;i++)
{
if(j==16)
{
j=j%16;
yu++;
xu=1;
}
gotoxy(xu+5*j,yu);
scanf("%4d",&x[i]);
j++;
}

printf("\nBroj koga izbacijes je: ");
scanf("%d",&izbaci);

/* Poziva se funkcija izbaci koja ako vrati vrednost 0 znaci da je niz ostao nepromenjen. */
if(izbaciizniza(x,&n,izbaci)!=0)
{
if(n!=0){
printf("\n\nSazeti niz X je:\n");
for(i=0;i<n;i++) printf("%d\t",x[i]);
}else printf("\n\nNiz vise nema elemenata!!");
}else printf("\n\nNiz je ostao nepromenjen!!");

gotoxy(1,25);
getch();
}

/* Funkcija izbaciizniza izbacuje iz niza sve one elemente koji imaju vrednost jednaku sa
vrednosti promenljive izbaci. U funkciji se n prenosi po referenci jer mu se u funkciji u
slucaju sazimanja menja vrednost. */

unsigned izbaciizniza(int x[], int *n, int izbaci)
{
unsigned i, k, br=0;
int *p=NULL;

43
/* Funkcija trazi vraca pokazivac na vrednost, te se morao deklarisati pokazivac
p koji ce prihvatiti adresu koju vraca funkcija trazi. */

while((p=trazi(izbaci,x,*n))!=NULL)
{

br++;

/* Indeks elementa niza jednak je razlici izmedju adrese tog elementa i
adrese pocetka niza. */

i=p-x;
for(k=i+1;k<*n;k++) x[k-1]=x[k];
x[*n-1]=0,(*n)--;
}

return br;
}


/* Funkcija trazi vraca pokazivac na element niza koji ima vrednost istu kao i vrednost
promenljive izbaci. */

int *trazi(int izbaci, int x[], int n)
{
unsigned i=0;

while(x[i]!=izbaci&&i<n) i++;

/* Adresa i-tog clana niza je x+i */
if(i<n) return x+i;
else return NULL;
}


Pokazivai na funkcije

Pokazivai pored toga to mogu da sadre adresu podatka, mogu da sadre i
adresu programskog koda.

Opti oblik pokazivaa na funkciju je:

tip (*indentifikator_pokazivaa)(niz_tipova_argumenata);

indentifikator_pokazivaa je pokaziva koji se definie.
niz_tipova_argumenata odreuje broj i tipove formalnih argumenata funkcija na
koje moe da pokazuje pokaziva koji se definie.

44
Priliko deklaracije zagrade u okviru kojih se nalazi pokaziva su neophodne, jer u
suprotnom umesto pokazivaa na funkcije imali bi smo funkciju koja vraa pokaziva.
Zagrade omoguavaju da se prvo izvri indirektno adresiranje pokazivaa, ime dolazimo
do adrese funkcije, a u drugoj zagradi nalaze se argumenti nad kojima e se funkcija
izvriti. Postoje dva sluaja kada se pokazivai najee koriste. Prvi je da pokaziva
zapamti adresu jedne od funkcija koja je izabrana, a da se naknadnim pozivanjem
pokazivaa na funkciju odabrana funkcija izvri. Drugi sluaj je da pokaziva na funkciju
predstavlja argument neke funkcije. Na taj nain se adresa jedne funkcije pomou
pokazivaa na funkciju prenosi drugoj funkciji.

Primer 2:
Napisati C program koji omoguava unos niza od n, n<11 taaka i tabelarni prikaz
vrednosti jedne od tri funkcije, na osnovu niza taaka. Funkcije su:

) 4 log(
, 1 ), 1 ( log*
2
2 2 2
+
= + = + =
x
e
y i x y x x y
x


Reenje

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

#define MAX 10

/* Prototipovi funkcija. */
void unos(double x[], int *n);
double fun1(double x);
double fun2(double x);
double fun3(double x);

/* Funkcija kao argument sadrzi pokazivac na funkciju. */
void tabela(double (*pok)(double ), double x[], int n);

void main(void)
{
int i,n=0;
double x[MAX];
char odluka;
for(i=0;i<MAX;i++) x[i]=0;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

/* Unosi se niz X od n tacaka. */
unos(x,&n);
45
/* Vrsi se izbor jedne od tri ponuene funkcije. */
printf("\nIzaberi jednu od tri sledece funkcije:\n");
printf("\t1: y = xlog(x+1)\n"); /* - ALT+253 */
printf("\t2: y = (x+1)\n");
printf("\t3: y = exp(x)/log(x+4)\n");
printf("\n\tVas izbor je: ");

do{
odluka=getch();
}while(odluka>'3'||odluka<'1');
printf("%c",odluka);

/* Prvi argument funkcije tabela je pokazivac na funkciju. Iz tog razloga njemu se
prosledjuje ime funkcije koje predstavlja adresu iz koda programa gde je pocetak
izvrsavanja te funkcije. */
switch(odluka)
{
case '1': tabela(fun1,x,n);
break;
case '2': tabela(fun2,x,n);
break;
case '3': tabela(fun3,x,n);
}
getch();
}

/* Funkcija unos omogucava unos niza tacak X od n elemenata. */
void unos(double x[], int *n)
{
unsigned xn,yn,xu,yu,i,j,k;

/* Vrsi se unos broja tacaka uz zastitu prilikom unosa. */
printf("Broj tacaka je:\n\tN = ");
xn=wherex(), yn=wherey();
do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
scanf("%d",&(*n));
}while((*n)<=0||(*n)>MAX);

printf("Unesite elemente niza tacaka X:\n");
xu=wherex(), yu=wherey();
for(j=0,i=0;i<*n;i++)
{
if(j==16) j=j%16, yu++, xu=1;
gotoxy(xu+5*j,yu);
scanf("%4lf",&x[i]);
j++;
}
}
46
/* Funkcija fun1 je prva funkcija iz izbora. */
double fun1(double x)
{
return x*x*log(x*x+1);
}

/* Funkcija fun2 je druga funkcija iz izbora. */
double fun2(double x)
{
return sqrt(x*x+1);
}

/* Funkcija fun3 je treca funkcija sa izbora. */
double fun3(double x)
{
return exp(x)/log(x*x+4);
}

/* Funkcija vrsi tabelarni prikaz apcise i odrinate funkcije. Prvi argumenat funkcije je
pokaziva na funkciju. */
void tabela(double (*pok)(double ), double x[], int n)
{
unsigned i;

printf("\n\n\tR.br. x f(x)\n");
printf("\t=============================================\n");

/* Pozivanjem pokazivaca na funkcija poziva se funkcija iju adresu on poseduje.
Prilikom pozivanja pokazivaca na funkciju moraju se pisati i stvarni argumenti funkcije,
kao i kod obicnog poziva bilo koje funkcije. */

for(i=0;i<n;i++) printf("\t%2d.%20.3f%20.3f\n",i+1,x[i],(*pok)(x[i]));
}

Test primer programa:


47


2.4. FORMIRANJE SOPSTVENE BIBLIOTEKE FUNKCIJA

Pretprocesor u C jeziku omoguava da se u izvorni kod programa ukljue
kompletne datoteke i na taj nain se znatno ubrza razvoj programa. Direktiva #include
ukljuuje u izvornu datoteku takozvane datoteke zaglavlja (header file) koji ima
ekstenziju h. Postoje dva naina ukljuivanja datoteke zaglavlja u programu:

#include <imedatoteke.h>
#include imedatoteke.h

Prvi nain pretrauje sistemske direktorijume u potrazi za datotekama zaglavlja,
dok drugi nain pretrauje trenutni radni direktorijum gde se nalazi program. Kada mi
formiramo header datoteku ukljuujemo je na drugi nain. Datoteka zaglavlja ima
ekstenziju h, formira se na isti nain kao i datoteka koda programa sa ekstenzijom C.
Nakon editovanja koda u datoteci zaglavlja, datoteka se snimi pod ekstenzijom h i potom
kompajlira. Datoteka zaglavlja ne sadri funkciju main i ne moe se pozvati poveziva
(prijavie se greka). Nakon kompajliranja stvorie se objektni fajl. U datotekama
zaglavlja pored direktiva pretprocesora, definisanja novih tipova podataka, deklaracije
promenljivih, nalaze se prototipovi funkcija i izvreno je njihovo definisanje.
Datoteke zaglavlja podravaju osnovne koncepte modularnog programiranja. Kako
u programu moe postojati vie datoteka zaglavlja. Svaka datoteka zaglavlja sadri
srodne funkcije (odnose se na isti pojam, rad sa miem, rad sa stringovima, rad sa
menijima, sortovi, itd...). Datoteka zaglavlja sadri funkcije koje pretstavljaju module.
Dobro kreirani modul komunicira sa spoljnim svetom samo preko parametara funkcije.
Na taj nain se vri zatita podataka. Jednom formirani moduo povezivanjem datoteke
zaglavlja sa programom, moemo koristiti u vie programa. Datoteke zaglavlja se
kompajliraju posebno to omoguava lake otklanjanja greaka.

Primer 1:
Napisati C program TEST1.C koji omoguava unos niza X od n elemenata i
njegovo sortiranje u rastuem redosledu i program TEST2.C koji formira niz Y od m
elemenata u opadajuem redosledu n<31 i m<41. Prilikom realizacije programa koristiti
funkcije unos_ceo koja omoguava unos celog broja tipa int, ali da se prilikom unosa
broja omogui zatita unosa (ne dozvoljava unos drugih karaktera osim dekadnih cifara).
U hederu NIZ.H se pored opisane funkcije nalaze i funkcije:
unos_niza - koja omoguava unos niza pozivajui funkciju unos_ceo,
unos_brc - koja omoguava unos broja lanava niza uz zatitu unosa pozivajui
funkciju unos_ceo,
sort - koja vrsi sortiranje niza u rastuem ili opadajuem redosledu u odreenom
intervalu, i
ispis_niza - koja omoguava ispis niza na ekranu.

Reenje

48
NIZ.H

#include <stdio.h>

/* Prototipovi funkcija. */
int unos_ceo(void);
int unos_brc(unsigned m);
void unos_niza(int x[], int n);
void sort(int x[], int p, int q, int odl);
void ispis_niza(int x[], int n, int startx, int starty, int endx);

/* Funkcija unos_ceo omogucava unos celog broja. */
int unos_ceo(void)
{
unsigned xu, yu;
char c;
int x, pom=1;

/* Sa unosom broja pocinjemo od trenutne pozicije na ekranu. */
xu=wherex(); yu=wherey();
x=0;
do{
c=getch();

/* U slucaju da je predznak negativan promenljiva pom
dobija vrednost -1. */
if(c=='-'&&x==0) pom=-1, putch(c);

/* Cifra je ako je karakter veci od 48 a manji od 57, jer su to redni brojevi koji
odgovaraju decimalnim ciframa iy ASCII tabele. Prva cifra ne moye da bude 0.
*/
if((c>48&&c<=57)||(c==48&&x!=0))
{
x=x*10+c-48;
putch(c);
}

/* Znajuci da ako broj predje granicu 32767 automatski postaje negativan,
utvrdjujemo da li se to desilo I usled prekoracenja vracamo korisnika na ponovni
unos. */
if(x<0)
{
x=0;
pom=1;
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
}

}while(c!='\r' || x==0);
49

/* Vracamo dobijeni broj pomnozen sa zapamcenim predznakom. */
return x*pom;
}

/* Funkcija omogucava unos broja clanova niza koriscenjem funkcije unos_ceo, uz
kontrolu unosa gde je dimenzija niza zapamcena u promenljivoj m. */
int unos_brc(unsigned m)
{
unsigned xn, yn;
int n;

printf("Broj elemenata niza je:\n\tN = ");
xn=wherex(), yn=wherey();
do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
n=unos_ceo();
}while(n<=0||n>m);

return n;
}

/* Funkcija unos_niza omogucava unos elemenata niza pozivajuci funkciju unos_ceo. */
void unos_niza(int x[], int n)
{
unsigned xu, yu, i, j;

printf("Unesite elemente niza:\n");
xu=wherex(), yu=wherey();


/* Niz se unosi pomocu ciklusa. */
for(j=0,i=0;i<n;i++)
{
if(j==16) j=j%16, yu++, xu=1;
gotoxy(xu+5*j,yu);
x[i]=unos_ceo();
j++;
}
}

/* Funkcija sort omogucava sortiranje niza izmedju dva indeksa i to u rastucem redosledu
ako je odl jednak 1, a u opadajucem redosledu ako je odl razlicit od 1. */
void sort(int x[], int p, int q, int odl)
{
unsigned i, j;

for(i=p;i<=q-1;i++)
{
50
for(j=i+1;j<=q;j++)
{
if(odl==1)
{
if(x[j]<x[i]) x[i]+=x[j],x[j]=x[i]-x[j],x[i]-=x[j];
}else{
if(x[j]>x[i]) x[i]+=x[j],x[j]=x[i]-x[j],x[i]-=x[j];
}
}
}
}

/* Funkcija ispis_niza omogucava ispis elemenata niza pocev od startnih pozicija na ekranu
startx i starty, do granice endx. */
void ispis_niza(int x[], int n, int startx, int starty, int endx)
{
unsigned i, j, m, xs, ys;

/* Utvrdjujemo koliko se brojeva moze ispisati na ekranu, polazeci od cinjenice da je
maksimalni broj 32767, a minimalni -32768 sto odgovara 6 mesta na ekranu.. Taj
podatak se upisuje u promenljivu m. */

m=(endx-startx)/6;
gotoxy(startx,starty);
xs=startx;
ys=starty;

for(j=0,i=0;i<n;i++)
{
if(j==m)
{
j%=m;
ys++;
gotoxy(xs,ys);
}
printf("%-6d",x[i]);
j++;
}
}

TEST1.C

#include <stdio.h>
#include <conio.h>

/* Ukljucivanje datoteke zaglavlja niz.h u program. */

#include "niz.h"

#define MAX 30

51
void main(void)
{

/* Deklaracjia promenljivih. */

int x[MAX], n, i;

/* Inicijalizacija niza X. */
for(i=0;i<MAX;i++) x[i]=0;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

/* Unos broja clanova niza X. */
n=unos_brc(MAX);
printf("\n\n");

/* Unos elemenata niza X. */
unos_niza(x,n);

/* Sortiranje elemenata niza X u rastucem redosledu. */
sort(x,0,n-1,1);

/* Ispis elemenata niza X. */
printf("\n\n\nSortirani niz:u rastucem redosledu:\n");
ispis_niza(x,n,wherex(),wherey(),79);

getch();

}

Test primer programa:



52
TEST2.C

#include <stdio.h>
#include <conio.h>

/* Ukljucivanje datoteke zaglavlja niz.h u program. */
#include "niz.h"
#define MAX_NIZ 40

void main(void)
{
/* Deklaracjia promenljivih. */
int y[MAX_NIZ], m, i;
/* Inicijalizacija niza Y. */
for(i=0;i<MAX_NIZ;i++) y[i]=0;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

m=unos_brc(MAX_NIZ);
printf("\n\n");
unos_niza(y,m);

/* Sortiranje elemenata niza Y u rastucem redosledu. */
sort(y,0,m-1,2);

printf("\n\n\nSortirani niz u opadajucem redosledu:\n");
ispis_niza(y,m,wherex(),wherey(),79);
getch();
}

Test primer programa:



53
Primer 2:
Zadat je celobrojan niz X od n elemenata n<51 i celobrojni podatak p. Napisati C
program koji korienjem to veeg broja funkcija iz ve formirane biblioteke NIZ.H na
ekranu tampa sve intervale niza koji imaju osobinu da je zbir elemenata niza sa tog
intervala jednak podatku p. Prilikom realizacije ovog problema zamislite da niz
predstavlja ogrlicu (posle zadnjeg elementa sledi prvi element niza). Interval mora
zadovoljiti osobinu da je vei ili jednak od 2 a manji ili jednak od n.
Deo niza koga obrazuje najvei interval i ujedno je zbir njegovih indeksa najvei, sa
gore navedenom osobinom, sortirati u rastuem redosledu a potom prikazati na ekranu
novonastali niz, kao i broj zamena elemenata niza koji se izvrio prilikom sortiranja dela
niza.

Na primer:
N = 12
X = 2 5 -6 4 3 2 1 2 23 4 1 2
P = 10

[1..6] 2 5 -6 4 3 2
[4..7] 4 3 2 1
[11..12] U [1..2] 1 2 2 5
12 U [1..5] 2 2 5 -6 4 3

Sortirani niz X = 2 2 3 4 5 2 1 23 4 1 -6
Prilikom sortiranja izvrsene su 3 izmene.

Reenje

#include <stdio.h>
#include <conio.h>
#include "niz.h"

#define MAX_NIZ 50

/* Prototipovi funkcija. */
void inicijalizacija(int a[]);
unsigned intervali(int x[], int n, int p, int *a, int *b);
int sortint(int x[], int a, int b, int n);

void main(void)
{
int x[MAX_NIZ],n,p,a=0,b=0,br=0;
inicijalizacija(x);

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

54
/* Unos koliko ce niz imati elemenata uz ogranicenje da ne bude vece od dimenzije niza.
*/

n=unos_brc(MAX_NIZ);
printf("\n\n");

/* Unos elemenata niza. */
unos_niza(x,n);
printf("\n\np = ");

/* Unos broja koji se sabiranjem intervala mora dobiti. */
p=unos_ceo();
printf("\n\n");

if(!intervali(x,n,p,&a,&b)) printf("Nema trazenih intervala!!");
else{
/* Sortira deo niza u rastucem redosledu. */
br=sortint(x,a,b,n);

/* Prikaz niza nakon sortiranja. */
printf("\n\nNakon sortiranja niz X je:\n ");
ispis_niza(x,n,wherex(),wherey(),79);
/* Ispis podatka koliko je izvrseno zamena. */
if(br==1||br>4)
printf("\n\n\nPrilikom sortiranja izvrseno je %d izmena.",br);
else printf("\n\n\nPrilikom sortiranja izvrsene su %d izmene.",br);
}
getch();
}

/* Funkcija inicijalizacija vrsi inicijalizaciju niza. */
void inicijalizacija(int x[])
{
int i;

for(i=0;i<MAX_NIZ;i++)
{
x[i]=0;
}
}

/* Funkcija intervali ispisuje na ekranu sve intervale sa osobinom da je zbir elemenata niza
sa tog intervala jednak broju p. Ako postoji barem jedan slucaj da je funkcija ispisala bice
vracena 1 a u suprotnom bice vracena 0. Bocnim efektom odredjuje pocetak i kraj intervala
koji je imao najveci zbir indeksa, jer se taj interval posle mora sortirati u rastucem
redosledu. */

unsigned intervali(int x[], int n, int p, int *a, int *b)
{
int i,j,k,s=0,m, kon=0;

55
/* Kroz niz prolazimo sa dvostrukim ciklusom jer se mora ispitati svi podintervali. Indeks
koji oznacava pocetak intervala krece se od 0 do n-1 jer je niz povezan kao ogrlica, a
kako interval ne moze biti veci od n elemenata to se pocetak intervala moze u najgorem
slucaju desiti od poslednjeg clana niza (posle nastupaju ponovljeni slucajevi). Indeks
kraja intervala krece se od 2*n jer ogrlica moze da se opise sa duplim nizom (niz i
inverzni poradak tog istog niza). Kako mi u stvarnosti nismo formirali dupli niz, vec smo
to zamislil, osnovna ideja je da se operatorom % obeybedjuje da se takvo kretanje
ostvari. */

for(i=0;i<=n-1;i++)
{
for(j=2*n;j>i;j--)
{
/* Izracunava se zbir sa intervala izmedju indeksa i i j */
for(k=i,s=0;k<=j;k++) s+=x[k%n];

if(s==p)
{
/* Ispis granica intervala. */
if(i%n+1<j%n+1) printf("\n[%d..%d]\t",i%n+1,j%n+1);
else{
if(i%n+1==n) printf("\n%d U [1..%d]\t", i%n+1,j%n+1);
else{
if(j%n+1==1) printf("\n[%d..%d] U %d\t", i%n+1,j%n+1);
else printf("\n[%d..%d] U [1..%d]\t", i%n+1,n,j%n+1);
}
}
/* Ispis elemenata sa tog intervala. */
for(m=i;m<=j;m++) printf("%d ",x[m%n]);
if(i>(*a)&&j>(*b)) (*a)=i,(*b)=j;
kon=1;
}
}
}
return kon;
}

/* Funkcija sortint sortira najveci interval koji yadovoljava svojstvo da mu je ybir jednak
broju p I ujedno ako ih ima vise poseduje najveci zbir indeksa. Funkcija vraca broj
izvrsenih zamena elemenata prilikom sortiranja intervala.*/
int sortint(int x[], int a, int b, int n)
{
int i,j,min,pom,poz,br=0;

/* Ovde je prikazana tehnika sortiranja gde se najmanji element smesta na pocetak
intervala, pa se posmatra podinterval gde nema prvog, odredi opet najmanji i smesti na
pocetnu poziciju tog podintervala, itd... */
for(i=a;i<b;i++)
{
min=x[i%n];
poz=i;
56
for(j=i;j<=b;j++) if(x[j%n]<min) min=x[j%n], poz=j%n;
if(x[i%n]!=min) br++;
pom=x[i%n];
x[i%n]=min;
x[poz%n]=pom;
}
return br;
}

Test primer programa:



























57

2.5. ZADACI IZ FUNKCIJA


Zadatak 1 (2)
Napisati C program koji na osnovu unetog prirodnog broja n i racionalnog broja x
izraunava i tampa sumu zaokruenu na etiri decimale. Sumu raunati pozivom
funkcije suma ija je sintaksa: double suma(int n, double x);
Suma je zadata oblikom:

n x
x
x
x
x
x
x
x
S
n
n
+ + + + +
+ +
+ + +
+
+ +
+
+
+ =
... 3 2 1
...
3 2 1 2 1 1
1
3
3
2
2



Zadatak 2 (2)
Napisati C program koji na osnovu unetih prirodnih brojeva n i x izraunava i
tampa sumu zaokruenu na tri decimale. Sumu raunati pozivom funkcije suma.
Suma je zadata oblikom:

n x n
x n
x
x
x S
n
n
+ + + + +

+ +
+ + +

+ + =

... 3 2 1 ) 1 (
...
3 2 1 2
3
1
1 2
3



Zadatak 3 (2)
Napisati C program koji korienjem unetog prirodnog neparnog broja n (2<n>12),
pozivom funkcije slika prikazuje na ekranu sliku od zvezdica sledeeg izgleda:


* * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
* * * * *
* * * * * * *
* * * * * * * * *
* * * * * * * * * * * Za n = 7 je napravljena ova slika,
* * * * * * * * * a 2n je broj zvezdica kvadrata.
* * * * * * *
* * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * *


Oko kvadrata nalazi se ram koji se uvek sastoji od dva reda zvezdica.
U unutranjosti kvadrata nalazi se deltoid ija manja dijagonala ima n zvezdica.
58

Zadatak 4 (2)
Napisati C program koji na osnovu unetog prirodnog broja n izraunava zbir
kvadrata prvih n prirodnih brojeva. Za izraunavanje zbira koristiti funkciju zbir.

Zadatak 5 (2)
Napisati C program koji na osnovu unetog prirodnog broja n izraunava
korienjem funkcije zbir, zbir prvih n lanova niza:

3, -6, 12, -24, 48, -96, ...

Zadatak 6 (2)
Napisati C program koji na osnovu unetog prirodnog broja n izraunava
korienjem funkcije suma, zbir predstavljen sledeim izrazom:


n
n
S
n
+ + + + +

+
+ + +

+ +

+
+

+ =

... 4 3 2 1
... 4 3 2 1
) 1 ( ...
4 3 2 1
4 3 2 1
3 2 1
3 2 1
2 1
2 1
1
1
2
1


Zadatak 7 (2)
Napisati C program koji korienjem funkcije suma izraunava zbir pozitivnih
elemenata celobrojnog niza X. Niz X ima n elemenata (n<41).

Zadatak 8 (2)
Zadati su celobrojni nizovi X i Y od po n elemenata n<50. Napisati C program koji
na osnovu nizova X i Y formira niz Z po sledeem pravilu: z[i] = max(x[i],y[i]), i=[1..n]
Odgovarajui element niza Z dobija se pozivom funkcije max.

Zadatak 9 (2)
Napisati C program koji pozivom funkcije trazi, utvruje da li se u celobrojnom
nizu X od n (n<31) elemenata nalazi broj p. Ako se broj p nalazi u nizu funkcija vraa 1
a u suprotnom 0.

Zadatak 10 (3)
Napisati program u programskom jeziku C koji na osnovu unetog broja zvezdica n
(n je neparan broj) korienjem funkcije kvadrat prikazuje simulaciju formiranja punog
kvadrata zvezdica iji centar e biti na koordinatama (41,13). Kvadrat se formira
zvezdica po zvezdica poev od donjeg desnog ugla u smeru kretanja kazaljke na
asovniku. Kvadrat se popunjava spiralnim pupunjavanjem.

Zadatak 11 (3)
Napisati C program koji vri konverziju dekadnog broja n (n<250) u njegov binarni
ekvivalent i vri njegov binarni ispis na ekranu. Pretvaranje i ispis realizovati funkcijom
bin_ispis.


59

Zadatak 12 (3)
Napisati C program koji na osnovu unetog prirodnog broja n izraunava pozivom
funkcije zbir, zbir prvih n lanova niza:

1, 1, 2, 5, 7, 74, ...

Prva dva lana niza imaju vrednost 1, a poev od treeg svaki sledei lan dobija se
kao zbir kvadrata predhodna dva lana.

Zadatak 13 (3)
Napisati C program koji na osnovu unetog prirodnog broja n korienjem funkcije
prost utvruje i na ekranu tampa sve proste brojeve koji se nalaze na intervalu 1..n.

Zadatak 14 (3)
Eksponencijalna funkcija
x
e y = moe se izraunati razvojem u Maklorenov red,
kao:


k
x x x
x e
k
x

+ +

+

+ + =
... 3 2 1
...
3 2 1 2 1
1
3 2



pri emu je k korak, ili broj lanova u razvoju.
Napisati C program koji korienjem funkcije ekspo izraunava priblinu vrednost
eksponencijalne funkcije
x
e y = za zadat broj koraka k i zadat argument x, i tampa
razliku izmeu tog rezultata i rezultata dobijenog pozivom biblioteke funkcije exp ija je
sintaksa double exp(double x); i nalazi se u math.h.


Zadatak 15 (3)
Napisati C program koji korienjem funkcije datum na osnovu rednog broja dana
u godini ispisuje datum koji odgovara tom rednom broju. Funkcija vraa 1 ako je redni
broj korektan, a u suprotnom 0. Funkcijom korienjem bonog efekta odrediti dan i
redni broj meseca.


Zadatak 16 (3)
Brojano su dati dan, mesec i godina. Ispisati dan u mesecu, naziv datog meseca,
godinu i dan u godini. Za izraunavanje dana u godini napisati funkciju reddan.

Na primer:

Dan: 15
Mesec:3 => 15 mart 1987 dan 74
Godina:1987
60

Zadatak 17 (3)
Zadat je celobrojan niz A od n elemenata n<100. Napisati C program koji za uneto
k, vri pozivom funkcije rotiraj rotiranje niza za k elemenata. Ako je k>0 vri se
rotiranje za k elemenata u desno, ako je k<0 za k elemenata u levo, a za k=0 ne vri se
rotacija niza. Funkcija vraa 0 ako nije vrila rotaciju niza, a u suprotnom vraa 1.

Zadatak 18 (3)
Zadat je celobrojan niz A od n elemenata n<100. Napisati C program koji na
osnovu niza A formira niz B u koji ulaze samo oni elementi niza A ija je apsolutna
vrednost manja od apsolutne vrednosti razlike izmeu maksimalnog i minimalnog
elementa niza A.
Niz B formirati funkcijom formb u okviru koje se pozivaju funkcije minimum i
maksimum za traenje minimalnog odnosno maksimalnog elementa niza A.


Zadatak 19 (3)
Dati su celobrojni nizovi A od n i B od m elemenata pri emu je m>n, n<50 i
m<50. Napisati C program koji na osnovu nizova A i B formira niz C po pravilu c[i] =
a[i] + br[i] + s[i], i = [1..n] , pri emu je br[i] broj elemenata niza B koji imaju vrednost
veu od a[i] a dobija se korienjem funkcije broji, a s[i] je zbir svih elemenata niza B
iji je indeks manji ili jednak sa i, a vrednost pozitivna a dobija se korienjem funkcije
suma.
.
Zadatak 20 (3)
Napisati C program koji na osnovu celobrojnog niza X formira niz Y. I-ti element
niza Y (i=[1..n]) jednak je zbiru svih prethodnika od i-tog elementa niza X. Za
izraunavanje zbira prethodnika koristiti funkciju zbir.

Zadatak 21 (4)
Napisati C program koji na osnovu unetog prirodnog broja n sa intervala 1..n trai
korienjem funkcije trazi_del broj koji ima najvie delilaca. tampati sve brojeve u
sluaju da ima vie takvih brojeva.. Funkcija trazi_del na osnovu prirodnog broja k
utvruje i vraa broj delilaca broja k.

Zadatak 22 (4)
Napisati C program koji po izboru korisnika vri sortiranje celobrojnog niza X od n
(n<41) elemenata u rastuem ili opadajuem redosledu. Sortiranje niza vri se pozivom
samo jedne funkcije pod imenom sort. Prenosom po referenci prosleuje se da li je
sortiranje u rastuem ili opadajuem redosledu.

Zadatak 23 (4)
Napisati C program koji korienjem funkcije utvrdi utvruje broj razliitih
elemenata u celobrojnom nizu X od n elemenata (n<41).


61

Zadatak 24 (4)
Napisati C program za poreenje dva niza celih brojeva A i B od po n elemenata
n<100. Poreenje dva niza vriti funkcijom poredi koja vraa -1 ako je niz A manji od
niza B, 0 ako je niz A jednak nizu B ili 1 ako je niz A vei od niza B.

Poreenje vriti po sledeem pravilu:

a) A<B, ako do nekog k-tog k=[1..n] elementa vai a[i]=b[i] i=[1..k], a
a[k+1]<b[k+1],
b) A>B, ako do nekog k-tog k=[1..n] elementa vai a[i]=b[i] i=[1..k], a
a[k+1]>b[k+1], i
c) A=B, ako je a[i]=b[i], i=[1..n]

Na ekranu tampati odgovarajuu poruku: NIZ A JE MANJI OD NIZA B,
NIZOVI A I B SU ISTI, ili NIZ A JE VECI OD NIZA B.


Zadatak 25 (4)
Zadat je celobrojan niz X od n elemenata n<100. Napisati C program koji pozivom
funkcije ekstremi tampa na ekranu ekstreme niza X na sledei nain:


VREDNOST TIP

**** minimum
**** maksimum


Funkcija ekstremi vraa 0 ako i-ti lan niza X x[i] i=[1..n] nije ekstrem, 1 ako je
maksimum i -1 ako je minimum.

Na primer:
Neka je X = 1, 5, 3, 6, 2, 1, 10, 11, 23 i 0.
tada e izvetaj imati sledei izgled:

VREDNOST TIP

5 maksimum
3 minimum
6 maksimum
1 minimum
23 maksimum



62
Zadatak 26 (4)
Zadat je niz X od n elemenata (n<51). Napisati C program koji pozivom funkcije
sazmi izbacuje iz celobrojnog niza svaku pojavu odgovarajueg broja broj. Ako broja
nema u nizu funkcija vraa 0, a u suprotnom koliko je elemenata niza imalo tu vrednost.

Zadatak 27 (4)
Zadat je niz X od n elemenata (n<51). Napisati C program koji odreuje prvi
interval elemenata kod koga svi elementi imaju veu vrednost od unetog racionalnog
broja a. Interval mora imati najmanje tri elementa. Funkcija interval vraa duinu
intervala ako postoji ili 0 u suprotnom, dok se bonim efektom odreuju indeksi poetka
i kraja intervala.

Zadatak 28 (4)
Zadat je niz X od n (n<41) elemenata. Napisati C program koji odreuje vrednost
zbira dela niza izmeu pozicija minimalnog i maksimalnog elementa i srednju vrednost
ostatka niza.
Za formiranje niza X od n elemenata koristiti funkciju unos. U nizu X nema
ponavljanja elemenata. Funkcija uradi izraunava i po vrednosti vraa zbir elemenata
niza izmeu pozicija minimalnog i maksimalnog elementa, a bonim efektom srednju
vrednost ostatka niza. Funkciji po referenci proslediti vrednost logike promenljiva koja
nakon zavretku funkcije dobija vrednost 1 ako je izraunata srednja vrednost ili 0 ako se
srednja vrednost ne moe izraunati. Funkcijom minmax odrediti i po referenci vratiti
pozicije minimalnog i maksimalnog elementa niza.

Zadatak 29 (4)
Napisati C program koji pozivom funkcije trazi, utvruje da li se u celobrojnom
nizu X od n (n<31) elemenata nalazi broj p. Ako se broj p nalazi u nizu funkcija vraa 1
a u suprotnom 0. Koristei funkciju trazi u funkciji izbaci, izbaciti svako viestruko
pojavljivanje broja p u nizu X. U nizu ostaviti onaj broj p koji je imao najvei indeks.
Funkcija izbaci vraa broj izbaenih elemenata iz niza X, ili 0 ako ni jedan element nije
izbaen iz niza.

Zadatak 30 (5)
Zadat je niz X od n (n<51) elemenata. Napisati C program koji odreuje najvei
rastui interval niza. Ako ima vie takvih intervala ispisati ih sve na ekranu, i za svaki
utvrditi da li sadri maksimalni element niza. Odreivanje najveih rastuih intervala niza
vri se pozivom funkcije interval koja vraa duinu podniza ili -1 ako rastueg intervala
nema, dok se poetak i kraj intervala vraa po referenci. Funkcija max utvruje vrednost
maksimalnog elementa niza, a funkciju pronadji (pozivom funkcije max) pripadnost
maksimalnog elementa najveem rastuem intervalu. Rastui interval mora imati barem
dva lana niza.

Zadatak 31 (5)
Napisati C program koji pozivom funkcije period utvruje da li je celobrojan niz X
od n (n<51) elemenata periodian. Funkcija vraa 0 ako niz nije periodian, ili broj
0 = p koji predstavlja traeni period.
63
Zadatak 32 (5)
Napisati C program koji omoguava ispis ASCII tabele na ekranu, a zatim za unos
nekog rednog broja oznaiti odgovarajui znak na ekranu. Oznaku odgovarajueg znaka
sa ekrana vri se pozivom funkcije oznaci.



Zadatak 33 (5)
Zadat je prirodan broj n. Napisati C program koji rastavlja prirodan broj n na dva
sabirka k i p tako da se sabirak p dobija od broja k brisanjem jedne cifre. Ukoliko je broj
k jednocifren broj tada je p nula. tampati sve mogue sluajeve.

Zadatak 34 (2)
Napisati C program koji na osnovu unetog prirodnog broja n korienjem
rekurzivne funkcije rek na ekranu tampa brojeve od 1 do n i od n do 1, tj:

1 2 3 4 5 ... n n ... 5 4 3 2 1

Zadatak 35 (2)
Napisati C program koji na osnovu unetog prirodnog broja n korienjem
rekurzivne funkcije faktorijal izraunava faktorijal prirodnog broja n. Faktorijel
prirodnog broja n rauna se po formuli:

1 2 3 ... ) 2 ( ) 1 ( ! = n n n n

Zadatak 36 (3)
Napisati C program koji korienjem rekurzivne funkcije zbir izraunava zbir
cifara dekadnog prirodnog broja n.

Zadatak 37 (3)
Napisati C program koji na osnovu unetog prirodnog broja n izraunava zbir prvih
n brojeva Fibonaijevog niza.
Fibonaijev niz ima sledei izgled: 1 1 2 3 5 8 13 21 34 55 ...
Za raunanje vrednosti k-tog lana Fibonaijevog niza koristiti rekurzivnu funkciju
fib.
64
Zadatak 38 (4)
Napisati C program za izraunavanje kolinika prirodnih brojeva n i m na k
decimala. Za odreivanje kolinika prirodnih brojeva n i m koristiti rekurzivnu funkciju
rekkol.

Zadatak 39 (4)
Napisati C program koji izraunava korienjim rekurzivne funkcije rekdet
determinantu D
p
oblika:

pxp
p
n
m
k
n
m n
m
k
n
m
k
n
D
.
.
.
.
0
0
0
.
.
.
.
0
0
0
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
0
0
.
.
.
.
0
0
0
0
.
.
.
.
0
0
0
.
.
.
.
0
0
.
.
.
.
0
= N k m n p e , , ,
Gde je p red determinante, a n,m i k su parametri.

Zadatak 40 (5)
Novac kojim raspolae (trenutno se nalazi u kasi) sluba platnog prometa jedne
banke zadata je nizom novac. Prvi lan niza sadri broj novanica apoena 1000, drugi
broj novaanica apoena 500, trei broj novanica apoena 200, sledei se odnosi na apoen
100, pa 50, pa 20, pa 10, pa 5, pa 2, pa 1 apoen.
Napisati C program koji treba da odredi kako e sluba isplatiti klijenta od N dinara
a da pri tome utoi to manje novanica sa manjim apoenima. Problem reiti funkcijom
isplata koja vraa vrednost 1 ako je mogue isplatiti klijenta, a 0 u suprotnom.
Korienjem bonog efekta i niza novac, ispisati kako je izvrena isplata, kao i koliko je
novca po apoenima ostalo u banci.

Zadatak 41 (4)
Formirati heder MOJEFUN.H gde e se nalaziti tvoje najee koriene funkcije.
Formirati funkciju un_ceo koja onemoguava unos znaka koji nije cifra (0..9), a
zavrava se unosom kada se pritisne taster ENTER. Funkcija vraa uneti broj koji se
ispisuje na ekranu, a kursor se nalazi posle zadnje unete cifre. Demonstrirati korienje
funkcije pisanjem glavnog C programa (sadri main funkciju).

Zadatak 42 (4)
Formirati funkciju un_rac i smestiti je u heder MOJEFUN.H koja onemoguava
unos znaka koji nije cifra (0..9) ili decimalna taka, a zavrava se unosom kada se pritisne
taster ENTER. Funkcija vraa uneti broj koji se ispisuje na ekranu, a kursor se nalazi
posle zadnje unete cifre. Demonstrirati korienje funkcije pisanjem glavnog C programa
(sadri main funkciju).
65
Zadatak 43 (5)
Dopuniti C program (zadatak 9 iz poglavja nizovi) tako da igra samo jedan igra, a
da je drugi igra raunar. Raunar uvek igra kao "X". Programski igra raunara je
realizovana funkcijom kompot. Funkcija vraa poziciju u nizu gde treba upisati broj 2
(to oznaava da digrao raunar). Pozicija mora biti korektna,tj na toj poziciji nalazi se u
nizu vrednost 0. Po moguustvu funkcija kompot treba da vraa takve poteze da na
kraju igre pobednik uvek bude raunar, ili je igra zavrena nereeno.



Zadatak 44 (4)
Formirati funkcije unos_niza i ispis_niza. Prilikom unosa niza koristiti funkciju
un_ceo koja je realizovana u 41 zadatku i nalazi se u hederu MOJEFUN.H.
Demonstrirati korienje funkcija pisanjem glavnog C programa (sadri main funkciju).

Zadatak 45 (3)
Formirati funkcije minimum, maksimum i sort_niz i smestiti ih u heder
MOJEFUN.H. Funkcija sort_niz moe da sortira u rastuem ili opadajuem redosledu.
Demonstrirati korienje funkcija pisanjem glavnog C programa (sadri main funkciju).

Zadatak 46 (3)
Zadat je celobrojan niz X od n elemenata pri emu je n paran broj i n<100. Napisati
C program koji korienjem funkcija unos_niza, ispis_niza i sort_niz koji se nalaze u
hederu MOJEFUN.H, prvu polovinu zadatog niza sortira u opadajuem redosledu, a
drugu polovinu u rastuem redosledu.

Zadatak 47 (3)
Napisati C program koji korienjem raspoloivih funkcija iz hedera MOJEFUN.H
omoguava unos racionalnog niza X od n elemenata (n<41) i utvruje koliko elemenata
niza ima vrednost veu od minimalne a manju od maksimalne.

Zadatak 48 (4)
Napisati funnkcije unos_dug_broja i ispis_dug_broja. Dugaak ceo broj se
smeta u niz pri emu svaki element niza poev od drugog sadri broj koji predstavlja
cifru od 0 do 9, dok prvi element sadri redni broj predznaka (+ ili -) iz ASCI I tabele.
Funnkcije smestiti u heder MOJEFUN.H. Demonstrirati korienje funkcija pisanjem
glavnog C programa (sadri main funkciju).
66
Zadatak 49 (5)
Napisati C program koji e korienjem funkcija saberi, oduzmi, ili mnozi po
izboru korisnika vri sabiranje, oduzimanje ili mnoenje dva dugaka cela broja. Dugaki
brojevi se nalaze smeteni u dva niza. Svaki element niza poev od drugog sadri broj
koji predstavlja cifru od 0 do 9, dok prvi element sadri redni broj predznaka (+ ili -) iz
ASCI I tabele Takoe za unos cifre koristiti funkciju unceo koja omoguava unos znaka
iz intervala 0..9 i vraa ceo broj (0..9) ili -1 ako je pogreno unet znak. Rezultat je takoe
dugaak ceo broj ije su cifre smetaju u niz, po gore navedenom pravilu. Sve napisane
funkcije treba smestiti u hederu MOJEFUN.H.

Zadatak 50 (5)
Dopuniti "Zmijicu" iz 50 zadatka oblasti nizovi, tako da se koriste funkcije.
Program mora imati etiri nivoa:
Prvi nivo je zadatak 50 iz prole glave stim to igra ima tri ivota, a igra gubi
ivot kada "Zmijica" sa glavom naie na samu sebe.
Drugi nivio dobija veliki vertikalni tunel, a ako se naie na zid tunela gubi se
ivot.
Trei nivo ima dva tunela: jedan horizontalni i jedan vertilkalni, a "Zmijica" se
dosta bre kree nego to je to bio usluaj u prva dva nivoa.
etvrti nivo ima dva tunela horizontalni i vertikalni, "Zmijica" se jo bre kree,
a posle svake pojedene hrane mora proi kroz jedan od dva tunela, jer ako opet pojede
hranu a nije prola kroz tunel zmijica gine.









67
2.6. TESTOVI IZ FUNKCIJA

TEST 1
GRUPA 1

Zadatak 1
Odrediti vrednosti promenljivih x, y, a i z nakon izvravanja sledeeg izraza:
int x,y,z, a;
a=x=z=y=1;
a=(--x) || (++y && ++z);
//Odgovor: a = x = z = y =

Zadatak 2
Kolika je vrednost promenljive s nakon zavretka for ciklusa, za razne vrednosti
promenljivih kraj i poc.

for(s=0,pom=poc;pom<=kraj;pom++) s++;
//Odgovor: s =

Zadatak 3
Dopuniti ciklus kako bi se utvrdilo koliko se ciklus puta ponovio.

s=0;
while(s=n) s+=3;

//Napisati novi kod



Zadatak 4
Sledeu switch strukturu realizovati pomou vie if-else struktura.
switch(k)
{
case 1: case 4: case 10: p++;
break;
case 2: p+=2;
break;
case 3: case 9: p--;
break;
default: p+=2;
}

//Napisati novi kod


Zadatak 5
Napisati deo koda koji omoguava unos elemenata niza X sve dok se ne unesu dva
uzastopna jednaka broja. Poslednji uneti element ne pripada nizu. Funkcija scanf se pojavljuje
samo na jednom mestu. Prikazati poruku na ekranu koliko elemenata ima niz.
//Napisati kod:
68
Zadatak 6
Ako funkcija trazi ima sledei prototip int *trazi(int x[], int n, int p); pri emu je n broj
elemenata niza X, a p broj koji se u nizu trai. Pokazati kako treba pozvati funkciju trazi u
funkciji izbaci tako da se p izbaci iz niza. Funkcija trazi vraa NULL ako p nije lan niza, ili
adresu ako je lan niza

//Definisanje funkcije izbaci
int izbaci(int x[], int *n, int p)
{
//Napisati ispod poziv funkcije trazi







}

Zadatak 7
ta mislite da radi sledei deo koda, ako niz X ima n elemenata. Ako ispravno radi
formirati definisanje funkcije sa odgovarajuim imenom koja e to isto raditi, a koja ima potreban
broj argumenata.

pom=x[n-1],i=n-1;
while(i>0) x[i]=x[i-1],i--;
x[0]=pom;

//Definisanje funkcije (ako je kod ispravan)





Zadatak 8
Ako je poznato da niz X ima n elemenata. Napisati funkciju sortdeo koja vri sortiranje
dela niza izmeu indeksa k i p u opadajuem redosledu. Funkcija vraa 1 ako je u stanju da izvri
sortiranje ili 0 u suprotnom.

// Definisanje funkcije
unsigned sortdeo(int x[], int k, int p, int n)
{







}

69
Zadatak 9
Napisati funkciju monoton koja utvruje da li je dati niz X strogo monotono rastui (svaki
lan niza je vei od svog prethodnika) te ako jeste vraa 1 a ako nije 0. Pozivom funkcije na
ekranu ispisati odgovarajuu poruku.

//Prototip funkcije

//Definisanje funkcije




//Poziv funkcije


Zadatak 10
ta radi sledei deo koda, a ako ima greaka objasniti koje su i ispraviti ih.

x[0]=max;
i=0;
while(i<n)
{
if(max<=x[i]) x[i]=max;
}
//Napisatio ispravljeni deo koda ako ima greaka




REENJA SA TESTA 1
GRUPA 1

Zadatak 1
Odrediti vrednosti promenljivih x, y, a i z nakon izvravanja sledeeg izraza:
int x,y,z, a;
a=x=z=y=1;
a=(--x) || (++y && ++z);
//Odgovor: a = 1 x = 0 z = 2 y = 2

Zadatak 2
Kolika je vrednost promenljive s nakon zavretka for ciklusa, za razne vrednosti
promenljivih kraj i poc.

for(s=0,pom=poc;pom<=kraj;pom++) s++;
//Odgovor: s = 0 ako je poc>kraj ili kraj-poc+1 u suprotnom.

Zadatak 3
Dopuniti ciklus kako bi se utvrdilo koliko se ciklus puta ponovio, ako je n>0.

s=0;
while(s=n) s+=3;
70

//Napisati novi kod
Ovo je beskonacan ciklus.

Zadatak 4
Sledeu switch strukturu realizovati pomou vie if-else struktura.
switch(k)
{
case 1: case 4: case 10: p++;
break;
case 2: p+=2;
break;
case 3: case 9: p--;
break;
default: p+=2;
}

//Napisati novi kod
if(k!=1&&k!=2&&k!=3&&k!=4&&k!=9&&k!=10) p+=2;
else{
if(k==1||k==4||k==10) p++;
if(k==2) p+=2;
if(k==3||k==9) p--;
}

Zadatak 5
Napisati deo koda koji omoguava unos elemenata niza X sve dok se ne unesu dva
uzastopna jednaka broja. Poslednji uneti element ne pripada nizu. Funkcija scanf se pojavljuje
samo na jednom mestu. Prikazati poruku na ekranu koliko elemenata ima niz.

//Napisati kod:
int x[30], pom, i=-1;
do{
i++;
if(i==0) scanf(%d,&x[i]);
else {
scanf(%d,&pom);
if(pom!=x[i-1]) x[i]=pom;
}
}while(i!=0&&x[i]==pom);


Zadatak 6
Ako funkcija trazi ima sledei prototip int *trazi(int x[], int *n, int p); pri emu je n broj
elemenata niza X, a p broj koji se u nizu trai. Pokazati kako treba pozvati funkciju trazi u
funkciji izbaci tako da se p izbaci iz niza. Funkcija trazi vraa NULL ako p nije lan niza, ili
adresu ako je lan niza

//Definisanje funkcije izbaci
int izbaci(int x[], int *n, int p)
{
71
//Napisati ispod poziv funkcije trazi
unsigned i;
int *pok;

pok=trazi(x,&(*n),p);
if(pok!=NULL)
{
i=pok-x;
while(i<n-1) x[i]=x[i+1],i++;
return 1;
}
return 0;
}

Zadatak 7
ta mislite da radi sledei deo koda, ako niz X ima n elemenata. Ako ispravno radi
formirati definisanje funkcije sa odgovarajuim imenom koja e to isto raditi, a koja ima potreban
broj argumenata.

pom=x[n-1], i=n-1;
while(i>0) x[i]=x[i-1],i--;
x[0]=pom;

//Definisanje funkcije (ako je kod ispravan)
Ovaj deo koda vrsi ispravno rotaciju niza X za jedno mesto u desno.

void rotiraj_desno(int x[], int n)
{
unsigned i;
int pom;

pom=x[n-1];
i=n-1;
while(i>0) x[i]=x[i-1],i--;
x[0]=pom;
}

Zadatak 8
Ako je poznato da niz X ima n elemenata. Napisati funkciju sortdeo koja vri sortiranje
dela niza izmeu indeksa k i p u opadajuem redosledu. Funkcija vraa 1 ako je u stanju da izvri
sortiranje ili 0 u suprotnom.

// Definisanje funkcije
unsigned sortdeo(int x[], int k, int p, int n)
{
unsigned i, j;
int pom;

if(k<||k>n||p<k||p>n) return 0;
for(i=0;i<n-1;i++)
{
72
for(j=i+1;j<n;j++)
{
if(x[j]?x[i]) pom=x[j], x[j]=x[i], x[i]=pom;
}
}
return 1;
}

Zadatak 9
Napisati funkciju monoton koja utvruje da li je dati niz X strogo monotono rastui (svaki
lan niza je vei od svog prethodnika) te ako jeste vraa 1 a ako nije 0. Pozivom funkcije na
ekranu ispisati odgovarajuu poruku.

//Prototip funkcije
unsigned monoton(int x[], int n);

//Definisanje funkcije
unsigned monoton(int x[], int n)
{
unsigned i=1;
while(i<n&&x[i]>x[i-1]) i++;
if(i<n) return 0;
else return 1;
}

//Poziv funkcije
if(monoton(x,n)) printf(Niz je strogo monotono rastuci!!);
else printf(Niz nije strogo monotono rastuci!!);

Zadatak 10
ta radi sledei deo koda, a ako ima greaka objasniti koje su i ispraviti ih

x[0]=max;
i=0;
while(i<n)
{
if(max<=x[i]) x[i]=max;
}

//Napisatio ispravljeni deo koda ako ima greaka
max=x[0];
i=0;
while(i<n)
{
if(max<=x[i]) x[i]=max;
i++;
}




73
TEST 1
GRUPA 2

Zadatak 1
Pretvoriti odgovarajui while ciklus u for ciklus.
k=0;
p=1;
while(p!=n)
{
k+=p;
p++;
}
p-=3;

//Napisati kod



Zadatak 2
Koliki biti zbir s u odnosu na celobrojan podatak n tipa int nakon zavretka sledeeg
dela koda:
s=0;
for(i=0;i<n; )
{
s+=++i;
}

//Napisati odgovor



Zadatak 3
Napisati funkciju utvrdi koja utvruje da li broja p ima u nizu X od n elemenata i vraa
indeks prvog elementa niza koji je jednak datom broju, ili -1 u suprotnom. Bonim efektom
(prenosom po referenci) vraa zbr elemenata niza od prvog lana niza do onog lana gde je
pronaen broj p ili zbir celog niza ako broja p nema u nizu.

//Prototip funkcije

//Definisanje funkcije (dopuniti)





//Poziv funkcije

Zadatak 4
Deo koda bi trebalo da utvrdi da li je dati niz sortiran u rastuem redosledu. Ispraviti ga
ako ima greaka i doraditi ga tako da se iz ciklusa iskoi im se zakljui da niz nije sortiran u
rastuem redosledu.
74
p=1;
for(i=1;i<=n;i++)
{
if(x[i+1]>x[i]) p=0;
}

if(p) printf(Niz je sortiran u rastucem redosledu!!);
else printf(Niz nije sortiran u rastucem redosledu!!);

//Napisati dopunjeni kod kod








Zadatak 5
Ako je poznato da funkcija rotiraj rotira niz za jedno mesto u levo, popraviti greke tako da
funkcija ispravno radi. Odgovor napisati paraleno sa desne strane papira.

//Prototip funkcije
void rotiraj(int x[], int *n);

//Definisanje funkcije (dopuniti)
void rotiraj(int x[], int *n)
{
unsigned i;
int pom;

pom=x[0], i=0;
while(i<n) x[i]=x[i+1],i++;
}

//Poziv funkcije
rotiraj(int[], int &n);

Zadatak 6
Sledeu strukturu realizovati iskljuivo pomou jedene switch strukture napisane u
najjednostavnijem obliku.
if(k==3 || k==7) p=2;
if(k==2) p=3;
if(k==4) p=4;
if(k==1) p=2;

Zadatak 7
Odrediti vrednosti promenljivih x, y, i z nakon izvravanja sledeeg izraza:
int x,y,z;
z=2*(x=4)+4*(y=7/2);
//Odgovor: x = y = z =
75

Zadatak 8
Napisati funkciju utvrdi koja utvruje koliko treba najvie sabrati elemenata beskonanog
niza da bi zbir postao to vei dvocifren broj. Funkcija prenosom parametara po referenci
odreuje zbir. Beskonaan niz ima sledei izgled:
1, 5, 7, 11, 13, 17, 19,

//Napisati prototip funkcije


//Napisati definisanje funkcije




//Napisati poziv funkcije kojim se odredjeni zbir upisuje u promenljivu s i broj clanova koji
se smesta u promenljivu br.


Zadatak 9
Napisati sledei deo koda pomou for ciklusa.

scanf(%d,&a[0]);
scanf(%d,&(*(a+1)));
scanf(%d,a+2);

//Napisati odgovor




Zadatak 10
Poznat je niz A od n elemenata. Poznato je da niz B ima isto n elemenata i ima takve
vrednosti, da u sutini pretstavlja redne brojeve trenutnih elemenata niza A, ali u takvom
redosledu, kao kada bi niz A sortirali u rastuem redosledu. Koristei samo jedan ciklus, bez
ikakvih premetanja elemenata niza A ili niza B, tampati sortirani niz A, a da ne vrite sortiranje.

Na primer:
A = 45 1 3 4 2 34
B = 2 5 3 4 6 1

//Napisati deo koda









76
TEST 1
GRUPA 3


Zadatak 1
Petvoriti sledei for ciklus u njemu odgovarajui do-while ciklus. Dopuniti tako da se u
promenljivoj p nae proizvod prvih n prirodnih brojeva. Smatrati da je n>0.

s=0;
p=1;
for(i=1;i<=n;i++)
{
s+=i;

}

//Napisati odgovor:





Zadatak 2
Napisati odgovarajuu strukturu samo pomou jedne if-else strukture:
if(x>p)
{
if(x<k) p++;
}

//Napisati odgovor:



Zadatak 3
Odrediti vrednosti promenljivih x, y, i z nakon izvravanja sledeeg izraza:
int x=1,y=1,z;
z=(x+(y--))*3 + (++x);
//Nodgovor: x = y = z =

Zadatak 4
Objasniti da li je u datom delu koda ispravno formiran niz Y na osnovu niza X, te ako nije
zbog ega i ispraviti greku. Niz X ima n elemenata. Ispod prikazati niz Y na ekranu.

i=0;
while(i<n)
{
j=0;
if(x[i]>0) y[j]=x[i];
j++;
i++;
}
77

//Napisati odgovor


//Napisati ispravljeni kod ako smatras da ima gresaka





//Prikazati niz Y


Zadatak 5
Ako je poznato da je funkcija utvrdi iji je prototip int utvrdi(int x[],int *n); utvruje da li
je niz sortiran u rastuem ili opadajuem redosledu, te vraa 0 ako je sortiran u rastuem, 1 ako je
u opadajuem ili -1 ako nije ni u rastuem ni u opadajuem redosledu. Napisati poziv funkciju u
selekcji switch kako bi se korisnik obavestio o kakvom je nizu re.

//Prikazati samo poziv funkcije u strukturi switch





Zadatak 6
Napisati funkciju koja odreuje prenosom po referenci vrednost maksimalnog elementa
niza X a da pri tome vraa vrednost minimalnog elementa niza X. Niz X je celobrojan i ima n
elemenata.

//Prototip funkcije


//Definisanje funkcije (dopuniti)





//Pozivanje funkcije


Zadatak 7
Realizovati sledei deo koda pomou pokazivaa poc, tako da se izvri zbir prvih n
lanova niza (n>10).

int x[30], *poc, s=0;

//Dopuniti kod
while( ) { }

78
Zadatak 8
ta radi sledei deo koda ili ta bi trebalo da radi ali zbog greke to nije sluaj. Ako postoje
takve greke objasniti kakve su i ispraviti ih.

for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(x[j]>x[i]) pom=x[j],x[j]=x[i],x[i]=pom;
}
}

//Napisati objasnjenje ako postoji greske

//Napisati ispravljeni kod ako smatras da ima gresaka


Zadatak 9
Napisati funkcioju utvrdi koja utvruje da li elementi niza X od n lanova pretstavljaju
lanove sa osobinom da je poev od drugog lana, svaki vei od svog prethodnika za istu
vrednost p. Funkcija vraa 1 ako je uslov zadovoljen ili 0 u suprotnom.

//Prototip funkcije
unsigned utvrdi(int x[], int n, int p);

//Definisanje funkcije





//Pozivanje funkcije


Zadatak 10
Funkcija zamena iji je prototip void zamena(int a, int b); treba da izvri zamenu dva
broja a i b. Dopisati potreban deo koda u telu funkcije ne menjajui njen prototip tako da je to
mogue uraditi.

//Prototip funkcije
void zamena(int a, int b);

//Definisanje funkcije (dopuniti)
void zamena(int a, int b)
{



}

//pozivanje funkcij
79

80










3
3. . P PO OG GL LA AV VL LJ J E E



V VI I E ED DI IM ME EN NZ ZI IO ON NA AL LN NI I N NI IZ ZO OV VI I
81


3.1. VIEDIMENZIONALNI NIZOVI



Definicija viedimenzionalnog niza:
Viedimenzionalni nizovi su nizovi iji su elementi takoe nizovi.

Definicija matrice:
Dvodimenzionalni niz ili matrica sastoji se od vrsta, pri emu je svaka vrrsta jedan
vektor (jednodimenzionalni niz), tj matrica je niz vektora. Po analogiji je
trodimenzionalni niz je niz matrica, itd.

Deklaracija viedimenzionalnog niza:
Deklaracija viedimanzionalnog niza je slina sa deklaracijom vektora, s tom
razlikom to viedimenzionalni niz ima vie dimenzija.

tip imeniza[MAX][MAX][MAX][MAX][MAX];

Svaka zagrada predstavlja novu dimenziju niza, a podatak u zagradi predstavlja
maksimalni broj elemenata koji poseduje data dimenzija. Elementi predstavljaju
nizovi manje dimenzije.

Na primer:
int matrica[3][4], trodniz[3][6][4];

Svi elementi viedimenzionalnih nizova su celi brojevi. Matrica je dvodimenzionalni niz
i prva dimenzija ima maksimalno 3 vektora pri emu se svaki vektor sastoji od
maksimalno 4 elementa. Trodimenzionalni niz ima tri dimenzije pri emu je prva
dimenzija sa maksimalno 3 matrice, a svaka matrica se sastoji od maksimalno 6 vektora,
pri emu svaki vektor ima 4 elementa koji su celi brojevi.

Viedimenzionalne nizove treba koristiti kada je potrebno opisati sloeni
podatak koji je opisan sa vie podataka, pri emu i indeksi koji opisuju
viedimenzionalni niz predstavljaju podatak neophodan za opis elementa.

Na primer ako posmatramo igricu minsko polje. Tada se svako polje moe opisati
sa x koordinatom, y koordinatom i brojem koji opisuje ta se nalazi na toj koordinati.
Koristili bi matricu gde bi prvi indeks opisivao horizontalnu poziciju, drugi vertikalnu
poziciju, a vrednost elementamatrice bi opisivalo ta se na toj poziciji nalazi: 1 postoji
mina ili 2 mina se nenalazi na toj poziciji.



82
Sa pojmom matrica susreete se i u matematici prilikom reavanja sistema
jednaina. Opisana je sa dve dimenzije pri emu se prva uvek odnosi na vrstu, a druga na
kolonu.
Na primer:

4 3
5 3 1 2
3 7 6 4
1 0 4 2
x
A
(
(
(

=

Matrica A ima tri vrste i etiri kolone. Deklaracija matrice A i ujedno njena inicijalizacija
s tim da matrica ima ovakav izgled je:

unsigned a[3][4]={{2, 4, 0, 1},{4, 6, 7, 3},{2, 1, 3, 5}};

Za sluaj da smo hteli inicijalizovati matricu a da pri tome ne napiemo sve elemente, ne
obuhvaenim elementima automatski bi se dodelila vrednost nula. Za sluaj da smo
deklarisali i inicijalizovali sa:

unsigned a[3][4]={{2, 4},{4, 6, 7, 3},{2, 1, 3}};

matrica a bi imala sledei izgled:

4 3
0 3 1 2
3 7 6 4
0 0 4 2
x
A
(
(
(

=


Smetanje viedimenzionalnih nizova u memoriju:
Operativna ili RAM memorija je po prirodi linearno organizovana
(predstavlja jednodimenzionalni niz), sa rastuim adresama, vektor se u memoriju
smeta na prirodan nain, gde su logiki i fiziki redosled elemenata u memoriji isti.
Prilikom smetanja matrice u memoriji mora se izvriti njena linearizacija.
Linearizacija se u programskom jeziku C vri po vrstama. Od poetne adrese
matrice prvo se smeta prva vrsta, pa druga vrsta, i tako redom do poslednje vrste.
Vrsta se tretira kao zapis koji ima onoliko elemenata koliko ima kolona.

Na primer:
int a[3][4];


A
00
A
01
A
02
A
03
A
10
A
11
A
12
A
13
A
20
A
21
A
22
A
23

Iz primera se lako vidi kako je izvrena linearizacija matrice u memoriji.

83
Kao i kod jednodimenzionalnog niza ili vektora tako i kod viedimenzionalnih
nizova postoji prisna veza izmeu pokazivaa i niza.
Pristup odgovarajuem podatku matrice moe se vriti pomou indeksa ili
pokazivaa Kod matrice ima dva indeksa (prvi je indeks vrste, a drugi je indeks kolone).
Indeksi moraju biti prirodni brojevi ili promenljive koje su celobrojnog tipa. Kao i kod
vektora u indeksu moe mostojati i celobrojni izraz.

Na primer:
unsigned s, i, j, a[3][4]={{2, 4, 0, 1},{4, 6, 7, 3},{2, 1, 3, 5}};

Pristup pomou operatora indeksiranja:

Prvi nain:
s=a[2][1]; - nakon ove naredbe dodele promenljiva s ima vrednost 1.

Drugi nain:
int i=1, j=0;
s=a[i][j]; - nakon ove naredbe dodele s je 4.

Pristup pomou pokazivaa:
Indentifikator a nije pokaziva na podatke tipa unsigned, ve pokaziva na nizove
(ima ih tri, jer ima tri vrste) koji su tipa unsigned. Zbog toga a+1 nije adresa elementa
matrice a[0][1] ve poetna adresa podniza a[1], a to je druga vrsta matrice iji je prvi
element a[1][0]. Zbog toga se primenom cast operatora u pokazivakoj aritmetici mora
indentifikator niza a pretvoriti u pokaziva na celobrojne podatke tipa unsigned.


unsigned s, i, j, k,a[MAXV][MAXK], b[P][Q][R];

a[i][j] *((unsigned *)a +MAXK*I +j)
b[i][j][k] *((unsigned *)b +Q*R*i + R*j +k)

Na slian nain se moe pristupiti i proizvoljnom elementi bilo koje
viedimenzionalne matrice.

Vano je uoiti da se u formulama za izraunavanje adrese datog elementa
viedimenzionalnog niza nikada ne pojavljjuje duina po prvoj dimenziji niza.
Ova sobina se koristi kod funkcija kada se prosleuje matrica, jer se ne mora
prosleivati prva dimenzija dok su ostale dimenzije neophodne.

Na primer:
int a[MAXV][MAXK];

Prototip funkcija koja koristi matricu a kao parametar imala bi sledei izgled:

int zbir(int a[][MAXK], int n);
84


3.2. PROLASCI KROZ VIEDIMENZIONALNI NIZ


Od viedimenzionalnih niziva najvie se koriste dvodimenzionalni nizovi ili
matrice. Matrice imaju dve dimenzije, prva dimenzija odnosi se na vrste (redove) a druga
dimenzija se odnosi na kolone. Kroz matricu se moe izvriti jedna od sledeih vrsta
prolazaka:
- Prolazak kroz matricu vrsta po vrsta,
- Prolazak kroz matricu kolona po kolona,
- Prolazak kroz matricu preko dijagonala (paralelnih glavnoj dijagonali pri
emu glavnu dijagonalu ine elementi koji imaju istu vrednost indeksa vrste
i kolone), i
- Spiralni prolasci kroz matricu.


Primer 1:
Zadata je matrica A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ).. Napisati C
program koji izraunaa zbir elemenata matrice prolazei kroz matricu vrsta po vrsta.

Reenje

#include<stdio.h>
#include<conio.h>

#define MAX 9

void main(void)
{
int a[MAX][MAX];
int m,n,s;
unsigned i,j,xu,yu,xp=5,yp=5;


for(i=0;i<MAX;i++)
{
for(j=0;j<MAX;j++) a[i][j]=0;
}

textmode(3);
textcolor(9);
textbackground(0);
clrscr();

/* Posebno se mora unositi koliko ima vrsta, a posebno koliko ima kolona. */
printf("Unesi broj vrsta: ");
xu=wherex(), yu=wherey();
85
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&m);
}while(m<=0||m>MAX);

printf("Unesi broj kolona: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0||n>MAX);

/* Matrica se unosi vrsta po vrsta. Iz a[i][j] vidi se da je indeks vrste i dok je indeks
kolone j. Kako je j brojac unutrasnjeg ciklusa to se on menja dok se vrednost brojaca
spoljasnjeg ciklusa i ne menja. To je znak da se kroz matricu krecemo vrsta po vrsta. */

printf("Unesi matricu: ");
xu=wherex(),yu=wherey();
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&a[i][j]);
gotoxy(xp,yp);
printf("%d",a[i][j]);
xp+=4;
}
yp++;
xp=5;
}

/* Prolazi se kroz matricu vrsta po vrsta jer je indeks vrste brojac spoljasnjeg ciklusa dok
je indeks kolone brojac unutrasnjeg ciklusa. */

s=0;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++) s+=a[i][j];
}

printf("\n\nZbir = %d",s);
gotoxy(1,25);
getch();
}
86
Primer 2:
Zadata je matrica A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ). Napisati C
program koji izraunva zbir elemenata matrice prolazei kroz matricu kolona po kolona.

Reenje

#include<stdio.h>
#include<conio.h>

#define MAX 9

void main(void)
{
int a[MAX][MAX];
int m,n,s;
unsigned i,j,xu,yu,xp=5,yp=5;

for(i=0;i<MAX;i++)
{
for(j=0;j<MAX;j++) a[i][j]=0;
}

textmode(3);
textcolor(9);
textbackground(0);
clrscr();

/* Posebno se mora unositi koliko ima vrsta, a posebno koliko ima kolona. */

printf("Unesi broj vrsta: ");
xu=wherex();
yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&m);
}while(m<=0||m>MAX);

printf("Unesi broj kolona: ");
xu=wherex();
yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0||n>MAX);
87
/* Matrica se unosi vrsta po vrsta. Iz a[i][j] vidi se da je indeks vrste i dok je indeks
kolone j. Kako je j brojac unutrasnjeg ciklusa to se on menja dok se vrednost brojaca
spoljasnjeg ciklusa i ne menja. To je znak da se kroz matricu krecemo vrsta po vrsta. */

printf("Unesi matricu: ");
xu=wherex(),yu=wherey();
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&a[i][j]);
gotoxy(xp,yp);
printf("%d",a[i][j]);
xp+=4;
}
yp++;
xp=5;
}

/* Prolazi se kroz matricu kolona po kolona jer je indeks vrste brojac unutrasnjeg ciklusa
dok je indeks kolone brojac spoljasnjeg ciklusa. */

s=0;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++) s+=a[j][i];
}

printf("\n\nZbir = %d",s);
gotoxy(1,25);
getch();
}

Primer 3:
Zadata je kvadratna matrica A dimenzije n ) 12 , ( < e n N n . Napisati C program koji
na osnovu matrice A formira niz B. Elemente niza B ini zbir elemenata matrice A koji
se nalaze na glavnoj dijagonali ili su elementi paralelni elementima sa glavne dijagonale.
Kao da smo sa desne strane matricu proirili za prvih n-1 kolonu. Iz razloga zanimljivosti
zadatka ne sme se vriti proirivanje matrice.

Reenje

#include<stdio.h>
#include<conio.h>
#define MAX 9

88
void main(void)
{
int a[MAX][MAX], b[MAX];
int m,n,s;
unsigned i,j,d,xu,yu,xp=5,yp=5;

for(i=0;i<MAX;i++)
{
b[i]=0;
for(j=0;j<MAX;j++) a[i][j]=0;
}

textmode(3);
textcolor(9);
textbackground(0);
clrscr();

printf("Unesi dimenyiju kvadratne matrice: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0||n>MAX);

printf("Unesi matricu: ");
xu=wherex(),yu=wherey();
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&a[i][j]);
gotoxy(xp,yp);
printf("%d",a[i][j]);
xp+=4;
}
yp++, xp=5;
}

/* Promenljiva d broji i odnosi se na to koja se dijagonala sabira. Ako je d
jednako 0 sabiraju se elementi sa glavne dijagonale. Glavni deo problema je j%n
89
koji omogucava da se sa sabiranjem nastavi bas tamo gde treba, jer ub slucaju da j
ima vrednost n krece se automatski na prvu kolonu, a to nam i treba. */

for(d=0;d<n;d++)
{
j=d;
for(i=0;i<n;i++) b[d]+=a[i][j%n],j++;
}

printf("\n\n B = ");
for(i=0;i<n;i++) printf("%d ",b[i]);
gotoxy(1,25);
getch();
}

Primer 4:
Data je matrica A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ). Napisati C
program koji bez korienja pomonih nizova ili matrica saima matricu izbacivanjem
odgovarajue i-te vrste i j-te kolone, pri emu se i i j unose sa ulaza i ] .. 1 [ ], .. 1 [ n j m i e e .

Reenje

#include<stdio.h>
#include<conio.h>

#define MAX 9

void main(void)
{
int a[MAX][MAX];
int m,n,p,q;
unsigned i,j,xu,yu,xp=5,yp=5;

/* Inicijalizacija nizova i matrice. */
for(i=0;i<MAX;i++)
{
for(j=0;j<MAX;j++) a[i][j]=0;
}

textmode(3);
textcolor(9);
textbackground(0);
clrscr();

printf("Unesi broj vrsta: ");
xu=wherex(), yu=wherey();
90
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&m);
}while(m<=0||m>MAX);

printf("Unesi broj kolona: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0||n>MAX);

printf("Unesi matricu: ");
xu=wherex(),yu=wherey();
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&a[i][j]);
gotoxy(xp,yp);
printf("%d",a[i][j]);
xp+=4;
}
yp++;
xp=5;
}

printf("\n\nUnesi redni broj vrste koja se brise: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&p);
}while(p<=0||p>m);
printf("Unesi redni broj kolone koja se brise: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
91
printf(" ");
gotoxy(xu,yu);
scanf("%d",&q);
}while(q<=0||q>n);

/* Ako se izbacuje poslednja kolona ne mora se vrsiti sazimanje matrice po
vrstama, vec se samo smanji broj vrsta matrice za 1 i time je ta vrsta izbacena iz
matrice. */

if(p==m) m--;
else{
/* Nema potrebe dirati prethodne vrste. Iz tih razloga je i=p-1.
Smanjujemo za jedan jer smo p uneli ne kao indeks vrste vec kao redni
broj vrste. */

for(i=p-1;i<m-1;i++)
{
for(j=0;j<n;j++) a[i][j]=a[i+1][j];
}
/* Nakon sazimanja broj vrsta moramo smanjiti za 1. */
m--;
}

/* Na slican nacin se izbacuje kolona iz matrice. */
if(q==n) n--;
else{
for(j=q-1;j<n-1;j++)
{
for(i=0;i<m;i++) a[i][j]=a[i][j+1];
}
n--;
}

/* Matrica se stampa na ekranu vrsta po vrsta. */
printf("\n\nNakon izbacivanja %d vrste i %d kolone matrica je:\n\n",p,q);
for(i=0;i<m;i++)
{
for(j=0;j<n;j++) printf("%4d",a[i][j]);
printf("\n");
}
gotoxy(1,25);
getch();
}



92


3.3. VIEDIMENZIONALNI NIZOVI I FUNKCIJE


Funkcija kao povratnu vrednost ne moe da vrati viedimenzionalni niz.
Viedimenzionalni niz moe biti argument funkcije, s tim da u odnosu na vektor
viedimenzionalni niz ne mora prosleivati prvu dimenziju funkciji, ali ostale se
moraju proslediti.

Razlog prosleivanja ostalih dimenzija funkciji lei u formuli po kojoj se rauna
adresa elementa viedimenzionalnog niza. Sa prolog asa se videlo kako u izrazu osim
prve dimenzije figuriu sve ostale.


Primer 1:
Zadata je matrica A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ). Napisati C
program koji na osnovu matrice A formira nizove X i Y. Niz X formiraju zbirovi
elemenata kolona matrice A. Niz Y predstavljaju broj onih elemenata iz vrsta matrice A
koji imaju vrednost razliitu od minimalne i maksimalne vrednosti vrste.

Za izraunavanje minimalne vrednosti vrste koristiti funkciju minvrsta, za
izraunavanje maksimalne vrednosti vrste koristiti funkciju maxvrsta, a za izraunavanje
zbira elemenata kolone koristiti funkciju zbirkolone.

Na primer: m = 6, n = 7

Matrica A je:
2 12 4 0 0 6 0
15 0 11 6 15 7 0
5 23 4 1 22 7 12
5 13 0 3 0 6 41
15 6 34 6 15 9 6
4 14 1 2 2 17 3

Nizovi X i Y su:
X = 46, 68, 54, 18, 54, 52, 62
Y = 3, 3, 5, 4, 3, 5

Reenje

#include<stdio.h>
#include<conio.h>

#define MAX 9

93
/* Prototipovi funkcija gde se vidi da se u prvoj dimenziji ne mora nista pisati, dok se u
drugoj dimenziji morala napisati dimenzija. */

int minvrsta(int a[][MAX], int n, unsigned i);
int maxvrsta(int a[][MAX], int n, unsigned i);
int zbirkolone(int a[][MAX], int m, unsigned j);

void main(void)
{
int max, min, a[MAX][MAX], x[MAX], y[MAX];
int m,n;
unsigned i,j,xu,yu,xp=5,yp=5;

/* Inicijalizacija nizova i matrice. */
for(i=0;i<MAX;i++)
{
x[i]=y[i]=0;
for(j=0;j<MAX;j++) a[i][j]=0;
}

textmode(3);
textcolor(9);
textbackground(0);
clrscr();

printf("Unesi broj vrsta: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&m);
}while(m<=0||m>MAX);

printf("Unesi broj kolona: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0||n>MAX);

printf("Unesi matricu: ");
xu=wherex(),yu=wherey();
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
gotoxy(xu,yu);
printf(" ");
94
gotoxy(xu,yu);
scanf("%d",&a[i][j]);
gotoxy(xp,yp);
printf("%d",a[i][j]);
xp+=4;
}
yp++, xp=5;
}

/* Mora se dobro procitati tekst zadatka kako bi se utvrdilo tacno sta koja funkcija radi.
Elemente niza X formira podatak koji vrati funkcija zbirkolone. Stvarni parametar
matrica upisuje se samo ime matrice. Broj elemenata niza X jednak je broju kolona
matrice A. */

for(j=0;j<n;j++) x[j]=zbirkolone(a,m,j);
printf("\n\nX = ");
for(i=0;i<n;i++) printf("%d ",x[i]);

/* Poziv funkcije maxvrsta i minvrsta ne treba pisati unutar drugog for ciklusa jer se na
taj nain funkcija umesto jednom poziva n puta cime se usporava program. Znamo da
svaki element niza Y prilikom inicijalizacije ima vrednost 0, te se is tih razloga ne mora
koristiti pomocni brojac, vec se direktno uvecava za 1 odgovarajuci element niza Y. */

for(i=0;i<m;i++)
{
max=maxvrsta(a,n,i);
min=minvrsta(a,n,i);
for(j=0;j<n;j++) if(a[i][j]!=min&&a[i][j]!=max) y[i]++;
}

printf("\n\nY = ");
for(i=0;i<m;i++) printf("%d ",y[i]);
gotoxy(1,25);
getch();
}

/* Funkcija minvrsta odredjuje vrednost minimalnog elementa vrste. */
int minvrsta(int a[][MAX], int n, unsigned i)
{

/* Proglasavamo da je prvi element iz posmatrane vrste minimalan. */
int min=a[i][0];
unsigned j;

/* Prolazimo kroz vrstu. To se vidi po tome sto se indeks vrste ne menja za razliku od
indeksa kolone. */
for(j=1;j<n;j++)
{
if(a[i][j]<min) min=a[i][j];
}

95
return min;
}

/* Funkcija maxvrsta odredjuje vrednost maksimalnog elementa vrste. */
int maxvrsta(int a[][MAX], int n, unsigned i)
{
int max=a[i][0];
unsigned j;

for(j=1;j<n;j++)
{
if(a[i][j]>max) max=a[i][j];
}

return max;
}

/* Funkcija zbirkolone utvrdjuje zbir elemenata odgovarajuce kolone. */
int zbirkolone(int a[][MAX], int m, unsigned j)
{
int s=0;
unsigned i;

/* Prolazimo kroz kolonu. To se vidi po tome sto se indeks kolone ne menja za razliku od
indeksa vrste. */

for(i=0;i<m;i++) s+=a[i][j];

return s;
}

Test primer programa:





96
Primer 2:
Napisati C program koji na osnovu celobrojne matrice A (dobijene korienjem
randomfunkcije) dimenzija nxn, (n je paran broj i n<10), formira niz B na osnovu slike:

(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(

- - - - - -
| +
- - - - - -
| | + +
- - - - - -
| | | + + +
- - - - - -
| | + +
- - - - - -
| +
- - - - - -
=
1
2
3
3
2
2
2

S2



S1

S1

1
S
S
S
A
i
za n = 6

S1
i
je zbir elemenata matrice A na gornjem i-tom ugaoniku, a
S2
i
je zbir elemenata matrice A na donjem i-tom ugaoniku,
pri emu ie|1..
2
n
|.
Niz B se formira po formuli:

>
=
suprotnom u 2
2 S1 1
i
i
i i
i
S
S S
b

Za raunanje zbira S1
i
i S2
i
koristiti funkciju zbir.

Reenje:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_DIM 9

/* Prototip funkcije. */
int zbir(int a[][MAX_DIM],int,int,int,int);

void main(void)
{
int n,i,j,s1,s2,b[MAX_DIM],a[MAX_DIM][MAX_DIM];

randomize();
97
textbackground(0);
textcolor(15);
do{
clrscr();
printf("\n\t\t Unesite dimenziju matrice (N<10): ");
printf("\n\t\t\t N = ");
scanf("%d",&n);
}while(n<1||n>MAX_DIM||n%2!=0);
for(i=0;i<n;i++)
for(j=0;j<n;j++) a[i][j]=random(8)+1;

printf("\n\n\n\t Matrica A je:\n");
for(i=0;i<n;i++)
{
printf("\n\t");
for(j=0;j<n;j++) printf(" %d",a[i][j]);
}

/* Ovde se vidi da parametri funkcije odredjuju sta funkcija moze da uradi.
Dobrim izborom parametara, za koje nas u zadatku niko nije ni u jednom
trenutku ogranicio (koliko ih je i koji treba da budu), data funkcija
moze resavati trazenje zbira s1 i zbira s2. */

for(i=0;i<n/2;i++)
{
s1=zbir(a,n-i,i,i,1);
s2=zbir(a,i-1,n-i-1,n-i-1,-1);
if(s1>s2) b[i]=s1;
else b[i]=s2;
}

printf("\n\n\n\t Niz B je:\n\n\t");
for(i=0;i<n/2;i++) printf(" %d",b[i]);
gotoxy(1,25);
}

int zbir(int a[][MAX_DIM],int m,int p,int k,int q)
{
/* Definicija lokalnih promenljivih i njihova inicijalizacija. */
int s=a[p][p],j=p+q;

/* Izracunavanje trazenog zbira. */
while(j!=m)
{
s=s+a[k][j]+a[j][k];
j+=q;
}

return s;
}

98
Primer 3:
Napisati C program koji omoguava unos rezultata svih utakmica na polusezoni, na
osnovu koje se formira matrica golova. Na osnovu matrice golova prikazuje se na ekranu
tabela lige sa brojem pobeda, nereenih, poraza, datih golova, primljenih golova i broja
osvojenih bodova na polusezoni. Potom se unose rezultati utakmica drugog dela sezone,
(vodei pri tome rauna ko je domain a ko gost) i ispisuje tabela na kraju sezone pri
emu su u tabeli odgovarajuim bojama vrste oznaene ekipe koje:

1 idu u kup ampiona,
2 idu u kup uefa, i
2 ispadaju iz lige.


Reenje

#include <stdio.h>
#include <conio.h>

#define MAX 10
#define BR 0
#define POB 1
#define NER 2
#define POR 3
#define DATI 4
#define PRIM 5
#define BOD 6
#define REZ 7

/* Prototipovi funkcija. */
int ispis(int n, int tabela[][REZ],int xi, int yi, int koji);
void unos(int n,int a[][MAX],int xu, int yu, int koji);
void sortiranje(int n, int tabela[][REZ], int a[][MAX], int koji);

void main(void)
{
int i,j,a[MAX][MAX],n,x,y,tabela[MAX][7],pom,k,xi,yi=0,xs,ys,xu,yu,yt;

/* Inicijalizacija matrice golova. */
for(i=0; i<MAX; i++)
for(j=0; j<MAX; j++) a[i][j]=0;

/* Inicijalizacija tabele prvenstva. */
for(i=0; i<MAX; i++)
{
for(j=0; j<REZ; j++) tabela[i][j]=0;
}
99

/* U tabelu se upisuju redni brojevi ekipa. */
for(i=0;i<MAX;i++) tabela[i][BR]=i+1;

textmode(64);
textattr(10);
clrscr();

do{
clrscr();
printf("\n\tBroj klubova: ");
scanf("%d", &n);
}while(n<2 || n>MAX);
printf("\n\n\tUnesite rezultate 1. dela");
xu=wherex()-26, yu=wherey()+1;

/* Funkcijom unos prvo se formira matrica golova prvog dela prvenstva. */
unos(n,a,xu,yu,1);

/* Sada se funkcijom sortiranje na osnovu matrice golova a, formira tabela
sortirana po broju bodova, a u sluaju istog broja bodova drugi kriterijum je gol
razlika. */

sortiranje(n,tabela,a,1);

/* Sada se prikazuje tabela prvog dela prvenstva, pozivajuci funkciju ispis. */
gotoxy(1,yu+3+n*(n-1)/4);
printf("\t\t\t TABELA POSLE 1. DELA");
printf("\n\t\b"); /* ALT+201 */
for(i=1;i<=57;i++) printf(""); /* ALT+205 */
printf(""); /* ALT+187 */
yt=wherey();
printf("\n\t Br.\tPob\tNer\tPor\tDati\tPrim\tBodovi\n\t");
xi=wherex(),yi=wherey();
yi=ispis(n,tabela,xi,yi,1);

for(i=0;i<n+1;i++)
{
gotoxy(8,yt+i+1),printf(""); /* ALT+186 */
gotoxy(66,yt+i+1),printf("");
}

printf("\n\t\b");
for(i=1;i<=57;i++) printf("");
printf("");

100

/* Unistava se matrica golova prvog dela prvenstva jer se moraju u nju smestiti
sada golovi drugog dela prvenstva. Matrica tabela se ne sme unistiti jer se
rezultati prenose u drugi deo lige. */

for(i=0; i<MAX; i++)
{
for(j=0; j<MAX; j++) a[i][j]=0;
}

gotoxy(45,yu-1);
printf("Unesite rezultate 2. dela");
xu=wherex()-25,yu=wherey()+1,yi-=2;

/* Unos matrice golova za drugi deo prvenstva. */
unos(n,a,xu,yu,2);

/* Sortiranje tabele na osnovu rezultata prvog i drugog dela prvenstva. */
sortiranje(n,tabela,a,1);

if(n<7) gotoxy(1,yi);
else gotoxy(1,yu+3+n*(n-1)/4);

printf("\t\t\t TABELA POSLE 2. DELA");
printf("\n\t\b");
for(i=1;i<=57;i++) printf("");
printf("");
yt=wherey();
printf("\n\t Br.\tPob\tNer\tPor\tDati\tPrim\tBodovi\n\t");
xi=wherex(),yi=wherey();

/* Ispis tabele drugog dela prvenstva. */
ispis(n,tabela,xi,yi,2);


/* Oznacavanje odredjenom bojom ekipe koja ide u kup sampiona, ekipa koje idu
u kup uefa i ekipa koje napustaju drustvo najboljih. */

for(i=0;i<n+1;i++)
{
/* Oznaka ekipe za kup sampiona. */
if(i==0)
{
textbackground(BLUE);
textcolor(15);
gotoxy(65,yt+i+2);
101
cprintf(" ");
}

/* Oznaka ekipa za kup uefa. */
if(i==1||i==2)
{
textbackground(GREEN);
textcolor(0);
gotoxy(65,yt+i+2);
cprintf(" ");
}


/* Oznaka ekipa koje ispadaju iz lige. */
if(n-1==i||i==n-2)
{
textbackground(RED); textcolor(YELLOW);
gotoxy(65,yt+i+2); cprintf(" ");
}
gotoxy(8,yt+i+1),printf("");
gotoxy(66,yt+i+1),printf("");
}

printf("\n\t\b");
for(i=1;i<=57;i++) printf("");
printf("");

gotoxy(65,50); textattr(32);
cprintf("Made by <mod64>");
_setcursortype(_NOCURSOR);
getch();
}

/* Funkcija ispis na osnovu formirane tabele prvenstva ispisuje tabelu prvog ili
drugog dela. Ako se promenljivoj koji prosledi broj 1 bice prikazana tabela prvog, a
u slucaju broja 2 drugog dela prvenstva. */

int ispis(int n, int tabela[][REZ],int xi, int yi, int koji)
{
int i,j;

for(i=0; i<n; i++)
{
if(koji==2)
{
if(i==0)textbackground(BLUE),textcolor(15);
102
if(i==1||i==2)textbackground(GREEN),textcolor(0);
if(i==n-1||i==n-2)textbackground(RED),textcolor(YELLOW);
}
for(j=0;j<REZ;j++)
{
gotoxy(xi+j*8,yi+i);
cprintf(" %d ",tabela[i][j]);
}
textattr(10);
}
yi=wherey()+n;
return yi;
}

/* Funkcija unos omogucava unos golova prvog ili drugog dela prvenstva. */
void unos(int n,int a[][MAX],int xu, int yu, int koji)
{
int i,j,x,y,br=0;

/* Klasican algoritam unosa, pri cemu u drugoj petlji j krece od i+1 kako bi se
izbegli susreti ekipe sa samom sobom ili dva puta igranja iste utakmice u jednom
delu prvenstva. */

for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
/* Unos vrsimo u dve kolone kako bi svi rezultati bili
pregledni na ekranu. Nakon unosa oba dela prvenstva bice
prikazane cetiri kolone. */

if(br>n*(n-1)/4+1) gotoxy(xu+17,yu-1+br%(n*(n-1)/4+1));
else gotoxy(xu-1,yu+br);

/* Moramo voditi racuna da se obrcu indeksi vrsta i kolona
zbog domacinstva za drugi deo prvenstva u odnosu na prvi
deo. Tako se mora izvrsiti i prikaz ekipa (domacin : gost)
da se korisnik programa ne bi zbunio. */

if(koji==1) printf("%2d. - %2d. = ", i+1,j+1);
if(koji==2) printf("%2d. - %2d. = ", j+1,i+1);
x=wherex()+1, y=wherey();

/* Golovi se unose pomocu funkcije getch polazeci od
pretpostavke da jedna ekipa na jednoj utakmici nece dati
vise od devet golova. */
103

if(koji==1) a[i][j]=getche()-48;
if(koji==2) a[j][i]=getche()-48;
gotoxy(x,y);
printf(" : ");

if(koji==1) a[j][i]=getche()-48;
if(koji==2) a[i][j]=getche()-48;
br++;
}
}
}


/* Funkcija sortiranje na osnovu matrice tabele prvenstva i matrice golova, sortira
tabelu po opadajucem kriterijumu u odnosu na broj osvojenih bodova. */

void sortiranje(int n, int tabela[][REZ], int a[][MAX], int koji)
{
int i,j,k,pom;

/* Vrsi se prvo preuredjivanje tabele tako da redni brojevi vrsta odgovaraju
rednim brojevima ekipa radi lakseg kasnijeg sortiranja, na osnovu matrice golova.
Sortiranje ne treba vrsiti za prvi deo prvenstva jer je sve vec podeseno kako treba.
*/

if(koji==1)
{
for(i=0;i<n;i++)
{
for(j=n-1;j>i;j--)
{
if(tabela[j][BR]<tabela[i][BR])
{
/* Vrsi se zamena dve vrste. */
for(k=0;k<REZ;k++)
{
pom=tabela[i][k];
tabela[i][k]=tabela[j][k];
tabela[j][k]=pom;
}
}
}
}
}

104
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
/* Bodovi, pobede, nereseno, porazi */
if(j!=i)
{
/* Ko ne zna pravila fudbala, za pobedu se dobija tri boda,
a za nereseno 1 bod. */

if(a[i][j]>a[j][i]) tabela[i][BOD]+=3,tabela[i][POB]++;
if(a[i][j]==a[j][i]) tabela[i][BOD]+=1,tabela[i][NER]++;
if(a[i][j]<a[j][i]) tabela[i][POR]++;

/* Dopisuje se broj datih i broj primljenih golova. */

tabela[i][DATI]+=a[i][j];
tabela[i][PRIM]+=a[j][i];
}
}
}

/* Vrsi se sortiranje zamenom odgovarajucih vrsta. */

for(i=0;i<n;i++)
{
for(j=n-1;j>i;j--)
{
/* Proverava se prvi kriterijunm, a toje broj osvojenih bodova. */

if(tabela[j][BOD]>tabela[i][BOD])
{
/* Vrsi se zamena odgovarajucih vrsta. */
for(k=0;k<REZ;k++)
{
pom=tabela[i][k];
tabela[i][k]=tabela[j][k];
tabela[j][k]=pom;
}

}

/* Proverava se sada drugi kriterijum, a to je u slucaju jednakog
broja bodova, bolja je ona ekipa cija je gol-razlika broj datih i
primljenih golova veca. */

105
if(tabela[j][BOD]==tabela[i][BOD]&&
tabela[j][DATI]-tabela[j][PRIM]>tabela[i][DATI]-tabela[i][PRIM])
{
for(k=0;k<REZ;k++)
{
pom=tabela[i][k];
tabela[i][k]=tabela[j][k];
tabela[j][k]=pom;
}
}
}
}
}

Test primer programa:


106

3.4. ZADACI IZ VIEDIMENZIONALNIH
NIZOVA


Zadatak 1 (2)
Zadata je kvadratna matrica A dimenzije n ) 12 , ( < e n N n . Napisati C program koji
utvruje koliko elemenata matrice A ima pozitivnu vrednost.

Zadatak 2 (2)
Zadata je kvadratna matrica A dimenzije n ) 12 , ( < e n N n . Napisati C program koji
utvruje koliko elemenata matrice je vee od maksimalnog elementa na glavnoj
dijagonali.

Zadatak 3 (2)
Zadata je kvadratna matrica A dimenzije n ) 12 , ( < e n N n . Napisati C program koji
na mestima gde su minimalni elementi upisati vrednosti maksimalnog elementa, a na
mestima gde se nalaze maksimalni elementi upisati vrednosti minimalnog elementa.

Zadatak 4 (2)
Zadata je kvadratna matrica A dimenzije n ) 12 , ( < e n N n . Napisati C program koji
vri zamenu elemenata glane dijagonale sa elementima sporedne dijagonale.

Zadatak 5 (2)
Zadata je kvadratna matrica A dimenzije n ) 12 , ( < e n N n . Napisati C program koji
vri zamenu elemenata prve i zadnje kolone.

Zadatak 6 (2)
Zadata je kvadratna matrica A dimenzije n ) 12 , ( < e n N n . Napisati C program koji
na osnovu matrice A formira niz B. Niz B pretstavljaju maksimalne vrednosti kolona
matrice A.

Zadatak 7 (3)
Napisati C program koji utvruje koliko elemenata matrice A dimenzije mxn ( m
10 , 10 , , < < e e n m N n N ) predstavlja ujedno najmanji element svoje vrste i kolone.

Zadatak 8 (2)
Zadata je matrica A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ). Napisati C
program koji vri sortiranje matrice A vrsta po vrsta.

Zadatak 9 (2)
Zadata je matrica X dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ). Napisati C
program koji na osnovu matrice X formira niz Z u koji ulaze redom minimalne vrednosti
kolona. Za odreivanje minimalne vrednosti kolone koristiti funkciju minmkolone.
107
Zadatak 10 (2)
Napisati C program koji na osnovu matrice A dimenzije mxn ( m
10 , 10 , , < < e e n m N n N ) formira matricu B dimenzije (m-1)xn tako to se iz matrice A
u matricu B ne upisuje ona vrsta koja ima najvei zbir elemenata.

Zadatak 11 (2)
Napisati C program koji na osnovu unetog prirodnog broja n formira kvadratnu
matricu X dimenzije nxn ) 12 , ( < e n N n sledeeg izgleda:


(
(
(
(




=
1 0 0 0 0 0 0
1 2 1 0
3 2 1
n
n
A


Zadatak 12 (3)
Data je matrica A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ). Napisati C
program koji bez korienja pomonih nizova ili matrica saima matricu izbacivanjem
odgovarajue i-te vrste i j-te kolone, pri emu se i i j unose sa ulaza i ] .. 1 [ ], .. 1 [ n j m i e e .

Zadatak 13 (3)
Napisati C program koji na osnovu unetog prirodnog broja n formira kvadratnu
matricu A dimenzije nxn ) 12 , ( < e n N n sledeeg izgleda:


(
(
(
(
(
(





=
1 2 1
4 1 2 3
3 1 2
2 1 1
n n n
n
n n
A


Zadatak 14 (3)
Napisati C program koji na osnovu unetog prirodnog broja n formira kvadratnu
matricu A dimenzije nx2n ) 12 , ( < e n N n sledeeg izgleda:

(
(
(
(





=
2 3 4 1 1 4 3 2
1 2 1 1 2 1
1 2 3 3 2 1
n n n n
n n
A


Matrica A se formira vrsta po vrsta korienjem funkcije formirajvrstu.
108
Zadatak 15 (3)
Napisati C program koji na osnovu matrice A dimenzije nxn ) 12 , ( < e n N n , pri
emu se elementi matrice unose sa jednog polja i stalno se ima vizuelni prikaz formiranja
matrice (na samom poetku formiranja svi elementi matrice imaju vrednost nula i tako su
i tampani na ekranu). Program treba da na osnovu matrice A formira niz B od n
elemenata na sledei nain:

b(1) = a(1,1)+a(1,2)+...+a(1,n)+a(2,1)+a(3,1)+...+a(n,1)
b(2) = a(2,2)+a(2,3)+...+a(2,n)+a(3,2)+a(4,2)+...+a(n,2)
.
.
.
b(n) = a(n,n)

Zadatak 16 (3)
Napisati C program koji omoguava unos matrice A dimenzije mxn ( m
10 , 10 , , < < e e n m N n N ) i sortira njene kolone u rastuem ili opadajuem redosledu.
Kolona j se sortira u opadajuem redosledu ako je srednja vrednost elemenata j-te kolone
manja ili jednaka srednjoj vrednosti svih elemenata matrice A, u suprotnom treba j-tu
kolonu sortirati u rastuem redosledu pri emu j uzima vrednost sa intervala [1..n]. Za
sortiranje elemenata kolona koristiti funkciju sortkol, a za pronalaenje sredenje
vrednosti koristiti funkciju srednja. Na ekranu tampati preureenu matricu A.

Zadatak 17 (3)
Napisati C program koji vri sortiranje matrice A dimenzije mxn ( m
10 , 10 , , < < e e n m N n N ) vrsta po vrsta, na osnovu maksimalnog zbira po vrstama. Za
izraunavanje zbira elemenata vrste koristiti funkciju zbirvrste. Za sortiranje matrice A
vrsta po vrsta koristiti funkciju sortmatrice.
Napomena: Prilikom realizacije programa ne smeju se koristiti pomoni nizovi ili
matrice.

Zadatak 18 (4)
Napisati C program koji na osnovu unetih prirodnih brojeva m i n koji sui manji od
sedam, korienjem generatora pseudosluajnih jednocifrenih ili dvocifrenih prirodnih
brojeva formira matrice Amxn, a potom utvruje zonu odreenu indeksima vrsta ili
kolona i, j, k i p (i, k - su indeksi vrsta koji obrazuju zonu i<k, a j, p - su indeksi
kolona koji obrazuju zonu j<p) koja ima najmanji zbir.
Zona mora sadrati minimalno etiri elementa matrice A. U sluaju da vie zona
ima isti minimalni zbir, na ekranu tampati indekse koji obrazuju zonu, a ispod nje celu
zonu, itd..

Zadatak 19 (3)
Data je matrica A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ). U matrici veliki
broj elemenata ima vrednost nula. Napisati C program koji odreuje i tampa najmanji
broj nula po vrstama odnosno kolonama. Za odreivanje broja nula u pojedinoj vrsti ili
koloni koristiti funkciju brojnula.
109

Na primer:
Ako matrica A ima sledei izgled:

1 0 3 0 9 1 0 0 5
0 0 0 3 0 0 2 0 1
2 2 0 1 2 2 0 1 2
0 0 1 0 1 0 1 0 0

NAJMANJI BROJ NULA PO VRSTAMA = 2
NAJMANJI BROJ NULA PO KOLONAMA = 1


Zadatak 20 (4)
Napisati C program koji na osnovu unetih prirodnih brojeva m, n i k koji sui manji
od sedam, korienjem generatora pseudosluajnih jednocifrenih prirodnih brojeva
formira matrice Amxn i Bmxk, a potom vri cirkularnu rotaciju matrica A i B
istovremeno za jedno mesto u desno.
Za pomeranje elemenata jedne vrste za jedno mesto u desno koristiti funkciju
pomvrs, a za cirkularnu rotaciju niza za jedno mesto u desno koristiti funkciju
cirkrotniz.

Na primer:
m = 5 n = 7 k = 4
Matrica A je: Matrica B je:
1 2 3 1 5 9 4 3 4 8 1
2 3 1 4 6 8 1 9 5 1 2
5 1 2 2 1 7 1 1 4 1 3
3 4 5 8 5 3 1 7 3 0 4
2 3 1 4 6 2 4 6 2 0 5

Nakon rotacije:
Matrica A je: Matrica B je:
5 1 2 3 1 5 9 4 3 4 8
1 2 3 1 4 6 8 1 9 5 1
2 5 1 2 2 1 7 1 1 4 1
3 3 4 5 8 5 3 1 7 3 0
4 2 3 1 4 6 2 4 6 2 0


Zadatak 21 (5)
Napisati C program koji na osnovu unetog prirodnog broja n 1<n<11 formira
kvadratnu matricu A dimenzije nxn i odreuje determinantu matrice A.
Determinanta matrice se odreuje postupkom kojim se matrica transformie da svi
elementi ispod glavne dijagonale imaju vrednost nula i tada proizvod elemenata na
glavnoj dijagonali predstavlja determinantu matrice.
110
Zadatak 22 (4)
Napisati C program koji za svakog studenta uitava broj indeksa i osvojene bodove
sa tri zadatka A, B i C, a zatim izraunava ukupan broj osvojenih bodova i na osnovu
toga pozivom funkcije ocena odreuje zakljunu ocenu.
Obezbediti da se reziltati tampaju po opadajuoj vrednosti broja bodova u obliku:

1. 5653 20 30 30 80 8
2. 5555 25 25 22 72 7
.
.
.

Zadatak 23 (4)
Napisati C program koji korienjem generatora pseudosluajnih jednocifrenih
prirodnih brojeva i unetog prirodnog broja n formira kvadratnu matricu dimenzije nxn,
n<10. Program utvruje koja dijagonala paralelna glavnoj dijagonali ima najvie
proizvoljno ponovljenoh elemenata (na primer ako se na i-toj dijagonali nalaze sledei
elementi 5 3 1 1 5 5 6 1 i 5, traeni broj ponavljanja je 4 jer se meu razliitim
brojevima 5 3 1 i 6 broj 5 najvie puta ponovio i to 4 puta). Za odreivanje traenog
broja jedne dijagonale koristiti funkciju odredi.
Broj dijagonala je n a kree se od glavne dijagonale kao prve a naredne se dobijaju
redom iz gornjeg trougla matrice. Svaka dijagonala ima tano po n elemenata (u sluaju
da ima n-3 elementa dopunjava se sa odgovarajuom dijagonalom iz donjeg trougla
matrice koja ima 3 elementa).

Zadatak 24 (4)
Data je matrica A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N ). Napisati C
program koji bez korienja pomonih nizova ili matrica odreuje redni broj vrste koja
sadri najvie razliitih elemenata. Za odreivanje broja razliitih elemenata vrste
koristiti funkciju brojrazvrste.

Zadatak 25 (4)
Podaci o dizaima tegova jednog turnira smetaju se u matricu DIZACI3xN pri
emu je N broj dizaa koji su uestvovali na turniru. U matrici A i-ta kolona sadri
podatke za i-tog dizaa tegova u istoj teinskoj kategoriji. Prvi podatak u koloni je teina
koju je takmiar podigao u dizanju sa trzajem, drugi je teina koju je takmiar podigao u
dizanju sa izvlaenjem, a trei je telesna teina takmiara.
U sluaju istih podataka, uzima se da je uspeniji takmiar manje telesne teine.
Napisati C program koji ispisuje redni broj dizaa koji je ampion: u prvoj kategoriji,
drugoj kategoriji i u obe kategorije (zbir teina) u ukupnom plasmanu.

Zadatak 26 (5)
Napisati C program koji matricu A dimenzije mxn ( m 10 , 10 , , < < e e n m N n N )
formira korienjem generatora pseudosluajnih jednocifrenih ili dvocifrenih prirodnih
brojeva, a zatim po izboru korisnika vri rotaciju matrice za 90
0
, 180
0
ili 270
0
.
korienjem funkcija rot90, rot180 ili rot270.
111
Zadatak 27 (5)
Napisati C program koji na osnovu unetog prirodnog broja n n<11, prikazuje
simulaciju spiralnog formiranja kvadratne matrice A (leva spirala) dimenzije nxn.

Napomena: Voditi rauna da li je n paran ili neparan broj to moe uticati na
formiranje matrice.

Na primer:
Za n = 5 matrica A ima sledei izgled:

1 16 15 14 13
2 17 24 23 12
3 18 25 22 11
4 19 20 21 10
5 6 7 8 9


Zadatak 28 (5)
Napisati C program koji e predstavljati igricu pod nazivom XOX dimenzije nxn
(2<n<10) Igra je namenjena za dva igraa. Pozicije polja na tabli numerisani su
brojevima od 1 do 9 o to moraju znati i igrai. Prvi je uvek "O", a drugi je "X".
Pobednik je onaj igra koji ima sastavljene n u nizu oznake ("O" ili "X"). Na kraju igre
ispisati koji je igra pobednik ili da je igra zavrena nereeno. Program realizovati
matricom A koja je dimenzije 60x50, koliko ima i polja za igru. Ako je vrednost lana 0
znai da niko od igraa do tada nije osdigrao potez na tom polju, ako je vrednost 1 na tom
polju je ranije ve odigran potez od strane igraa "O", a ako je vrednost 2 na tom polju je
ranije ve odigran potez od strane igraa "X". Igra se moe zavriti i ranije ako neko od
igraa odigra nulu kao potez sa numerike tastature, i tada se na ekranu ispisuje koji je
igra predao partiju.

Zadatak 29 (5)
Napisati C program koji omoguava formiranje matrica Amxn i Bkxp te po izboru
korisnika izraunava i prikazuje: zbir, razliku ili proizvod matrica A i B.
Funkcijom prikaziizbor treba prikazati sledeu sliku na ekranu:

*********************************
* RAD SA MATRICAMA *
*********************************
* 1) - UNOS MATRICA A I B *
* 2) - SABIRANJE MATRICA, A+B *
* 3) - RAZLIKA MATRICA, A-B *
* 4) - MNOZENJE MATRICA, A*B *
* 5) - IZLAZ IZ PROGRAMA *
*********************************
* VAS IZBOR: _ *
*********************************
112
Funkcija prikaziizbor omoguava da korisnik izabere jednu od ponuenih opcija i
vraa redni broj izabrane opcije.
Funkcija unos matrica omoguava unos matrica A i B pri emu se prvo unose
dimenzije matrice A uz ispisan opseg vrednosti promenljivih m i n, a potom se
omoguava unos matrice tako to se na ekranu ispisuje koji se element matrice unosi (na
primer a(1,1) = ). Elementi se unose vrsta po vrsta pri emu su vrste razdvojene praznim
redom (na ekranu). Na isti nain se frmira i matrica B. Funkcija nakon unosa vraa
vrednost 1 ako je unos uspeno uraen.
Funkcija sabiranjematrica omoguava da se saberu matrice A i B ako je to
mogue. U sluaju da je sabiranje mogue funkcija vraa 1 a u suprotnom 0. Matrice se
mogu sabrati ako imaju iste dimenzije i ako su prvo unesene matrice. Na ekranu ispisati
odgovarajuu poruku zato se matrice nisu mogle sabrati.
Funkcija oduzimanjematrica omoguava da se oduzmu matrice A i B ako je to
mogue. U sluaju da je oduzimanje mogue funkcija vraa 1 a u suprotnom 0. Matrice
se mogu oduzeti ako imaju iste dimenzije i ako su prvo unesene matrice. Na ekranu
ispisati odgovarajuu poruku zato se matrice nisu mogle oduzeti.
Funkcija mnozenjematrica omoguava da se pomnoe matrice A i B ako je to
mogue. U sluaju da je mnoenje mogue funkcija vraa 1 a u suprotnom 0. Matrice se
mogu pomnoiti ako je broj vrsta matrice A jednak broju kolona matrice B. Rezultujua
matrica imae broj vrsta jednak broju vrsta matrice A i broj kolona jednak broju kolona
matrice B. Matrice moraju prvo biti unesene. Na ekranu ispisati odgovarajuu poruku
zato se matrice nisu mogle pomnoiti.

Zadatak 30 (5)
Napisati C program koji predstavlja igricu pogodi. Igra je namenjena za samo
jednog igraa. Na ekranu se iscrtava tabla koja se sastoji od hodnika i zidova. U
hodnicima mogu se nalaziti kose crte u desno ili kose crte u levo. Na vrhu table nalazi se
pokretni kliza koji se stalno kree sve dok se ne pritisne SPACE. Nakon pritiska na
SPACE kliza prestaje da se kree iz iz njega na dole sputa se loptica. Loptica moe da
se kree samo kroz tunele, na dole slobodnim padom, ako naie na kosa crta na desno da
se kree na desno sve dok ne naie do kraja table ili na rupu na dole, ili ako naie na kosa
crta na levo da se kree na levo sve dok ne naie do kraja table ili na rupu na dole.
Sa leve i desne strane na krajevima table nalaze se zidovi, a sa donje strane nalaze
se polja koja su tamne boje i koja treba pogoditi, a ima ih est (numerisani su od 1 do 6) i
razbacani su u donjem redu table. Nakon pritisnutog tastera SPACE kuglica u obliku
slova o poinje da se kree i ako se spusti na neki broj taj broj promeni boju tako da je
vidno da je pogoen. Ako kuglica udari u jedan od zidova kugla nije nita uradila i kliza
ponovno poinje sa kretanjem. Tabla se moe (ne ukljuujui liniju sa klizaem i liniju
sa brojevima) rorirati za jedno mesto cirkularno na gore ili za jedno mesto cirkularno na
dole (upravljanje se vri sa strelicama na gore ili strelicama na dole). Rotiranje table
moe se vriti samo dok se kliza kree (tj nema loptice da se kree kroz tablu). Ako
igra sa lopticom pogodi ve pogoeno mesto (broj je oznaen svetlom bojom) broj
potamni tako da izgleda kao da ranije nije ni pogodio to polje. Na raspolaganju igra ima
deset pokuaja da pree tablu.
Problem se reava sa statinom matricom koja se mora dobro osmisliti tako da igra
ima smisla.
113

114








115









4
4. . P PO OG GL LA AV VL LJ J E E



S ST TR RI IN NG GO OV VI I
116


4.1. STRINGOVI

Definicija stringa:

String je niz znakova koji se zavrava znakom '\0'. Prazan string sadri samo
znak '\0'.

U definiciji stringa naznaeno je da je string niz. To znai da se kroz string
prolazi kao i kroz niz sa indeksom. Indeks prvog znaka stringa je 0. Za string ne moramo
znati koliko ima znakova jer je poslednji znak stringa '\0'. Uslov izlaska iz ciklusa kada se
prolazi kroz string je: prolazi kroz string sve dok je znak stringa razliit od znaka '\0'.

Deklaracija stringa:

char imestringa[MAX];

Prilikom inicijalizacije stringa prvo se navodi rezervisana re char koja oznaava
da elementi niza pretstavljaju znakovi. Srednje zagrade oznaavaju da je u pitanju niz.
Konstantan izraz MAX mora imati uvek za 1 veu vrednost u odnosu na klasian niz, jer
string mora sadrati znak '\0'. Na primer ako string treba da prihvati JMBG (jedinstveni
matini broj graana) koji uvek ima 13 brojeva, to MAX mora imati vrednost 14.

Inicijalizacija stringova:

String se moe inicijalizovati prilikom deklaracije stringa ili u toku
izvravanja programa. Inicijalizacijom stringa se vri tako to se prvom elementu
stringa dodeli znak '\0 ' koji oznaava kraj stringa.

Inicijalizacija stringa prilikom deklaracije:
char imestringa[MAX]=""; /* Nema nista izmedju znakova navoda. */

Inicijalizacija stringa u toku izvravanja programa:
imestringa[0]= '\0';


Unos stringa:
Unos stringa se najee vri bez indeksa, kao to je to sluaj kod niza, a uz
pomo funkcija scanf ili gets.

scanf("%s ",imestringa); ili
gets(imestringa);

117
Format %s oznaava konverziju u string. Funkcija fgets omoguava unos stringa
sve dok se ne pritisne ENTER i time dodaje znak '\0'. Ako funkcija naie na greku
prilikom unosa vraa simboliku konstantu NULL.

Ispis stringa:
Ispis stringa se najee vri bez korienja indeksa (za razliku od niza) a uz
pomo funkcija printf ili puts.

printf("%s ",imestringa); ili
puts(imestringa);

Funkcija puts izvrava ispis znakova sve dok se ne doe do znaka '\0' i prelazi u
novi red.

Primer 1:
Napisati C program koji omoguava unos stringa s i utvruje koliko se puta znak
c nalazi u stringu s. Znak c se unosi sa tastature.

Reenje

#include <stdio.h>
#include <string.h> /* U ovoj biblioteci se nalazi funkcija fgets. */

#define MAX 30

main()
{
char c, s[MAX];
unsigned i,br;
s[0]='\0'; /* Inicijalizacija stringa s. */


printf("String = ");
gets(s) /* Unos stringa s. */
printf("Znak = ");
//c=getche();

br=0, i=0;
while(s[i]!='\0')
{
if(s[i]==c) br++;
i++; /* Kada koristite while ciklus cesto zaboravite da povecate indeks sa
kojim se prolazi kroz string. */
}
printf("\n\nBroj pojave = %d.",br);
//getch();
}

Test primer programa:
118




Primer 2:
Napisati C program koji vri saimanje stringa s, tako to se uzastopni viestruki niz
praznina zamenjuje sa samo jednom prazninom.

Reenje

#include <stdio.h>
#include <string.h>

#define MAX 30
main()
{
char c, s[MAX];
unsigned i,j;
s[0]='\0';
printf("String = ");
gets(s);

i=0;
while(s[i]!='\0')
{
/* Preskaci znakove do prve praznine. */
while(s[i]!=' '&&s[i]!='\0') i++;

if(s[i]!='\0')
{
if(s[i+1]!=' ') i++;
else{
/* Sazimanje stringa. */
j=i;
while(s[j]!='\0') s[j]=s[j+1],j++;
}
}
}
119
printf("\n\nNovi string = %s",s); /* Ispis novog stringa. */
//getch();
}

Test primer programa:





4.2. STRINGOVI I FUNKCIJE

Iz definicije se vidi da je string niz znakova. To znai da sve osobine koje su
vaile za niz vae i za string.

Kao i kod nizova string se ne moe preneti kao argument funkcije, ve se po
referenci prosleuje adresa poetka stringa. Za rad sa stringovima u funkcijama
osim adrese poetka stringa nita vie nije potrebno, jer se string zavrava sa
znakom '\0'.
Prilikom testiranja zadataka sa stringovima, potrebno je samo prilikom
prvog testa uneti string. Sva ostala testiranja kada se unosi string pritiskate taster
desna strelica i string koji ste poslednji uneli bie ponovno ispisan.

Primer 1:
Napisati funkciju unos koja omoguava unos imena. Zavretak unosa imena je
pritisak na taster ENTER. Ako korisnik unese neki karakter koji nije slovo, osim praznog
mesta, string e se izbrisati i morae se izvriti ponovni unos. Prvom slovo mora bitio
veliko, a ako nije funkcija prvo slovo konvertuje u veliko slovo.
Napisati C program koji demonstrira primenu funkcije unos.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
120

/* Prototip funkcije za unos imena. Funkcija vraca adresu na formirani string.*/
char *unos(char *s);

void main(void)
{
/* Deklaracija stringa. */
char str[30]= "";

textmode(3);
textbackground(0);
textcolor(15);
clrscr();
printf("Unesite ime: ");
unos(str);

printf("\n\nVase ime je %s!!",str);
getch();
}


/* Definisanje funkcije. */
char *unos(char *s)
{
/*Deklaracija lokalnih promenljivih. */
unsigned xp, yp, i=0, j;
char c;

xp=wherex(), yp=wherey();
do{
c=getch();

if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||c==' ')
{
/* Ako je prvo slovo malo, vrsi se pretvaranje u veliko.
*/
if(i!=0) if(c>='A'&&c<='Z') s[i]='a'+c-'A';
else s[i]=c;
else if(c>='a'&&c<='z') s[i]='A'+c-'a';
else s[i]=c;

/* Sada je slovo ispravno i moze se stampati na ekranu.
*/
printf("%c",s[i]);
i++;
}else{

/* Ako nije slovo ispitujemo da li je ENTER te ako nije mora
izvrsiti ponovni unos. ENTER odgovara karakteru \r */

if(c!='\r')
121
{
gotoxy(xp,yp);
for(j=0;j<i;j++) printf(" ");
gotoxy(xp,yp);
i=0;
}
}
}while(c!='\r');
s[i]='\0';
gotoxy(xp+strlen(s),yp);
return s;
}

Primer 2:
Napisati C program kojim se unosi korektno zapisan aritmetiki izraz sa
zagradama, a zatim odreuje njegova vrednost. Operandi u izrazu su celi brojevi, a
operacije mogu biti (+,-,* i /) pri emu je / celobrojno deljenje. Pri odreivanju vrednosti
izraza voditi rauna o prioritetu operacija. Prikazati simulaciju formiranja rezultata izraza
red po red, pri emu se u svakom novom redu ispisuje izraz bez izraza (koji se alazio
izmeu dve zagrade sa najveim prioritetom) i zagrada izmeu kojih se izraz nalazio.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 200

/* Prototipovi funkcija. */
void brisipraznineitabulatore(char *s);
char *izraz1(char *s);
char *izraz(char *s);
int operand(char *s, int k, char *s1);
int operacija(char *x, char *y, char op);
void pretvori(int rez, char *s);
char *brisi(char *s, int k, int m);
void ubaci(char *s, int k, char *s1);

void main(void)
{
int x,y;
char s[MAX];

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

122
printf("Unesite izraz:\n");
gets(s);
brisipraznineitabulatore(s);
printf("\n = %s",s); /* Prikaz stringa s bez praznina i tabulatora. */
izraz1(s);
getch();
}

/* Funkcija brisipraznineitabulatore brise sve moguce praznine i tabulatore iz stringa s. */
void brisipraznineitabulatore(char *s)
{
int i=0, j;

while(s[i]!='\0')
{
if(s[i]==' '||s[i]=='\t')
{
/* Ako naidjemo na prazninu ili tabulator \t pomeramo string sdesna na levo tako da se taj
karakter izbrise iz stringa. */

j=i+1;
while(s[j]!='\0') s[j-1]=s[j],j++;

/* Obavezno dodati \0 za kraj stringa. */
s[j-1]='\0';
}else i++;

/* Brojac se pomera samo ako karakter nije praznina ili tabulator, inace da se i povecava
uvek za jedan nastali bi problemi ako bi string imao uzastopan niz praznina ili tabulatora. Ne bi se
svi obrisali. */
}
}

/* Funkcija izraz1 izracunava izraz koji poseduje zagrade pozivajuci funkciju izraz koja
racuna izraz bez zagrada. */
char *izraz1(char *s)
{
int i,j,k,br;
char s1[MAX],*s2;

/* Pokazivac s2 nam treba jer funkcija izraz vraca pokazivac.
Prvo se mora izdvojiti izraz koji je izmedju zagrada. Da bi se to postiglo prvo se trazi
zatvorena zagrada, prolazeci kroz string sleva na desno, te se od nje krece nazad da bi se pronasao
indeks otvorene zagrade. Izraz izmedju zagrada se smesta u string s1 i brise se taj deo stringa
zakljucno sa zagradama. Izracunava se izraz koji se nalazi u stringu s1 i rezultat smesta u string
s2. String s2 se ubacuje u string s.
Postupak se ponavlja dok postoji zagrada u izrazu. */

do{
i=0;
while(s[i]!=')'&&s[i]!='\0') i++;
123
if(s[i]!='\0')
{
j=i;
while(s[j]!='(') j--;
for(k=j+1;k<i;k++) s1[k-j-1]=s[k];
s1[k-j-1]='\0';
brisi(s,j,i);
s2=izraz(s1);
if(atoi(s2)<0)
{

/* Ako je rezultat izraza izmedju zagrada negativan broj ne smemo ubaci kao takvog ako
je pre zagrada bio neki operator, jer bismo tada dobili dva operatora jedan do drugog. Problem se
resava tako sto se upise njegova pozitivna vrednost, a menja znak prvom znaku plus u minus ili
minus u plus koji su prethodili tim zagradama. Ako se dodje do prve otvorene zagrade ili pocetka
izraza, to je znak da se posle otvorene zagrade ili na pocetku izraza mora ubaciti negativni
predznak. */

k=1;
while(s2[k]!='\0') s2[k-1]=s2[k],k++;
s2[k-1]='\0';
ubaci(s,j,s2);
k=j;
while(s[k]!='+'&&s[k]!='-'&&s[k]!='('&&k>0) k--;
if(k==0&&s[k]!='+'&&s[k]!='-'&&s[k]!='(') strcpy(s2,"-"),ubaci(s,0,s2);
else{
if(s[k]=='+') s[k]='-';
else
{
if(s[k]=='-') s[k]='+';
else if(s[k]=='(')
strcpy(s2,"-"),ubaci(s,k+1,s2);
}
}
}
else ubaci(s,j,s2);
}else{
s2=izraz(s);
strcpy(s,s2);
}

/* Ispisujemo izraz jer smo se u ovom trenutku oslobodili jednog izraza izmedju zagrada. */
printf("\n = %s",s);

/* Uvek se mora brojati broj operatora, jer se u izrazu izmedju zagrada moze osloboditi
vise od jednog operatora. */

br=0;
i=0;

while(s[i]!='\0')
124
{
if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/') br++;
i++;
}
if(br==1&&s[0]=='-') br--;
}while(br>0);

return s;
}

/* Funkcija izraz omogucava izracunavanje izraza bez zagrada uz postovanje prioriteta
operacija. */
char *izraz(char *s)
{
/* U funkciji je a prvi operand, b je drugi operand, d je treci operand, a c je rezultat.
Promenljiva op1 je prvi operator a op2 drugi operator. */

int i,i1,i2,i3,rez,k,br=0;
char a[MAX],b[MAX],c[MAX],d[MAX],op1,op2;

/* Prvo utvrdimo koliko dati izraz sadrzi operatora. */
i=0;
while(s[i]!='\0')
{
if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/') br++;
i++;
}
/* Izraz se izracunava sve dokle god izraz sadrzi bar jedan operator. */
do{
i1=operand(s,0,a); /* Uzima se prvi operand. */
op1=s[i1]; /* Izdvaja se prvi operator. */
i2=operand(s,i1+1,b)+i1+1; /* Izdvaja se drugi operand. */

if(br>1)
{
i3=operand(s,i2+1,d)+i2+1; /* Izdvaja se treci operand. */
op2=s[i2]; /* Izdvaja se drugi operator. */

/* Sada se mora resiti problem prioriteta operatora, te se zbog toga posmatra drugi operator,
i ako je on * ili / on ce se prvi izvrsiti. Izracuna se operacija izmedju dva operanda (mora se voditi
racuna ko je levi a ko desni operand), pretvori se rezultat iz broja u string c. Prethodni izraz koga
su cinila dva operanda i operacija se izbrisu iz stringa s i umesto njih se ubacuje rezultujuci string
c. */
if(op2=='*'||op2=='/')
{
rez=operacija(b,d,op2);
pretvori(rez,c);
brisi(s,i1+1,i3-1);
ubaci(s,i1+1,c);
}else{
rez=operacija(a,b,op1);
125
pretvori(rez,c);
brisi(s,0,i2-1);
ubaci(s,0,c);
}
}else{
rez=operacija(a,b,op1);
pretvori(rez,c);
brisi(s,0,i2-1);
ubaci(s,0,c);
}

/* Broj operatora se smanjuje ali ne uvek za jedan nakon zavrsetka uzraza. Stoga uvek
moramo brojati broj operacija koji je preostao. */
br=0;
i=0;
while(s[i]!='\0')
{
if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/') br++;
i++;
}

/* Moze se desiti da se u izrazu nalazi samo jedna operacija koja pretstavlja predznak
broja, tada u sustini nema vise operatora i broj operacija se mora smanjiti na nulu. */

if(br==1&&s[0]=='-') br--;
}while(br>0);

return s;
}

/* Funkcija operand iz stringa s koji pretstavlja izraz bez zagrada izdvaja string koji
pretstavlja operand. Operand se vadi od indeksa k do sledeceg operatora ili kraja stringa s. String
s1 pretstavlja formirani operand, a funkcija vraca indeks pojave znaka \0. */
int operand(char *s, int k, char *s1)
{
int i=0;

/* Moramo preskociti predznak operanda, pa tek tada traziti kraj operanda, a on se nalazi
pri pojavi sledece operacije. */

if(s[k]=='+'||s[k]=='-') s1[0]=s[k],i++;
while(s[k+i]!='+'&&s[k+i]!='-'&&s[k+i]!='*'&&s[k+i]!='/'&&s[k+i]!='\0') s1[i]=s[k+i],i++;

s1[i]='\0'; /* Formirani string mora sadrzati znak '\0'. */

/* Funkcija vraca adresu pocetka formiranog stringa. */

return strlen(s1);
}

126
/* Funkcija operacija izracunava operaciju izmedju dva operanda i vraca celobrojni rezultat.
Operandi su stringovi. */
int operacija(char *x, char *y, char op)
{
int rez;

switch(op)
{
case '+': rez=atoi(x)+atoi(y);
/* Funkcija atoi konvertuje string u ceo broj. */
break;
case '-': rez=atoi(x)-atoi(y);
break;
case '*': rez=atoi(x)*atoi(y);
break;
case '/': if(atoi(y)!=0) rez=atoi(x)/atoi(y);
else{
/* Deljenje sa nulom. */
printf("ERROR");
exit(1);
}
}
return rez;
}

/* Funkcija vrsi pretvaranje broja rez u string s. */
void pretvori(int rez, char *s)
{
int i,j,k;

/* Prvo se utvrdi da li operand ima negativni predznak. Zatim utvrdimo koliko cifara ima
broj rez i taj podatak smestimo u promenljivu k. */

if(rez<0)
{
strcpy(s,"-");
j=1;
}else{
s[0]='\0';
j=0;
}
i=abs(rez);

k=1;
while(i!=0) k*=10,i/=10;
k/=10;

/* Sada treba konvertovati cifru po cifru u karakter i upisivati ga u string. */
rez=abs(rez);
while(k!=0)
{
127
s[j]=rez/k+48;
rez=rez-(rez/k)*k;
k/=10;
j++;
}
s[j]='\0';
}

/* Funkcija brisi brise deo stringa s pocev od pozicije k do pozicije m i vraca pokazivac
na pocetak stringa */
char *brisi(char *s, int k, int m)
{
int i=0;
while(s[m+i+1]!='\0')
{
s[k+i]=s[m+i+1];
i++;
}
s[k+i]='\0';
return s;
}

/* Funkcija ubaci vrsi ubacivanje stringa s1 (koji pretstavlja resenje dela izraza u obliku
jednog broja) u string s pocev od pozicije k. */
void ubaci(char *s, int k, char *s1)
{
int i=0,n,p;

n=strlen(s); /* Funkcija strlen izracunava duzinu stringa (broji znakove do znaka \0). */
while(s1[i]!='\0')
{
p=n+1;
while(p>=k+i) s[p]=s[p-1],p--;
s[k+i]=s1[i];
i++;
n++;
}
}

Test primer programa:

128









4.3. STRINGOVI I POKAZIVAI

- Indentifikator stringa je konstantan pokaziva (ne smete mu promeniti
adresu na koju pokazuje) na poetak stringa,
- Veza izmeu stringa i pokazivaa moe se predstaviti pomou formule

s[i] *(s + i)

- Kraj stringa oznaava se sa znakom '\0' ija je vrednost broj nula.
- Prenosom po referenci adrese poetka stringa formalnom argumentu
funkcije omoguava da se pomou formalnog argumenta prolazi kroz string.

Primer 1:
Napisati C program koji omoguava unos stringa i korienjem funkcije duzina
odreuje duinu stringa. Duinu stringa pretstavlja broj znakova stringa bez znaka '\0'.
Prilikom realizacije funkcije nemojte koristiti lokalne promenljive (samo formalne
argumente) kao ni bilo koju biblioteku funkciju.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>

129
#define MAX 30

unsigned duzina(char *s, int k);

void main(void)
{
char s[MAX];

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\n\tString = ");
gets(s);

printf("\n\tDuzina stringa = %d",duzina(s,0));
gotoxy(1,25);
getch();
}

/* Funkcija izracunava duzinu stringa, a kako se ne smeju koristiti lokalne promenljive
prosledili smo jos jedan parametar koji pretstavlja brojac karaktera. */

unsigned duzina(char *s, int k)
{

/* Uslov koji se nalazi u while naredbi je jako interesantan. Prvo se nailazi na operator
diferenciranja, te ako karakter nije '\0' vrednost argumenta s se povecava za 1 cime je
adresa povecana za 1 i prelazi se na sledeci karakter stringa. Kada se dodje na kraj
stringa, diferenciranjem (*s) pokazace karakter '\0', a kako je njena vrednost broj 0, time
je zavrsen while ciklus. Brojac k nije odbrojao karakter '\0'. */

while(*s++) k++;

/* Funkcija vraca broj karaktera koji ima string, a ujedno ta vrednost pretstavlja indeks
kraja stringa, odnosno poziciju gde se nalazi znak '\0'. */

return k;
}

Primer 2:
Napisati C program koji omoguava brisanje dela stringa pomou funkcije brisi.
Funkcija brisi omoguava brisanje dela stringa s izmeu indeksa k i p, ukljuujui i
karaktere koji se nalaze na tim indeksima Funkcija vraa 1 ako je uspeno obavila posao
ili 0 u suprotnom. Prilikom realizacije funkcije nemojte koristiti lokalne promenljive
(samo formalne argumente) kao ni bilo koju biblioteku funkciju osim funkcije duzina iz
prolog zadatka.

Reenje
130

#include <stdio.h>
#include <conio.h>
#include <string.h>

#define MAX 30

unsigned duzina(char *s, int k);
unsigned brisi(char *s, int k, int p);

void main(void)
{
char s[MAX];
int k, p;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\n\tString = ");
gets(s);
printf("\tk = ");
scanf("%d",&k);
printf("\tp = ");
scanf("%d",&p);

if(brisi(s,k,p)) printf("\n\n\tNovi stringa = %s",s);
else printf("Ova operacija brisanja se ne moze izvrsiti!!");


gotoxy(1,25);
getch();
}

/* Funkcija izracunava duzinu stringa. */
unsigned duzina(char *s, int k)
{
while(*s++) k++;
return k;
}

/* Funkcija omogucava brisanje dela stringa izmedju indeksa k i p. */
unsigned brisi(char *s, int k, int p)
{
if(p<k||k>duzina(s,0)) return 0;

/* Pracenjem promenljive s videcete da nestaje raniji deo stringa (koji se prati) kada se
menja vrednost promenljive s, jer s predstavlja pokazivac na pocetak stringa. */

s+=k;
131
while(*(s+p-k))
{
*s=*(s+p-k);
*s++;
}
*s='\0';

return 1;
}

Primer 3:
Napisati C program koji poredi dva stringa korienjem funkcije poredi. Funkcija
poredi poredi string s kao prvi argument sa stringom t koji je drugi argument funkcije i
vraa: 0 ako su stringovi isti, pozitivna vrednost ako je s>t, ili negativnu vrednost ako
je s<t. String s je vei od stringa t ako su do indeksa k svi karakteri stringa s bili isti kao i
kod stringu t, a na k-tom indeksu je redni broj (iz ASCI I tabele) karaktera iz stringa s
imao veu vrednost od rednog broja karaktera na k-tom indeksu stzringa t.
Prilikom realizacije funkcije nemojte koristiti lokalne promenljive (samo formalne
argumente) kao ni bilo koju biblioteku funkciju.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>

#define MAX 30

int poredi(char *s, char *t);

void main(void)
{
char s[MAX], t[MAX];
int k;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\n\tPrvi string = ");
gets(s);
printf("\tDrugi string = ");
gets(t);

k=poredi(s,t);
if(k<0) printf("\n\n\tString s je manji od stringa t!!");
else{
if(k==0) printf("\n\n\tStringovi su jednaki!!");
else printf("\n\n\tString s je veci od stringa t!!");
132
}

gotoxy(1,25);
getch();
}

/* Funkcija poredi dva stringa. */
int poredi(char *s, char *t)
{
/* Dokle gos su karakteri iz stringova jednaki i nismo dosli do kraja niti jednog stringa
ciklus se izvrsava. */

while(*s++ == *t++ && *s && *t);

/* Zbog inkrementiranja presli smo na sledeci karakter iz stringa. Iz tih razloga moramo
se vratiti na prethodni karakter. Razlika njihovih rednih brojeva (a kada se vrsi
oduzimanje karaktera vrsi se oduzimanje njihovih rednih brojeva) pretstavlja trazeno
resenje. */

return *(--s)-*(--t);
}


4.4. OSNOVNE FUNKCIJE ZA RAD SA ZNAKOVIMA I
STRINGOVIMA


Osnovne funkcije za rad sa znakovima

Zaglavlje <ctype.h> deklarie funkcije za proveravanje znakova, tj odreuje u
koju kategoriju spada dati znak (malo slovo, veliko slovo, broj, itd).


int insalnum(int character);

character je ASCII znak koji se proverava.

Funkcija insalnumvraa vrednost razliitu od nule ako je navedeni znak character
slovo ili cifra.


int isalpha(int character);

character je ASCII znak koji se proverava.

Funkcija isalpha vraa vrednost razliitu od nule ako je navedeni znak slovo.


133

int isdigit(int character);

character je ASCII znak koji se proverava.

Funkcija isdigit vraa vrednost razliitu od nule ako je navedeni znak character
cifra.


int isgraph(int character);

character je ASCII znak koji se proverava.

Funkcija isgraph vraa vrednost razliitu od nule ako se navedeni znak character
moe prikazati na ekranu (opseg kodova od 33 do 126) izuzimajui znak za razmak.

int islower(int caracter);

character je ASCII znak koji se proverava.

Funkcija islower vraa vrednost razliitu od nule ako je navedeni znak character
malo slovo.

int isupper(int character);

character je ASCII znak koji se proverava.

Funkcija isupper vraa vrednost razliitu od nule ako je navedeni znak character
veliko slovo.

int isspace(int character);

character je ASCII znak koji se proverava.

Funkcija isspace vraa vrednost razliitu od nule ako je navedeni znak character
nevidljiv na ekranu (tabulator, vertikalni tabulator,...)


int isprint(int character);

character je ASCII znak koji se proverava.

Funkcija isprint vraa vrednost razliitu od nule ako se navedeni znak character
moe prikazati na ekranu.

int toupper(int character);
134

character je ASCII znak koji se proverava.

Funkcija toupper konvertuje malo slovo u veliko. Ako je navedeno slovo character
veliko funkcija ga ostavlja nepromenjenim.


int tolower(int character);

character je ASCII znak koji se proverava.

Funkcija tolower konvertuje veliko slovo u malo. Ako je navedeno slovo character
malo funkcija ga ostavlja nepromenjenim.



Osnovne funkcije za rad sa stringovima

U zaglavlju <string.h> definisane su funkcije za rad sa stringovima.


char *strcpy(char *s, char *t);

Funkcija strcpy kopira string t u string s znak po znak. Prethodni sadraj stringa s se
gubi. Funkcija vraa pokaziva na string s.


char *strncpy(char *s, char *t, int n);

Funkcija strncpy kopira prvih n znakova iz stringa t u string s. Funkcija vraa
pokaziva na string s.


char *strcat(char *s, char *t);

Funkcija strcat dodaje string t na kraj stringa s i vraa pokaziva na string s.


char* strncat(char *s, char *t, int n);

Funkcija strncat dopisuje najvie n znakova iz stringa t na kraj stringa s.


int *strcmp(char *s, char *t);

135
Funkcija strcmp poredi dva stringa znak po znak. Ako je znak u prvom stringu s
vei od odgovarajueg znaka u drugom stringu t, funkcija vraa negativnu vrednost. Ako
su stringovi indentini funkcija vraa 0.

int *strncmp(char *s, char *t, int n);

Funkcija strncmp poredi prvih n bajtova dva niza znakova. Funkcija je identina
funkcija strcmp, stim to poredi samo prvih n karaktera.


char *strchr(char *s, int character);

Funkcija strchr trai prvo pojavljivanje navedenog ASCII znaka character u
stringu s, te ako uspeno obavi zadatak funkcija vraa pokaziva na prvo pojavljivanje
navedenog znaka ili vrednost NULL u suprotnom.


char *strrchr(char *s, int character);

Funkcija strrchr vraa pokaziva na prvu pojavu odreenog znaka character s
desne strane stringa s. Ako funkcija uspeno obavi zadatak bie vraen pokaziva na prvu
poziciju unutar stringa, ili vrednost NULL u suprotnom.


char *strstr(char *s, char *t);

Funkcija strstr vraa pokaziva na prvu pojavu podstringa t unutar stringa s. Ako
uspeno obavi zadatak funkcija vraa pokaziva na prvu pojavu podstringa, ili vrednost
NULL u suprotnom.

int strlen(char *s);

Funkcija strlen vraa duinu stringa s u bajtovima, tj broj znakova stringa bez
znaka '\0'.


char *strtok(char *s, char *tokeni);

Funkcija strtok vraa pokaziva na lokaciju tokena u stringu. U stringu s se trae
tokeni. Ako je string NULL, funkcija strtok koristi zavrnu lokaciju prethodnog stringa.
tokeni predstavlja string koji sadri tokene koje treba nai. Ako uspeno obavi zadatak,
funkcija vraa pokaziva na poziciju tokena. Ako ni jedan token nije pronaen funkcija
strtok vraa vrednost NULL.



136

Funkcije za numerike konverzije

int atoi(char *s);

Funkcija atoi konvertuje string s u celobrojnu vrednost. Funkcija vri konvertovanje
sve dok se ne naie na nevaei karakter unutar stringa ili znaka '\0'. Funkcija ne prua
informaciju da li postoje nevaei znakovi unutar stringa.


double atof(char *s);

Funkcija atof konvertuje string s u decimalnu vrednost. Funkcija vri konvertovanje
sve dok se ne naie na nevaei karakter unutar stringa ili znaka \0. Funkcija ne prua
informaciju da li postoje nevaei znakovi unutar stringa.


4.5. NIZ POKAZIVAA NA STRINGOVE


Niz pokazivaa na stringove pretstavlja niz koji sadri adrese prvih lanova
(poetne adrese) stringova.

Deklaracija niza pokazivaa na stringove:
char *niz[MAX];

U deklaraciji uglaste zagrade oznaavaju da je u pitanju niz, a operator zvezdica,
da taj niz sadri pokazivae na promenljive tipa char.
Prilikom deklaracije niza pokazivaa na stringove moe se izvriti i njihova
inicijalizacija.

Na primer:
char *imena[3]={ "Petar","Misa","Slavko"};

Zona u memoriji gde su smeteni stringovi jedan iza drugog











P e t a r \0 M i s a \0 S l a v k o \0



137
imena


Sa slike se moe videti da je promenljiva imena pretstavlja niz pokazivaa koji
sadre adrese (pokazuju) na prva slova stringova (imena). Prilikom praenja promenljive
imena u watch prozoru C okruenja, imali bismo utisak da niz pokazivaa na stringove
pretstavlja niz stringova (kao to se vidi i iz deklaracije).

Inicijalizacija niza pokazivaa na stringove:
Inicijalizacija niza pokazivaa na stringove vri se kao i inicijalizacija niza,
pomou ciklusa, pri emu svaki lan niza sadri simboliku konstantu NULL.

for(i=0;i<MAX;i++) niz[i]=NULL;

Mora se obezbediti da prvi pokaziva iz niza pokazivaa pokazuje na neki prostor
u memoriji koji je dosta veliki (u stanju je da rei bilo koji sluaj).

char *niz[MAX], c[VELIKI_PROSTOR], *pom=c;
niz[0]=pom;
for(i=1;i<MAX;i++) niz[i]=NULL;

Pokazivac pom pokazuje na adresu prvog elementa stringovne promenljive c.
Poev od te lokacije smetae se redom stringovi u memoriji. Dodeljujemo prvom
pokazivau iz niza pokazivaa adresu od po;etka stringa c, dok se svi ostali pokazivai iz
niza pokazivaa postavljaju na NULL, to oznaava da ti pokazivai ne sadre nikakvu
adresu.

Formiranje niza pokazivaa na stringove:

Niz pokazivaa na stringove moraju sadrati takve adrese da se zadovolji gornja
predstava. Svaki pokaziva pokazuje na poetak sledeeg stringa, a stringovi su
nadovezani jedni iza drugih u memoriji (iza poslednjeg znaka jednog stringa '\0'
nadovezuje se prvi karakter sledeeg stringa). Kao i svaki drugi niz, i niz stringova se
formira sa ciklusom. Ako hoemo da unesemo n stringova, zadatak moemo uraditi na
sledei nain:

char *niz[MAX], c[VELIKI_PROSTOR], *pom=c;
niz[0]=pom;
for(i=1;i<MAX;i++) niz[i]=NULL;

for(i=0;i<n;i++)
{
/* Svaki sledeci clan niza dobija adresu tako sto se na adresu prethodnog
clana niza sabere duzina stringa na koji on pokazuje i dodaje 1 kako bi se
preskocio znak '\0'. */

138
if(i!=0) niz[i]=niz[i-1]+strlen(niz[i-1])+1;
gets(s)
strcpy(niz[i],s);
}

Razlike izmeu matrice znakova i niza pokazivaa na stringove:
esto se izmeu matrice znakova i niza pokazivaa na stringove ne pravi razlika,
jer se niz pokazivaa na stringove smatra nizom stringova. Niz pokazivaa na stringove
omoguava da se stringovi smetaju jedan do drugog u memoriji. Ovim se uteuje na
zauzetosti memorijskog prostora. Osim toga za prenos matrice znakova u funkciju
potrebno je preneti drugu dimenziju, dok kod niza pokazivaa na stringove to niije
potrebno. Rad sa matricama znakova je jednostavniji u odnosu na rad sa nizom
pokazivaa na stringove.

Primer 1:
Napisati C program koji omoguava unos imena i prezimena n osoba n<31, a
potom vri njihovo sortiranje po abecednom redosledu. Prilikom realizacija zadatka
koristiti niz pokazivaa na stringove. Unos imena i prezimena vriti odvojeno
korienjem funkcije unos. Funkcija unos prvo slovo imena ili prezimena pretvara u
veliko a sva ostala u mala slova. Unos imena ili prezimena zavrava se pritiskom na
SPACE, ENTER ili TAB. Ako se unese karakter koji nije slovo funkcija trazi ponovni
unos imena ili prezimena (jer je nastala greka).

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>

#define MAX 30
#define VELIKI_PROSTOR 5000

/* Definisanje prototipa funkcije. */
char *unos(char *s);

void main(void)
{
/* Deklaracija promenljivih. */
char *niz[MAX], s[MAX], pom[MAX], c[VELIKI_PROSTOR], *pom1=c;
unsigned i, j, xu, yu;
int n;

/* Inicijalizacija niza pokazivaca na stringove. */
niz[0]=pom1;
for(i=1;i<MAX;i++) niz[i]=NULL;

textmode(3);
textcolor(15);
139
textbackground(0);
clrscr();

/* Koliko imena i prezimena treba uneti. */
printf("N = ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0);

/* Unos imena i prezimena. */
printf("\n\nPrerzime:\tIme:\n--------\t-----\t\n");

for(i=0;i<n;i++)
{
if(i!=0) niz[i]=niz[i-1]+strlen(niz[i-1])+1;

/* Unos imena. */
unos(pom);
strcpy(s,pom);

/* Nadovezivanje praznog mesta. */
strcat(s," ");
printf("\t\t");

/* Unos prezimena i njegovo nadovezivanje na kraj stringa s. Sada string s sadrzi
ime i prezime. */

unos(pom);
strcat(s,pom);
strcpy(niz[i],s);
printf("\n");
}

/* Sortiranjem imena i prezimena ne vrsi se nikakvo fizicko premestanje stringova u
memoriji, vec zamena adresa koje sadrze elementi niza pokazivaca. */

for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(strcmp(niz[i],niz[j])>0)
{
pom1=niz[i];
niz[i]=niz[j];
niz[j]=pom1;
}
}
140
}
printf("\nSortirana imena\n");
printf("Prezime i Ime:\n--------------\n");
for(i=0;i<n;i++) printf("%s\n",niz[i]);
getch();
}

/* Funkcija unos omoguava unos imena ili prezimena. */
char *unos(char *s)
{
/*Deklaracija lokalnih promenljivih. */
unsigned xp, yp, i=0, j;
char c;

xp=wherex(), yp=wherey();

do{
c=getch();

if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))
{

/* Ako je prvo slovo malo, vrsi se pretvaranje u veliko. */

if(i!=0) if(c>='A'&&c<='Z') s[i]='a'+c-'A';
else s[i]=c;
else if(c>='a'&&c<='z') s[i]='A'+c-'a';
else s[i]=c;

/* Sada je slovo ispravno i moze se stampati na ekranu. */

printf("%c",s[i]), i++;
}else{
if(c!='\r'&&c!=' '&&c!='\t')
{
gotoxy(xp,yp);
for(j=0;j<i;j++) printf(" ");
gotoxy(xp,yp);
i=0;
}
}
}while(c!='\r'&&c!=' '&&c!='\t');

s[i]='\0';
gotoxy(xp+strlen(s),yp);
return s;
}

Ako je na primer izvren samo unos imena pomou niza pokazivaa imena (redom
Petar, Misa i Slavko) imaemo sledeu sliku.
141

pom1 Zona u memoriji gde su smeteni stringovi jedan iza drugog











imena


Nakon opisanog sortiranja imena slika, ima sledei izgled:

pom1
Zona u memoriji gde su smeteni stringovi jedan iza drugog











imena


Primer 2:
Napisati C program koji omoguava unos stringa u formatu:

String = "brv/brk/string_od_slova"

Znak tabulacije u stringu mora se nalaziti samo na jednom mestu. Na osnovu
unetog stringa formirati matricu znakova koja ima brv vrsta i brk kolona. Podaci se
dobijaju iz unetog stringa i razdvojeni su znakom '/'. U stringu me postojati samo na dva
mesta znak '/'. Iza drugog znaka '/' nalazi se string koji se smeta u matricu znakova.
Matrica se formira vrsta po vrsta, pri emu se znak tabulacije '\t' zamenjuje znakom '\0'.
Deifrovani string se dobija tako to se kroz matricu znakova prolazi levom
spiralom do znaka '\0', Svaki znak '_' zamenjuje se znakom praznina ' '.
P e t a r \0 M i s a \0 S l a v k o \0



P e t a r \0 M i s a \0 S l a v k o \0



142
Na primer:

String = "5/6/Mop_imiz _sl eliti\tcim_da_"

Nastala matrica je:

M o p _ i m
i z _
s l e
l i t i \0 c
i m _ d a _

Desifrovani string = "Mislim da ce mi pozliti"

Reenje

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>

#define MAX 80

void main (void)
{
char s[MAX],*c,*s1,m,n,a[10][10];
int i,j,k,p=0;
s[0]='\0';

/* Inicijalizacija matrice znakova. */
for(i=0;i<10;i++)
{
for(j=0;j<10;j++) a[i][j]='_';
}

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

/* Unos sifriranog stringa po uslovu teksta zadatka, bez kontrole unosa. */
printf("\n\tString:");
gets(s);

/* Izdvajanje iz striga koliki je broj vrsta i broj kolona. */
strcpy(s1,s);

/* Izdvaja se deo stringa do znaka '/'. Taj string pretstavlja broj vrsta matrice, te se
funkcijom atoi dati string konvertuje u broj. */
143

c=strtok(s1,"/");
m=atoi(c);

/* Prilikom rada sa funkcijom strtok potrebno je koristiti pokazivac na karakter, jer
funkcija vraca pokazivac na karakter. */

c=strtok(NULL,"/");
n=atoi(c);

/* Utvrdjivanje pozicije drugog pojavljivanja znaka '/'. */
i=0;
while(s[i]!='\0')
{
if(s[i]=='/') k=i;
i++;
}

/* Brisanje dela stringa koji sadrzi zakljucno sa drugom kosom crtom. */
i=0;
while(s[k]!='\0')
{
s[i]=s[k+1];
i++,k++;
}
s[i]='\0';

/* Formiranje matrice znakova na osnovu stringa. Tamo gde se nalazi znak '\t' treba upisati
znak '\0'*/
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(s[i*n+j]!='\t') a[i][j]=s[i*n+j];
else{a[i][j]='\0';}
}
}

/* Matrica znakova se stampa vrsta po vrsta. */
for(i=0;i<m;i++)
{
for(j=0;j<n;j++) gotoxy(15+3*j,5+i),printf("%c ",a[i][j]);

}

/* Formira se novi string s koji predstavlja desifrovani string, na osnovu spiralnog
prolaska kroz matricu znakova (leva spirala). Kroz matricu se spiralno prolazi sve dok se
ne dodje do znaka '\0', cime je i formiran desifrovani string. */
k=0;
while(a[i][j]!='\0')
{
144
j=p;
for(i=p;i<m-p-1;i++) s[k]=a[i][j],k++; /* Vertikalno na dole. */
i=m-p-1;
for(j=p;j<n-p-1;j++) s[k]=a[i][j],k++; /* Horizontalno s leva na desno. */
j=n-p-1;
for(i=m-p-1;i>p+1;i--) s[k]=a[i][j],k++; /* Vertikalno na gore. */
i=0-p;
for(j=n-p;j>=p+1;j--) s[k]=a[i][j],k++; /* Horizontalno s desna na levo. */
p++;
}

/* Prolazi se kroz formirani string i svaki karakter _ zamenjuje se sa prazninom. */
while(s[i]!='\0')
{
if(s[i]=='_') s[i]=' ';
i++;
}
s[k]='\0';

/* Ispis desifrovanog stringa. */
printf("\n\n\n\t Desifrovani string: %s",s);

gotoxy(1,25);
getch();
}

Test primer programa:










145
















4.6. MAKROI I FUNKCIJE SA PROMENLJIVIM
BROJEM ARGUMENATA


Makroi:

Definicije simbola u C jeziku se nazivaju makroi. Svi indentifikatori definisani
direktivama define do eventualnog unitavanja direktivom undef smatraju se
makroima.

Definisanje makroa:

#define INDENTIFIKATOR niz_simbola ili
#define INDENTIFIKATOR (niz_argumenata) niz_simbola

Uobiajeno je da se indentifikator pie velikim slovima kako bi se skrenula panja
da je u pitanju makro. U drugoj definiciji ne sme biti razmaka izmeu indentifikatora
makroa i otvorene zagrade koja zapoinje listu argumenata.

Na primer:
#define MAX 30
#define PORUKA { \
gotoxy(25,24);\
printf("Za nastavak pritisnite SPACE taster!!");\
getch();
}
#define MAXBROJ(a,b) a>b a : b
#define KVADRAT(a) a*a

146
Prvi primer smo ve ranije koristili za definisanje simbolike konstante. Nakon
indentifikatora MAX koji je napisan velikim slovom jer je indentifikator makroa
(poeljno je da je velikim slovom ispisan, iako prevodilac prihvata da je malo), sledi niz
simbola, a to je u ovom sluaju broj 30. Tokom celog programa gde god se pojavi
indentifikator MAX prevodilac e ga zamenjivati brojem 30. Niz simbola ne sme se
zavriti sa znakom taka zarez.
Drugi primer koristi blok jer se niz simbola ne sme zavriti znakom taka zarez.
Dugaak niz simbola, koji se ne moe napisati u jednom redu znakom '/' na kraju reda
oznaava da je nastavak u sledeem redu. Makro moe da se zamenjuje nekim delom
sloene upravljake strukture (da osim funkcija sadri selekcije i cikluse).
Kod prvog i drugog primera makroi se pozivaju navoenjem imena makroa iza
koga ne mora pisati znak taka zarez.
Trei primer koristi makro MAXBROJ koji slino funkcijama sadri formalne
argumente a i b. Stvarni argument se prosleuju formalnim argumentima izrauna se
izraz i vrednost se nalazi u indentifikatoru makroa. U ovom sluaju bie vraena vrednost
argumenta a ili b.
Osnovna razlika izmeu poziva makroa i poziva funkcije je u tome to se prilikom
poziva makroa tip argumenta makroa moe biti proizvoljan. Makroi se zamenjuju jo
pre prevoenja izvornog programa, dok funkcije postoje i za vreme izvrenja programa.
Za razliku od funkcija gde se prvo izraunala vrednost izraza, pa se vrednost prosledila
formalnom argumentu funkcije, kod poziva makroa to nije sluaj, ve se ceo izraz
prosleuje formalnom argumentu i kao takav uestvuje u nizu simbola.

Iz tih razloga etvrti primer radie pogtreno.

Na primer ako pozovemo makro sa:
x= KVADRAT(3)
niz simbola postaje 3*3 i daje taan rezultat 9 koji se prosledio promenljivoj x.

Meutim ako pozovemo makro sa
x=KVADRAT(2+1)
niz simbola postaje 2+1*2+1 i vrednost promenljive x postaje 5 to je pogrean
rezultat.
Da bi makro KVADRAT ispravno radio moraju se koristiti zagrade u nizu simbola
kako bi se izbegli problemi sa prioritetima operatora.

#define KVADRAT(x) (x)*(x)

Nakon pozivanja makroa
x=KVADRAT(2+1)
niz simbola postaje (2+1)*(2+1) te x dobija vrednost 9 to je taan rezultat.

Preporuuje se strogo korienje zagrada oko svakog korienja formalnog
argumenta u nizu simbola. Prilikom korienja makroa izrazi kao stvarni
argumenti doslovce e se uvrstiti u formalne argumente makroa. To prouzrokuje
147
velike probleme ako se u stvarnim argumentima nalaze izrazi sa operatorima koji
prouzrokuju bone efekte.

Ako funklcije i makroi mogu da prime ulazne vrednosti putem parametara ta
kada koristiti?

Korienje funkcije prouzrokuje dodatna optereenja usled poziva funkcije, jer se
vreme troi na smetanje podataka na stek, prenoenje izvravanja programa na drugo
mesto u memoriji i zatim nazad na naredbu iza poziva funkcije. To e uzrokovati da
program sporije radi. Makro se razvija u svoj niz simbola zamene, svaki put kada
procesor sretne ime simbola. Pozivanjem makroa poveava se brzina izvravanja
programa, ali je cena toga poveanje veliine izvrivog programa. Dobit od funkcija je da
se izvri kod koga prevodilac proizvodi pojavljuje u programu samo jednom, a moe se
pozivati proizvoljan broj puta bez ikakvog poveanja programa.



Funkcije sa promenljivim brojem argumenata:

Funkcija sa promenljivim brojem argumenata ima nekoliko obaveznih argumenata
iza kojih moe da postoji proizvoljan broj neobaveznih argumenata.

Prototip funkcije sa promenljivim brojem argumenata je:

tip naziv_funkcije(lista_obaveznih_argumenata, lista_neobaveznih_argumenata);

Postojanje neobaveznih formalnih argumenata se prilikom deklarisanja ili
definisanja funkcije oznaava stavljanjem tri take iza poslednjeg obaveznog formalnog
argumenta. Tri take se mogu nalaziti samo na kraju liste obaveznih formalnih
argumenata.

Na primer:
Prototip funkcije prikaz koja ima etiri obavezna formalna argumenta.
int prikaz(int x, int y, int br, char *text,...);

Funkcija prikaz imae prilikom pozivanja minimalno etiri stvarna argumenta.
Primeri pozivanja funkcija prikaz:
prikaz(5,10,4, "UNOS","ISPIS","PRIKAZ");
prikaz(15,6,7, "OBRADA","ISPIS","PRONADJI","KRAJ");

Iz primera se moe zakljuiti da je prilikom pozivanja funkcija prikaz broj
parametara razliit od poziva do poziva funkcije.

Prilikom pozivanja funkcija prevodilac moe da proverava ispravnost broja i tipova
samo obaveznih argumenata. Iza njih prihvatie proizvoljan broj stvarnih argumenata
proizvoljnih tipova, promenljivo od poziva do poziva. Za obavezne argumente vrie se
148
uobiajena automatska konverzija tipova. Kod neobaveznih argumenata argument tipa
char se obavezno konvertuje u tip int, a argumenti tipa float u tipa double.
Prilikom pozivanja funkcije u obaveznim stvarnim argumentima se krije
informacija o broju i tipu neobaveznih srgumenata.

Standardno zaglavlje stdarg.h sadri skup definisanih makroa koje definiu kako se
prolazi kroz listu neformalnih argumenata. Tip va_list se koristi za deklarisanje
promenljive ap (skraeno od argument pointer) koja redom ukazuje na svaki neobavezni
argument funkcije.

va_list ap;

Makro va_start inicijalizuje pokazivaku promenljivu ap tako da pokazuje na prvi
neobavezni argument. Makro va_start se mora pozvati jedanput pre korienja
pokazivaa ap.

va_start(ap, indentifikator_poslednjeg_obaveznog_argumenta);
Svaki poziv makroa va_arg vraa jedan argument i pomera pokaziva ap na
naredni argument.

va_arg(ap, tip);

Na kraju makro va_end pretstavlja zavretak dohvatanja argumenata.

va_end(ap);

Primer:
Napisati C program koji demonstrira koriscenje funkcije zbir sa promenljivim
brojem argumenata. Funkcija zbir izraunava zbir uzastopnih celih argumenata i nakon
toga zbir uzastopnih racionalnih argumenata.

Reenje

#include <stdio.h>
#include <conio.h>
#include <stdarg.h>

/* Prototip funkcije sa promenljivim brojem argumenata. */
void zbir(unsigned brc, unsigned brr, int *s1, double *s2,...);

void main(void)
{
int s1=0;
double s2=0; /* Obratiti paznju sta ce se desiti da smo deklarisali s2 da je tipa float. */

textmode(3);
textcolor(15);
textbackground(0);
149
clrscr();

printf("\tDemonstracija funkcije sa promenljivim brojem argumenata!!\n");
zbir(4,3,&s1,&s2,1,2,3,4,2.5,3.4,1.2);
printf("\n\n\t1 + 2 + 3 + 4 = %d\n\t2.5 + 3.4 + 1.2 = %.2f",s1,s2);

/* Vidi se prilikom poziva da je razlicit broj argumenata u prvom i drugom pozivu
funkcije. */

zbir(5,8,&s1,&s2,5,4,3,3,2,3.1,2.5,1.7,2.8,4.2,2.1,1.1,3.3);
printf("\n\n\t5 + 4 + 3 + 3 + 2 = %d\n",s1);
printf("\t3.1 + 2.5 + 1.7 + 2.8 + 4.2 + 2.1 + 1.1 + 3.3 = %.2f",s2);

getch();
}

/* Definisanje funkcije sa promenljivim brojem argumenata. Funkcija mora sadrzati dva
formalna obavezna argumenta, gde ce jedan pretstavljati broj uzastopnih celih argumenata, a
drugi, broj uzastopnih racionalnih argumenata. */

void zbir(unsigned brc, unsigned brr, int *s1, double *s2,...)
{
unsigned i;

/* Deklarise se pokazivac ap na neobavezne argumente. */
va_list ap;

/* Pokazivacu ap se prosledjuje adresa poslednjeg obaveznog formalnog argumenta, a to
je *s2. */

va_start (ap,*s2);

/* Sa makroom va_arg pomeramo pokazivac ap na sledeci argument, navodeci mu tip
argumenta, kako bi znao gde da se pomeri. Vrsimo njegovo sabiranje. */

for(i=1;i<=brc;i++) *s1+=va_arg(ap,int );

/* Nakon sabiranja celih brojeva pokazivac ap se pozicionirao i pokazuje na prvi
sledeci racionalni argument. Nastavljamo sa sabiranjem ali sada uzastopnog niza
racionalnih argumenata. Vidi se da je jako vazno ispravno pozicioniranje pokazivaca ap, te
jako dobro moramo voditi racuna o tome gde se koji neobavezni argument nalazi i kog je
tipa. Napravila bi se velika greska da smo promenljivu s2 deklarisali kao float, jer se
vrednost neformalnog argumenta automatski iz float konvertuje u double. */

for(i=1;i<=brr;i++) *s2+=va_arg(ap,double );

/* Nakon zavrsetka prolaska kroz neobavezne formalne argumente, mora se to saopstiti
prevodiocu pozivom makroa va_end. */

va_end(ap);
}
150
















4.7. ZADACI IZ STRINGOVA

Zadatak 1 (2)
Napisati C program koji iz stringa datum zapisan u obliku: dan.mesec.godina
(09.12.1968 ili 9.12.1968) izdvaja podstringove dan, mesec i godina.

Zadatak 2 (2)
Aritmetiki izraz unet sa tastature zapisan je u stringu s. Napisati C program koji
utvruje broj pojavljivanja aritmetikih operatora (+,-,* i /) u izrazu.

Zadatak 3 (2)
Napisati funkciju koja iz stringa s brie svako pojavljivanje slova c. Funkcija vraa
0 ako slova c nema u stringu s ili broj izbrisanih slova iz stringa s.

Zadatak 4 (2)
Napisati C program koji u stringu s, svaku pojavu slova zapisane u promenljivoj c
zamenjuje slovom zapisane u promenljivoj d. Slovo koje se menja i slovo sa kojim se
vri zamena uneti sa tastature.
Za realizaciju zamene koristiti funkciju zameni koja vraa broj izvrenih zamena.
Na ekranu prikazati novonastali string, kao i broj izvrenih zamena.

Na primer:
c = n d = m
String = Mislin da ni je zadatak iz stringa dosao kao kec na deset.

Novi String = Mislim da mi je zadatak iz stringa dosao kao kec na deset.
Broj zamena = 2

Zadatak 5 (3)
Napisati funkciju koja vraa pokaziva na prvo pojavljivanje odreenog znaka c
s desne strane stringu s, ili NULL ako slova c nema u stringu s.
151

Zadatak 6 (2)
Napisati C program koji utvruje koliku u strigu s ima znakova interpunkcije: taka,
zarez, taka zarez, znak pitanja i znak uzvika. Za odreivanje pojave odreenog znaka
interpunkcije koristiti funkciju odredi. Na ekranu se prikazuje broj pojavljivanja onih
znakova interpunkcije kojih je bilo uopte u stringu.

Na primer:
String=Sta!! Ne svidja ti se zadatak, koji je pred tobom. Da li ga uraditi?

Znak Pojava
, 1
. 1
? 1
! 2
Zadatak 7 (2)
Napisati C program koji iz stringa s viestruki niz praznina zamenjuje sa samo
jednom prazninom.

Zadatak 8 (3)
Napisati funkciju dodaj koja korienjem pokazivaa (bez indeksa) vri
nadovezivanje stringa t na kraj stringa s.

Zadatak 9 (2)
Napisati funkcijju void umetni(char *s, int k, char *t); koja umee string t u string
s poev od pozicije k.

Zadatak 10 (5)
Napisati C program koji korienjem funkcije brisizagrade, iz stringa s uklanja
podstring koji se nalazi izmeu zagrada ukljuujui i same zagrade. Podstring se uklanja
iako sadri u sebi druge zagrade. Funkcija brisizagrade vraa broj izbrisanih
podstringova.

Zadatak 11 (3)
Napisati C program koji utvruje koliko rei ima u stringu s i transformie string s
tako to najduu i najkrau re pretvara u rei sa velikim slovima. Ako ima vie najduih
ili najkraih rei sve ih pretvoriti u velika slova. Pretvaranje malog slova u veliko
realizovati funkcijom malauvelika.

Zadatak 12 (4)
Napisati C program koji u stringu s prvo brie viestruke praznine, a potom svaku
re u stringu zamenjuje reju koja se dobija tako to se data re stringa zapisuje u istom
stringu ali u inverznom poretku. Za brisanje praznina koristiti funkciju brisipraznine, a
za transformaciju stringa funkciju inverznarec.

Na primer:
152
String = Mislim da mi je zadatak iz stringa dosao kao kec na deset.

Novi String = milsiM ad im ej katadaz zi agnirts osaod oak cek an tesed.

Zadatak 13 (3)
Napisati C program koji utvruje broj rei u stringu s unesenog sa tastature i brie
viestruke praznine u stringu. Za utvrivanje broja rei u stringu koristiti funkciju
brojreci, a za brisanje viestrukih praznina funkciju brisipraznine, koja vraa 0 ako nije
bilo viestrukih praznina u tekstu.

Na primer:
String = Mislim da mi je zadatak iz stringa dosao kao kec na deset.

Novi String = Mislim da mi je zadatak iz stringa dosao kao kec na deset.
Broj reci u stringu je: 12.
Zadatak 14 (3)
Napisati funkciju int strrindex(char *s, char *t); koja vraa krajnju desnu poziciju
u kojoj se string t nalazi u stringu s, ili -1 ukoliko se t ne pojavljuje u s. Napisati C
program koji demonstrira primenu funkcije strindex.

Zadatak 15 (3)
Napisati funkcijju int strend(char *s, char *t); koja vraa 1 ako se string t nalazi na
kraju stringa s, ili 0 ukoliko se t ne pojavljuje na kraju stringa s. Napisati C program koji
demonstrira primenu funkcije strend.


Zadatak 16 (3)
Napisati funkciju int brisistring(char *s, intk, int n); kojom se iz stringa s brie k
znakova poev od pozicije n. Ako od pozicije n do kraja stringa nema k znakova funkcija
vraa 0, a u suprotnom 1.

Zadatak 17 (4)
Napisati funkciju char *satoi(unsigned broj); koja celobrojni podatak broj pretvara
u string i vraa pokaziva na poetak stringa.

Zadatak 18 (4)
Napisati funkciju entab koja u stringu niz praznina zamenjuje minimalnim brojem
tabulatora i praznina da bi se postigao isti prazan prostor. Funkcija vraa broj koji
pokazuje za koliko je string manje duine od prvobitnog stringa i po referenci vraa
koliko string ima tabulatora a koliko praznina.

Zadatak 19 (4)
Napisati funkciju za ifrovanje i deifrovanje stringa. ifrovanje stringa se vri tako
to se svako slovo rei iz stringa kruno pomeri za k mesta udesno.

Zadatak 20 (3)
153
Napisati C program koji po izboru korisnika transformie rei koje se nalaze u
stringu s po sledeim pravilima:

1) Sve rei u stringu moraju poeti velikim slovom, a sva ostala malim slovom; ili
2) Sva slova koja su bila mala postaju velika, a slova koja su bila velika postaju
mala.
Svaka opcija mora biti realizovana posebnom funkcijom.

Na primer:
String = Mislim da MI je ZADATAK iz strINGA dosao KAo keC na DESET.

Ako korisnik izabere opciju:
1. Novi = Mislim Da mi Je Zadatak Iz stringa Dosao Kao Kec Na Deset.
2. Novi = mISLIM DA mi JE zadatak IZ STRinga DOSAO kaO KEc NA deset.

Zadatak 21 (4)
Napisati C program koji demonstrira primenu funkcije tokeni koja vraa koji se
prvi token pojavio u stringu s, pri emu su tokeni karakteri iz stringa t.

Zadatak 22 (4)
Napisati funkciju zbir koja vri sabiranje brojeva koji se nalaze u stringu s. Broj
moe uopteno biti realan (sadri decimalnu taku) i da ispred (bez praznina izmeu)
stoji znak broja.
Na primer:
String = Ako na -32.21 saberem 13.21 a potom dodam broj -21.2, ne znam sta bih
dobio. Pomozi mi druze!!
Zbir = -40.2

Zadatak 23 (4)
Napisati C program koji je zatien. Prilikom startovanja programa od korisnika
programa se trai da unese ifru i prikazano mu je sa oznakama *, koliko ifra ima
karaktera. Nakon unesene ifre, ako ifra nije ispravna korisnik dobija odgovarajuu
poruku o tome, a zatim se obavetava koji put po redu unosi ifru. Ima tri pokuaja da
pogodi koja je ifra. Ako ne pogodi iz tri pokuaja ispisae se odgovarajua poruka
praena zvunim signalom, a u sluaju da pogodi ifru odgovarajua poruka praena
drugim zvunim signalom.

Zadatak 24 (4)
Napisati C program koji umee string t (tj. re) ispred najdue rei iz stringa s. Ako
postoji vie najduih rei, string t umetnuti ispred rei koja je bila najblia poetku
stringa s. Za odreivanje pozicije u stringu s gde treba umetnuti string t koristiti funkciju
odredi, a za umetanje stringa t u string s funkciju umetni.

Na primer:
String = Mislim da mi je zadatak iz stringa dosao kao kec na deset.
Rec koja se umece = ovaj
154
Novi String = Mislim da mi je ovaj zadatak iz stringa dosao kao kec na deset.

Zadatak 25 (5)
Napisati C program kojim se unosi korektno zapisan izraz u jednoj liniji, a zatim
odreuje njegova vrednost. Operandi u izrazu su celi brojevi, a operatori mogu biti (+,-,*
i /) pri emu je / celobrojno deljenje. Pri odreivanju vrednosti izraza voditi rauna o
prioritetu operacija, i u izrazu je dozvoljeno korienje zagrada.

Zadatak 26 (5)
Dopuni prethodni zadatak koji je u stanju da rei sledee programske zahteve:
- Ako je izraz neispravno zapisan na izlazu prikazati re ERROR.
- Ako se oslobaamo zagrada, a rezultat u zagradi je negativan broj, negativan
broj ostaje u zagradi i zagrada e nestati tek nakon sledee operacije, ili ako je
to krajnji rezultat.
- Ako postoje zagrade koje su ispravno zapisane ali su viak potrebno ih je na
poetku programa izbrisati.

Zadatak 27 (5)
Napisati C program koji je u stanju da deifruje string s unesen sa tastature na
osnovu matrice. U stringu nema praznina, ve je praznina zamenjena sa donjom crticom.
Deifrovanje stringa se vri pomou matrice znakova.
Matrica se formira na osnovu stringa tako to je poznato koliko matrica ima vrsta,
tako to prvi karakter stringa pretstavlja broj vrsta matrice.
Karakteri iz stringa se u matricu upisuju kolona po kolona.
Prilikom deifrovanja stringa kree se od znaka koji se nalazi kao prvi element
matrice i prolazimo kolona po kolona s tim to svaka naredna kolona ima po: dva znaka
manje iz stringa koji je rezultat deifrovanja od prethodnog (ako je prethodni broj
znakova bio vei od 1, a ilo se od pune kolone prema koloni koja e imati jedan znak),
odnosno dva znaka manje u suprotnom.
Na primer:
ifrovani string = 5Ovaj_pdazoaaapk_kato_ce_mod_isbaogfc_iceglaveab!!

Matrica znakova:
O p a _ _ o b c g a
v d a k c d a _ .l b
a a a a e _ o i a !
j z p t _ i g c v !
_ o k o m s f e e

Deifrovani string = Ovaj zadatak ce mi doci glave!!

Zadatak 28 (5)
Napisati C program koji vri ifrovanje i deifrovanje stringa s. ifrovanje stringa
vri se tako to se svaka re stringa zarotira cirkularno za k mesta, a potom se svaki niz
praznina imeu rei zamenjuje sa brojem praznina u toj rei. Smatrati da u reima nema
155
drugih simbola osim malih ili velikih slova abecede. U stringu se osim slova abecede
mogu pojaviti i znakovi interpunkcije (. , ; ! ?).
Za realizaciju ifrovanja koristiti funkciju sifruj, a za deifrovanje funkciju
desifruj.

Zadatak 29 (5)
Napisati funkciju kompresija koja vri kompresiju stringa po sledeem pravilu
datom u primeru.
aabaab -> 2(aab) -> 2(2(a)b)
Funkcija kompresija vraa broj tipa double koji (na osnovu poetne i krajnje
duine) vraa procenat izvrene kompresije.

Zadatak 30 (5)
Napisati funkciju dekompresija koja vraa nastali string iz prolog zadatka u
prvobitan poloaj.

4.7. TESTOVI IZ VIEDIMENZIONALNIH NIZOVA I STRINGOVA

TEST 2
GRUPA 1

Zadatak 1
Napisati funkciju utvrdi koja utvruje da li je karakter slovo i vraa 1 ako jeste ili 0 u
suprotnom.

//Prototip funkcije
unsigned utvrdi(char c);

//Definisanje funkcije (dopuniti)
unsigned utvrdi(char c)
{


}

//Pozivanje fubkcije


Zadatak 2
Zadat je niz X od n elemenata koji je ve sortiran u opadajuem redosledu. Napisati
funkciju binarna_pretraga koja utvruje da li broja p ima u nizu i vraa 1 ako ga ima ili 0 u
suprotnom, a bonim efektom utvruje koliko je puta izvreno poreenje elemenata niza sa datim
brojem p.

//Prototip funkcije

//Definisanje funkcije (dopuniti)


156


//Pozivanje fubkcije

Zadatak 3
Napisati funkciju proizvod koja sadri promenljivi broj argumenata. Prvi argument
funkcije pretstavlja broj argumenata koji posle njega slede. Funkcija izraunava proizvod
argumenata funkcije poev od drugog argumenta.
//Prototip funkcije

//Definisanje funkcije (dopuniti)





//Pozivanje fubkcije
Zadatak 4
Kada se koriste hederi (moduli), gde se nalazi prototip funkcije, gde se vri definisanje
funkcije i kako i gde se vri pozivanje funkcije. Napiite funkciju formniz koja omoguava
formiranje niza X od n elemenata. Koristiti module.
//Prototip funkcije

//Definisanje funkcije (dopuniti)




//Pozivanje fubkcije

Zadatak 5
Napisati deo koda koji omoguava unos niza od n imena i njihovo sortiranje po abecednom
redosledu. Unos imena vriti korienjem funkcije unime iji je prototip:

char *unime(char *s);

//Unesite deo koda


Zadatak 6
Zadata je matrica A dimenzije nxn. Napisati deo koda koji vrste sa neparnim rednim
brojem sortira u rastuem redosledu, a vrste sa parnim rednim brojem u opadajuem redosledu.
Prilikom realizacije koristiti funkciju sort sledeeg prototipa:

void sort(int a[][30], int n, int j, int p);

pri emu:
- ako p ima vrednost 1 vri se sortiranje u rastuem redosledu, a ako p ima vrednost -
1 vri se sortiranje u opadajuem redosledu.
- j predstavlja indeks vrste koja se sortira.

157
//Napisati deo koda

Zadatak 7
Ako je zadata matrica A dimenzije nxn. Napisati deo koda programa koji koristei samo
jedan dvostruki ciklus (spoljanji je while, a unutranji for), omoguiti formiranje matrice B
dimenzije 2nx2n, koja se satoji od etirin zone (A1, A2, A3, A4). Zona A1 dobija se tako to je
svaki odgovarajui elemenat matrice A pomnoen sa brojem 2. Zonu A2 pretstavljaju elementi
matrice A. Zonu A3 pretstavljaju elementi matrice A umanjeni za broj jedan. Zonu A4
pretstavljaju elementi matrice A uveani za broj jedan.

B =
(
(
(

4 | 3
_ _ _
2 | 1
A A
A A


//Napisati deo koda
Zadatak 8
Napisati funkciju char *nadovezi(char *s, char *t); koja vri, bez korienja indeksa,
nadovezivanje stringa t na kraj stringa s.

//Prototip funkcije




//Definisanje funkcije (dopuniti)







//Pozivanje fubkcije

Zadatak 9
Napisati deo koda koji omoguava: inicijalizaciju stringa od 15 karaktera, unos stringa i
brisanje praznina i tabulatora iz stringa.
//Napisati deo koda





Zadatak 10
Napisati funkciju utvrdi koja utvruje da li rei r ima u stringu s. Funkcija vraa 1 ako se
re nalazi u stringu ili 0 u suprotnom.

//Prototip funkcije

158

//Definisanje funkcije (dopuniti)




//Pozivanje fubkcije



REENJA SA TESTA 2
GRUPA 1


Zadatak 1
Napisati funkciju utvrdi koja utvruje da li je karakter slovo i vraa 1 ako jeste ili 0 u
suprotnom.
//Prototip funkcije
unsigned utvrdi(char c);

//Definisanje funkcije (dopuniti)
unsigned utvrdi(char c)
{
if((c>=a&&c<=z)||(c>=A&&c<=Z)) return 1;
else return 0;
}

//Pozivanje funkcije
if(utvrdi(c)) printf(Karakter %c je slovo!!,c);
else printf(Karakter %c nije slovo!!,c);

Zadatak 2
Zadat je niz X od n elemenata koji je ve sortiran u opadajuem redosledu. Napisati
funkciju binarna_pretraga koja utvruje da li broja p ima u nizu i vraa 1 ako ga ima ili 0 u
suprotnom, a bonim efektom utvruje koliko je puta izvreno poreenje elemenata niza sa datim
brojem p.

//Prototip funkcije
unsigned binarna_pretraga(int x[], int n, int p, int *br);

//Definisanje funkcije (dopuniti)
unsigned binarna_pretraga(int x[], int n, int p, int *br)
{
unsigned donja=0, gornja=n-1, sredina, nadjen=0;
while(donja<=gornja && !nadjen)
{
sredina=(donja+gornja)/2;
(*br)++;
if(broj==niz[sredina]) nadjen=1;
else{
if(broj<niz[sredina]) gornja=sredina-1;
159
else donja=sredina+1;
}
}
if(!nadjen) return 0;
else return 1;

//Pozivanje funkcije
k=binarna_pretraga(x,n,p,&br);
if(k) printf(Nadjen je broj %d u nizu i vrsilo se %d poredjenja!!,p,br);
printf(Nije nadjen je broj %d u nizu i vrsilo se %d poredjenja!!,p,br);

Zadatak 3
Napisati funkciju proizvod koja sadri promenljivi broj argumenata. Prvi argument
funkcije pretstavlja broj argumenata koji posle njega slede. Funkcija izraunava proizvod
argumenata funkcije poev od drugog argumenta.
//Prototip funkcije
int proizvod(int n, );
//Definisanje funkcije (dopuniti)
int proizvod(int n, )
{
int p,i;
va_list pok;
va_start(pok,n);
for(p=1, i=1;i<=n;i++) p*=va_arg(pok, int);
va_end(pok);
return p;
}

//Pozivanje fubkcije
pro=proizvod(5,2,3,4,1,8);

Zadatak 4
Kada se koriste hederi (moduli) gde se nalazi prototip funkcije, gde se vri definisanje
funkcije i kako i gde se vri pozivanje funkcije. Napiite funkciju formniz koja omoguava
formiranje niza X od n elemenata. Koristiti module.
//Prototip unkcije i definisanje funkcija nalaze se u hederu, a pozivanje funkcije vrsi
//se u glavnom programu. Heder se preko direktive pretprocesora ukljucuje u glavni
//program. Heder je fajl sa ekstenzijom H.

//Prototip funkcije
void formniz(int x[], int n);

//Definisanje funkcije (dopuniti)
void formniz(int x[], int n)
{
unsigned i;
for(i=0;i<n;i++) scanf(%d,&x[i]);
}

//Pozivanje funkcije
formniz(x,n);
160

Zadatak 5
Napisati deo koda koji omoguava unos niza od n imena i njihovo sortiranje po abecednom
redosledu. Unos imena vriti korienjem funkcije unime iji je prototip:
char *unime(char *s);
//Unesite deo koda
char *ime[30], *pom=;
for(i=0;i<n;i++) gets(ime[i]);

for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(strcmp(ime[j],ime[i])<0)
strcpy(pom,ime[i]), strcpy(ime[i],ime[j]), strcpy(ime[j],pom);
}
}
Zadatak 6
Zadata je matrica A dimenzije nxn. Napisati deo koda koji vrste sa neparnim rednim
brojem sortira u rastuem redosledu, a vrste sa parnim rednim brojem u opadajuem redosledu.
Prilikom realizacije koristiti funkciju sort sledeeg prototipa:

void sort(int a[][30], int n, int j, int p);

pri emu:
- ako p ima vrednost 1 vri se sortiranje u rastuem redosledu, a ako p ima vrednost -
1 vri se sortiranje u opadajuem redosledu.
- j pretstavlja indeks vrste koja se sortira.


//Napisati deo koda
for(i=0;i<n;i++)
{
ff(i & 0x1) sort(a,n,i,-1);
else sort(a,n,i,1);
}
Zadatak 7
Ako je zadata matrica A dimenzije nxn. Napisati deo koda programa koji koristei samo
jedan dvostruki ciklus (spoljanji je while, a unutranji for), omoguiti formiranje matrice B
dimenzije 2nx2n, koja se satoji od etirin zone (A1, A2, A3, A4). Zona A1 dobija se tako to je
svaki odgovarajui elemenat matrice A pomnoen sa brojem 2. Zonu A2 pretstavljaju elementi
matrice A. Zonu A3 pretstavljaju elementi matrice A umanjeni za broj jedan. Zonu A4
pretstavljaju elementi matrice A uveani za broj jedan.

B =
(
(
(

4 | 3
_ _ _
2 | 1
A A
A A


//Napisati deo koda
161
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
b[i][j]= 2*a[i][j];
b[i][n+j]= a[i][j];
b[n+i][j]= a[i][j]-1;
b[i][j]= 2*a[i][j]+1;
}
}

Zadatak 8
Napisati funkciju char *nadovezi(char *s, char *t); koja vri bez korienja indeksa
nadovezivanje stringa t na kraj stringa s.

//Prototip funkcije
char *nadovezi(char *s, char *t);
//Definisanje funkcije (dopuniti)
char *nadovezi(char *s, char *t)
{
while(*s++);
while(*t++) *s++=*t;
*s=\0;
}
//Pozivanje fubkcije
printf(Nadovezani string je %s.,nadovezi(s,t));

Zadatak 9
Napisati deo koda koji omoguava: inicijalizaciju stringa od 15 karaktera, unos stringa i
brisanje praznina i tabulatora iz stringa.
//Napisati deo koda
char s[16]=;
gets(s);
i=0;
while(s[i]!=\0)
{
if(s[i]==\t || s[i]== )
{
j=i;
while(s[j+1]!=\0) s[j]=s[j+1], j++;
s[j]=\0;
}else i++;
}

Zadatak 10
Napisati funkciju utvrdi koja utvruje da li rei r ima u stringu s. Funkcija vraa 1 ako se
re nalazi u stringu ili 0 u suprotnom.
//Prototip funkcije
unsigned utvrdi(char *s, char *r);

//Definisanje funkcije (dopuniti)
162
int utvrdi(char s[], char r[])
{
int i=0,j=0,k;
while(s[i]!='\0')
{
while(s[i]==' '||s[i]=='\t'&&s[i]!='\0'&&(s[j]=='.'||
s[j]==','||s[j]=='?'||s[j]=='!'||s[j]==' '||s[j]=='\t')) i++;
if(s[i]!='\0')
{
j=i, k=0;
while(r[k]!='\0'&&s[j]!='\0'&&s[j]==r[k]&&s[j]!='.'&&s[j]!=','&&
s[j]!='?'&&s[j]!='!'&&s[j]!=' '&&s[j]!='\t') j++, k++;
if(r[k]=='\0') return 1;
if(s[j]=='\0') return 0;
}
i++;
}
return 0;
}

//Pozivanje funkcije
if(utvrdi(s,rec)) printf(Rec %s se nalazi u ulaznom stringu.);
else printf(Reci %s nema u ulaznom stringu.);

TEST 2
GRUPA 2


Zadatak 1
Napisati funkciju utvrdi koja utvruje da li je karakter veliko slovo i vraa 1 ako jeste ili 0
u suprotnom.
//Prototip funkcije
unsigned utvrdi(char c);

//Definisanje funkcije (dopuniti)
unsigned utvrdi(char c)
{




}

Zadatak 2
Napisati funkciju boubble_sort koja vri sortiranje dela niza X od n elemenata izmeu
indeksa k i p u opadajuem redosledu. Prilikom pozivanja funkcije omoguiti potreban broj
pozivanja tako da se posebno sortira prva polovina, a posebno druga polovina niza (obe u
opadajuem redosledu). Prva polovina niza ima manje ili jednak broj elemenata sa drugom
polovinom niza.

//Prototip funkcije
163

//Definisanje funkcije (dopuniti)





//Pozivanje fubkcije


Zadatak 3
Napisati rekurzivnu funkciju zbir koja omoguava izraunavanje zbira prvih n prirodnih
projeva. Koristiti rekurzivnu formulu
S(n) = n + S(n-1)
//Prototip funkcije


//Definisanje funkcije (dopuniti)




//Pozivanje fubkcije

Zadatak 4
Napisati funkciju meni sa promenljivim brojem argumenata. Prvi argument je broj opcija,
a ostali argumenti su opcije. Funkcija vraa redni broj najdue opcije.
//prototip funkcije
unsigned meni(unsigned vropc, char *text, );

//Definisanje funkcije (dopuniti)




//Pozivanje fubkcije


Zadatak 5
Napisati deo koda koji omoguava unos niza imena i njihovo sortiranje na osnovu duine
stringa u opadajuem redosledu, a potom prikazati imena (svako ime u novom redu). Svako ime
moe imati najvie 20 karaktera. Unos imena vriti korienjem funkcije unime iji je prototip
char *unime(char *s);

//Unesite deo koda






164


Zadatak 6
Zadata je matrica A dimenzije nxn. Napisati deo koda koji vrste sa neparnim rednim
brojem sortira u rastuem redosledu, a vrste sa parnim rednim brojem u opadajuem redosledu.
Prilikom realizacije koristiti funkciju sort sledeeg prototipa:

void sort(int a[][30], int n, int j, int p);

pri emu:
- ako p ima vrednost 1 vri se sortiranje u rastuem redosledu, a ako p ima vrednost -
1 vri se sortiranje u opadajuem redosledu.
- j pretstavlja indeks vrste koja se sortira.

//Napisati deo koda


Zadatak 7
Napisati deo programa koji omoguava formiranje niza B na osnovu celobrojne matrice A
dimenzija mxm. Pravilo formiranja je da je i-ti elemenat niza B zbir elemenata sa i-te dijagonale
matrice A. Prvi lan je zbir elemenata sa glavne dijagonale, drugi lan je zbir elemenata sa
dijagonale koja je paralelna glavnoj dijagonali, kree ispod glavne dijagonale (sa prve kolone i i-
te vrste) a kada doe do poslednje vrste nastavlja se sa sabiranjem u gornjem trouglu
odgovarajue dijagonale, itd
//Napisati deo koda






Zadatak 8
Napisati funkciju koja vraa adresu prvog pojavljivanja znaka c u stringu s ili NULL u
suprotnom.
//Prototip funkcije


//Definisanje funkcije (dopuniti)





//Pozivanje fubkcije


Zadatak 9
Napisati deo koda koji omoguava unos vremena u obliku stringa HH:MM:SS i pretvara
vreme u sekunde.
//Napisati deo koda

165





Zadatak 10
Napisati funkciju odredi koja odreuje i vraa broj rei u stringu s. Prilikom realizacije
funkcije ne smeju se koristiti pomone (lokalne) promenljive.
//Prototip funkcije


//Definisanje funkcije (dopuniti)




//Pozivanje fubkcije
TEST 2
GRUPA 3


Zadatak 1
Napisati funkciju koja vri zatitu alfanumerikog znaka bitom parnog pariteta i vraa
kodirani znak.
//Prototip funkcije
char zastita(char c);

//Definisanje funkcije (dopuniti)
char zastita(char c)
{



}

//Pozivanje fubkcije

Zadatak 2
Zadat je niz X od n elemenata. Napisati funkciju sekvencijalna_pretraga koja utvruje da
li broja p ima u nizu X i vraa pokaziva na prvu pojavu broja p posmatrano od kraja niza, ili
NULL ako broja nema u nizu.
//Prototip funkcije

//Definisanje funkcije (dopuniti)




//Pozivanje funkcije

Zadatak 3
166
Simulacijom praenja promenljivih sa steka prilikom izvravanja sledeeg programa koji
poziva rekurzivnu funkciju fun. Utvrditi ta program radi, kao i ta e biti ispisano na ekranu.

#include <stdio.h>
#include <conio.h>

int fun(int m, int x[]);

void main(void)
{
int x[30]={3,1,5,2,4},i, n=5;
textbackground(0);
textcolor(15);
clrscr();
printf("Rez = %d",fun(n-1,x));
getch();
}
int fun(int m, int x[])
{
if(m>=0&&x[m]>0) return x[m]*fun(m-1,x);
else return 1;
}

//Npisati odgovor





Zadatak 4
Zadata je matrica A dimenzije mxn. Napisati deo koda programa koji utvruje koliko
elemenata matrice A ima vrednost nula.
//Napisati deo koda.




Zadatak 5
Napisati funkciju koja omoguava ispis celobrojnog niza X od n elemenata. Elementi niza
X imaju najvie etiri cifre. Omoguiti da se niz ispisuje tabelarno red po red, pri emu u jednom
redu moe biti najvie 10 lanova niza, a izmeu njih minimalno dva prazna mesta razmaka.
Funkciju smestioti u heder NIZ.H Glavni program se nalazi u PRIM.C

//NIZ.H (Napisati osnovno sta se nalazi a vezano je za funkciju)







167

//PRIM.C (Napisati osnovno sta se nalazi a vezano je za funkciju)








Zadatak 6
Niz stringova niz od n elemenata, pretstavljaju celi brojevi. Napisati deo koda koji
omoguava izraunavanje zbira tih brojeva.

//Unesite deo koda


Zadatak 7
Napisati deo koda koji omoguava da se svaki karakter u stringu s koji pretstavlja malo
slovo zameni velikim slovom, a karakter koji pretstavlja veliko slovo zameni malim slovom.
Ostali karakteri ostaju nepromenjeni. String s ima najvie 15 karaktera.
//Napisati deo koda





Zadatak 8
Ako je zadata matrica A dimenzije nxm. Napisati funkciju izbaci koja omoguava
izbacivanje one vrste iz matrice koja ima najvei zbir i ujedno najvei indeks. Prilikom realizacije
funkcije koristiti poziv funkcije vrsta koja vraa indeks one vrste koja ima najvei zbir i ujedno
najvei indeks. Prototip funkcije vrsta je:

unsigned vrsta(int a[][MAX], int *k, int *p);
- k je broj vrsta, a p je broj kolona matrice A

//Prototip funkcije
void izbaci(int a[][MAX], int m, int *n);

//Definisanje funkcije (dopuniti)





//Pozivanje fubkcije

Zadatak 9
Napisati funkciju utvrdi koja bez korienja indeksa utvruje broj tabulatora u stringu s.
//Prototip funkcije

168
//Definisanje funkcije (dopuniti)





//Pozivanje funkcije

Zadatak 10
Napisati funkciju pretvori koja vri pretvaranje celobrojne promenljive p (moe biti i
negativan broj) u string s. Funkcija vraa pokaziva na poetak stringa.
//Prototip funkcije


//Definisanje funkcije (dopuniti)



169










5
5. . P PO OG GL LA AV VL LJ J E E



T TE EK KS ST TU UA AL LN NE E D DA AT TO OT TE EK KE E
170


5.1. DEFINICIJA DATOTEKE, PODELA DATOTEKA

Definicija:
Datoteka je osnovna logika jedinica u pogledu zapisa informacija na
jedinicama masovne memorije.

Za unos velikog obima podataka u programu ne koristimo ulaz sa tastature ve iz
datoteke (to takoe vai i u sluaju izlaza).

Prema nainu smetanja podataka, postoje dve vrste datoteka:
- tekstualne datoteke, i
- binarna datoteke.

Tekstualne datoteke sastoje se od niza znakova koji je znakovima za prelazak u
novi red ('\n') podeljen u redove. Binarne datoteke sastoje se od niza bajtova iji je
sadraj verna slika naina predstavljanja podataka u memoriji. U toku prenosa ne
primenjuje se konverzija, ve se vri prosto prenoenje podataka bajt po bajt. Podela
tekstualnih datoteka u redove je logika, a ne fizika organizacija. Tekstualne datoteke su
samo dugaki niz znakova (bajtova).

Pri radu sa datotekama postoje sledee radnje:
- pravljenje datoteke
- otvaranje datoteke,
- pristup datoteci,
- ispitivanje stanja datoteke, i
- zatvaranje datoteke.

Otvaranje datoteke slui za uspostavljanje veze sa fizikom datotekom. Tom
prilikom stvara se u memoriji odreena struktura podataka koja omoguava efikasan
pristup datoteci u toku rada. Ta struktura sadri odreene podatke o trenutnom stanju
datoteke. Pristupom datoteci realizuje se prenos podataka u datoteku ili iz datoteke sa ili
bez konverzije u toku prenosa. Ispitivanjem stanja datoteke mogu da se dobiju
informacije o eventualnim grekama koje su nastale u toku prenosa podataka. Zatvaranje
datoteke je zavrna radnja kojom se raskida veza sa fizikom datotekom. Tom prilikom
ponitavaju se strukture podataka stvorene prilikom otvaranja datoteke.
Opisane radnje mogu se ostvariti samo pod odreenim uslovima:
- Funkcije za rad sa datotekama tretiraju datoteku kao sekvencijalni niz
karaktera.
- Datotekama se pristupa pomou pokazivaa na sistemsku strukturu u
oznaci FILE. Struktura FILE je definisana u datoteci zaglavlja stdio.h, a
sadri lanove koji opisuju tekue stanje datoteke.
- U datoteci zaglavlja su definisane dve simbolike konstante:
171
Konstanta EOF (End of file) koja definie oznaku kraja datoteke i
prema inicijalizaciji u datoteci zaglavlja ima vrednost -1.
Konstanta NULL koja oznaava neuspeno izvravanje nekih
funkcija za upravljanje datotekama ija je vrednost 0 definisana u
datoteci zaglavlja stdio.h.
- Standardizovane funkcije koriste bafer odakle itaju ili upisuju podatke.
Kad se bafer napuni njegov sadraj se prebacuje na datoteku. Kad se bafer
isprazni njegov sadraj se popunjava iz datoteke. Korienjem bafera
smanjuje se broj pristupa datoteci. Standardizovane funkcije su: fopen(),
fgetc(), fputc(), fprintf(), fscanf(), fgets(), fputs(), feof(), fclose(), ftell(),
fseek(), rewind(), fread() i fwrite().

Za svaku datoteku koja se koristi u programu mora da postoji pokaziva na podatak
tipa FILE. Neka je to pokaziva pod nazivom dat, njegova deklaracija je:

FILE *dat;

Na osnovu deklaracije pokazivaa dat saoptava se prevodiocu da je dat pokaziva
(ispred dat nalazi se *) koji moe da sadri adresu podatka tipa FILE. On trenutno ne
pokazuje na strukturu jer strukture trenutno nema.


























172



5.2. OTVARANJE I ZATVARANJE DATOTEKE



Datoteka pre bilo kakve obrade mora biti otvorena. To se postie funkcijom
fopen(). Funkcija fopen otvara navedenu datoteku i vraa pokaziva na tu datoteku (tip
FILE), a ako doe do greke funkcija vraa vrednost NULL. Prototip funkcije fopen je:

FI LE fopen(const char *ime_staze, const char *access_mode);

ime_staze- je niz znakova koji sadri kompletnu stazu do navedene datoteke.
access_mode - odreuje nain pristupa datoteci. Dozvoljene vrednosti za
access_modesu:

"r" - otvara tekstualnu datoteku samo za itanje.
"w" - otvara tekstualnu datoteku samo za pisanje, odbacujui postojei sadraj
ako postoji bez opomene, ili kreirajui datoteku ako ona ne postoji.
"a" - otvara tekstualnu datoteku za pisanje, dodajui nove elemente na njen
kraj, ili stvarajui potpuno novu datoteku ako je nema.
"r+" - otvara tekstualnu datoteku za auriranje, itanje i pisanje, postavljajui
pokaziva na poetak datoteke.
"w+" - otvara tekstualnu datoteku za auriranje, itanje i pisanje, odbacujui
postojei sadraj ako postoji, ili kreira datoteku ako ona ne postoji.
"a+" - otvara tekstualnu datoteku za auriranje, itanje i pisanje, dodajui nove
elemente na njen kraj, ili stvara novu datoteku ako je nema.
Reimi otvaranja datoteka: "rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b",
"ab+", "a+b" imaju istu sematiku kao i prethodno opisani naini, sa jednom razlikom
to oznaka b upuuje na binarni umesto tekstualnog reima pristupa datoteci.

Na primer:

FILE *dat;
dat = fopen("primer.txt","r");

Nakon poziva funkcije fopen(); pokaziva dat kaemo da pokazuje na datoteku, ali
on u sutini ne pokazuje na stvarnu datoteku, ve na strukturu FILE.

Struktura FILE sadri lanove:
- pokaziva na prihvatnu memoriju (bafer);
- broj bajtova, koje treba preneti;
- poetnu adresu prihvatne memorije;
- stanje indentifikastora; i
173
- brojna oznaka datoteke.
U ovom primeru deklaracijom pokazivaa dat saopteno je prevodiocu da je dat
pokaziva koji e sadrati u sebi adresu promenljive tipa FILE. Nakon poziva funkcije
fopen(), funkcija fopen() trai datoteku primer.txt na direktorijumu gde se nalazi exe fajl
naeg programa. Ako ga nae formirae strukturu tipa FILE u ZONI PODATAKA,
upisae brojnu oznaku datoteke, poetnu adresu prihvatne memorije i inicijalizovae
pokaziva na prihvatnu memoriju. Nakon popunjavanja strukture pokazivau dat bie
prosleena adresa strukture u ZONI PODATAKA. Druge funkcije e kasnije koristiti
strukturu preko pokazivaa dat, kako bi na osnovu poetne adrese prihvatne memorije i
pokazivaa na prihvatnu memoriju smetale podatke na prihvatnu memoriju.

Zatvaranje datoteke vri se funkcijom fclose(); iji je prototip:

int fclose(FI LE *dat);

Zatvaranje jedne datoteke znai da se prekida veza, koja postoji izmeu pokazivaa
na datoteku i imena datoteke, tj pokazivaa na strukturu koji dobija vrednost NULL.
Prilikom izvravanja funkcije fclose, a pre prekidanja veze izmeu pokazivaa na
datoteku i imena datoteke, dolazi do ispisivanja sadraja prihvatne memorije u datoteku.
Funkcija vraa vrednost 0 u sluaju uspenog zatvaranja datoteke, ili EOF u sluaju
otkrivanja greaka.
Zavretak izvravanja programa dovodi do automatskog zatvaranja svih otvorenih
datoteka. Programi rade optimalnije kada ima otvoreno manje datoteka(od 10 do 20
datoteka). Zatvorenoj datoteci ne moemo pristupiti bez ponovnog otvaranja.

Primer:
Napisati deo koda koji omoguava definisanje pokazivaa na datoteku, a potom
omoguiti otvaranje datoteke PRIMER.TXT za itanje. Ako datoteka nije uspeno
otvorena prikazati odgovarajuu poruku.

Reenje:

FILE *dat;

if((dat = fopen("primer.txt","r")==NULL)
{
printf("Datoteka primer.txt ne moze biti otvorena!!");
return;
}

fclose(dat);





174



5.3. ZNAKOVNO USMERENI ULAZ I IZLAZ


Funkcijama za prenos znakova vri se itanje ili pisanje pojedinanih znakova ili
nizova znakova bez konverzije. Sada e biti prikazani prototipovi i opisi nekih od
funkcija:

int fgetc( FI LE *dat);

dat - je pokaziva na datoteku koji je dobijen kao rezultat funkcije fopen();

Funkcija fgetc(); ita znak iz navedene datoteke, vraa znak i pomera se na sledei
znak u datoteci. Ako je uspeno obavila zadatak, funkcija e vratiti znak iz datoteke koji
je bio na redu za itanje. Ako doe do greke ili kraja datoteke, bie vraena vrednost
EOF.

int fputc(int character, FI LE *dat);

character - je znak koji se upisuje u datoteku
dat - je pokaziva na datoteku koji je dobijen kao rezultat funkcije fopen();

Funkcija fputc(); upisuje znak u datoteku. Ako funkcija uspeno obavi svoj zadatak,
bie vraen znak koji je upisan u datoteku, inae, bie vraena vrednost EOF.


char *fgets(char *buffer, int max_char, FI LE *dat);

buffer - je poetna adresa bafera u koji funkcija smeta proitane znakove.
max_char - je vrednost kojom odreujete maksimalan broj znakova koje treba
proitati iz datoteke.
dat - je pokaziva na datoteku koji je dobijen kao rezultat funkcije fopen();

Funkcija fgets(); ita niz znakova iz navedene datoteke. Funkcija moe da proita
maksimalno max_char - 1 znakova ili do pojave znaka za novi red '\n' (koga ne stavlja u
string promenljivu buffer) i iza proitanih znakova doda znak '\0'.
Ako funkcija uspeno obavi svoj zadatak bie vraen pokaziva na niz proitanih
znakova (buffer). Ako doe do greke ili kraja datoteke, bie vraena vrednost NULL.


int fputs(char *buffer, FI LE *dat);

dat - je pokaziva na datoteku koji je dobijen kao rezultat funkcije fopen();
buffer - je niz znakova koji treba upisati u datoteku.
175

Funkcija fputs(); upisuje znakovni niz u odreenu datoteku


int ungetc(int character, FI LE *dat);

dat - je pokaziva na datoteku koji je dobijen kao rezultat funkcije fopen();
charakter - je znak koji treba biti vraen u datoteku, kako bi taj znak bio vraen pri
sledeem itanju.

Funkcija ungetc(); dodaje znak nazad u datoteku. Znak EOF se ne moe dodati
nazad. Funkcija vraa znak koji je dodat nazad ili EOF u sluaju greke.


int feof(FI LE *dat);

dat - je pokaziva na datoteku koji je dobijen kao rezultat funkcije fopen();

Funkcija feof(); testira indikator kraja datoteke i daje kao rezultat vrednost razliitu
od nule, ukoliko je dostignut kraj datoteke, inae e biti vraena vrednost nula.


int fflush(FI LE *dat);

dat - je pokaziva na datoteku koji je dobijen kao rezultat funkcije fopen();

Funkcija fflush(); brie sadraj izlaznog bafera ili brie sadraj ulaznog bafera. Ako
je funkcija uspeno obavila zadatak bie vraena vrednost nula, inae, funkcija e vratiti
vrednost EOF.

Primer 1:
Napisati C program koji u tekstualnoj datoteci PRIMER.TXT utvruje koliko se
puta uitani znak sa tastature pojavljuje u datoteci.

Reenje

#include <stdio.h>
#include <conio.h>


void main(void)
{
char c, e;
unsigned br=0;
FILE *dat;

textmode(3);
176
textcolor(15);
textbackground(0);
clrscr();

printf("\n\tZnak koji se posmatra> ");
c=getche();

if((dat=fopen("PRIMER.TXT","r"))==NULL)
printf("\n\n\tDatoteka PRIMER.TXT se ne moze otvoriti!!!");
else{
printf("\n\n\n\tDatoteka PRIMER.TXT je uspesno otvorena!!");
while((e=fgetc(dat))!=EOF)
{
if(e==c) br++;
}
fclose(dat);
printf("\n\n\tU datoteci se znak %c pojavio %d puta.",c,br);
}

gotoxy(1,25);
getch();
}


Primer 2:
Napisati C program koji u tekstualnoj datoteci PRIMER.TXT jedan znak
zamenjuje drugim znakom. Znak kojeg treba zameniti i znak sa kojim se vri zamena
uneti sa tastature.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>

#define DUZINA_LINIJE 81 /* Za jedan je vise od 80 zbog kraja stringa '\0' */

void sredi(char *s, char c, char d);

void main(void)
{

char c[81*25],d,e,*s1, *s2[DUZINA_LINIJE],*pom=c;
unsigned i,j;

FILE *dat;

for(i=0;i<DUZINA_LINIJE;i++) s2[i]=NULL;
s2[0]=pom;

177
textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\n\tUnesite znak koji se menja> ");
c=getche();

printf("\n\tUnesite znak sa kojim se vrsi zamena> ");
d=getche();

if((dat=fopen("PRIMER.TXT","r"))==NULL)
{
printf("\n\n\tDatoteka PRIMER.TXT se ne moze otvoriti!!!");
return;
}


printf("\n\n\n\tDatoteka PRIMER.TXT je uspesno otvorena!!");
i=0;
while(fgets(s1,DUZINA_LINIJE-1,dat)!=NULL)
{
sredi(s1, c, d);
strcpy(s2[i],s1);
if(i!=0) s2[i]=s2[i-1]+strlen(s2[i-1])+1;
i++;
}
fclose(dat);

dat=fopen("PRIMER.TXT","w");

for(j=0;j<i;j++) fputs(s2[j],dat); /* Upis niza stringova u datoteku. */

fclose(dat);

gotoxy(1,25);
getch();
}


/* Funkcija u stringu s menja svaku pojavu znaka c sa znakom d. */

void sredi(char *s, char c, char d)
{
unsigned i;

i=0;
while(s[i]!='\0'&&s[i]!='\n')
{
if(s[i]==c) s[i]=d;
i++;
178
}
}

Primer 3:
Napisati C program koji iz zadate tekstualne datoteke ekstrahuje i prikazuje
ispravno zapisane datume. Svaki red datoteke DATUMI.TXT sastoji se od samo jednog
datuma. Datum se smatra ispavno zapisan ako je u obliku:

datum = dan separator mesec separator godina
separator = {. | / | -}
dan = {01...09...31 | 1...31}
mesec = {01...09...12 | 1...12}
godina = {00...99 | 1...2999}

DATUMI.TXT (Izgled test datoteke)

28.03.2002
29.2.02
13/1/99
15-6-78
31/9/1000
55/6/4000
1/1/3000
28.2.2000
29.2.2000
12.05/2003

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 81
void main (void)
{
FILE *dat;
unsigned i;
char c, *p=NULL, s[MAX], string[MAX]="";
unsigned dan, mesec, godina;

dan=mesec=godina=0;

clrscr();

if ((dat=fopen("DATUMI.TXT","r"))!=NULL)
{
179
do {
string[0]='\0';

/* Sve podatke iz datoteke smestamo u string. */

i=0;
do {
string[i++]=fgetc(dat);
}while (string[i-1]!='\n'&& string[i-1]!=EOF);

/* U ovom delu programa koristi se funkcija strtok. Niz poziva funkcije
strtok(p,str); deli string p u tokene koji su medjusobno razdvojeni nekim
znakom iz stringa str. Prvi poziv u tom nizu poziva, ima string p koji nije
jednak NULL. On pronalazi prvi token u p koji se sastoji od znakova koji
ne pripadaju stringu str, i zavrsava rad upisujuci znak \0 preko
narednog znaka stringa p i vraca pokazivac na taj token. Svaki naredni
poziv odredjen vrednoscu NULL za p, vraca sledeci takav token, trazeci
ga od pozicije koja se nalazi odmah iza prethodnog tokena. Funkcija
strtok vraca NULL kada nijedan dalji token nije pronadjen. String str
moze biti razlicit u svakom pozivu. */


if (string[i-1]=='\n')
{

/* Kraj reda se u datotekama obelezava znakom '\n', a kraj
stringa sa '\0' */

string[i]='\0';
strcpy(s,string);

/* Sada se pomocu funkcije strtok iz stringa p odvaja deo stringa
sve do prvog znaka koji moze biti znak '/' ili znak
'-'. Funkcija vraca pokazivac na string p. Funkcijom atoi se
string konvertuje u broj, sto pretstavlja dan. */

p=strtok(s,"./-");
/* U promenljivoj c pamti se prvi separator. Oba separatora
moraju biti ista. */

i=strlen(p);
c=string[i];
dan=atoi(p);

if (dan>0 && dan <32)
{
/* Iz preostalog stringa se izvlaci sledeci string do
pojave nekog od znakova '/' ili '-'. Taj deo stringa
pretstavlja mesec. */

p=strtok(NULL,"./-");
180
i+=strlen(p)+1;
mesec=atoi(p);

if (mesec>0 && mesec<12 && string[i]==c)
{
/* Sledeci deo stringa je godina. */

p=strtok(NULL,"./-\n");
godina=atoi(p);
if (godina>0 && godina<2999)
{
if (((mesec==1||mesec==3||mesec==5
||mesec==7||mesec==8||mesec==10
||mesec==12) && (dan < 32)) ||
((mesec==4||mesec==6||mesec==9
||mesec==11) && (dan < 31)) ||
((mesec==2) && (dan<30)
&& (!(godina%4)
&& (godina%400) ||
((mesec==2)&&(dan<29)))))
printf("%s",string);
}
}
}
}

/* Radi lakseg otklanjanja gresaka pokazivac se uvek pre ponovnog
koriscenja mora inicijalizovati. */

p=NULL;
}while(string[i-1]!=EOF);

/* Datoteka se uvek mora zatvoriti. */
fclose(dat);

}else printf("\nNemoguce je otvoriti datoteku DATUMI.TXT\a");

printf("\nPritisnite bilo koji taster za zavrsetak programa..");
getch();
}










181



5.4. ARGUMENTI IZ KOMANDNE LINIJE

Operativni sistem koji podrava razvoj softvera u programskom jeziku C
omoguava i prenos parametara u glavni program, kao da je u pitanju komanda
operativnog sistema. Formalno posmatrano, svaki program kreiran u C jeziku se sa nivoa
komandnog poziva operativnog sistema poziva kao funkcija sa dva argumenta. Prvi
argument je argc koji specificira broj argumenata (broj nizova karaktera) prenetih sa
komandne linije u funkciju main() i uvek je celobrojna vrednost. Drugi argument koji se
naziva argv specificira vrednosti pomou niza pokazivaa na stringove, koji u sutini
predstavljaju argumente funkcije main(). Argc uvek ima poetnu vrednost 1, jer prvi
element niza argv pokazuje na ime programa.

Zaglavlje main() funkcije ima sledei izgled:

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

Funkcija main() kao prvi argument ima indentifikator tipa int (ne mora ime
indentifikatora biti argc), a kao drugi argument indentifikator tipa niza pokazivaa na
stringove (ne mora ime indentifikatora biti argv).
Ako se program PRIMER.EXE dobijen linkovanjem PRIMER.C ili PRIMER.CPP
izvornog koda programa, startuje iz komandne linije naredbom:

C:\TC\BIN>PRIMER A:\PRIMER1.TXT A:\PRIMER2.TXT

Vrednosti argumenata funkcije main() su:
argc: 3
argv: "PRIMER", "A:\PRIMER1.TXT", "A:\PRIMER2.TXT"
Argument argc ima vrednost 3 jer se niz stringova argv sastoji od tri stringa.
argv[0]: PRIMER
argv[1]: A:\PRIMER1.TXT
argv[2]: A:\PRIMER2.TXT

U ovom primeru navedene su putanje datoteka PRIMER1.TXT i PRIMER2.TXT,
ali ako se ne navedu podrazumeva se da se datoteke nalaze na trenutno aktivnom
direktorijumu.

Primer 1:
Napisati C program koji izraunava zbir brojeva zapisanih u tekstualnim
datotekama. Brojevi su realni i svaki broj nalazi se zapisan u novom redu tekstualne
datoteke. Omoguiti unos datoteka iz komandne linije. Utvrditi koja datoteka ima najvei
zbir. Ukoliko doe do greke prilikom otvaranja datoteke, ispisati poruku koja datoteka
nije uspeno otvorena.

182

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

float zbir(FILE *dat);

void main(int argc, char *argv[])
{
FILE *dat;
unsigned i, k;
float s, smax;

textmode(3), textbackground(0), textcolor(15), clrscr();

for(i=1;i<argc;i++)
{
if((dat=fopen(argv[i],"r"))==NULL)
{
printf("\n\tDatoteka %s nije uspesno otvorena!!", argv[i]);
return;
}else{
s=zbir(dat);
if(i==1) smax=s, k=1;
else if(s>smax) smax=s, k=i;
}
fclose(dat);
}

printf("Datoteka %s je imala najveci zbir %f od svih datoteka.",argv[k], smax);

gotoxy(1,25);
getch();
}

/* Funkcija zbir izracunava zbir brojeva iz jedne datoteke na koju pokazuje pokazivac dat.
Datoteka je vec ranije uspesno otvorena.*/

float zbir(FILE *dat)
{
char *s;
float sz=0;

while(fgets(s,81,dat)!=NULL) sz+=atof(s);

return sz;
}
183



Primer 2:
Napisati C program koji utvruje koliko tekstualna datoteka sadri rei koje
poinju i zavravaju se znakom '#', kao i tabelarni prikaz pojava takvih rei u datoteci po
redovima. U datoteci nema reci koje poinju u jednom redu a zavravaju se u drugom.
Naziv tekstualne datoteke sa putanjom unosi se sa tastature ili iz komandne linije.

Na primer:

Unesite naziv tekstualne datoteke: PRIMER.TXT

U tekstualnoj datoteci ima 25 reci koje pocinju i zavtsavaju se znakom #.

REDNI BROJ REDA BROJ POJAVLJIVANJA
----------------------------------------------------------------------
1 12
2 8
3 0
4 0
5 5

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>

#define MAX_NIZ 100

void main(int BrArg, char *naziv[])
{
char izvor[30],s[150];
unsigned i, k=0, brre, br=0, niz[MAX_NIZ];

FILE *dat;

for(i=0;i<MAX_NIZ;i++) niz[i]=0;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

if(BrArg==1)
{
printf("Unesite naziv datoteke sa putanjom: ");
gets(izvor);
184
}else strcpy(izvor, naziv[1]);


if((dat=fopen(izvor,"r"))==NULL)
{
printf("\n\n\n\n\tDatoteka %s se ne moze otvoriti!!");
return;
}

/* Ucitava se red po red iz tekstualne datoteke. Brojac br broji ukupan broj znakova '#',
dok brojac brre broji broj znakova '#' u jednom redu. Tabelarni prikaz se moze napraviti
ako se podaci o broju pojavljivanja znaka '#' podeljen sa 2 sacuva u nizu. Osnovni
zakljucak je da kako sve svaka rec nalazi zapisana u jednom redu, to je broj reci izmedju
znakova '#' jednak broju znakova '#' podeljeno sa 2. */

while(fgets(s,150,dat)!=NULL)
{
brre=0;

/* Prolazimo kroz string s koji predstavlja jedan red datoteke. */
i=0;
while(s[i]!='\0')
{
if(s[i]=='#') brre++,br++;
i++;
}
niz[k]=brre/2;
k++;
}

printf("\n\nU datoteci %s ima %d reci koje pocinju",izvor,br/2);
printf(" i zavrsavaju se znakom '#'.\n\n");

printf("\n\n\tREDNI BROJ REDA\t\t\tBROJ POJAVLJIVANJA\n");
printf("\t---------------------------------------------------\n");
for(i=0;i<k;i++) printf("\t\t%d\t\t\t\t%-3d\n",i+1,niz[i]);

getch();
}

Primer 3:
Napisati C program koji vri deifrovanje reenice zapisane u tekstualnoj dazoteci
iji naziv sa putanjom se unosi sa tastature. U datoteci namerno postoji jedna re koja
poinje i zavrava sa duplim slovom. Ako data tekstualna datoteka sadri takvu re i ako
se takva re nalazi u datoteci SIFARNIK.TXT, znak je da je iz datoteke potrebno
deifrovati reenicu.
Datoteka SIFARNIK.TXT sadri u svakom redu po jedan format oblika:
ifrovanare brorei/brojreenice* brorei/brojreenice...@interpunkcijskiznak

ifrovanare je re koja je pronaena u datotci,
185
brojrei je redni broj rei u reenici sa rednim brojem brojreenice.
oznaka ... znai da postoji vie rei u reenici
Prva re iz deifrovane reenice mora poeti velikim slovom, izmeu rei je jedna
praznina, a reenica se zavrava sa jednim interpunkcijskim znakom koji se nalazi posle
znaka @.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX_NIZ 100

char *utvrdi(FILE *dat, char *s);
char *formrecenicu(char *t, char *niz[]);

void main(int BrArg, char *naziv[])
{
char izvor[30],ss[2000],*pom,*niz[150],s[1500]="",t[150]="",tt[150]="";
unsigned i,j,k;

FILE *dat;

niz[0]=ss;
for(i=1;i<150;i++) niz[i]=NULL;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

if(BrArg==1)
{
printf("Unesite naziv datoteke sa putanjom: ");
gets(izvor);
}else strcpy(izvor, naziv[1]);


if((dat=fopen(izvor,"r"))==NULL)
{
printf("\n\n\t\tDatoteka %s se ne moze otvoriti!!",izvor);
getch();
return;
}

/* Pozivamo funkciju utvrdi koja utvrdjuje da li ulazna datoteka sadrzi sifrovanu rec. Ako
ne sadrzi funkcija vraca NULL, a u suprotnom pokazivac na string gde se nalazi format
186
uz pomoc koga se dobija desifrovana recenica. Prenosom po referenci funkcija u string s
smesta celokupnu ulaznu datoteku. */

if((pom=utvrdi(dat,s))==NULL)
{
printf("\n\n\t\tDatoteka nema sifrovanu rec!!");
fclose(dat);
return;
}
fclose(dat);
strcpy(t,pom);

/* Na osnovu stringa s gde je smestena ulazna datoteka formiramo niz pokazivaca na
stringove niz, gde ce svaki string sadrzati po jednu recenicu datoteke. */

i=0;
j=0;
while(s[i]!='\0')
{
k=0;
while(s[i]!='\0'&&s[i]!='.'&&s[i]!='!'&&s[i]!='?') tt[k]=s[i],k++,i++;
while(s[i]!='\0'&&(!isalpha(s[i]))) tt[k]=s[i],k++,i++;
tt[k]='\0';
strcpy(niz[j],tt);
j++;
tt[0]='\0';
if(j!=0) niz[j]=niz[j-1]+strlen(niz[j-1])+1;
}

/* Funkcija formrecenicu na osnovu stringa t gde je smesten format za desifrovanje
recenice i niza pokazivaca niz, formira trazenu recenicu, i vraca pokazivac na string gde
se ta recenica nalazi. */
printf("\n\nTrazena recenica je: %s",formrecenicu(t,niz));
getch();
}

/* Funkcija utvrdi utvrdjuje da li ulazna datoteka sadrzi sifrovanu rec. Ako ne sadrzi
sifrovanu rec funkcija vraca NULL, a u suprotnom pokazivac na string gde se nalazi format
uz pomoc koga se dobija desifrovana recenica. Prenosom po referenci funkcija u string s
smesta celokupnu ulaznu datoteku.*/

char *utvrdi(FILE *dat, char *s)
{
char sifra[50]="",c,sifrarec[100]="",*pom=NULL;
unsigned i,j,k,kk;
FILE *dat1;

if((dat1=fopen("SIFARNIK.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka SIFARNIK.TXT se ne moze otvoriti!!");
getch();
187
exit(1);
}
/* Ucitavamo ulaznu datoteku karakter po karakter i smestamo u string s. */
i=0;
while((c=fgetc(dat))!=EOF) s[i]=c,i++;
s[i]='\0';

/* U stringu s trazimo sifrovanu rec. Prvo utvrdjujemo koja rec pocinje duplim slovom.
Ako nadjemo takvu rec utvrdjujemo da li se i zavrsava sa duplim slovom. */
i=0;
while(s[i]!='\0')
{
while(s[i]!='\0'&&s[i]!=s[i+1]) i++;
if(s[i]!='\0')
{
j=i+1;
while(s[j]!='\0'&&s[j]!=' '&&s[j]!= '\t'&&s[j]!='.'&&s[j]!='!'&&s[j]!='?')
j++;

if(s[j]!='\0'&&s[j-1]==s[j-2])
{
/* Nasli smo rec koja pocinje duplim slovom i zavrsava se sa duplim
slovom, ali moramo utvrditi da li takve reci postoji u sifarniku. Prvo rec
izdvajamo u poseban string sifra, i prvo slovo tog stringa pretvaramo u
veliko jer svaka sifrovana rec u sifarniku pocinje sa velikim slovom. */
k=0;
for(kk=i+1;kk<j-1;kk++) sifra[k]=s[kk],k++;
sifra[k]='\0';

sifra[0]=toupper(sifra[0]);

/* Ucitavamo iz datoteke SIFARNIK.TXT red po red jer se u
svakom redu nalazi po jedan format sifrovane reci. */

while(fgets(sifrarec,100,dat1)!=NULL)
{
/* Izdvajamo sifrovanu rec znajuci da se posle nje nalazi
prazno mesto. */

pom=strtok(sifrarec," ");
if(!strcmp(pom,sifra))
{
/* Ako nadjene reci postoji u sifarniku,
zatvaramo datoteku i vracamo format
desifrovane rcenice. */

fclose(dat1);
return strtok(NULL,"\0,\n");

}else sifrarec[0]='\0';
}
188
}
}
/* ako nadjene reci nema u sifarniku pozicioniramo se na pocetak datoteke
SIFARNIK.TXT, i pocinjemo nadalje traziti u stringu s gde se nalazi ulazna
datoteka rec koja pocinje i zavrsava se sa duplim slovom. */

rewind(dat1);
i++;
}
fclose(dat1);

/* U slucaju da nema reci koja pocinje i zavrsava se duplim slovom i ujedno se nalazi u
sifarniku, funkcija vraca NULL.*/

return NULL;
}

/* Funkcija formrecenicu na osnovu stringa t gde je smesten format za desifrovanje
recenice i niza pokazivaca niz, formira trazenu recenicu, i vraca pokazivac na string gde se
ta recenica nalazi. */

char *formrecenicu(char *tt, char *niz[])
{
unsigned i, j, k, br=0, kon, brrec,brrece,brpom;
char *pom, s[150], p[150], res[150]="",t[150]="";

strcpy(t,tt);

/* Prvo prebrojimo koliko ima znakova '/' u formatu t, jer taj broj ce predstavljati i broj
reci koje ce sadrzati desifrovana recenica. */
i=0;
while(t[i]!='\0')
{
if(t[i]=='/') br++;
i++;
}

/* Iz cinjenice da funkciji strtok samo prvi put moramo proslediti string u kojem ce se
traziti tokeni, a svaki sledeci put se prosledjuje NULL, to prvo moramo desifrovati prvu
rec. */

pom=strtok(t,"/*");
brrec=atoi(pom);
pom=strtok(NULL,"/*@");
brrece=atoi(pom);
strcpy(s,niz[brrece-1]);

/* Promenljiva brpom sadrzace u svakom trenutku redni broj utvrdjene reci iz
recenice tekstualne datoteke, koja je vec ranije smestena u niz pokazivaca na stringove
niz, dok ce promenljiva kon kontrolisati da li je stvarno pronadjena prava rec ciji je redni
189
broj u recenici brrec. Kada se rec pronadje kontrolna promenljiva kon imace vrednost 1.
*/

i=0;
brpom=0;
kon=0;
while(s[i]!='\0'&&kon==0)
{

/* U stringu s nalazi se trazena recenica sa rednim brojem brrece. */
while(s[i]!='\0'&&(!isalnum(s[i]))) i++;

/* Utvrdjujemo da li je rec i brojac reci povecavamo za 1. */
if(s[i]!='\0') brpom++;

/* Utvrdjujemo da li je to nasa rec, te ako nije preskacemo je. */
if(brpom!=brrec)
{
while(s[i]!='\0'&&isalnum(s[i])) i++;
}else{

/* U slucaju da je to nasa trazena rec izdvajamo je u string p i kontrolnoj
promenljivoj kon dodeljujemo vrednost 1. */

j=0;
while(isalnum(s[i])) p[j]=s[i],j++,i++;
p[j]='\0';

kon=1;
}
}

if(br!=1)
{
/* Na nacin koji je gore opisan izdvajaju se preostale reci i formiraju string res,
koja predstavlja trazenu recenicu. */

for(k=1;k<=br;k++)
{
strcat(res,p);
strcat(res," ");
pom=strtok(NULL,"/*");
brrec=atoi(pom);
pom=strtok(NULL,"/*@");
brrece=atoi(pom);
strcpy(s,niz[brrece-1]);

i=0;
brpom=0;
kon=0;
while(s[i]!='\0'&&kon==0)
190
{
while(s[i]!='\0'&&(!isalnum(s[i]))) i++;
if(s[i]!='\0') brpom++;
if(brpom!=brrec)
{
while(s[i]!='\0'&&isalnum(s[i])) i++;
}else{
j=0;
while(isalnum(s[i])) p[j]=s[i],j++,i++;
p[j]='\0';
kon=1;
}
}
}

/* Formirana je recenica od potrebnih reci. */
res[strlen(res)-1]='\0';
}

/* Izdvajaju se interpunkcijski znaci koji su se nalazili posle znaka '@' u sifrovanoj
recenici iz sifarnika. */

i=0;
while(tt[i]!='@') i++;
i++;
j=0;
while(tt[i]!='\0') p[j]=tt[i],i++,j++;
p[j]='\0';

/* Interpunkcijski znaci se nadovezuju na kraj formirane recenice i prvo slovo recenice se
pretvara u veliko slovo. */

strcat(res,p);
res[0]=toupper(res[0]);

return res;
}

Test primer programa:

Test primer programa obuhvata tekstualne datoteke SIFARNIK.TXT I PRIMER.TXT.
U datoteci PRIMER.TXT nalaze se rei zapisane u datoteci SIFARNIK.TXT koje obrazuju
traenu reenicu. Datoteka SIFARNIK.TXT formirana je po uslovima zadatka i u sprezi je sa
datotekom PRIMER.TXT (rei i pozicije rei se moraju polapati).

SIFARNIK.TXT

Povracanje 2/3*5/4@.
Srecan 1/2*5/3*12/4@!
Tuzan 7/2*12/4*13/5*11/2@.
Taster 6/1*8/9*5/8*6/2*12/9*6/7@.
191
Milostiv 5/2*4/1*12/6*11*3*20/3*11/1*25/6*32/4@?


PRIMER.TXT

Da bi forma bila funkcionalna mora joj se dodeliti kontrole. Kontrole su objekti
koje postavljate na formu da bi interagovali sa njima. Sve kontrole koje mozete
dodati formi nalaze se u kutiji sa alatom Toolbox. Najlaksi nacin da dodate kontrolu
formi je dupli klik na kontrolu koja se nalazi u okviru sa alatom. Ukoliko hocete
odmah da postavite kontrolu gde zelite mozete je prevuci na formu. Kada se kursor
otprilike nalazi gde zelite da kontrola bude kreirana oslobodite ttasterr misa.
Poslednji i najprecizniji metod postavljanja kontrole na formu je crtanje kontrole
na formi. Iz okvira sa alatkama kliknete na formu. Pomerate pokazivac misa na mesto
gde zelite da se gornji levi ugao forme nalazi, pa kliknete i drzite taster misa.
Prevucite pokazivac gde zelite da se nalazi donji desni ugao kontrole i oslobodite
dugme misa. Ova klasa definise osnovno funkcionisanje kontrola, zbog cega su mnogi
dogadaji osobine kontrola indenticni.


Izgled programa nakon pokretanja.

















192




5.5. FORMATIRANI ULAZ I IZLAZ

Funkcije koje predstavljaju formatirani ulaz i izlaz su: fprintf() i fscanf(). Ove dve
funkcije su sline sa funkcijama printf() i scanf(), tj. sve je isto osim to im je potrebno
dodati argument pokaziva na datoteku sa kojom e se raditi.
Kada sistem startuje program, automatski se otvaraju tri datoteke. Ove datoteke su
indentifikovane sa tri konstantna pokazivaa na tip FILE i to su: stdin, stdout i stderr,
koji su definisani u datoteci stdio.h. Pokaziva stdin indentifikuje standardni ulaz
programa i pridruen je terminalu sa kog je program startovan. Sve standardne ulazne
funkcije ne zahtevaju eksplicitni argument za indentifikaciju ulazne datoteke, jer po
definiciji koriste pokaziva stdin. Pokaziva stdout indentifikuje standardni izlaz, koji je
takoe pridruen terminalu sa kog je program aktiviran. Pokaziva stderr indentifikuje
standardnu datoteku za tampanje poruka o grekama, generisanih od strane sistema.
Pokaziva stderr je pridruen terminalu sa kojeg je program aktiviran.

Primer:
scanf("%d",&n); <=> fscanf(stdin,"%d",&n);
printf("N = %d",n); <=> fprintf(stdout,"N = %d",n);

Osim ova tri pokazivaa DOS operativni sistem podrava i pokazivae: stdprn
usmeren na standardni prikljuak za tampa, i stdaux koji ide na standardnu funkciju za
serijsku komunikaciju.

Primer:
Napisati C program koji utvruje broj rei u tekstualnoj datoteci ije ime sa
putanjom se unosi sa tastature.

Reenje

#include <stdio.h>
#include <conio.h>

#define DUZINA 81

unsigned brojireci(char *s);

void main(void)
{
char *ime, *s;
unsigned n=0;
FILE *dat;

textmode(3);
193
textbackground(0);
textcolor(15);
clrscr();

printf("\n\tUnesite ime datoteke: ");
gets(ime);

if((dat=fopen(ime,"r"))==NULL)
fprintf(stderr,"\n\n\t\tGreska!! Datoteka se ne moze otvoriti!!");
else{
while(fgets(s,DUZINA,dat)!=NULL) n+=brojireci(s);
}
fclose(dat);
fprintf(stdout,"\n\n\tU datoteci %s nalazi se %u reci.",ime,n);

gotoxy(1,25);
getch();
}

unsigned brojireci(char *s)
{
unsigned br=0;

while(*s)
{
while(*s == ' ' || *s == '\n' || *s == '\t') s++;
if(*s)
{
br++;
while(*s != ' ' && *s != '\n' && *s != '\t' && *s != '\0') s++;
}
}

return br;
}

Test primer programa:
Test primer programa koristi datoteku PRIMER.TXT iz prolog zadatka.

Izgled programa:

194



5.6. POZICIONIRANJE UNUTAR DATOTEKE


Pozicioniranje unutar datoteke pretstavlja direktan pristup datoteci. Najee se za
pozicioniranje unutar datoteke koriste funkcije fseek, ftell i rewind.


int fseek(FI LE *dat, long offset, int mode );

Funkcija fseek podeava poziciju datoteke za tok dat. Narednim itanjem ili
pisanjem pristupa se podacima na poetku te nove pozicije. Datoteka se tretira kao niz
bajtova, a funkcija fseek omoguava da se direktno pristupi do bilo kog bajta u datoteci.
Argument mode oznaava polaznu taku, i moe imati jednu od tri vrednosti zapisanih u
simbolikim konstantama:

- SEEK_SET poetak datoteke
- SEEK_CUR trenutna pozicija
- SEEK_END kraj datoteke

Simbolike konstante SEEK_SET, SEEK_END i SEEK_CUR definisane su u
zaglavlju stdio.h.

Argument offset koliko daleko u bajtovima treba da se pomeramo od poetne take.
Ako offset ima pozitivnu vrednost kree se napred, ili negativnu vrednost kree se nazad.
U sluaju tekstualne datoteke offset moe da ima vrednost nula ili vrednost koju je dala
funkcija ftell, dok mode mora imati vrednost SEEK_SET.
Funkcija fseek vraa vrednost 0 ako je uspeno obavila posao, ili -1 u suprotnom
(pokuaj pozicioniranja izvan granica datoteke).
Funkcija fseek mora obavezno da se poziva pre prvog itanja posle nekoliko
upisivanja, odnosno pre prvog upisivanja posle nekoliko itanja. Na primer prepisujemo
jedan podatak preko drugog, a potom hoemo da itamo sledei podatak. Bez obzira to
se ita sledei bajt mora se pozvati funkcija fseek.
195


long ftell(FI LE *dat);

Funkcija ftell trenutnu poziciju datoteka za tok dat izraen u bajtovima u odnosu na
poetak datoteke, ili -1 u sluaju greke.


void rewind(FI LE *dat);

Funkcija vri pozicioniranje na poetak datoteke.

Primer 1:
Napisati C program koji u tekstualnoj datoteci PRIMER.TXT jedan znak
zamenjuje drugim znakom. Znak kojeg treba zameniti i znak sa kojim se vri zamena
uneti sa tastature. Na ekranu tampati izmenjeni sadraj datoteke.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>

void main(void)
{
char c,d,car;
long poz;
FILE *dat;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\n\tUnesite znak ji se menja: ");
c=getche();
printf("\n\tUnesite znak sa kojim se vrsi zamena: ");
d=getche();

/* Otvaramo datoteku za citanje i pisanje te se stavlja r+ mod. */
if((dat=fopen("PRIMER.TXT","r+"))==NULL)
{
printf("\n\n\tDatoteka PRIMER.TXT se ne moze otvoriti!!!");
return;
}

printf("\n\n\n\tDatoteka PRIMER.TXT je uspesno otvorena!!\n\n");
do{
/* Pamtimo trenutnu poziciju u datoteci i smestamo u promenljivu poz. */
196
poz=ftell(dat);

/* Ucitavamo karakter iz datoteke i smestamo ga u promenljivu car, i automatski
se prelazi na sledeci karakter (bajt) u datoteci. */
car=fgetc(dat);

/* Ako je karakter iz datoteke onaj koji se menja vrsi se zamena. */
if(car == c)
{
/* Pozicioniramo se na prethodni karakter u datoteci (onaj kojeg je
ucitala funkcija fgetc), a poziciju smo zapamtili pozivom funkcije ftell u
promenljivoj poz.
Vrsimo upis karaktera u datoteku pomocu funkcije fputc. */

fseek(dat,poz,SEEK_SET);
fputc(d,dat);

/* Kako posle pisanja vrsimo citanje podatka iz datoteke moramo izvrsiti
ponovno pozicioniranje pozivom funkcije fseek. */
fseek(dat,poz+1,SEEK_SET);

/* Stampamo izmenjeni podatak na ekranu. */
printf("%c",d);
}else printf("%c",car);
}while(car!=EOF);
fclose(dat);

gotoxy(1,25);
getch();
}

Primer 2:
Napisati C program koji predstavlja poznatu igru "slagalica" iz televizijskog kviza
muzika slagalica. Korisnik unosi deset slova engleske abecede. Nakon svakog
pritisnutog tastera SPACE u odgovarajue polje upisuje se po jedan znak. Korisnik ima
jedan minut na raspolaganju da unese svoju re sa to vie slova od ponuenih. Program
utvruje da li je re ispravno unesena na osnovu ponuenih slova, a potom na osnovu
tekstuale datoteke RECI.TXT daje svoje reenje koje ima najvei broj slova u sebi.

Reenje

#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<dos.h>
#include<time.h>
#include<ctype.h>

#define BR 18
197
#define ESC 27
#define VREME 60
#define ZADNJIDEO 10

/* Prototipovi funkcija. */
void rand(char *rec,char *slova);
void crtaj(void);
unsigned bacaj(char *slova);
int provera(char *slova,char *druga);
unsigned uzmi(char *druga);

void main(void)
{
int i=0,j=0;
char *rec="",*slova,c,*druga;
FILE *fajl;

randomize();
textmode(3);
textcolor(3);
textbackground(0);
clrscr();

/* U datoteci RECI.TXT nalaze se najduze reci naseg jezika. */
if( (fajl=fopen("reci.txt","r")) ==NULL)
{
printf("Nesto nije u redu sa fajlom RECI!!");
getch();
return;
}

/* Pozicioniramo se na pocetak datoteke. Znamo da se u jednom redu
nalazi tacno jedna rec. Iz tog razloga kada ucitamo znak '\n' znaci
da smo ucitali jednu rec. U ovom delu koda brojimo reci. */

fseek(fajl,0,SEEK_SET);
while(c!=EOF)
{
if((c=fgetc(fajl))=='\n')i++;
};

/*Utvrdili smo broj reci i ponovno se pozicioniramo na pocetak datoteke. */
rewind(fajl);

/* Na slucajan nacin biramo najduzu rec iz datoteke RECI.TXT i to ce navodno biti i
najduza rec koju je racunar pronasao. Ucitana rec se smesta u promenljivu rec i datoteka
se zatvara. */
randomize();
for(j=0;j<random(i);j++) fgets(rec,BR+2,fajl);
fclose(fajl);

198
/* Svaki string se zavrsava sa znakom '\0'. */
*(rec+strlen(rec)-1)='\0';

/* Sva slova date reci se pretvaraju u velika. */
rec=strupr(rec);

slova=" "; /* String slova ima sada BR praznina. */

rand(rec,slova);
gotoxy(15,5);
crtaj();
if(bacaj(slova)==0) return;

gotoxy(15,14);
if(uzmi(druga)==0) return;

druga=strupr(druga);
if((i=provera(slova,druga))!=0)
{
gotoxy(15,15);
printf("Ova rec ne moze da se prizna, fale %d slova!!",i);
}

if((i=provera(slova,druga))!=0&&strlen(druga)<strlen(rec))
{
delay(1700);
gotoxy(15,17);
printf("To nije najduza rec!");
}

gotoxy(15,18);
printf(" ");
gotoxy(15,18);printf("Kompjuter je nasao rec: ");
delay(1500);
gotoxy(15,20);
for(i=0;i<strlen(rec);i++) printf("%c ",rec[i]);
gotoxy(1,25);
getch();
}

/* Funkcija rand formira rec od 18 slova koja sadrzi sva slova iz reci ucitane
iz datoteke, a ostalo popunjenih proizvoljnim slovima.
Datu rec ce igrac kasnije navodno izabrati. */
void rand(char *rec,char *slova)
{

int i,j,d,r;
char cr;
d=strlen(rec);
randomize();

199
/* Popunjava se string od slova koji ce pretstavljati navodno izabrana slova od
strane igraca. String se popunjava na slucajan nacin razbacivanjem slova iz reci
koja je ucitana iz datoteke. */

for(i=0;i<d;i++)
{
do{
r=random(BR);
}while(slova[r]!=' ');
slova[r]=rec[i];
}


/* Ostace jos nepopunjenih mesta u stringu slova jer rec ucitana iz datoteke ima
manje slova nego rec koja se formira navodnim biranjem od strane korisnika. */
for(i=0;i<BR-d;i++)
{
/* Izaberemo nepopunjenu poziciju. */
do{
r=random(BR);
}while(slova[r]!=' ');

/* Slova moraju biti velika a ona se u ASCII tabeli nalaze od rednog
broja 65, a ima ih 26. . */
do{
cr=random(26)+65;
}while(cr=='Y'||cr=='X'||cr=='W'||cr=='Q'||cr=='A'||cr=='O'||
cr=='E'||cr=='I'||cr=='U');
slova[r]=cr;
}
}

/* Funkcija crtaj stampa izgled igrice. */
void crtaj(void)
{
int i,j;
gotoxy(15,2);printf("\t\tS L A G A L I C A");

for(i=10;i<70;i++) gotoxy(i, 4), printf(""); /* ALT+178 */
for(i=10;i<72;i++) gotoxy(i,22), printf("");
for(i=4;i<22;i++) gotoxy(10,i), printf("");
for(i=4;i<22;i++) gotoxy(70,i), printf("");
for(i=10;i<70;i++) gotoxy(i,10), printf("");
for(i=10;i<70;i++) gotoxy(i,16), printf("");
gotoxy(15,6);
printf("Izaberite slova: ");
gotoxy(15,12);
printf("Vasa rec je: ");
gotoxy(15,18);
printf("Kompjuter je nasao rec: ");
gotoxy(21,23);
200
cprintf("Ako ste sastavili rec pritisnite ENTER");
for(i=0;i<60;i++)
{
gotoxy(11+i,24);
cprintf(""); /* ALT+177 */
}
}

/* Funkcija bacaj simulira izgled bacanja slova ali kako se slova
brzo vrte igrac nece ni znati da slovo koje je izabrao nije stampano
na ekranu. */
unsigned bacaj(char *slova)
{
int i,c,cr;

_setcursortype(_NOCURSOR);
for(i=0;i<BR;i++){
do{
do{
cr=random(26)+65;
gotoxy(23+(2*i),8);
putch(cr);
delay(100);
}while(!kbhit());
c=getch();
if(c==ESC) return 0;
}while(c!=32);
gotoxy(23+(2*i),8);
putch(slova[i]);
}
return 1;
}

/* Funkcija provera utvrdjuje da li slova iz reci koje je formirao
korisnik ima u stringu slova koje je izabrao bacanjem. */
int provera(char *slova,char *druga)
{
int p,i,j,d=strlen(druga),k=0;
char *sl2;

/* Rec od slova dobijenih bacanjem, zapamti se u pomocnom stringu jer ce se taj
string modifikovati. U njega na pozicijama gde je karakter nadjen upisuje se
karakter '*', kako se isto slovo vec utvrdjeno da postoji u stringu ponovo
ucestvovalo u poredjenju. */
sl2=slova;
for(i=0;i<d;i++)
{
for(j=0;j<BR;j++)
{
if(*(druga+i)==*(sl2+j))
{
201
*(sl2+j)='*';
j=BR;
}
}
}
/* Izbrojimo koliko ima karaktera '*' u modifikovanom stringu, jer je razlika izmedju
duzine stringa koje je korisnik odabrao da je najduza rec i broja karaktera '*' upravo broj
slova kojih nema u reci koja je dobijena bacanjem. */
for(i=0;i<BR;i++)if(*(sl2+i)=='*') k++;
if(k==d) return 0;
else return (d-k);

}
/* Funkcija omogucava korisniku da izabere najduzu rec. */
unsigned uzmi(char *druga)
{
char c;
int i=0;
time_t t;
long start,vr;

_setcursortype(_NOCURSOR);

/* Pre pocetka same igre ucitava vreme koje pokazuje sistemski sat u sakundama. */
start=time(&t);

do{
do{

/* Izracunava se uvek razlika izmedju trenutnog vremena koje
pokazuje sistemski sat i vremena koje je pokazao na pocetku
igre, a to je trenutno vreme trajanja igre, */
vr=time(&t)-start;

/* Pale se polja sa palete, i na taj nacin korisnik ima vizuelni
izgled trajanja igrice. Zadnji deo vremena se na paleti prikazuje
crvenom bojom. */
gotoxy(11+vr,24);
if(vr<VREME-ZADNJIDEO) textcolor(14);
else textcolor(4);
cprintf(""); /* ALT+178 */

_setcursortype(_NORMALCURSOR);

if(vr==VREME)
{
gotoxy(20,23);
printf(" ");
gotoxy(32,23);
printf("VREME JE ISTEKLO");
return 0;
202
}
gotoxy(15+i*2,14);
delay(20);
}while(!kbhit());
c=getch();
if(c==ESC) return 0;

/* Pretvaramo karakter u veliko slovo, u slucaju da je malo, dok funkcija
isalpha utvrdjuje da li je karakter slovo. */
c=toupper(c);
if(c!= '\b'&&c!= '\r'&&isalpha(c)&&
c!=' '&&c!='X'&&c!='Y'&&c!='Q'&&c!='W'&&i<=BR)
{
druga[i++]=c;
druga[i]='\0';
gotoxy(13+i*2,14);
printf("%c",c);
}

/* Ako je pritisnut BACKSPACE mora se izbrisati i zadnje uneto slovo
iz stringa. */
if(i>0&&c=='\b')
{
druga[i--]='\0';
gotoxy(14+i*2,14);
printf(" ");
}
}while(c!= '\r');
return 1;
}

Test primer programa:




203










5.7. ZADACI IZ TEKSTUALNIH DATOTEKA


Zadatak 1 (2)
Napisati C program koji izraunava zbir brojeva zapisanih u tekstualnoj datoteci iji
naziv bez putanje se unosi sa tastature. Brojevi su realni i svaki broj nalazi se zapisano u
novom redu tekstualne datoteke.

Zadatak 2 (2)
Napisati C program koji utvruje broj linija u tekstualnoj datoteci i tampa najduu
liniju iz datoteke. Naziv datoteke bez putanje se unosi sa tastature.


Zadatak 3 (2)
Napisati C program koji utvruje koliko tekstualna datoteka sadri rei. Naziv
tekstualne datoteke moe se uneti preko komandne linije ili tastature.


Zadatak 4 (3)
Napisati C program koji odreuje liniju koja sadri najduu re. Ispisati na ekranu
redni broj linije i najduu re. Naziv tekstualne datoteke moe se uneti preko komandne
linije ili tastature.

Zadatak 5 (3)
Napisati funkciju koja uporeuje dve tekstualne datoteke i vraa redni broj reda u
kojoj se po prvi put datoteke razlikuju, ili 0 ako su datoteke indentine. Naziv tekstualne
datoteke moe se uneti preko komandne linije ili tastature.

Zadatak 6 (3)
Napisati C program koji pozivanjem funkcije brisi, viestruki uzastopni niz
znakova zamenjuje sa jednim znakom, u tekstualnoj datoteci ije ime bez ekstenzije se
unosi sa tastature. Veliko i malo slovo tretira se istim znakom.

Na primer:

204
PRIMER.TXT
Eeeh da miiiii jje laksiiii zzaddattak dao!!
Ovi pppprofesorrri uvekkk naas muce i mmaltreeetirraju.
Nnnnapokonn sam zavrssiooo.

Nakon sreivanja datoteka ima sledei izgled:

PRIMER.TXT
Eh da mi je laksi zadatak dao!!
Ovi profesori uvek nas muce i maltretirraju.
Napokon sam zavrsio.
Zadatak 7 (2)
Napisati C program koji omoguava unos naziva tekstualne datoteke sa putanjom i
prebrojava koliko ima rei da a koliko ne u tekstualnoj datoteci. Za brojanje rei koristiti
funkciju brojireci.

Zadatak 8 (3)
Napisati C program koji utvruje koja linija u tekstualnoj datoteci poseduje najvie
rei. Ispisati datu liniju na ekranu i broj rei koliko ima data datoteka. Naziv tekstualne
datoteke moe se uneti preko komandne linije ili tastature.

Zadatak 9 (2)
U tekstualnoj datoteci MATRICA.TXT nalazi se matrica. Prvi red datoteke sadri
dva celobrojna podatka: broj vrsta i broj kolona koje ima matrica. Podaci su razdvojeni
blanko mestom (mestima) ili tabulatorom (tabulatorima).
Napisati C program koji izraunava zbir elemenata matrice, i vri zatim saimanje
matrice izbacivanjem svih onih kolona koji imaju zbir manji od zbira celokupne matrice.
Za izraunavanje zbira celokupne matrice koristiti funkciju zbir, a za izraunavanje zbira
elemenata jedne kolone funkciju zbirkolone.
Ispod ve postojee matrice napraviti dva prazna reda, a zatim ispisati zbir
elemenata matrice, a ispod jedan prazan red pa novonastalu matricu, u istom formatu
kakav je i bio u datoteci.

Na primer:

MATRICA.TXT

5 7
-3 1 2 0 -2 -6 -7
-3 0 -1 4 5 -2 -6
7 -4 0 -11 -3 4 10
5 1 0 -1 -2 7 22
4 -1 -10 -3 4 -4 -5


Zbir matrice = 2
205


5 3
-3 -2 -7
-3 5 -6
7 -3 10
5 -2 22
4 4 -5



Zadatak 10 (3)
Napisati C program koji uklanja komentare iz nekog C programa. Komentari u C
programu poinju sa /* a zavravaju se sa */.


Zadatak 11 (4)
Napisati C program koji prikazuje sadraj tekstualne datoteke na ekranu, tako to je
centrirano u prvoj liniji ekrana ispisan naziv datoteke a od 3 do 22 linije ispisano 20 linija
teksta datoteke, a u 24 liniji ekrana je centrirano ispisan redni broj strane koji se
prikazuje. Smatrati da svaka strana ima po 20 linija teksta. Za nastavak prikazivanja
sledee strane koristiti taster SPACE.


Zadatak 12 (4)
Zadata je tekstualna datoteka ULAZ.TXT, pri emu svaki red ove datoteke ima
samo jednu potpunu reenicu koja se zavrava takom. Znai da posle take nema vie
karaktera u reenici. Izmeu rei u reenici moe postojati vie praznih mesta. Reenica
moe imati najvie 80 karaktera. Koristei funkciju najveci iz svakog reda datoteke
utvruje se re koja je najdua, a potom se svi karakteri (mala slova) rei pretvaraju u
velika slova. Uz pomo funkcije upis, ove rei se upisuju u izlaznu datoteku
IZLAZ.TXT. Funkcijom ispis se sadraj datoteke IZLAZ.TXT tampa na ekranu.
Program realizovati u programskom jeziku C.


Zadatak 13 (4)
Napisati C program koji utvruje koja reenica u tekstualnoj datoteci poseduje
najvie rei. Ispisati koliko ima reenica u datoteci kao i reenicu koja ima najvie rei i
broj rei koliko ima data reenica.
Reenica se zavrava takom, upitnikom ili uzvinikom.


Zadatak 14 (4)
Napisati C program koji pronalazi sva pojavljivanja date rei (sekvenca od
maksimalno 30 karaktera) u datoj tekstualnoj datoteci. Na izlazu tampati redne brojeve
206
reenica iz datoteke u kojima se re pojavljuje Ignorisati viestruko pojavljivanje rei u
jenoj reenici.


Zadatak 15 (3)
Napisati C program koji spaja dve sortirane datoteke u treu sortiranu datoteku koja
sadri samo razliite elemente ulaznih datoteka. Program omoguava rad sa vie ulaznih
sortiranih datoteka, pri emu se imena datoteka unose iz komandne linije.
Datoteke se sastoje od redova pri emu se u svakom redu nalazi po dve rei (ime i
prezime) razdvojeni blanko mestom. Obe rei poinju velikim slovom. Ako se pojave
greke da neka od rei poinje malim slovom program automatski ispravlja tu greku u
izlaznoj datoteci.
Zadatak 16 (4)
Napisati C program koji vri ifrovanje datoteke tako to se svaka re u datoteci
zapisuje u invernom poretku. Ako je neka re poinjala velikim slovom i rotirana re
poinjae sa velikim slovom. Tabulatori, praznine, prelazak u novi red i znakovi
interpunkcije ostaju na istim pozicijama u datoteci.
Za ifrovanje datoteke koristiti funkciju void sifrujdat(FI LE *filepointer); U
okviru funkcije sifradat koristiti i funkciju char *izdvojrec(char *s); iz linije fajla koji je
zapisan u stringu s.


Zadatak 17 (5)
Napisati C program koji u tekstualnoj datoteci vri zamenu svake pojave rei s sa
rei t. Program realizovati funkcijom int zamenirec(FI LE *filepionter, chat *s, char *t);
koja vraa 0 ako rei s nema u datoteci, a 1 u suprotnom.


Zadatak 18 (5)
Napisati C program koji u datoj tekstualnoj datoteci, pronalazi i brie reenice koje
se viestruko ponavljaju. Reenice poinju velikim slovom ili brojem, a zavravaju se
takom, uzvinikom, upitnikom ili oznakom EOF. Omoguiti unos naziva iz komandne
linije.

Zadatak 19 (5)
Napisati C program koji prikazuje spisak referenci u datoj tekstualnoj datoteci.
Svaka referenca u tekstu je oznaena sa svojim brojem u uglastim zagradama. Na izlazu
tampati reference sa brojevima, svaka referenca u novom redu.


Zadatak 20 (4)
Napisati C program koji utvruje koliko datoteka, ije ime sa ekstenzijom se unosi
iz komandne linije, sadri pasusa. Pasus koji sadri najvei broj rei formatizovati tako
da sve rei budu pretvorene rei sa velikim slovima.


207
Zadatak 21 (5)
Uenici su napisali velike C programe na praktinoj nastavi. Profesor je zadao
pravilo da se u programu ne sme koristiti naredba bezuslovnog skoka goto. Kako
profesora mrzi da kontrolie ceo kod, potrebno je napisati C program koji utvruje da li
proizvoljni C ili CPP program ije ime sa ekstenzijom se unose sa tastature sadri
naredbu goto, te ako jeste na ekranu ispisuje poruku.


Zadatak 22 (5)
Potrebno je modifikovati tekstualnu datoteku ije ime se unosi sa tastature, tako da
se u svakom redu nalazi tano jedna reenica. Ako reenica ima vie od 80 karaktera
nastavlja se upis u novom redu.
Zadatak 23 (5)
Napisati C program koji utvruje koliko ima zbirova u datoteci. Svaki zbir poinje
u novom redu datoteke i zavrava se znakom jednakosti. Zbir se moe prostirati u vie
redova. Brojevi mogu biti celobrojni ili racionalni. U izrazima nema zagrada, ali se mora
potovati prioritet operatora. Ako se zbir nastavlja u sledeem redu poslednji znak mora
biti znak operacije. Formirati novu datoteku REENJE.TXT koja e sadrati isto to i
ulazna datoteka, stim to se posle jednakosti mora nalaziti i rezultat, ime se zavrava taj
red. Naziv ulazne datoteke uneti sa tastature ili iz komandne linije.


Zadatak 24 (4)
U tekstualnoj datoteci iji naziv se uitava sa tastature nalazi se inicijalizacija
trodimenzionalne matrice. Potrebno je modifikovati datoteku tako da u njoj ostaju samo
elementi trodimenzionalne matrice odvojeni meusobno jednim praznim mestom.
U jednom redu datoteke nalazi se samo jedna dimenzija matrice. Posle elemenata
koji pretstavljaju poslednje elemente druge dimenzije postoji prazan red.


ULAZ.TXT

Int matrica[MAX][MAX][MAX]={
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{
{4, 3, 4, 5},
{5, 6, 7, 8},
{9, 4, 11, 22}
}
}


208
Modifikovana ulazna datoteka je:

ULAZ.TXT

1 2 3 4
5 6 7 8
9 10 11 12

4 3 4 5
5 6 7 8
9 4 11 22

Zadatak 25 (5)
Data je tekstualna datoteka pod imenom TEKST.TXT. Napisati C program koji
tampa sadraj datoteke na ekran, ali tako da kompletan tekst bude poravnat i po desnoj i
po levoj margini na sledei nain.:
- Poravnavanje na levo vriti najobinijim tampanjem od prve kolone ekrana;
- Poravnavanje na desno vriti tako da desna margina bude u onoj koloni u
kojoj se zavrava najdui redoriginalnog teksta; i
- Ostale redove (koji su krai od originalno najdueg), Produavati tako to
e se izmeu rei ubacivati priblino ravnomerno prazna mesta, onoliko
njih koliko je potrebno da red dostigne duinu najdueg.

Zadatak 26 (5)
Na osnovu C programa koji je obraen u zadatku 30 oblasti viedimenzionalni
nizovi, igrica POGODI, doraditi program tako da poseduje tri nivoa.
Prvi nivo je ve obraen u predhodnoj verziji.
Drugi nivo omoguava da se mora redom pogaati brojevi od 1 do 6. Ako se pogodi
pogreno polje ne menja se boja (ostaje tamna).
Trei nivo omoguava da se polja moraju tako pogaati da na kraju dobijemo
sortiran niz brojeva. Nakon svakog pogotka na neki broj on se zarorira sa svojim
sledbenikom, dok u sluaju da se pogodi poslednji broj on se rotira sa prvim elementom u
nizu. Svaki nivo ima po pet tabli. Table se nalaze zapisane u tekstualnoj datoteci
POGODI.TXT, pri emu su table odvojene sa jednim praznim redom.
Za svaki pogodak u polje dobija se jedan broj, dok se za svaku preenu tablu dobija
po 5 bodova pomnoeno sa brojem nivoa koji je poslednji preen u igri.

Zadatak 27 (5)
U tekstualnoj datoteci nalazi se neki tekst sastavljen od rei i taaka koje
oznaavaju krajeve reenica. Izmeu rei se nalazi jedna ili vie praznina.
Napisati C program koji vri formatiranje teksta po sledeim pravilima:
- Izmeu rei moe da bude tano jedna praznina;
- Ispred prve rei teksta nema praznina;
- Ispred take nema praznine;
- Iza take postoji tano jedna praznina i prva re iza take poinje uvek
velikim slovom; i
209
- duina reda u datoteci ne sme biti vea od 80 karaktera.

Zadatak 28 (5)
Potrebno je napraviti tekst procesor koji je u stanju da:
1) unosi tekst;
2) umee nove redove teksta;
3) kretanje kroz tekst pomou strelica;
4) sa breakspace brie znak iz teksta uz pomeranje teksta toga reda u levo za
jedno mesto; i
5) uz pomo tastera delete brie jedan red teksta gde se trenutno kursor nalazi.

Omoguiti unos imena datoteke sa ekstenzijom iz komandne linije ili sa tastature.
Zadatak 29 (5)
Date su tekstualne datoteke REZULTATI.TXT i GOLOVI.TXT sa sledeim
izgledom:

REZULTATI.TXT

Tim Pobede Nereeno Porazi Dati golovi Primljeni golovi
1 13 4 8 23 13
2 15 3 7 25 14 itd...

GOLOVI.TXT

Tim Igra 1 Igra 2 Igra 3 ... Igra 22
1 0 0 2 ... 1
1 2 2 0 ... 1 itd...

Spisak ekipa sa igraima nalazi se u tekstualnoj datoteci EKIPE.TXT. Prvo se
navodi naziv ekipe, a ispod u svakom redu po jedno prezime i ime igraa raydvojenih
praznim mestom. Ekipe su razdvojene sa jednim praznim redom.
Napisati C program koji uitava tekstualne datoteke i na ekranu i u datoteci
TABELA.TXT tampa tabelu prvenstva, dok u datoteci IGRACI.TXT i na ekranu
tampa listu golgetera.

Zadatak 30 (5)
Napisati C program koji pretstavlja poznatu igricu TETRIS. Omoguiti formiranje
etiri nivoa igrice. Postoji vie oblika u tetrisu. Stalno se prikazuje koji je sledei oblik.
Sledei oblik se dobija na sluajan nain. Sa strelicom levo pomera se oblik na levo, sa
strelicom desno pomera se oblik na desno, sa strelicom na gore vri se rotiranje oblika, a
sa strelicom na dole vri se brzo sputanje na dole. Kraj igrice je ako se pritisne taster
ESC. Ako se skupi odreeni broj bodova prelazi se u sledei nivo. U sluaju da se ne
uspe u tom nivou vraa se na prethodni nivo.
U tekstualnoj datoteci uvati pet najboljih rezultata. Rezultat je opisan sa
skljupljenim brojem poena i imenom igraa.

210








211










6
6. . P PO OG GL LA AV VL LJ J E E



S ST TR RU UK KT TU UR RE E I I B BI IN NA AR RN NE E D DA AT TO OT TE EK KE E
212


6.1. DEFINICIJA STRUKTURE DEKLARACIJA STRUKTURE
PRISTUP LANOVIMA STRUKTURE ITIPOVI
KOJE DEFINIE KORISNIK


Definicija strukture:
Struktura predstavlja izvedeni tip podatka koji sadri promenljive istog ili
razliitog tipa. Koristi se u sluajevima kada su podaci u meusobnoj vezi, jer se
mogu grupisati pod istim imenom.

Strukture omoguavaju kreiranje potpuno korisniki orjentisane tipove podataka.

Deklaracija ablona strukture:

struct ime_strukture {
niz_deklaracija
};

niz_deklaracija nabrajaju se polja strukture, oblikom tip polje;
Tip polja strukture ne moe da bude struktura koja se definie, ali moe da bude
pokaziva na strukturu.

Deklaracija strukturne promenljive:

struct ime_strukture ime_strukturne_promenljive;

Pristup lanovima structure:
Pristup lanovima strukture vri se pomou operatora lana strukture (.).

Primer 1:
Napisati C program koji omoguava formiranje strukture radnik sa poljima:

1) Prezime i ime od maksimalno 30 karaktera;
2) Koeficijen za dato radno mesto; i
3) Godine radnog staa.

Poznato je da je vrednost boda k dinara, a da se na svaku godinu radnoga staa
dohodak uveava za 0.5%. Pripravnik je onaj radnik gde se za godine radnoga staa
unese broj 0 i ima 80% dohodak u odnosu na radnika sa obavljenim pripravnikim
staom. Progam treba da ispie koliki je dohodak radnika.

Reenje

213
U zadatku je logino koristiti strukturu, jer kad kaemo radnik ne moe se opisati
kao jedan osnovni podatak, jer se sastoji od vie podataka koji ga opisuju: Prezime i ime
je string, datum roenja je string, godina radnoga staa je celobrojan podatak, koeficijent
je racionalan podatak. Ne moe se opisati ni nizom jer kod niza svi podaci moraju biti
istog tipa Radnik se ne moe opisati sa jednim podatkom osnovnog tipa. Tip podatka je
izvedeni tip i nije niz ve struktura.
Kako struktura predstavlja izvedeni tip podatka koga prevodilac ne poznaje, to se
iznad main funkcije ili u nekom hederu koji je povezan sa programom struktura mora
definisati. Prilikom definisanja strukture ne zauzima se nikakva memorija, ve se
prevodilac upoznaje sa novim tipom podataka kako ga u programu ne bi tretirao kao
nedefinisani indentifikator. Tek nakon deklaracije strukturne promenljive u operativnoj
memoriji se odvaja prostor na osnovu imena izvedenog tipa strukture i njene definicije
koja je gore navedena. Strukturna promenljiva se sastoji od podataka razliitog tipa.
Ti podacin predstavljaju polja ili lanove strukture, a u nekim literaturama se sree i
termin atributi strukture.

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include<ctype.h>

#define MAX 31

/*Definicija strukture radnik, kao novi tip podatka. Obavezno se uz radnik uvek ispred
mora pisati rezervisana rec struct kako bi prevodilac bio siguran da je to strukturni tip
podatka. */
struct radnik{
char prezime_i_ime[MAX];
double koeficijent;
int staz;
double dohodak;
}

void main(void)
{
struct radnik a; /* Deklarise se promenljiva a koja predstavlja slozeni tip podatka, ali ga
prevodilac tretira kao jedan podatak koji je smesten u promenljivoj a.
*/
unsigned xu, yu;
double k;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\t\tUNESITE PODATKE O RADNIKU:\n\n");

printf("\tIme i prezime: ");
214
gets(a.prezime_i_ime); /* Polju strukture se pristupa pomocu operatora tacka, stim sto je
od ranije poznato da se string unosi najcesce sa funkcijom
gets. */

printf("\tKoliki je koeficijenat: ");
xu=wherex();
yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%lf",&a.koeficijent); /* Polju strukture se pristupa pomocu operatora
tacka. */
}while(a.koeficijent<=0);

printf("\tGodine radnoga staza = ");
xu=wherex();
yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&a.staz);
}while(a.staz<0);

printf("\n\n\tVrednost boda je: ");
xu=wherex();
yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%lf",&k);
}while(k<1);

if(a.staz!=0)
{
a.dohodak=a.koeficijent*k;
a.dohodak+=0.5*a.staz*a.dohodak;
}else{
a.dohodak=a.koeficijent*k;
a.dohodak=0.8 * a.dohodak;
}

printf("\n\n\n\tRadnik %s ima dohodak %.2f dinara.",
a.prezime_i_ime, a.dohodak );

gotoxy(1,25);
getch();
}

215
Izvedeni tipovi podataka esto imaju dugaka imena, to zahteva mnogo pisanja i
nepreglednost koda. Da bi se ovaj problem reio koristi se rezervisana re typedef.

Primenom na strukture to je:

typedef struct ime_strukture {
Niz_deklaracija
}ime_tipa;

Primenimo li to na ovaj primer reenje programa imalo bi sledei izgled:

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include<ctype.h>

#define MAX 31

typedef struct radnik{
char prezime_i_ime[MAX];
double koeficijent;
int staz;
double dohodak;
} Tradnik; /* Sada je Tradnik novi tip podatka (izvedeni tip podatka). */

void main(void)
{
Tradnik a; /* Deklarise se promenljiva a koja predstavlja slozeni tip podatka, ali ga
prevodilac tretira kao jedan podatak koji je smesten u promenljivoj a. */
unsigned xu, yu;
double k;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\t\tUNESITE PODATKE O RADNIKU:\n\n");
printf("\tIme i prezime: ");
gets(a.prezime_i_ime); /* Polju strukture se pristupa pomocu operatora tacka, stim sto je
od ranije poznato da se string unosi najcesce sa funkcijom
gets. */
printf("\tKoliki je koeficijenat: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%lf",&a.koeficijent);
}while(a.koeficijent<=0);
216
printf("\tGodine radnoga staza = ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&a.staz);
}while(a.staz<0);

printf("\n\n\tVrednost boda je: ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%lf",&k);
}while(k<1);

if(a.staz!=0)
{
a.dohodak=a.koeficijent*k;
a.dohodak+=0.5*a.staz*a.dohodak;
}else{
a.dohodak=a.koeficijent*k;
a.dohodak=0.8 * a.dohodak;
}

printf("\n\n\n\tRadnik %s ima dohodak %.2f dinara.",
a.prezime_i_ime, a.dohodak );
gotoxy(1,25);
getch();
}

Primer 2:
Napisati C program koji utvruje i na ekranu iscrtava (korienjem teorije
bioritma), skale fizikog, intelektualnog i emocionalnog stanja tog dana. Dan se utvruje
korienjem strukture struct dateza oitavanje sistemskog datuma. Bioritam se utvruje
na osnovu datumac roenja po sledeoj formuli:
)) mod (
2
sin( x d
x
y

=
t
gde je mod operator ostataka celobrojnog deljenja
U formuli je d broj dana od roenja, a x moe imati tri vrednosti | | 33 , 28 , 23 e x
23 - fiziko stanje,
28 - emocionalno stanje, i
33 - umno stanje

Bioritam se na ekranu prikazuje pomou tri skale (fizika. emocionalna i
intelektualna) pri emu je svaka skala obeleena drugom bojom i numerisana u
procentima (-100% do *100%). Datum roenja se unosi u obliku stringa pri emu su dan
mesec i godina razdvojeni separatorima (taka, zarez ili prazno mesto).
217
Reenje

#include<stdio.h>
#include<conio.h>
#include <string.h>
#include <stdlib.h>
#include<dos.h>
#include<math.h>

#define PI 3.141592654
#define ESC 27

/* Funkcija utvrdjuje ispravnost unesenog datuma u obliku stringa. Ako je datum ispravan
funkcija vraca 0, a u suprotnom 1. */

int pitdat(char *s, int saddan, int sadmes, int sadgod, int *dan, int *mes, int *god);

void main(void)
{
struct date sad; /* Novi tip podatka je struct date koji je nalazi u biblioteci DOS.H i sadrzi tri
pola dan, mesec i godinu u datom trenutku. */
/* Da se ne bi ispitivalo koji je mesec, formiran je niz m koji sadrzi dane po mesecima. */
int m[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int god,mes,dan,sdan,saddan,sadmes,sadgod,i,j;
float in,fiz,emo;
unsigned xu,yu;
char s[30];


textmode(3);
do{
sdan=0; /* Broj dana od datuma rodjenja do danasnjeg dana. */
clrscr();
getdate(&sad); /* Funkcija getdate ucitava sistemski datum i smesta u strukturnu
promenljivu sad. */
textcolor(15);
textbackground(0);
clrscr();
printf(" \n");
for(i=0;i<26;i++) printf(" \n");
gotoxy(1,1);

saddan=sad.da_day; /* U saddan upisuje se sadasnji dan. */
sadmes=sad.da_mon; /* U sadmes upisuje se sadasnji mesec. */
sadgod=sad.da_year; /* U sadgod upisuje se sadasnja godina. */

/* Unosi se datum rodjenja u obliku stringa s. Postupak unosa se ponavlja ako je datum
neispravno unesen.*/

printf("Datum rodjenja: ");
xu=wherex(), yu=wherey();
218
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
gets(s);
}while(!pitdat(s,saddan,sadmes,sadgod,&dan,&mes,&god));

/* Kada se trazi ukupan broj dana od rodjenja do danas razlikuju se dva slucaja. Godina
rodjenja se poklapa sa trenutnom godinom, ili ako to nije slucaj. */

sdan=0;
if(god==sadgod)
{
/* Sabira se broj dana od meseca rodjenja do predhodnog meseca. */
for(i=mes;i<sadmes;i++) sdan+=m[i-1];

/*Dodaje se jos jedan dan ako je obuhvacen februar mesec a godina prestupna. */
if(mes<=2&&(god%4==0||god%400==0)) sdan++;

/* Oduyima se broj dana u mesecu do dana rodjenja. */
sdan=sdan-dan+1;

/* Sabira se danasnji broj proteklih dana u mesecu. */
sdan+=saddan;
}else{

/* Sabira se broj dana od meseca rodjenja do kraja godine. */
for(i=mes;i<=12;i++)sdan+=m[i-1];

/*Dodaje se jos jedan dan ako je obuhvacen februar mesec a godina prestupna. */
if(mes>=2&&(god%4==0||god%400==0)) sdan++;

sdan=sdan-dan+1; /* Oduzima se dan rodjenja. */

/* Sabiraju se dani u proteklim godinama do sadasnje godine. */
for(i=god+1;i<sadgod;i++)
{
if(i%4==0 || i%400==0) sdan+=366;
else sdan+=365;
}

/* Dodaju se dani od pocetka godine do danasnjeg meseca. */
for(i=0;i<sadmes-1;i++) sdan+=m[i];

/*Dodaje se jos jedan dan ako je obuhvacen februar mesec a godina prestupna. */
if(sadmes>2&&(sadgod%4==0||sadgod%400==0)) sdan++;

/* Sabira se danasnji broj proteklih dana u mesecu. */
sdan+=saddan;
}

219
gotoxy(4,22); printf("\n\tIma %d dana.",sdan);

in =sin((2*PI)/33*(sdan%33)); /* Utvrdjuje se intelektualno stanje. */
emo=sin((2*PI)/28*(sdan%28)); /* Utvrdjuje se emocionalno stanje. */
fiz=sin((2*PI)/23*(sdan%23)); /* Utvrdjuje se fizicko stanje. */
gotoxy(4,24);

/* Prikazuje se u procentima parametri stanja na ekranu. */
printf("Intelektualni: %.2f%c Emocionalni: %.2f%c Fizicki: %.2f%c",
in*100,'%',emo*100,'%',fiz*100,'%');

/* Ako je stanje negativno, sabiranjem sa 1 i mnozenjem sa duzinom skale 30 dobija se
broj na osnovu koga ce se ciklusom dobiti prikaz stanja na skali. */

j=(1+in)*30;
textbackground(1); /* Postavlja se boja skale. */
gotoxy(2,10);printf("Intelektualni:");
for(i=0;i<j;i++)cprintf(" "); /* Crta se skala. */

j=(1+emo)*30;
textbackground(0); gotoxy(16,11);
printf("| | |");
textbackground(2);
gotoxy(4,12);printf("Emocionalni:");
for(i=0;i<j;i++)cprintf(" ");

j=(1+fiz)*30;
textbackground(0); gotoxy(16,13);
printf("| | |");
textbackground(4);
gotoxy(8,14);printf("Fizicki:");
for(i=0;i<j;i++)cprintf(" ");

textbackground(0);
gotoxy(16,15);
printf("| | |");
gotoxy(14,16);
printf("-100% 0 100%");

gotoxy(1,25);
}while(getch()!=ESC);
}

/* Funkcija pitdat utvrdjuje da li je datum rodjenja unesen u string s ispravan. Ako je ispravan
funkcija vraca 0, a u suprotnom vraca 1. */

int pitdat(char *s, int saddan, int sadmes, int sadgod, int *dan, int *mes, int *god)
{
char *pok;

220
/* Izmedju dana, meseca i godine rodjenja mora se nalaziti separator (tacka, zarez ili
prazno mesto). Funkcijom strto izdvajaju se delovi stringa. */

pok=strtok(s,":,. "); *dan=atoi(pok);
pok=strtok(NULL,":,. "); *mes=atoi(pok);
pok=strtok(NULL,":,. "); *god=atoi(pok);

/* Godina rodjenja ne sme biti veca od sadasnje godine, ili ako je jednaka mesec rodjenja
ne sme biti veci od trenutnog meseca, ili ako se godine i meseci poklapaju, tada dan
rodjenja ne sme biti veci od sadasnjeg dana. */

if(*god>sadgod) return 1;
if(*god==sadgod && *mes>sadmes) return 1;
if(*god==sadgod && *mes==sadmes && *dan>saddan) return 1;

/* Sada se proverava ispravnost broja dana u mesecu u odnosu na mesec. */
if(*god>0 && *god<2999)
{
if (((*mes==1 || *mes==3 || *mes==5
|| *mes==7 || *mes==8 || *mes==10
|| *mes==12) && (*dan < 32)) ||
((*mes==4 || *mes==6 || *mes==9
|| *mes==11) && (*dan < 31)) ||
((*mes==2) && (*dan<30) && (!(*god%4) && (*god%100) ||
((*mes==2) && (*dan<29))))) return 1;
}
return 0;
}

Test primer programa:



221


6.2. INICIJALIZACIJA STRUKTURE
NIZ STRUKTURA


Inicijalizacijom strukture obezbeuje da svi lanovi strukture imaju
definisanu poetnu vrednost. Za numerike tipove podataka uobiajno je dodeliti
vrednost nula, dok je kod stringovnih promenljivih uobiajno je da se funkcijom strcpy
koja se nalazi u string.h stringovnoj promenljivi upie prazan string. Prazan string sadri
samo znak kraja stringa '\0'. Kada lan niza predstavlja pokaziva moramo ga postaviti
na vrednost NULL.
Na primer za strukturu radnik sa prolog asa inicijalizacija imala bi sledei izgled.

/* Definicija strukture radnik. */
struct radnik{
char prezime_i_ime[MAX];
unsigned starost;
unsigned staz;
} Tradnik;

/* Deklaracija strukturne promenljive a i b tipa Tradnik. */
Tradnik a, b;

/* Inicijalizacija strukturne promenljive a. */
strcpy(a.prezime_i_ime, ""); /* "" je prazan string. */
a.starost = 0;
a.staz = 0;

/* Naredbu dodele mozemo koristiti izmedju struktura. */
b = a;

Prilikom naredbe dodele vri se automatsko kopiranje odgovarajuih polja jedne
strukture u drugu. U ovom sluaju vrednosti polja strukture a su prekopirane u strukturu
b. Ovim se skrauje kod programa i ne mora se koristiti funkcija strcpy da bi se polje
koje predstavlja string prekopirao iz polja strukture a u polje strukture b.

Strukturna promenljiva se moe inicijalizovati i prilikom deklaracije.
Tradnik a = {"", 0, 0};

Kada je programu potrebno koristiti vie struktura istog tipa, logino je da
se tada koristi niz, pri emu svaki lan niza predstavlja strukturni tip podatka.

Ako se u ovom primeru hoe koristiti vie radnika tada koristimo niz struktura.
Niz struktura se definie na isti nain kao bilo koji niz Svaki lan niza je tipa strukture, a
u ovom primeru je to Tradnik.
222
Tradnik x[50], a; /* Ovde je a jedna strukturna promenljiva, a x predstavlja niz
struktura. */
unsigned i;

Inicijalizacija niza struktura vri se kao inicijalizacija bilo kog niza. Prvo inicijalizujemo
strukturnu promenljivu a.

strcpy(a.prezime_i_ime, ""); /* "" je prazan string. */
a.starost = 0;
a.staz = 0;

a potom niz struktura pomou ciklusa tako to svaki element niza dobija vrednost a, koja
je predhodno inicijalizovana.

for(i=0;i<50;i++) x[i]=a;

Prilikom pristupa odgovarajuem polju i-tog lana niza strukture piemo:
x[i].starost = 35;

Prvo se pe indeks niza, a potom operator taka da se pristupa lanu strukture.


Primer 1:
Napisati C program koji omoguava unos n uenika n<31 sa podacima: ime do 15
karaktera, prezime do 15 karaktera i broj izostanaka. Prikazati spisak pet ucenika sa
najveim brojem izostanaka sortiranih u opadajuem redosledu po broju izostanaka. Ako
dva ili vie uenika imaju isti broj izostanaka drugi kriterijum je po abecednom
redosledu.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>

#define MAX 30

/* Definicija sablona strukture. */
typedef struct ucenik{
char ime[16];
char prezime[16];
unsigned izostanci;
} Tucenik;

/* Prototipovi funkcija. */
void brisi(unsigned xu, unsigned yu);
void unesistring(char s[], unsigned k);
223
void main(void)
{
Tucenik niz[MAX], a = {"","",0}, pom;
unsigned i, j, k, xn, yn, xu, yu;
int n;

/* Inicijalizacija niza struktura. */
for(i=0;i<MAX;i++) niz[i]=a;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("Broj ucenika: ");
xn=wherex(),yn=wherey();
do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0||n>MAX);

printf("\n\nUnesite podatke o ucenicima:\n\n");
xu=wherex(),yu=wherey();
for(i=0;i<n;i++)
{
brisi(xu,yu);
gotoxy(xu,yu);
printf(" %d UCENIK\n",i+1);
printf("Ime: ");
unesistring(niz[i].ime,15);
printf("\nPrezime: ");
unesistring(niz[i].prezime,15);
printf("\nBroj izostanaka = ");
scanf("%u",&niz[i].izostanci);
}

/* Sortiranje niza strukture kako je definisano tekstom zadatka. */

for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(niz[j].izostanci>=niz[i].izostanci)
{
if(niz[j].izostanci>niz[i].izostanci)
{
pom=niz[j];
niz[j]=niz[i];
niz[i]=pom;
224
}else{

if(strcmp(niz[j].prezime,niz[i].prezime)<0)
{
pom=niz[j];
niz[j]=niz[i];
niz[i]=pom;
}else{
if((strcmp(niz[j].prezime,niz[i].prezime)==0)&&
(strcmp(niz[j].ime,niz[i].ime)<0))
{
pom=niz[j];
niz[j]=niz[i];
niz[i]=pom;
}
}
}
}
}
}


/* Tabelarni prikaz resenja zadatka. */
printf("\n\nPREZIME\t\t\tIME\t\tIZOSTANCI\n");
for(i=1;i<=50;i++) printf("-");
printf("\n");

if(n<5) k=n;
else k=5;

for(i=0;i<k;i++)printf("%-15s\t\t%-15s\t%u\n", niz[i].prezime,niz[i].ime,niz[i].izostanci);
getch();
}


/* Funkcija brise deo ekrana koji je koriscen prilikom predhodnog unosa podataka vezanih
za odredjenog ucenika, a time je obezbedio isti prostor za unos sledeceg ucenika. */

void brisi(unsigned xu, unsigned yu)
{
unsigned i,j;

gotoxy(xu,yu);
for(i=1;i<=25-yu;i++)
{
for(j=1;j<=80-xu;j++) printf(" ");
}
}



225
/* Funkcija omogucava unos stringa koji sadrzi k slova abecede. */
void unesistring(char s[], unsigned k)
{
unsigned i;
char c;

for(i=0;i<k&&c!=13;)
{
if(isalpha(c=getch())) printf("%c",c),s[i]=c,i++;
}
s[i]='\0';
}

Primer 2:
Napisati C program koji uitava tekstualnu datoteku UCENIK.TXT koja u prvom
redu sadri centrirano ispisan naziv odeljenja, sledi prazan red, pa spisak uenika sa
podacima, pri emu se u jednom redu nalaze podaci o jednom ueniku.

Podaci o uenika su:
- Ime;
- Prezime;
- Ime oca; i
- Ocene iz predmeta.

Podaci od jednog uenika su razdvojeni sa blanko mesto, a ocene su spojene.
Oene mogu imati vrednosti od 0 5, pri emu ocena 0 oznaava da uenik iz tog
predmeta nije ocenjen. Program treba da na osnovu uitanih podataka uenika formira niz
struktura, pri emu je svaka struktura opisana sa poljima: Ime, Prezime, Ime oca, srednja
ocena i uspeh (odlian, vrlo dobar, dobar, dovolja, nedovoljan i neocenjen).
Ako je neocenjen u polju srednja_ocena pise broj predmeta iz kojih nije ocenjen, a
ako je nedovoljan u polju srednja_ocena pie broj nedovoljnih ocena.
Na ekranu u prvoj liniji centrirani ispis ocene za odeljenje pa naziv odeljenja,
prazan red, pa tabelarni prikaz uspeha u obliku.

Prezime Srednje slovo imena oca Ime Uspeh Prosena ocena

Ako je uenik nedovoljan u polju prosena ocena pisae broj nedovoljnih ocena, a
ako je neocenjen broj neocenjenih predmeta. U raunanje prosene ocene odeljenja ne
raunaju se oni uenici koji su nedovoljni ili neocenjeni.

Reenje

#include <conio.h>
#include <stdio.h>
#include <string.h>

#define MAX 32

226
/*Definisanje strukture Tucenik. */
typedef struct ucenik{
char ime[15];
char prezime[15];
char imeoca[15];
double sr;
char uspeh [11];
}Tucenik;

void main(void)
{
/* Deklaracija promenljivih. */
FILE *dat;
Tucenik niz[31],a={"","","",0,""};
int i,j,k,l,pit1=0,pit2=0;
double sr;
char s1[7],ss[81],ssc[81],*pom;

textmode(64);
textattr(10);
clrscr();

for(i=0;i<MAX;i++) niz[i]=a;

if((dat=fopen("UCENIK.TXT","r"))==NULL)
{
printf("Datoteka se ne moze otvoriti");
getch();
return;
}

i=0,k=0;
while((fgets(ss,80,dat))!=NULL)
{
if(i==0)
{
/* Ako je prvi red izdvojice se naziv odeljenja */
for(j=0,k=0;ss[j]!='\n'&&ss[j]!='\0';j++)
{
if(ss[j]!=' '&&ss[j]!='\t') s1[k]=ss[j],k++,s1[k+1]='\0';
}
}
else{
/* Izdvajamo podatke za jednog ucenika. */
strcpy(ssc,ss);
pom=strtok(ssc," ");
strcpy(niz[i-1].ime,pom);
pom=strtok(NULL," ");
strcpy(niz[i-1].prezime,pom);
pom=strtok(NULL," ");
strcpy(niz[i-1].imeoca,pom);
227
pom=strtok(NULL," ");

/* Posmatraju se ocene pri cemu ako je ucenik nedovoljan promenljiva
pit2 imace vrednost 1, a u slucaju da je neocenjen promenljiva pit1 imace
vrednost 1. */

for(sr=0,j=0,pit1=0,pit2=0,k=0,l=0;j<strlen(pom)-1;j++)
{
sr+=(pom[j]-'0');
if(pom[j]=='0') pit1=1,k++;
if(pom[j]=='1') pit2=1,l++;
}
sr=sr/j;
niz[i-1].sr=sr;

if(sr>=1.5) strcpy(niz[i-1].uspeh,"DOVOLJAN");
if(sr>=2.5) strcpy(niz[i-1].uspeh,"DOBAR");
if(sr>=3.5) strcpy(niz[i-1].uspeh,"VRLO DOBAR");
if(sr>=4.5) strcpy(niz[i-1].uspeh,"ODLICAN");

/* Ako je ucenik zavrsio sa nedovoljnim umesto srednje ocene pisace
broj nedovoljnih ocenena. */

if(pit2==1)
{
strcpy(niz[i-1].uspeh,"NEDOVOLJAN");
niz[i-1].sr=l;
}

/* Ako je ucenik iz nekih predmeta neocenjen umesto srednje ocene
pisace broj predmeta iz kojih je neocenjen. */

if(pit1==1)
{
strcpy(niz[i-1].uspeh,"NEOCENJEN");
niz[i-1].sr=k;
}
}
i++;
}

/* Racuna se prosek odeljenja u koji se na racunaju proseci ucenika koji su nedovoljni ili
neocenjeni. */

i--,sr=0,k=0;
for(j=0;j<i;j++)
{
if(strcmp(niz[j].uspeh,"NEDOVOLJAN")!=0&&
strcmp(niz[j].uspeh,"NEOCENJEN")!=0) sr+=niz[j].sr,k++;
}
sr=sr/k;
228

/* Tabelarni prikaz ucenika sa ostvarenim uspehom. */
clrscr();
printf(" %s %.2lf\n\n",s1,sr);
printf("");
printf("\n");
printf(" Prezime Sr. ime Ime Uspeh Prosecna ocena \n");
printf("");
printf("\n");

for(j=0;j<i;j++)
{
gotoxy(1,6+j), printf(" %s",niz[j].prezime);
gotoxy(18,6+j), printf(" %c",niz[j].imeoca[0]);
gotoxy(30,6+j), printf(" %s",niz[j].ime);
gotoxy(44,6+j), printf(" %s",niz[j].uspeh);
if(strcmp(niz[j].uspeh,"NEDOVOLJAN")!=0&&
strcmp(niz[j].uspeh,"NEOCENJEN")!=0)
gotoxy(58,6+j), printf(" %.2lf",niz[j].sr);
else gotoxy(58,6+j),printf(" %.0lf %sA",niz[j].sr,niz[j].uspeh);
gotoxy(77,6+j), printf("\n");
}

printf("");
printf("");
getch();
}

Test primer programa:

PRIMER.TXT
R31
Slobodan Prljevic Zdravko 54453554545545
Marko Novakovic Djura 221421232122
Darko Pejakovic Ranko 425554332344
Marijan Beg Andrija 555555555555
Andrea Pavlovic Zoran 243125121332

Izgled programa:


229

6.3. STRUKTURE I FUNKCIJE



Osobine struktura su:
- Strukture su tipovi koje definie programer.
- Podaci strukturnih tipova se smatraju pojedinanim podacima, bez
obzira na njihovu sloenost. To u stvari znai da se na odreenim
mestima koriste kao prosti podaci.
- Podaci meusobno jednakih strukturnih tipova mogu meusobno da se
dodeljuju pomou operatora za dodelu vrednosti. Time se celokupni
sadraj izvorinog podatka prekopira u odredinu strukturnu
promenljivu polje po polje, ne smeta da se meu poljima nalaze i nizovi
ili stringovi.
- Adresa strukturne promenljive moe da se dobije adresnim operatorom
&, ali isto tako mogu da se deklariu i promenljive koje su pokazivai
na strukture. Pristup poljima strukture preko pokazivake promenljive
vri se operatorom diferenciranja *.


Primer 1:
Definii nov tip podatka Tucenik, sa poljima prezime (od maksimalno 30
karaktera) i brizostanaka. Potom deklarii promenljive a i b tipa Tucenik, kao i
pokaziva pok koji moe da pokazuje na promenljive tipa Tucenik.

Reenje:

typedef struct ucenik{
char ime_prezime[31];
unsigned brizostanaka;
} Tucenik;

Tucenik a, b, *pok=NULL;

a i b su strukturne promenljive, dok je pok pokaziva koji moe da pokazuje samo
na strukturne promenljive tipa Tucenik. Pokazivaka promenljiva pok dobija vrednost
NULL koja znai da pokazivaka promenljiva trenutno ne pokazuje ni na jednu
strukturnu promenljivu tipa Tucenik.

pok=&a;

Inicijalizacija strukture se moe izvriti i pomou pokazivake promenljive pok jer
ona sada sadri adresu strukturne promenljive a.

230
strcpy((*pok).ime_prezime,"");
pok->brizostanaka=0;

Strukture i funkcije:
- Prosleivanje lana strukture kao argumenta funkcije.
- Prosleivanje strukture kao argumenta funkcije, i
- Prosleivanje pokazivaa na strukturu kao argumenta funkcije.

Prilikom prosleivanja strukture kao argumenta funkcije, bez obzira na sloenost,
smatra se jednim podatkom. Podrazumevani nain prenoenja strukture u funkciju je
pomou vrednosti. Na ovaj nain se i niz smeta na stek. Iz istih razloga strukture moga
da budu i vrednosti funkcije. Poto niz ne moe da bude vrednost funkcije, ako je to ba
potrebno, moe da se definie struktura ije je jedino polje niz i da se definie strktura
koja vraa upravo podatak tipa te strukture.
Poto strukture mogu da budu jako velike preporuuje se da se one u funkciju
prosleduju po referenci. Takoe radi efikasnosti preporuuje se da se za vrednost
funkcije umesto strukture koristi pokaziva na strukturu.

Primer 2:
Napisati C program koji primenom struktura omoguava unos dva datuma roenja,
osobe A i osobe B. Struktura datuma je opisana sa godinom, mesecem i danom roenja.
Program utvruje koja osoba je starija i za koliko dana.
Prilikom unosa osobe koristiti funkciju unos koja na osnovu oznake osobe (A ili B)
omogucava unos podataka o toj osobi i vraca istrukturu koja opisuje datu osobu.
Prilikom utvrdjivanja koja je osoba starija i za koliko dana koristiti funkciju razlika
koja vraca karakter (A ili B) koji opisuje koja je osoba starija, a prenosom po referenci i
podatak za koliko dana.

Reenje

#include <stdio.h>
#include <conio.h>

/* Definicija sablona strukture. */
typedef struct datum{
unsigned godina;
unsigned mesec;
unsigned dan;
} Tdatum;

/* Prototipovi funkcija. */
Tdatum unos(char *s);
char razlika(Tdatum a, Tdatum b, int *raz);
unsigned zbir(Tdatum *x);


void main(void)
{
231
Tdatum a,b; /* Deklaracija dve strukturne promenljive. Prva se odnosi na osobu A, a
druga na osobu B. */
char raz=0,star=0;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

a=unos("A"); /* Funkciji unos pomou stringa prosledjuje se koja je osoba (A ili B). */
b=unos("B");

/* Funkcija razlika utvrdjuje razliku izmedju dva datuma i vraca karakter 'A' ako je osoba
A starija od osobe B, 'B' ako je osoba B starija od osobe A, ili '\0' ako su rodjene istog
datuma. */

star=razlika(a,b,&raz);
switch(star)
{
case 'A': printf("\n\n\tOsoba A je starija od osobe B za %d dana.",raz);
break;
case 'B': printf("\n\n\tOsoba B je starija od osobe A za %d dana.",raz);
break;
default: printf("Osobe A i B su rodjene istog dana.");
}

gotoxy(1,25);
getch();
}

/* Funkcija omoguava unos datuma rodjenja odredjene osobe A ili B, stim da se u stringu
s nalazi slovo A ili B. Funkcija vraca podatak tipa strukture. */

Tdatum unos(char *s)
{
Tdatum x;
unsigned xu,yu;
int pom;

printf("\n\n\tUnesite datum rodjenja osobe %s:\n",s);
printf("\tGodina: ");
xu=wherex(),yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&pom);
}while(pom<=1900||pom>2020);
x.godina=pom;
printf("\tMesec: ");
xu=wherex(),yu=wherey();
232
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&pom);
}while(pom<=0||pom>12);
x.mesec=pom;

printf("\tDan: ");
xu=wherex(),yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&pom); /* Kod funkcije scanf kao i za promenljive osnovnog tipa
mora se postavljati adresni operator.
*/
}while(pom<=0||pom>31||(x.mesec==2&&(pom!=28||pom!=29)));
x.dan=pom; /* Polju strukture pristupa se operatorom tacka. */

return x; /* Funkcija vraca kao vrednost promenljivu strukturnog tipa. */
}

/* Funkciju razlika koja vraca karakter (A ili B) koji opisuje koja je osoba starija, a
prenosom po referenci i podatak za koliko dana je starija. */
char razlika(Tdatum a, Tdatum b, int *raz)
{
unsigned s1, s2;

/* Izracunavamo ukupan broj dana osobe A od racunanja kalendara pa do rodjenja osobe A.
Priliko pozivanja funkcije gde se argumenti prosledjuju po referenci (prosledjuje se adresa
pokazivackoj promenljivi).
*/
s1=zbir(&a);

/* Izracunavamo ukupan broj dana osobe 'B' od racunanja kalendara pa do rodjenja osobe
'B'. */
s2=zbir(&b);

if(s1<s2)
{
*raz=s2-s1;
return 'A';
}
if(s2<s1)
{
*raz=s1-s2;
return 'B';
}
return '0';
}
233

/* Funkcija izracunavamo ukupan broj dana osobe od racunanja kalendara pa do njenog
rodjenja. */.
unsigned zbir(Tdatum *x)
{
int i;
long int k=0;

/* U zagradi se naglasava da prvo diferenciranjem moramo doci do adrese strukturne
promenljive, pa tek onda operatorom tacka pristupiti odgovarajucem polju strukturne
promenljive. Prevoduilac ce prijaviti gresku jer su oba operatora istog prioriteta. */

for(i=1;i<=(*x).godina-1;i++)
{
if(i%4 == 0 || i%400==0) k+=366;
else k+=365;
}

for(i=1;i<=(*x).mesec-1;i++)
{
switch(i)
{
case 1: case 3: case 5: case 7: case 8: case 12: case 10: k+=31;
break;
case 2: if(i%4 == 0 || i%400==0) k+=29;
else k+=28;
break;
case 4: case 6: case 9: case 11: k+=30;
}
}

k+=x->dan; /* U primeru je umesto (*x).dan ekvivalentno sa x->dan, cime se skracuje
zapis. */
return k;
}

Primer 3:
Napisati C program koji korienjem funkcije unos omoguava unos napona i struje
na jednom potroau u kompleksnom obliku. Prototip funkcije unos je:

Tkomp unos(char c),

Karakter c moe imati vrednosti 'U' ili 'I'. Ako ima vrednost 'U' unosie se napon u
kompleksnom obliku, a ako ima vrednost 'I' unosie se struja u kompleksnom obliku.
Funkcija vraa strukturu tipa Tkomp koja se sastoji od realnog i imaginarnog dela
kompleksnog broja.
Korienjem funkcije potrosac utvruje se prenosom po referenci impendasa
potroaa i prividna snaga u kompleksnom obliku tipa Tkomp.

234
Funkcija vraa:
1 - ako je potroa induktivnog karaktera;
-1 ako je potroa kapacitivnog karaktera; ili
0 ako potroa nije induktivnog ni kapacitivnog karaktera.

Program ispisuje impedansu u kompleksnom obliku i prividnu snagu u
kompleksnom obliku, kao i tip potroaa: AKTIVAN, .INDUKTIVAN ili
KAPACITIVAN.

Reenje

#include <stdio.h>
#include <conio.h>

/* Definise se struktura kompleksnog broja u algebarskom obliku. */
typedef struct komp{
float real;
float imag;
}Tkomp;

/* Prototipovi funkcija. */
Tkomp unos(char c);
int potrosac(Tkomp u, Tkomp i, Tkomp *z, Tkomp *S);

void main(void)
{
/* Deklarisu se promenljive za napon u, struju i, impedansu z i prividnu snagu S, koje se
predstavljaju u kompleksnom obliku te im je tip struktura kompleksnog broja Tkomp. */

Tkomp u, i, z, S;
int k;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

/* Unosi se napon u u kompleksnom obliku, a prosledjuje se karakter 'U' koji oznacava da
se unosi napon. */
printf("Unesite napon u kompleksnom obliku:\n");
u=unos('U');

/* Unosi se struja i u kompleksnom obliku, a prosledjuje se karakter 'I' koji oznacava da
se unosi struja. */
printf("\nUnesite struju u kompleksnom obliku:\n");
i=unos('I');
/* Poziva se funkcija potrosac koja po referenci izracunava impedansu, i prividnu snagu
potrosaca, a vraca broj koji nam simbolicno govori o tipu potrosaca. */
k=potrosac(u,i,&z,&S);
switch(k)
235
{
case 1: printf("\n\nPotrosac je induktivnog karaktera!!");
break;
case -1: printf("\n\nPotrosac je kapacitivnog karaktera!!");
break;
default: printf("\n\nPotrosac je cisto aktivan!!");
}

/* Prikazujemo impedansu u kompleksnom obliku. */
if(z.imag==0) printf("\n\nZ = %f",z.real);
else{
if(z.imag>0) printf("\n\nZ = %f + %fj",z.real,z.imag);
else printf("\n\nZ = %f - %fj",z.real,-(z.imag));
}

/* Prikazujemo prividnu snagu u kompleksnom obliku. */
if(S.imag==0) printf("\n\nS = %f",S.real);
else{
if(S.imag>0) printf("\n\nS = %f + %fj",S.real,S.imag);
else printf("\n\nS = %f - %fj",S.real,-(S.imag));
}

gotoxy(1,25);
getch();
}

/* Funkcija unos na osnovu karaktera c unosi i formira strukturu oblika kompleksnog broja
koja predstavlja napon ili struju. */
Tkomp unos(char c)
{
Tkomp pom;

if(c=='U')
{
printf("Re(U) = ");
scanf("%f",&pom.real);
printf("Im(U) = ");
scanf("%f",&pom.imag);
}else{
printf("Re(I) = ");
scanf("%f",&pom.real);
printf("Im(I) = ");
scanf("%f",&pom.imag);
}
/* Funkcija vraca uneseni podatak (napon ili struja) tipa Tkomp. */
return pom;
}

/* Funkcija potrosac prenosom po referenci izracunava impedansu, i prividnu snagu
potrosaca, a vraca broj koji nam simbolicno govori o tipu potrosaca. */

236
int potrosac(Tkomp u, Tkomp i, Tkomp *z, Tkomp *S)
{
/* Na osnovu izvedene formule za deljenje dva komplerksna broja, nastaju formule kojim
se izracunavaju realni imaginarni deo rezultujuceg kompleksnog broja. Derljenje se vrsi
jer je impedansa jednaka koliniku napona i struje u kompleksnom obliku. */

(*z).real=(u.real*i.real+u.imag*i.imag)/(i.real*i.real+i.imag*i.imag);
(*z).imag=(u.imag*i.real-u.real*i.imag)/(i.real*i.real+i.imag*i.imag);

/* Prividna snaga se racuna kao kolicnik napona i konjugovane struje. Konjugovana
struja dobija se tako sto se promeni predznak kod imaginarnog dela. Izracunavanjem
proizvoda dva kompleksna broja dobicete formulu ciji realni i imaginarni deo moze da se
opise formulama. */

(*S).real= u.real*i.real+u.imag*i.imag;
(*S).imag= u.imag*i.real-u.real*i.imag;

/* Sada se na osnovu imaginarnog dela impedanse utvrdjuje tip potrosaca. Ako je njegova
vrednost pozitivna potrosac je induktivnog karaktera, ako je negativna potrosac je
kapacitivnog karaktera, a ako je jednaka nuli radi se o cisto aktivnom potrosacu. */

if((*z).imag<0) return -1;
else{
if((*z).imag>0) return 1;
else return 0;
}
}
}

Test primer:






237
6.4. RAD SA BINARNIM DATOTEKAMA


Prilikom podele datoteka u programskom jeziku C izvrena je podela na
tekstualne i binarne datoteke. Binarne datoteke najee imaju ekstenziju DAT. Binarna
datoteka se otvara funkcijom fopen, pri emu se mod rb koristi za itanje binarne
datoteke, a wb za upis u binarnu datoteku.

Na primer:
FILE *dat;
dat=fopen("PRIMER.DAT","rb");

Prilikom rada sa binarnim datotekama koriste se dve funkcije: fread (za uitavanje
podataka) i fwrite(za upis podataka) u binarnu datoteku.

Uitavanje podataka iz datoteke:

int fread(void *niz, int vel, int br, FI LE *dat);

Funkcija fread ita iz datoteke na koju pokazuje pokaziva dat najvie br
podataka veliine vel bajtova i smeta u memoriju poev od pozicije niz.
itanje podataka poinje od pozicije gde je prethodni pristup datoteci zavren.
Nakon zavretka itanja pozicionira se nakon poslednjeg proitanog bajta.
Prilikom itanja podataka mora se voditi rauna o logikoj strukturi datoteke, jer
e se u suprotnom itati pogreni podaci. Dunost programera je da o tome vodi rauna.
Vrednost funkcije je uspean broj uitanih podataka.
Najee se prilikom uitavanja vri uitavanje jednog podatka (podatak po
podatak). Podatak je uopteno tipa strukture.

Upis podataka u datoteku:

int fwrite(void *niz, int vel, int br, FI LE *dat);

Funkcija fwrite upisuje u datoteku na koju pokazuje pokaziva dat br podataka
veliine vel bajtova iz memorije poev od adrese niz.
Pisanje podataka u datoteci poinje gde je prethodni pristup datoteci zavren.
Ako trenutna pozicija nije na kraju datoteke podaci se upisuju preko postojeih
podataka. Po zavretku pisanja nastavlja se posle poslednjeg upisanog bajta.
Funkcija vraa broj prenetih podataka.

Primer 1:
Zadata je binarna datoteka SMENE.DAT. Datoteka se sastoji od binarnih rei, koje
predstavljajju podatke o jednodnevnom uinku smene..
Napisati C program koji na osnovu binarne datoteke o jednodnevnom uinku smene
daje po izboru korisnika: tabelarni prikaz uinka odgovarajue smene i tabelarni
238
uporednidni prikaz uinka sih smena. U toku jednog dana rade etiri smene (1...4 smene),
tokom svake smene se broje proizvodi (do 50 000 komada). na 64 merna mesta.
Podaci su smeteni u 24 bitnu re oblika:

0 - 15 bita - broj proizvoda
16 - 21 bita - broj mernog mesta
22 - 23 bita - broj smene

Binarna datoteka se sastoji od vie podataka (za svaku smenu i merno mesto jedan
podatak, tj binarna re), pri emu je svaki podatak smeten u 24-bitnu re.

Reenje

#include <stdio.h>
#include <conio.h>

/* Definisanje novog tipa podatka Tmatrica. */
typedef unsigned TMatrica[4][5];

/* Prototipovi funkcija. */
void UcinakSmene(TMatrica JednUcinak);
void UporednaLista(TMatrica JednUcinak);
char OsnMeni();
char UcitajPodatke(TMatrica JednUcinak);
void Inicijalizacija(TMatrica JednUcinak);

void main (void)
{
char kraj=0;
TMatrica JednUcinak;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

/* Inicijalizacija matrice. */
Inicijalizacija(JednUcinak);


/* Ucitavanje podataka iz binarne datoteke u matricu. */
if(UcitajPodatke(JednUcinak))
{
do{
/* Izbor jedne od tri ponudjene opcije. */
switch(OsnMeni())
{
/* Ispisuje se ucinak jedne smene. */
case '1': UcinakSmene(JednUcinak);
break;
239
/* Prikazuje se uporedni prikaz smena. */
case '2': UporednaLista(JednUcinak);
break;
/* Izlazak iz programa. */
case '3': kraj=1;
}
} while (!kraj);
}
}

/* Funkcija inicijalizacija vrsi inicijalizaciju matrice. */
void Inicijalizacija(TMatrica JednUcinak)
{
unsigned i,j;

for (i=0;i<4;i++)
{
for (j=0;j<5;j++) JednUcinak[i][j]=0;
}
}

/* Funkcija UcitajPodatke ucitava podatke iz binarne datoteke i smesta ih u matricu. */
char UcitajPodatke(TMatrica JednUcinak)
{

/* Kako ce se u programu vrsiti shiftovanje na nivou bitova to se mora promenljiva temp,
gde se podaci smestaju iz datoteke i koja ce se shiftovati, deklarisati kao nenegativan
podatak, tj podatak tipa unsigned. */

unsigned i,j,BrKomada;
FILE *dat;
unsigned long temp;

/* Ucitavanje datoteke SMENE.DAT. */
if ((dat=fopen("SMENE.DAT","rb"))==NULL)
{

printf("\n\n NE POSTOJI DATOTEKA `FABRIKA.DAT`");
printf("\n\n Pritisnite bilo koji taster za izlazak iz programa..");
getch();
return 0;

}else{

/* Ucitavamo funkcijom fread jer je datoteka binarna, jednu po jednu rec, a kako
je rec duzine 24 bita = 3 bajta, ucitavamo stalno po 3 bajta iz datoteke. */

while(fread(&temp,3,1,dat))
{
/* Matrica se formira tako sto indekis i matrice pretstavlja broj smene,
indeks j pretstavlja broj mernog mesta, a vrednost matrice na poziciji i,j
240
pretstavlja broj proizvoda koje je i-ta smena napravila na j-tom mernom
mestu. */

i=(temp>>22) & 0x3 ;
j=(temp>>16) & 0x3f;
BrKomada=(temp & 0xffff);
JednUcinak[i][j]+=BrKomada;
}
fclose(dat);
return 1;
}
}

/* Funkcija OsnMeni iscrtava meni koji prikazuje ponudjene opcije I izbor jedne od ponudjenih
opcija. */
char OsnMeni(void)
{
char odg,i;

clrscr();
printf("\n\nProgram za ispisivanje ucinka fabrike.");
printf("\n\nIzaberite opciju prema njenom rednom broju.");
printf("\n---------------------------------------------");
printf("\n 1. Lista ucinka odredjene smene.");
printf("\n 2. Uporedna lista za sve smene.");
printf("\n 3. Kraj rada.");
printf("\n---------------------------------------------");
printf("\nVas izbor je (1-3) --> ");

i = wherex(); /* Kolona gde je kursor. */
do{
odg = getche();
/* Vraca kod tastera sa ehom, getch() bez eha. */
if (odg == '\r') /*Ako je odmah pritisnut Enter*/
{
gotoxy(i,wherey()); /*Vrati se gde si bio*/
printf("\a");
}else if (odg < '1' || odg > '5') printf("\b \b\a");
}while (odg < '1' || odg > '3');

return(odg);
}


/* Funkcija UcinakSmene omogucava da se vidi tabelarni prikaz ucinka jedne smene. */
void UcinakSmene(TMatrica JednUcinak)
{
unsigned short smena,j,i;
unsigned long suma=0;
char odg;

241
do{
/* Korisnik unosi broj smene za koju hoce da vidi tabelarni prikaz. */
clrscr();
do{
printf("Unesite smenu za koju zelite da vidite ucinak (1..4): ");
scanf("%i",&smena);
if((smena<1)||(smena>4))
printf("Uneli ste nepostojecu smenu!");
} while((smena<1)||(smena>4));

/* Tabelarni prikaz izabrane smene. */

clrscr();
printf(" Ucinak %i. smene",smena);
printf("\n-------------------------------------------------------");
for (j=0;j<5;j++)
{
printf("\n Merno mesto:%u Broj proizvoda: %u",
j+1,JednUcinak[smena-1][j]);
suma+=JednUcinak[smena-1][j];
}
printf("\n---------------------------------------------");
printf("\nUkupan broj proizvoda smene je: %lu\n\n\n",suma);
printf("\n---------------------------------------------");
printf("\nZelite li da pogledate jos neku smenu (D/N)?");

/* Omogucava se korisniku da ako hoce moze pogledati i ucinak neke druge ili
ponovno iste te smene. */

i = wherex();
do{
odg = getche();
if (odg!='D'&&odg!='d'&&odg!='N'&&odg!='n')
{
if (odg == '\r') gotoxy(i,wherey());
else printf("\b \b");
printf("\a");
}
}while(odg!='D'&&odg!='d'&&odg!='N'&&odg!='n');
} while (odg == 'D' || odg == 'd');
}



/* Uporedna lista ucinka sve cetiri smene. */
void UporednaLista(TMatrica JednUcinak)
{
unsigned long suma=0,sumasmena1=0,sumasmena2=0,
unsigned long sumasmena3=0,sumasmena4=0;
int j;

242
clrscr();
printf("Br. mer. I smena II smena III smena IV smena Ukupno za");
printf("\nmesta mer. mesto\n");
printf("--------------------------------------------------------------------");
for (j=0;j<5;j++)
{
sumasmena1+=JednUcinak[0][j];
sumasmena2+=JednUcinak[1][j];
sumasmena3+=JednUcinak[2][j];
sumasmena4+=JednUcinak[3][j];
suma=JednUcinak[0][j]+JednUcinak[1][j]+JednUcinak[2][j]+
JednUcinak[3][j];
printf("\n%-10u%-12u%-12u%-13u%-12u%-9lu",j+1,
JednUcinak[0][j],JednUcinak[1][j],JednUcinak[2][j],
JednUcinak[3][j],suma);
}
printf("\n--------------------------------------------------------------------");

suma=sumasmena1+sumasmena2+sumasmena3+sumasmena4;
printf("\nUKUPNO %-12lu%-12lu%-13lu%-12lu%-9lu",
sumasmena1,sumasmena2,sumasmena3,sumasmena4,suma);
printf("\n\n Pritisnite bilo koji taster za nastavak programa..");
getch();
}
Binarnu datoteku jako je teko formirati u editoru teksta, ve je to potrebno reiti
programski. Iz tog razloga napisaemo mali program koji omoguava formiranje binarne
datoteke SMENE.DAT koja e vam posluiti za testiranje.

Primer 2:
Napisati C program koji omoguava formiranje datoteke SMENE.DAT koja e
nam posluiti za testiranje prethodnog zadatka.

Reenje

# include <stdio.h>
# include <conio.h>

#define MAX 20

void main (void)
{
FILE *dat;
long broj;

/* Formira se niz gde ce svaki clan niza imati vrednost 0 ili 1. */
unsigned x[24];
long p,i,j,k;
/* Otvara se binarna datoteka za upis podataka. */
clrscr();
dat=fopen("SMENE.DAT","wb");
243

/* Unecemo MAX reci, pri cemu svaka rec je 24-bitna. */
for (i=0;i<MAX;i++)
{
printf("Unesite %d. broj ",i+1);
for(j=0;j<24;j++) x[j]=getche()-48;

/* Pretvaramo iz binarnog u broj, a prilikom upisa on ce automatski biti
upisan u binarnom obliku. */
p=1,broj=0;
for (k=0;k<24;k++)
{
broj=broj+x[23-k]*p;
p=p*2;
}
/* Upisujemo rec u binarnu datoteku. */
fwrite(&broj,3,1,dat);

printf("\n");
}

fclose(dat);
}


























244

6.5. FORMIRANJE HEDERA ZA RAD SA MIEM

Kreiraemo heder sa imenom MIS.H kojeg emo koristiti kad god nam je u
programu potrebno koristiti mia. Nije potrebno znati kako funkcije rade ako hoete
koristiti mia. Potrebno je samo znati ta radi koja funkcija i poznavati dobro strukturu
mia, tj tip podatka Tmiss koja je definisana u hederu MIS.H.

MIS.H

/* U hederu dos.h nalazi se struktura REGS I funkcija int86. */
#include <dos.h>
#include <stdio.h>
#include <conio.h>

/* Interapt 33H omogucava kacenje drajvera misa. Interapti se pisu u heksadecimalnom obliku*/

const MOUSE_INTR = 0x33;

/* Prototipovi funkcija. */
void mis(void);
int da_levod(void);
int da_desnod(void);
int citaj(void);
void kursor_uklj(void);
void kursor_isklj(void);
int reset(void);

/* Definicija strukture misa. */
struct Miss {
int instaliran; /* Indikator da li je mis instaliran. */
int x; /* Trenutna x koordinata kursora misa. */
int y; /* Trenutna y koordinata kursora misa. */
int starax; /* Pamti se predhodna x koordinata kursora misa. */
int staray; /* Pamti se trenutna y koordinata kursora misa. */
int vidljiv; /* Indikator da li se kursor misa vidi na ekranu. */
int levod; /* Indikator da li je pritisnut levi taster misa. */
int desnod; /* Indikator da li je pritisnut desni taster misa. */
} TMiss;


/* Funkcija mis omogucava da se instalira mis i podese pocetne vrednosti. */
void mis(void)
{

/* Ako promenljiva instaliran dobije vrednost 0 znak je da mis nije instaliran. */

TMiss.instaliran = reset();
TMiss.x = TMiss.y = TMiss.starax = TMiss.staray = -1;
245
TMiss.vidljiv = 0;
kursor_uklj();
}

/* Funkcija da_levo utvrdjuje da li je pritisnut levi taster misa. */
int da_levod(void)
{
union REGS r;

if(!TMiss.instaliran) return 1;

/* U akumulator se upisuje vrednost 3 i poziva se interapt 33h preko funkcije int68. */

r.x.ax = 3;
int86(MOUSE_INTR,&r,&r);

/* U registru BX zapisan je status tastera. Ako je njegova vrednost jednaka 1 znai da je
pritisnut levi taster misa. */

return r.x.bx & 1 ? 1 : 0;
}

/* Funkcija da_desno utvrdjuje da li je pritisnut desni taster misa. */
int da_desnod(void)
{
union REGS r;

if(!TMiss.instaliran) return 0;
r.x.ax = 3;
int86(MOUSE_INTR,&r,&r);

/* U registru BX zapisan je status tastera. Ako je njegova vrednost jednaka 2 znai da je
pritisnut desni taster misa. */

return r.x.bx & 2 ? 1 : 0;
}

/* Funkcija citaj vraca vrednost nula ako mis nije instaliran ili ako nije pritisnut niti jedan taster
misa a niti je mis pomeren na drugu poziciju. U suprotnom vraca vrednost jedan.*/
int citaj(void)
{
union REGS r;

if(!TMiss.instaliran) return 0;
r.x.ax = 3;
int86(MOUSE_INTR,&r,&r);

/* U startx i starty sacuvaju se predhodne pozicije misa. */
TMiss.starax = TMiss.x;
TMiss.staray = TMiss.y;

246
/* Koordinate misa se uvek zadaju kao da se radi o grafikom reimu. Iz tih razloga vri se
deljenje koordinata sa 8 kako bi se izvrilo pretvaranje u tekstualni reim. */
TMiss.x = r.x.cx/8+1;
TMiss.y = r.x.dx/8+1;
if(TMiss.levod == r.x.bx & 1 && TMiss.desnod == r.x.bx & 2 &&
TMiss.starax == TMiss.x && TMiss.staray == TMiss.y) return 0;
TMiss.levod = r.x.bx & 1 ? 1 : 0;
TMiss.desnod = r.x.bx & 2 ? 1 : 0;

return 1;
}

/* Poziv funkcije za prikazivanje kursora misa. */
void kursor_uklj(void)
{
union REGS r;

if(TMiss.vidljiv) return;

/* Mis se prikazuje tako to se u akumulatoru upie vrednost 1 i pozove interapt 33h. */
r.x.ax = 1;
int86(MOUSE_INTR,&r,&r);

/* Promenljiva vidljiv ima vrednost 1 ako je mis vidljiv na ekranu, a 0 u suprotnom. */
TMiss.vidljiv = 1;
}

/* Funkcija onemogucava prikazivanje kursora misa. */
void kursor_isklj(void)
{
union REGS r;

if(!TMiss.vidljiv) return;

/* Mis se ne prikaziuje ako se u akumulator upie vrednost 2 i pozove interapt 33h. */
r.x.ax = 2;
int86(MOUSE_INTR,&r,&r);

TMiss.vidljiv = 0;
}

/* Funkcija reset omogucava resetovanje misa. */
int reset(void)
{
union REGS r;
r.x.ax = 0;
int86(MOUSE_INTR,&r,&r);

return r.x.ax ? 1 : 0;
}

247
Primer:
Napisati C program koji omoguava demonstraciju rukovanja sa miem u
programima pod DOS-om. Nakon pritiskanja levog tastera mia na tekuoj poziciji se
upisuje na ekranu vrednost 1, a ako se pritisne desni taster na ekranu se prikazuje broj 2.
Prilikom realizacije programa obavezno koristiti heder MIS:H. Iz programa se izlazi ako
se pritisne neki taster sa tastature.

Reenje

#include <stdio.h>
#include <conio.h>
#include "mis.h"


void main(void)
{
textmode(3);
textcolor(15);
textbackground(0);
clrscr();

/* Iskljucujemo kursor. */
_setcursortype(_NOCURSOR);

/* Ukljucujemo misa u program. */
mis();

/* Stalno utvrdjujemo poziciju kursora misa i da li je pritisnut levi ili desni taster misa. */

while(citaj())
{

/* Ako je pritisnut levi taster misa levod imace vrednost 1. */
if(TMiss.levod)
{
/* Obavezno pre ispisivanja necega na ekranu iskljuciti kursor misa, jer
ako to ne uradite na poziciji gde se kursor trenutno nalazi nece biti nista
ispisano. */

kursor_isklj();
gotoxy(TMiss.x,TMiss.y);
textbackground(0);
cprintf("1");
TMiss.levod=0;

/* Nakon ispisivanja teksta potrebno je ponovno ukljuciti kursor misa. */

kursor_uklj();
}

248
/* Ako je pritisnut desni taster misa desnod imace vrednost 1. */
if(TMiss.desnod)
{
kursor_isklj();
textbackground(0);
gotoxy(TMiss.x,TMiss.y);
cprintf("2");
TMiss.desnod=0;
kursor_uklj();
}


if(kbhit())
{
/* Iz programa izlazimo kada se pritisne neki taster sa tastature. Te iz tih
razloga koristimo funkciju kbhit. Pre izlaska iz programa potrebno je
obavezno iskljuciti kursor misa. */

kursor_isklj();
return;
}
}

}

Test primer programa:











249
6.6. ZADACI IZ STRUKTURA, NIZOVA STRUKTURA I BINARNIH
DATOTEKA



Zadatak 1 (2)
Napisati C program koji omoguava unos dva ugla i izraunava njihov zbir.
Svaki ugao je okarakterisan sa poljima:

1) stepen (0
0
-360
0
),
2) minut (0'-59'), i
3) sekund (0"-59")

Zadatak 2 (2)
Napisati C program koji korienjem funkcije dekupol prevodi taku zadatu sa x i y
koordinatama Dekartovog koordinatnog sistema u polarni koordinatni sistem opisan sa
radijusom i uglom.

Zadatak 3 (2)
Napisati C program koji omoguava unos napona i struje pomou stringova u
trigonometrijskom obliku: ) cos( max ) ( + = wt U t u i ) cos( Im ) ( + = wt ax i i .
Program treba da predstavi struju i napon u algebarskom obliku, a potom da izrauna
impedansu potroaa.

Zadatak 4 (2)
Napisati C program koji izraunava obim poligona koji se zadaje sa nizom svojih
taaka. Svaka taka je opisana sa x i y koordinatom.


Zadatak 5 (2)
Napisati C program koji formira i na ekranu tampa tabelarni prikaz sledeeg
oblika:

R. Br. Reda Broj reci Broj samoglasnika Broj suglasnika
1 7 24 56
2 10 35 45 , itd

Naziv tekstualne datoteke uneti sa tastature ili iz komandne linije.


Zadatak 6 (3)
U Dekartovom koordinatnom sistemu zadat je skup od n, n<100 krunica. Svaka
krunica opisana je sa poljima: x-koordinata centra, y-koordinata centra i poluprenikom.
Napisati C program koji pronalazi i na ekranu tampa one krunice koje u sebi sadre
najvie drugih krunica.

250
Zadatak 7 (2)
U tekstualnoj datotecin POLIGON.TXT nalazi se u svakom redu dva podatka
razdvojena sa po jednim blanko mestom. Prvi podatak predstavlja x, a drugi y koordinatu
take konveksnog poligona. Ako se take u datoteci nalaze zapisane po redu koji
odgovara matematikom smeru obilaska kroz poligon, napisati C program koji
izraunava pozivom funkcije teziste koordinate teita poligona.
Teite poligona rauna se po formulama:

=
=
n
i
i
x
n
xt
1
1
i

=
=
n
i
i
y
n
yt
1
1


Zadatak 8 (3)
Napisati C program koji omoguava unos razlomka u obliku strukture pod imenom
racionalni koja se sastoji od dva polja: brojilac i imenilac. Koristei funkciju skrati
omoguiti da se razlomak dovede u oblik koji se ne moe skratiti, i kao takav se tampa
na ekranu.

Zadatak 9 (3)
Napisati C program koji uitava niz struktura o uspehu uenika na prijemnom
ispitu, a zatim klasifikuje kandidate u tri kategorije A, B i C. Svaka struktura koja se
uitava sa ulaza sadri dva polja: ime i poeni, a u obradi treba dodeliti i tree polje rang.
Kandidat je u rangu: A ako ima vie od 80% od ukupnog broja bodova koji se moe
osvojiti na ispiti, B ako ima vie od 35%, ili C u suprotnom. Niz struktura se uitava iz
binarne datoteke ije ime se unosi sa tastature.

Zadatak 10 (3)
Napisati C program koji omoguava unos dva razlomka i pozivom odgovarajuih
funkcija izrauna i prikae na ekranu njihov zbir, razliku, proizvod i kolinik. Razlomak
je u obliku strukture pod imenom racionalni koja se sastoji od dva polja: brojilac i
imenilac.

Zadatak 11 (3)
Napisati C program koji omoguava uitavanje podataka iz najmanje jedne
tekstualne datoteke u niz struktura. U svakom redu tekstualne datoteke nalazi se Prezime,
Ime i broj bodova sa ispita za svakog studenta. Datoteke se unose iz komandne linije.
Niz struktura sortirati u opadajuem redosledu po broju bodova, a ukoliko vie
kandidata ima isti broj bodova, drugi kriterijum je sortiranje u rastuem abecednom
redosledu. Obraene podatke iz niza struktura upisati u novu tekstualnu datoteku.

Zadatak 12 (3)
Napisati C program koji uitava tekastualnu datoteku i formira niz struktura sa
poljima: re i broj pojave te rei u datoteci, sortira niz struktura u opadajuem redosledu
po broju pojavljivanja rei u datoteci, a u sluaju da vie rei ima isti broj pojavljivanja,
po abecedi. Na kraju tampati na ekranu tabelarni prikaz pojave rei u tekstualnoj
datoteci.

251
Zadatak 13 (3)
Formirati tekstualnu datoteku UCENICI.TXT pa u tu datoteku uneti podatke za n
uenika n<50, i to (prezime, ime, datum roenja oblika dd.mm.gg, uspeh opisno izraen,
putnik Da ili Ne, i izostanci). U svakom redu nalaze se podaci o samo jednom ueniku.
Oitati datoteku i podatke smestiti u niz struktura. Strukturu sortirati po abecednom
redosledu i tampati je na ekranu.

Zadatak 14 (3)
Napisati C program za praenje glasanja na muzikom festivalu. Svaka pesma
dobija ocenu irika (od 0 do 10) i ocenu publike (od 0 do 10). Program treba da omogui:
unos naziva pesme, naziv izvoaa, broj osvojenih bodova, kao i izlistavanje rezultata po
opadajuem redosledu broja bodova

Zadatak 15 (3)
U tekstualnoj datotecin POLIGON.TXT nalazi se u svakom redu dva podatka
razdvojena sa po jednim blanko mestom. Prvi podatak predstavlja x, a drugi y koordinatu
take konveksnog poligona. Ako se take u datoteci nalaze zapisane po redu koji
odgovara matematikom smeru obilaska kroz poligon, napisati C program koji
izraunava pozivom funkcije povrsina povrinu poligona.
Povrina trougla zadata sa koordinatama temena taaka A(xa,ya), B(xb,yb) i
C(xc,yc) rauna se po formulu:
) ( ) ( ) (
2
1
yb ya xc ya yc xb yc yb xa P + + =

Zadatak 16 (4)
Napisati C program koji formira niz struktura na osnovu tekstualne datoteke
IGRACI.TXT o takmiarima svetskog prvenstva u fudbalu tako da svaka struktura
takmiara sadri sledea polja: Prezime, Ime, Broj na dresu, Godine ivota, Ime
reprezentacije, Broj uea na svetskim prvenstvima, Broj zlatnih, Broj srebrnih i Broj
bronzanih medalja.
Sortirati reprezentacije prema uspenosti na svetskim prvenstvima i ispitati koja
reprezentacija ima najveu cenu na tritu.

Zadatak 17 (4)
U datoteci RADNICI.TXT nalaze se podaci o radnicima neke firme, zapisani u
obliku:
broj radnika... prvi red
ime radnika1.. drugi red
godina staa... trei red
plata radnika... etvrti red
ime radnika2... peti red, itd.

Oitati podatke o radnicima pa sortirati radnike prema plati i po abecednom
redosledu ako imaju istu platu. Na svaku godinu staa dodaje se po 0,2% na platu
radnika. Tako sortirane rezultate ponovo smestiti u istu datoteku ne menjajui prvi red
datoteke.
252
Zadatak 18 (4)
Napisati C program za mesenu evidenciju saobraaja vozila preko mostova. Podaci
se nalaze u datoteci organizovanoj po 32-bitnim reima jednog brojanja:

0 bit - bit parnog pariteta,
1 - 14 bita - broj vozila koja su tada prela most,
15 - 19 - sat,
20 - 24 - dan,
25 - 28 - nesec, i
29 - 31 - ifra mosta.

Program treba da omogui sledee:
- Uitavanje podataka barem iz jedne datoteke uz proveru informacija 0-tog
bita parnog pariteta,
- Prikaz tabele (mesec most i prosean broj vozila po satima), i
- Odreivanje ifre vozila koje je toga meseca najvie puta prelazilo most.

Zadatak 19 (4)
Napisati C program koji omoguava evidenciju stanja bankovnih rauna korisnika
u jednoj banci. Jedan raun se opisuje brojem rauna, imenom i prezimenom vlasnika
rauna, matinim brojem vlasnika rauna, stanjem rauna. Program treba da omogui
pregled stanja rauna za zadatog korisnika, izlistavanje svih rauna koji su u minusu,
otvaranje novog rauna za novog korisnika, kao i funkciju za prenos zadate svote sa
jednog na drugi raun u okviru banke. Jedan korisnik moe imati samo jedan otvoreni
raun u banci. Obezbediti trajno uvanje podataka u datoteci ACCOUNT.DAT.


Zadatak 20 (4)
Zadata je tektualna datoteka PROMENE.TXT u formatu: pr_sifra (dvanaest
cifara), pr_kolicina (pet celih i dva decimalna mesta), pr_cena (0 ulaz, ili 1 - izlaz) i
pr_smer (sedam celih i dva decimalna mesta).
Napisati C program koji sekvencijalno ita datoteku PROMENE.TXT i formira niz
struktura sortiranu u rastuem redosledu ifre iji elementi sadre sledea polja: st_sifra,
st_kolicina, st_cena i st_vrednost.


=
1 0
_ _ _
smerom sa sifre
te promene sve za
smerom sa sifre
te promene sve za
kolicina pr kolicina pr kolicina st

st_cena je najvea cena u svim strukturama promene za tu ifru.
st_vrednost = st_cena * st_kolicina

Na kraju tampati niz struktura u proizvoljnom formatu, ali tako, da se posle
tampanja poslednjeg elementa strukture odtampa ukupna vrednost sve robe u
magacinu.


253
Zadatak 21 (5)
Napisati C program za elektronsko voenje kolske biblioteke. Svaki lan
biblioteke je okarakterisan sa:

1) Prezime i ime,
2) lanski broj,
3) Adresa stanovanja,
4) Razred,
5) Telefon, i
6) Broj uzetih knjiga.

Program treba da omogui:

a) Upis novog lana, pri emu automatski dobija lanski broj,
b) Brisanje pojedinog lana iz biblioteke pod uslovom da je vratio sve knjige
koje je iz biblioteke zaduio,
c) Izmene pojedinih podataka o lanu,
d) Ispis podataka o svim lanovima po kriterijumu broja zaduenih knjiga,
e) Utvivanje koji razred ima najvie neurednih korisnika biblioteke,
f) Na kraju kolske godine prikaz svih lanova etvrte godine koji nisu vratili
knjige, i
g) Automatso preimenovanje oznake svih odeljenja kole na poetku kolske
godine.


Zadatak 22 (5)
Napisati C program koji na osnovu unetog prirodnog broja n, 1<n<11 i formira
kvadratnu matricu A dimenzije nxn i inverznu matricu AINZ matrice A. Elementi
matrice A i AINZ su strukture koje se sastoje od dva polja: brojilac i imenilac.
Postupak za odreivanje inverzne matrice je sledei: Prvo se formira jedinina
matrica AINZ. Matrica je jedinina ako su svi elementi na glavnoj dijagonaliu jednaki
jedan. Sada se od matrice A formira jedinina matrica. Kod matrice se mogu izvravati
sledee transformacije: sabiranje jedne vrsta (kolone) sa drugom vrstom (kolonom),
mnoenje vrste (kolone) brojem razliitim od nule ili mnoenjem jedne vrste (kolone)
brojem i dodavanjem drugoj vrsti (koloni). Sav postupak koji se radi sa vrstama
(kolonama) matrice A tako da ona postane jedinina raditi i sa vrstama (kolonama)
matrice AINZ. Kada nakon ovih postupaka matrica A postane jedinina tada e matrica
AINZ postati inverzna matrica matrice A.
Program omoguava tampanje inverzne matrice tako da elementi budu
predstavljeni u obliku prostih razlomaka (razlomaka koji se ne mogu skratiti).

Zadatak 23 (5)
Napisati C program kkoji primenom Gausovog postupka eliminacije u matrinom
obliku omoguava reavanje sistema linearnih jednaina.

Gausov postupak eliminacije glasi:
254
Uopteni sistem jednaina moe se predstaviti u obliku:
n n nn n n n
n n
n n
c x a x a x a x a
c x a x a x a x a
c x a x a x a x a
= + + + +
= + + + +
= + + + +
1 3 3 2 2 1 1
2 1 2 3 23 2 22 1 21
1 1 1 3 13 2 12 1 11
...
.
.
.
...
...


Sistem n jednaina sa n nepoznatih moe se ekvivalentno predstaviti i u matrinoj
formi: C X A = , pri emu su A, X i C matrice.

(
(
(
(

=
nn n n n
n
n
a a a a
a a a a
a a a a
A
. . .
. . . . . .
. . .
. . .
3 2 1
2 23 22 21
1 13 12 11

(
(
(
(

=
n
x
x
x
X
.
2
1

(
(
(
(

=
n
c
c
c
C
.
2
1


Reenje matrine jednaine je dato u obliku: C A X =
1
gde je A
-1
inverzna
matrica matrice A. Slino kao i u predhodnom zadatku potrebno je obezbediti da reenja
budu u obliku razlomaka koji se ne mogu skratiti. Sistem jednaina nalazi se zapisan u
tekstualnoj datoteci iji naziv sa putanjom se unosi sa tastature.

Zadatak 24 (5)
Napisati C program za voenje takmienja iz osnova elektrotehnike. Svaki
takmiar je opisan sa imenom i prezimenom, naziv kole, ime grada i broj osvojenih
poena. Na osnovu unetih podataka formira se lista takmiara. Na osnovu liste rezultata
formirati dve datoteke. U datoteku POBEDNICI.TXT upisati takmiare koji su se
plasirali na daljnje takmienje (20% uesnika). U datoteku PLASMAN.TXT upisati
plasman kola uesnica na takmienju po rezultatu (ukuopan broj bodova koje su
takmiari te kole ostvarili).
Omoguiti da se formirane datoteke mogu tampati na tampau (77 linija 12
inna duina papira). Stranice moraju imati zaglavlje i numeraciju.


Zadatak 25 (5)
Napisati C program koji na osnovu uitane datoteke sa C programom i na ekranu
prikazuje sledei tabelarni prikaz pojave naredbi selekcije if, if-else ili naredbi ciklusa
for, while ili do-while po redovima u datoteci, u obliku:

if1 while1 if2 do-while1 for1 if3...
10 23 12 34 55 56
10 30 60 38 55 58
nema 62 nema
else 62 else
255
Zadatak 26 (5)
Napisati C program za klasifikaciju uplata na raune banka/preduzee. Svaka
uplata je okarakterisana sa: brojem rauna (14 cifara prvih pet oznaava SPP
poslovnicu a ostali su interni za datu poslovnicu), i uplaenim iznosom Program treba da
prihvati sve uplate jednog dana iz date binarne datoteke i klasifikuje ih u tekstualne
datoteke SPP poslovnica tako da svaka SPP poslovnica za koju postoji barem jedna
uplata ima svoju tekstualnu datoteku pod nazivomm UPLxxxxx.TXT gde je xxxxx broj
SPP poslovnice iz broja rauna. Jedna linija ove tekstualne datoteke sadri devet internih
cifara iz broja rauna, jedno prazno mesto i uplaen iznos.
Sumarni izvetaj o klasifikaciji (5-to cifreni broj SPP poslovnice i ukupno uplaen
iznos za tu poslovnicu) memorisati u tekstualnoj datoteci KLASUPL.TXT.

Zadatak 27 (5)
U tekstualnoj datoteci SOKOBAN.TXT nalaze se zapisane table koje je potrebno
prei od popularne video igrice SOKOBAN. Table su razdvojene sa jednim praznim
redom. Vrednosti polja table moe imati jednu od sledeih vrednosti: 0 hodnik kroz
koji se gura crvena kockica i gde se kursor moe kretati, 1 zid, 2 cevena kockica koju
treba pregurati na neko od postavljenih mesta obeleenih sa crnom kockicom, 3 crna
kockica ili mesto gde treba dogurati crvenu kockicu i 4 kursor u obliku smeska kojim se
kroz hodnike kreete sa strelicama i moete gurati crvene kockice.
Broj crvenih kockica jednak je sa brojem crnih kockica. Kada se guranjem sve
crvene kockice postave na mesta gde se nalaze crne kockice uz zvuni signal prelazi se u
sledei nivo. Kursor moe gurati samo jednu kockicu u jednom smeru, a ako pogua
odjednom gurati njih vie ili se pokua gurati kockica a da je iza zid uje se zvuni signal.
U sluaju da se pogreilo tako da se ne moe prei nivo sa SPACE se vraa na poetak
tog nivoa. Ako se stisne ESC zavrava se igrica a od korisnika se trai ime kako bi se
podaci sauvali u datoteci i time omoguilo da se prilikom ponovnog startovanja igrice
ne kree od prve table ve od one koju poslednji put nije preena.



256
Zadatak 28 (5)
Napisati C program koji predstavlja poznatu igricu MINE stim da e se u ovom
sluaju igrica igrati sa tastaturom. Na samom poetku programa pojavljuje se naslov sa
velikm slovima MINE koje su dobijene crtanjem kockica po kockica, a ispod toga meni
ija je prvobitna opcija oznaena crvenom bojom. Kroz meni se moete kretati sa
strelicama na gore i na dole. Sa leve strane nalazi se obavetenje da se sa velikim slovom
L moe dobiti lista 10 najboljih rezultata za dati nivo sa poljima ime igraa i vreme za
koje je igricu reio, a ispod slovo S sa kojim se ukljuuje ili iskljuuje zvuk. U igrici
postoje nivoi: VERY EASY (25), EASY(40), NORMAL(55), HARD(70), VERY
HARD(85) i NIGHTMARKE(100), pri emu u zagradi napisani broj oznaava broj
mina koje se na tabli nalaze.
Kada se izabere odreeni nivo pritisne se ENTER formira se tabla za igru pri emu
se a desne strane moe videti vreme koje protie dok traje igra. U gornjem levom uglu
nalazi se podatak koliko je zastavica ostalo. U gornjem desnom uglu nalazi se slovo S i
pored odgovarajua poruka koja obavetava ta e se desiti sa zvukom ako se unese
veliko slovo S.
Na sredini table nalazi se kursor sa kojim se strilicama moe kretati po tabli. Sa
tasterom SPACE otvara polje, a sa tasterom ENTER postavlja zastavica u obliku znaka
uzvika, ako je na tom polju nema ili se ukida sa tog polja ako je ranije ve postavljena.
Ako je zastavica postavljena na nekom polju to polje se nemoe otvoriti. Kada se postavi
zastavica broj zastavica u gornjem levom uglu se automatski smanjuje za jedan.
U sluaju da se tabla rei sve zastavice e blinkovati i nakon pritisnutog tastera
ENTER ako je ostvareno vreme meu prvih 10 pojavie se lista najboljih sa imenom
Anonimus koje se moe sa BACKSPACE izbrisati ili sa ENTER potvrditi.
U sluaju da se otvorilo polje gde postoji mina otvaraju se sva polja i mine koje su
obeleene sa crvenom zvezduicom e blinkovati. Ako se otvori polje gde nije mina
pojavie se broj koji opisuje koliko mina to polje granii, a ako je taj broj nula, broj se ne
prikazuje ve se prikazuju svi najblii brojevi koji nisu nule a nalaze se oko tog polja.
Nakon zavretka igranja na odgovarajuoj tabli vraamo se u meni. Iz menija se
izlazi sa ESC.
Nema datoteke u kojoj se nalaze table sa nivoima ve se table sa rasporedom mina
formiraju na sluajan nain.

Izgled programa nakon pokretanja: Izgled programa u toku igranja:
257
Zadatak 29 (5)
Napisati C program koji pretstavlja popularnu igricu ASOCIJACIJE iz muzike
slagalice. Igrica je namenjena za dva igraa. U tekstualnoj datoteci u svakom redu nalazi
se po jedna re. Re ne sme da bude dua od 15 karaktera. Prva re odnosi se na polje
A1, druga re na polje A2, trea re na polje A3, etvrta re na polje A4, peta re je
reenje kolone A, esta re je polje B1, sedma re je polje B2, osma re je polje B3,
deveta re je polje B4, deseta re je reenje kolone B, itd. Ima etiri kolone A, B, C i D.
Poslednja re je reenje asocijacije. U datoteci postoji vie asocijacija. Asocijacije su
razdvojene praznim redom. Na sluajan nain se bira asocijacija. Polja koje je pogodio
igra 1 iscrtavaju se crvenom bojom, a polja koje je pogodio igra 2 iscrtavaju se
tamnoplavom bojom.
Postoji polje sa oznakom DALJE koje kada kliknete obavetavate da igra sledei
igra. Igrica se igra sa miem. Postoji polje KRAJ koje kada kliknete zavravate igricu, i
iscrtava se reenje asocijacije. Kada kliknete na polje za odgovor na kolonu ili konano
reenje, pojavljuju se zvezdice, ali broj zvezdica je uvek isti i ne zavisi od reenja tog
polja. Ako igra pogodi reenje kolone cela kolona se iscrtava u njegovoj boji i za reenje
dobija pet poena. Moe otvarati sledee polje ili kliknuti na DALJE ime omoguava da
polje otvara sledei igra. Igra ne moe da otvara polje za reenje ako nije otvorio neko
ne otvoreno polje. Polje moe otvarati iz bilo koje kolone.
Pogodak na konano reenje nosi 10 poena, pri emu ako neka od kolona nisu
pogoena dobijaju se i poojeni (za svaku ne pogoenu kolonu po 5 poena) za te kolone.



258
Zadatak 30 (5)
Napisati C program koji pretstavlja igricu UKRTENICA. Prilikom startovanje
igrice unosi se ime tekstualnog fajla gde je zapisan format jedne ukrtenice. Na osnovu
tog formata iscrtava se prazna ukrtenica. Igrica se igra miem ili tastaturom. Na osnovu
poloaja kursora na donjim poljima (horizontalno, vertikalno) ispisuje se pitanje koje
odgovara odgovoru u toj vrsti ili koloni. Prilikom klika mia na neko polje na donjim
poljima se ispisuje horizontalno i vertikalno pitanje. Koje je horizontalno ili vertikalno
pitanje moe se dobiti klikom na polje sa pitanjem. Kroz ukrtenicu moe se kretati
strelicama. Unose se slova koja sde iscrtavaju utom bojom.
Igrica se zavrava kada se klikne desim tasterom mia. Tada se dobijaju odgovori
na postavljena pitanja, pri emu su slova crvene boje ako su na tim mestima bili pogreni
odgovori, plave boje ako su bili tani odgovori, ili ute boje ako korisnik na tim poljima
nije dao nikakav odgovor.
Na sledeoj strani dat je format tekstualne datoteke u kojoj je smetena ukrtenica
sa pitanjima. Komentarima su data objanjenja pravila po kojima je datoteka formirana.
Te komentare ne smete pisati u vaoj datoteci kada je budete formirali.
Format datoteke je predstavljen na sledeoj strani:







259
11*16 /* dimenzije ukrstenice */
`````%*b******** /* podaci o tome gde je koje slovo */
`````*promucuran /* ` oznacava sliku */
`````*tavan*tada /* * oznacava polje s pitanjima */
`````%*jad*bodar /* ... */
`````*ma*arekipo
%*%***onagar*ot*
*d*ivanapavlovic
*o*nepodesni*ero
*brak*kalkan*zar
*rec*almaata*ana
*ime*bistrica*ek
pitanja: /* jedan novi red (bilo sta u njemu) */
belgija@platina /* pitanja za polja su napisana */
levo-dole: kanadski pevac@pokazna zamenica /* redom, s leva na desno, i tako */
-@ostrvo u indijskom okeanu /* red po red. Prvo ide */
@ujedinjene nacije (skr.) /* horizontalno pitanje, pa znak"@", */
-@23. slovo azbuke /* pa vertikalno pitanje. Ako nema */
-@usce reke /* nekog od pitanja onda se samo */
-@komunikazija purem radija /* stavi "-" ili nesto slicno */
-@adaptacija
-@japanski grad na ostrvu honsu
dovitljiv@-
gornji deo kuce@-
u to vreme@stanovnik berlina
nevolja, nesreca@opticka naprava za jedno oko (mn.)
krepak, vedar, cio@poravnavati
mazurijum@-
grad u peruu@prijava visem sudu (lat.)
-@valjani
-@u drugom slucaju
-@period od sto godina
vrsta divljeg magarca@autonomna pokrajina
osnovna tarifa (skr.)@obim
-@lazni metak
dama u sahu (skr.)@-
nasa pop pevacica@-
kiseonik@-
koji nisu podesni, nepogodni@romulov brat
hercegovac@-
zajednica muza i zene@-
zabat na kuci (turc.)@pocetak azbuke
uzvicno-upitna recenica@-
deo recenice@-
glavni grad kazahstana@-
nasa voditeljka dmitrovic@amper
naziv@-
deo Novog Sada@-
enigmatski klub@-
format: /* jedan novi red */
05,07
06,07:
09,08:
00,07/

/* (u DOS-u izgleda kao ), oznacava razmak u vertikalnoj */
/* reci, na y=5 i x=7 koordinati */

/* : oznacava razmak u horizontalnoj reci, na tacki x=6 i y=7 */
/* : isto i za x=9 i y=8 */
/* "/" za strelicu na mestu y=0 i x

260

261










7
7. . P PO OG GL LA AV VL LJ J E E



D DI IN NA AM MI I K KE E S ST TR RU UK KT TU UR RE E P PO OD DA AT TA AK KA A
262


7.1. DINAMIKA DODELA MEMORIJE

Prilikom delaracije podataka u zoni podataka se odvaja potreban memorijski prostor
na osnovu tipa podataka. To znai da se u vreme prevoenja programa mora tano znati
koliko ima podataka. U sluaju nizova mora se unapred rezervisati memorijski prostor za
smetanje niza. To se obino radi tako to se deklarie niz sa oekivanim maksimalnim
brojem elemenata. To dovodi do nepotrebnog utroka memorije. Programski jezik C
dozvoljava da se u toku izvrenja programa od operativnog sistema trai dodeljivanje
memorijskog prostora

Definicija:
Deo memorije koji se dodeljuje u toku izvravanja programa naziva se
dinamika zona memorije ili hip memorija.

Osobine dinamikih podataka:
Podaci smeteni u dinamikoj zoni memorije nazivaju se dinamiki podaci.
Dinamii podaci postoje sve dok ih programer eksplicitno ne uniti ili do zavretka
programa kada se automatski unitavaju. Dinamiki podaci nemaju svoje
indentifikatore ve im se pristupa pomou pokazivaa iz zone podataka.

Upravljanje dinamikim podacima vri se pomou funkcija malloc, calloc,
realloc i free koje se nalaze u biblioteci stdlib.h. U ovoj lekciji objasniemo funkcije
malloc i free.
void *malloc(size_t size);

Funkcija malloc alocira size bajtova u dinamikoj zoni memorije. Ako uspeno
obavi zadatak funkcija vraa generiki pokaziva na alocirani prostor u memoriji.
Ako doe do greke bie vraena vrednost NULL.

void free(void *buffer);

Funkcija free oslobaa prethodno alociranu memoriju na iju poetnu adresu sadri
pokaziva buffer. Pokaziva buffer dobio je adresu pozivom funkcije malloc, calloc ili
realloc.

Primer 1:
Napisati deo koda koji omoguava deklaraciju pokazivaa na tip podataka Tucenik,
a potom formira objekat na koga taj pokaziva pokazuje. U sluaju da se objekat nije
mogao formirati prikazati poruku da nije bilo dovoljno memorije.

Reenje:

Tucenik *pokazivac = NULL;

263
if(pokazivac = (Tucenik *) malloc(sizeof(Tucenik)) == NULL)
{
printf("Nije dobro alocirana memorija!! "),
return;
}
free(pokazivac);

Primer 2:
Napisati C program koji omoguava formiranje strukture radnik sa poljima:

1) Prezime i ime od maksimalno 30 karaktera;
2) Koeficijen za dato radno mesto; i
3) Godine radnog staa

Poznato je da je vrednost boda k dinara, a da se na svaku godinu radnoga staa
dohodak uveava za 0.5%. Pripravnik je onaj radnik gde se za godine radnoga staa
unese broj 0 i ima 80% dohodak u odnosu na radnika sa obavljenim pripravnikim
staom. Progam treba da ispie koliki je dohodak radnika. Prilikom realizacije programa
koristiti dinamiku zonu memorije.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include<ctype.h>
#include <stdlib.h>

#define MAX 31

/* Definisanje strukture. */
typedef struct radnik{
char prezime_i_ime[MAX];
double koeficijent;
int staz;
double dohodak;
} Tradnik;

/* Sada je Tradnik novi tip podatka (izvedeni tip podatka). */

/* Prototipovi funkcija. */
Tradnik *unos(int startx,int starty);
void racunaj_dohodak(Tradnik **pok);
void ispis_dohotka(Tradnik *pok);

void main(void)
{
Tradnik *pok; /* Deklarise se promenljiva pok koja predstavlja pokazivac na slozeni tip
podatka Tradnik, i nalazi se u zoni podataka */
264

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

printf("\t\tUNESITE PODATKE O RADNIKU:\n\n");
if((pok=unos(wherex(),wherey()))==NULL) return;

racunaj_dohodak(&pok);
ispis_dohotka(pok);

gotoxy(1,25);
getch();
}


/* Funkcija omogucava formiranje objekta i vraca pokazivac na taj objekat, kao i unos
podataka u objekat. */

Tradnik *unos(int startx,int starty)
{
Tradnik *pokazivac; /* pokazivac je promenljiva koja moze da sadrzi adresu podatka ili
objekta tipa Tradnik. */
double a;
int b;
unsigned xu,yu;

/* Radi sigurnosti potrebno je izvrsiti konverziju generickog pokazivaca u pokazivac tipa
Tradnik, pa tek tada izvrsiti dodelu adrese promenljivoj pokazivac. Ako promenljiva
pokazivac bude imala vrednost NULL znacice da se objekat nije formirao usled
nedostatka operativne memorije. Ovo ispitivanje potrebno je uvek vrsiti. */

if((pokazivac=(Tradnik *)malloc(sizeof(Tradnik)))==NULL)
{
printf("Nema dovoljno memorije!!");
return NULL;
}

strcpy(pokazivac->prezime_i_ime,"");
pokazivac->koeficijent=0;
pokazivac->staz=0;
pokazivac->dohodak=0;

gotoxy(startx,starty);
printf("\tIme i prezime: ");
gets(pokazivac->prezime_i_ime);
printf("\tKoliki je koeficijenat: ");
xu=wherex();
yu=wherey();

265
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%lf",&a);
}while(a<=0);
pokazivac->koeficijent=a;

printf("\tGodine radnoga staza = ");
xu=wherex();
yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&b);
}while(b<0);
pokazivac->staz=b;

/* Funkcija vraca adresu formiranog objekta. */
return pokazivac;
}

/* Funkcija racunaj_dohodak izracunava dohodak radnika. Podaci o radniku nalaze se u
objektu cija adresa se prosledjuje pokazivacu pok. */
void racunaj_dohodak(Tradnik **pok)
{
double k;
unsigned xu,yu;

printf("\n\n\tVrednost boda je: ");
xu=wherex();
yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%lf",&k);
}while(k<1);

if((*pok)->staz!=0)
{
(*pok)->dohodak=(*pok)->koeficijent*k;
(*pok)->dohodak+=0.5*(*pok)->staz*(*pok)->dohodak;
}else{
(*pok)->dohodak=(*pok)->koeficijent*k;
(*pok)->dohodak=0.8 * (*pok)->dohodak;
}
}

266
/* Funkcija ispis_dohotka ispisuje dohodak koji je radnik ostvario i oslobadja prostor u
dinamickoj zoni memorije jer se objekat vise nece koristiti. */

void ispis_dohotka(Tradnik *pok)
{
printf("\n\n\n\tRadnik %s ima dohodak %.2f dinara.",
pok->prezime_i_ime, pok->dohodak );
free(pok);
}

Test primer programa:























267

7.2. JEDNOSTRUKO SPREGNUTA LISTA
Pojam i definicija, dodavanje elementa u listu



7.2.1. Kakva podruja memorije priprema operativni sistem prilikom
zapoinjanja programa?
Operativni sistem priprema pet podruja memorije:
- prostor za kod programa
- prostor podataka
- stek
- dinamika (hip) memorija
- registarska memorija


7.2.2. ta je to pokaziva?
Pokaziva je promenljiva koja sadri (pokazuje) adresu neke druge promenljive ili
objekta.

Na primer:
int a = 0, *pok = NULL;
pok=&a;

Zona podataka:
Pok a

CBD3


7.2.3. Gde i kako se u programskom jeziku C formira objekat?
Objekat se nalazi u dinamikoj zoni memorije, dok se promenljive nalaze u zoni
podataka. Objekat se u programskom jeziku C formira pomou funkcije malloc:

pok=(Tcvor *)malloc(sizeof(Tcvor));

Funkcija malloc formira u dinamikoj zoni objekat veliine (u bajtovima) koja
odgovara tipu podataka Tucenik, i adresu nakon formiranja upisuje u pokaziva pok.
Pokaziva pok se nalazi u zoni podataka.
CBD3 0
268


Kako se unitava objekat?
U programskom jeziku C objekat se unitava pomou funkcije free.
Na primer:
free(pok);
pok=NULL;

Prilikom unitavanja objekta saoptava se operativnom sistemu da je taj prostor
memorije slobodan.

Kada programeri kau da je nastupilo curenje memorije?
Programeri kau da je nastupilo curenje memorije ako objekat nije uniten,
nijedan pokaziva na njega ne pokazuje (ne sadri) njegovu sdresu.

7.2.4. ta t dnostruko spregnuta lista?
dnostruko spregnuta lista najjednostavnija struktura podataka s
sastoji d bjekata meusobno povezanih (spregnutih) pokazivaa, pri emu svaki d
vorova pokazuje na svog sledbenika.
Listi s pristupa preko nog spoljanjeg pokazivaa glava (nalazi s u zoni
podataka) i pokazuje na prvi vor, nije d liste.
Poslednji vor naziva s repom liste. n nema svog sledbenika, t njegov
pokaziva ima vrednost NULL.

Fizika predstava Logika predstava
Zona podataka
Dinamika zona
Na primer:
objekat
269
Prikaz logike i fizike predstave dnostruko spregnute liste

Iz navedenog prikaza vidi se d logiki i fiziki poredak nisu isti.

s vri definisanje vora liste?
Definisanje vora liste vri s gd i definisanje struktura. vor liste strukturni tip
podataka i s sastoji d dva polja : informacionog sadraja i pokazivaa. Informacioni
sadraj uopteno strukturni podatak i predstavlja risni sadraj vora. Pokaziva
polje sadri dresu sledeeg vora liste ili NULL rep liste.
typedef struct cvor{
Tslog info;
struct cvor *sledeci;
}Tcvor ;
U ovom definisanju vora liste:
Tslog - ip podataka strukture i ranije definisan.
info - polje ipa Tslog i sadri u bi vie polja dati korisne
informacije.
sledeci - pokaziva i u stanju d pokazuje n bjekat ipa Tcvor.


7.2.5. s vri inicijalizacija liste?
dnostruko spregnutoj listi pristupa s pomou spoljanjeg pokazivaa glava.
lista nema vorova (nema liste) tada pokaziva glava ima vrednost NULL.
Inicijalizacijom jednostruko spregnute liste pokazivau glava dodeljuje s vrednost
NULL.
270

void inicijalizacijaliste(Tcvor **glava)
{
*glava =NULL;
}

7.2.6. Naini dodavanja novog elementa u jednostruko spregnutu listu
Jednostruko spregnuta lista najee s formira dodavanjem novog vora na
poetak liste ili dodavanjem novog vora na kraj liste.
oju tehniku primeniti zavisi d auriranja liste. Kod auriranja liste
podrazumeva se traenje elementa u listi, brisanje elementa iz liste i modifikacija
(promena) informacionog sadraja vora liste.
Potrebno da s d vora liste to bre doe, d bi s t desilo vor liste
mora biti to blii prvom voru liste, ili da prvi vor liste.

Dodavanje novog elementa n poetak liste
ristiti s da potrebno auriranje vorova liste ji su poslednji
uneseni. Dodavanje novog vora na poetak liste bre i fikasnije d dodavanja novog
vora n kraj liste.
void dodajnapocetakliste(Tcvor **glava)
{
Tcvor *novi =NULL;
novi =formcvor();
if(*glava==NULL) *glava=novi;
else{
novi ->sledeci=*glava;
*glava=novi;
}
}

Prilikom dodavanja elementa na poetak liste mogu se razluiti dva sluaja:
- Prvi sluaj je kada lista nema elemenata (prazna je), tj pokaziva glava
ima vrednost NULL.
- Drugi sluaj je kada lista sadri barem jedan element.


Prvi sluaj:



271

Drugi sluaj:




REZIME

Postoji znaajna razlika izmeu jednostruko spregnute liste i niza struktura.
Kod nizova isti logiki i fiziki poredak elemenata. Elementu s pristupa
pomou indeksa. Znai lak i brz pristup, to ini prednosti niza struktura u
dnosu n dnostruko spregnutu listu.
Kod niza je potrebno locirati statiki fiksan memorijski prostor i s
dimenzionie prema maksimalno ekivanom broju elemenata, to doprinosi
slabijem iskorienju memorijskog prostora. Takoe kod niza je neefikasno
brisanje i umetanje elemenata n proizvoljnom mestu, r ni zahtevaju
pomeranje elemenata niza, dok se kod liste izvri samo promena vrednosti
pokazivaa kojima su vorovi liste povezani.




272


7.3. JEDNOSTRUKO SPREGNUTA LISTA
Dodavanje novog elementa na kraj jednostruko spregnute liste,
Traenje elementa u jednostruko spregnutoj listi, i
Brisanje jednostruko spregnute liste
uz oslobaabje zauzete memorije

7.3.1. Dodavanje novog elementa na kraj jednostruko spregnute
liste
ristiti s da potrebno auriranje vorova liste ji su prvi uneseni, tj
potrebno je zadrati hronoloki redosled elemenata.

void dodajnakrajliste(Tcvor **glava)
{
Tcvor *novi, *tek;
tek=NULL;

novi =formcvor();
if(*glava==NULL) *glava=novi;
else{
tek=*glava
while(tek->sledeci!=NULL) tek=tek->sledeci;
tek ->sledeci=novi;
}
}

Razlikuju se dva sluaja. Prvi kada nema elemenata u listi i drugi kada ima
elemenata u listi. U prviom sluaju radi se isto kao i kod vezivanja na poetak liste, samo
se povezuje pokaziva glava da pokazuje na novi element.

Prvi sluaj:


U drugom sluaju koriste se jo jedan pomoni pokaziva tek. Njegov zadatak je
da se proe kroz listu tako da pokaziva tek na kraju po izlasku iz ciklusa pokazuje na
poslednji element u listi. Sada se uz pomo pokazivaa tek element lako vezuje na kraj
liste.
273
Drugi sluaj:












274
7.3.2. Traenje elementa u jednostruko spregnutoj listi
Traenje elementa u listi podrazumeva utvrivanje da li neki elemenat liste ima
isti informacioni sadraj kao i klju (sloeni podatak sa kojim se poredi).
Traenje elementa vri se pomou funkcije koja vraa adresu elementa u listi koji
ima isti informacionmi sadraj kao i klju, ili NULL ako nema takvog elementa u listi.
U listi samo jedan elemenat prilikom traenja poseduje takvo svojstvo. Funkciji
se po vrednosti prosleuju pokaziva glava i klju. Prosleivanje po vrednosti se vri iz
razloga to se vrednosti pokazivaa glava nee promeniti, a ni klju koji je tipa Tslog kao
i informacioni sadsraj vora liste.
Traenje se vri pomou pomonog pokazivaa koji se postavlja na poetku da
pokazuje na prvi element liste (gde i glava). Kroz listu se prolazi sa while ciklusom jer se
ne zna koliko lista ima elemenata. Ako se pronae takav element pomoni pokaziva tek
posedovae adresu tog elementa liste, a u sluaju da se ne pronae imae vrednost
NULL.
Tcvor *trazi(Tcvor *glava, Tslog kljuc)
{
Tcvor *tek=glava;

while(tek!=NULL&&tek->info!=kljuc) tek=tek->sledeci;
if(tek==NULL) return NULL;
else return tek;
}
Prilikom traenja elementa u listi razlikuju se dva sluaja, Prvi da postoji element
liste koji ima isti informacioni sadraj kao i klju, i drugi da takvog elementa nema u listi.
Klju moe da bude podatak sloenog tipa. U ovom primeru radi lakeg praenja klju i
informacioni sadraj su podaci osnovnog tipa int.

Prvi sluaj:
KLJU:15




275
Drugi sluaj:
KLJU:30








7.3.3. Brisanje liste i oslobaanje zauzete memorije
Prilikom rada sa dinamikim strukturama podataka na kraju programa mora se
osloboditi zauzeta memorija u dinamikoj zoni podataka (hip-a). To se u ovom sluaju
radi pomou funkcije kojoj se prosleuje pokaziva glava po referenci (jer e mu se
vrednost prilikom brisanja menjati).
276
Pri realizaciji koristi se pomoni pokaziva tek, a brisanje se vri sa poetka liste
(onaj ijiu adresu sadri pokaziva glava). Kada pokaziva glava bude imao vrednost
NULL znai da je lista obrisana iz memorije.

void brisanjeliste(Tcvor **glava)
{
Tcvor *tek=glava;

while(*glava!=NULL)
{
tek=*glava;
*glava=tek->sledeci;
free(tek);
}
}

U primeru posmatraemo listu od tri elementa, pa moramo prilikom brisanja imati
tri iteracije.

Iteracija 1






277
Interacija 2







Iteracija 3








278
Primer:
Zadata je tekstualna datoteka BANKA.TXT koja sadri podatke o tediama jedne
banke. U svakom redu datoteke nalaze se podaci o jednom tedii banke u formatu:

ifra#Prezime#Ime#Godine starosti#Stanje#Zaposlen(P,D,N)#proseni dohodak

ifra indentifikacioni broj tekueg rauna;
Stanje stanje tekueg rauna u trenutku podnoenja zahteva;
Zaposlen u privatnom preduzeu (oznaka P), drutvenom preduzeu (oznaka D)
ili nezaposled (oznaka N);
Proseni dohodak Proseni lini dohodak u proteklih 12 meseci pre podnoenja
zahteva

U datoteci KREDITI.TXT nalaze se zahtevi za stambene kredite. Svaki red
datoteke sadri podatke o jednom zahtevu u formatu: ifra#iznos.
Uslovi za dobijanje kredita su:
1) Da je tedia banke;
2) Podnosilac je stariji od 18 a mlai od 65 godina starosti;
3) Zaposlen je u drutvenom preduzeu;
4) Nema minus na tekuem raunu banke; i
5) Mesena rata kredita ne prelazi polovinu prosenog linog dohotka.
Kredit se moe dobiti na maksimalno 20 godina, ako je podnosilac zahteva mlai
od 45 godina. U sluaju da je stariji od 45 godina, kredit se odobrava na broj godina do
65 godine ivota. Godinja kamata u ovom trenutku za dobijanje stambenog kredita je
4.75% i zapiite je u simbolikoj konstanti KAMATA.
Napisati C program koji formira datoteke ODOBRENI.TXT (spisak osoba kojima
je kredit odobren) i NEODOBRENI.TXT (spisak osoba kojima kredit nije odobren).
Svaki red datoteke ODOBRENI.TXT je u formatu:
ifra, Prezime, Ime, Na koliko godina je odobren kredit i Mesena rata.
Svaki red datoteke NEODOBRENI.TXT je u formatu:
ifra i Redni broj opcije (broj jedan) zbog koga kredit nije odobren) u sluaju da
podnosilac kredita nije tedia banke, ili ifra, Prezime, Ime i Redni brojevi opcija zbog
kojih kredit nije odobren (meusobno odvojeni zarezima).

Reenje

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

#define KAMATA 4.75

typedef struct zah{
char sifra[20];
double iznos;
}Tzah; /* Struktura zahteva, gde ce se upisivati podaci o osobi koja podnosi zahtev. */
279

typedef struct slog{
char sifra[20];
char prezime[30];
char ime[30];
char posao[2];
double stanje;
double pros;
unsigned god;
}Tslog; /* Struktura koja poseduje podatke o stedisama banke. */

typedef struct cvor{
Tslog info;
struct cvor *sled;
}Tcvor; /* Struktura cvora

/* Prototipovi funkcija. */
void inicijalizacija(Tcvor **glava); /* Inicijalizacija liste.. */
void smesti(Tcvor **glava, char *s); /* Upis podataka jednog stedise u listu. */
void dodajnapocetak(Tcvor **glava,Tcvor *novi); /* Dodavanje cvora na pocetak liste. */.
void uradi(Tcvor *glava); /* Na osnovu podataka liste formira datoteke. */
void oslobodimemoriju(Tcvor **glava); /* Oslobadja memoriju koju je lista zauzela. */

void main(void)
{
FILE *dat;
Tcvor *glava;
char s[100];

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

if((dat=fopen("BANKA.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka BANKA.TXT se ne moze otvoriti!!");
return;
}

inicijalizacija(&glava);

/* Ucitava se red po red iz datoteke i pozivanjem funkcije smesti podaci se
upisuju u objekat i uvezuju u listu. */

while(fgets(s,100,dat)!=NULL) smesti(&glava,s);
fclose(dat);

uradi(glava);
printf("\n\n\tPosao je uspesno obavljen!!");
280
/* Po zavrsetku programa obavezno obrisati listu iz memorije. */
oslobodimemoriju(&glava);
}

void inicijalizacija(Tcvor **glava)
{
*glava=NULL;
}

void smesti(Tcvor **glava, char *s)
{
char *pok=s;
Tcvor *novi;

novi=(Tcvor *)malloc(sizeof(Tcvor));
novi->sled=NULL;

/* Funkcijom strtok izdvajamo podatke iz formata stringa. */
pok=strtok(s,"#"); strcpy(novi->info.sifra,pok);
pok=strtok(NULL,"#"); strcpy(novi->info.prezime,pok);
pok=strtok(NULL,"#"); strcpy(novi->info.ime,pok);
pok=strtok(NULL,"#"); novi->info.god=atoi(pok);
pok=strtok(NULL,"#"); novi->info.stanje=atof(pok);
pok=strtok(NULL,"#"); strcpy(novi->info.posao,pok);
pok=strtok(NULL,"#"); novi->info.pros=atof(pok);

/* Formirani objekat se funkcijom dodajnapocetak uvezuje na pocetak liste. */
dodajnapocetak(&(*glava),novi);
}

void dodajnapocetak(Tcvor **glava,Tcvor *novi)
{
if(*glava==NULL) *glava=novi;
else novi->sled=*glava, *glava=novi;
}

void uradi(Tcvor *glava)
{
FILE *ul, *ne, *od;
char s[100], *pok=s, odgovor[10];
Tzah zah;
Tcvor *tek;
double rata;
unsigned god;

if((ul=fopen("KREDITI.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka KREDITI.TXT se ne moze otvoriti!!");
return;
}
281

od=fopen("ODOBRENI.TXT","w");
ne=fopen("NEODOBRENI.TXT","w");

/* Ucitava se red po red iza datoteke. Pomocu funkcije strtok izdvoje se podaci i
smestaju u strukturu zahtev. */

while(fgets(s,100,ul)!=NULL)
{
strcpy(odgovor,"");
pok=strtok(s,"#");strcpy(zah.sifra,pok);
pok=strtok(NULL,"#"); zah.iznos=atof(pok);

/* Utvrdjuje se da li je podnosilac zahteva stedisa banke. /*
tek=glava;
while(tek!=NULL&&strcmp(tek->info.sifra,zah.sifra)) tek=tek->sled;

/* Formira se string odgovor koji ce sadrzati redne brojeve opcija zbog
kojih kredit nije odobren. Ako nakon provere svih opcija string odgovor
ostane prazan zahtev se odobrava, a u suprotnom se ne odobrava. */

if(tek==NULL) strcat(odgovor,"1");
else{
if(tek->info.god<18 || tek->info.god>=65) strcat(odgovor,"2 ");
if(strcmp(tek->info.posao,"D")) strcat(odgovor,"3 ");
if(tek->info.stanje<0) strcat(odgovor,"4 ");
if(tek->info.god>=18&&tek->info.god<65&&!strcmp(tek->info.posao,"D"))
{
if(tek->info.god<45) god=20;
else god=65-tek->info.god;
rata=((zah.iznos/god)+(zah.iznos/god)*KAMATA/100)/12;
if(rata>tek->info.pros/2) strcat(odgovor,"5 ");
}
}

if(tek==NULL) fprintf(ne,"%-5s %s\n",zah.sifra,odgovor);
else{
if(strcmp(odgovor,"")) fprintf(ne,"%-5s %-15s %-15s\t%s\n",
tek->info.sifra,tek->info.prezime,tek->info.ime,odgovor);
else fprintf(od,"%-5s %-15s %-15s %d\t%.3f\n",
tek->info.sifra,tek->info.prezime,tek->info.ime,god,rata);
}
}
fclose(od);
fclose(ne);
}



282

void oslobodimemoriju(Tcvor **glava)
{
Tcvor *tek;

while(*glava!=NULL)
{
tek=*glava;
*glava=(*glava)->sled;
tek->sled=NULL;
free(tek);
}
}





































283

7.4. JEDNOSTRUKO SPREGNUTA LISTA
Brisanje elementa iz jednostruko spregnute liste
Formiranje sortirane jednostruko spregnute liste


7.4.1. Brisanje elementa iz jednostruko spregnute liste
Dinamika struktura podataka sadri u svakom trenutku optimalan broj elemenata
ime se vri uteda memorije. Prilikom brisanja elementa iz liste oslobaa se zauzeta
memorija, tj operativnom sistemu se saoptava da osloboeni deo memorije moe
koristiti. Kako bi lista bila funkcionalna mora se izvriti prelanavanje liste, odnosno
promena vrednosti pokazivaa, ime se obezbeuje ispravan logiki poredak elemenata
liste.
Brisanje elementa liste urediemo korienjem funkcije brisanjeelementa. Obrisae
se samo jedan element liste koji ima isti informacioni sadraj kao klju traenja kljuc.
Pokaziva na poetak liste mora se preneti po referenci jer se prilikom brisanja prvog
elementa liste vrednost pokazivaa glava mora promeniti.

unsigned brisanjeelementa(Tcvor **glava, Tslog kljuc)
{
Tcvor *tek, *pret;
tek=pret=NULL;

tek=trazi(*glava,kljuc);
if(tek==NULL) return 0;

if(tek==*glava)
{
*glava=tek->sledeci;
tek->sledeci=NULL;
}else{
pret=*glava;
while(pret->sledeci!=tek) pret=pret->sledeci;
pret->sledeci=tek->sledeci;
tek->sledeci=NULL;
}
free(tek);

return 1;
}

Prilikom brisanja elementa liste razlikuju se dva sluaja:



284
Prvi sluaj:
Prvi sluaj je kada je element koji se brie prvi elemenat liste. Prilikom brisanja
elementa mora se prvo utvrditi da li elementa ima u listi, to se radi pomou funkcije
trai koja je obraena na prolom asu. Ako funkcija vrati vrednost NULL znak je da
elementa nema u listi, a u suprotnom pomoni pokaziva tek dobija adresu pronaenog
elementa koga treba izbrisati iz liste. U prvom sluaju pokazivai tek i pret pokazuju gde
i pokaziva glava.




Drugi sluaj:
Drugi sluaj obuhvata varijante kada je element koji se brie nije prvi element
liste. Prilikom brisanja elementa mora se prvo utvrditi da li elementa ima u listi, to se
radi pomou funkcije trazi koja je obraena na prolom asu. Ako funkcija vrati vrednost
NULL znak je da elementa nema u listi, a u suprotnom pomoni pokaziva tek dobija
adresu pronaenog elementa koga treba izbrisati iz liste. Kada smo nali elementa koga
treba izbrisati i njegovu adresu sadri pokaziva tek, kako je lista jednostruko spregnuta
ne postoji pokaziva kojim bismo lako doli do elementa koji je logiki predhodnik od
elementa koji se brie, moramo koristiti jo jedan pomoni pokaziva pok. Prolazimo
while ciklusom kroz listu sve dok pok ne dobije adresu predhodnika od elementa koji se
brie. Izvri se prelanavanje liste i sa funkcijom free oslobodi memorija.



285


7.4.2. Formiranje sortirane jednostruko spregnute liste
Formiranje sortirane jednostruko spregnute liste ne znai da lista koja ve postoji
sortira po nekom kriterijumu, ve da se prilikom dodavanja novog elementa u listu,
element ulanava na onu poziciju koja obezbeuje da lista stalno bude sortirana po
zadatom kriterijumu sortiranja.
Formiranje sortirane jednostruko spregnute liste moe se uraditi na dva naina:
- Iterativnim postupkom, ili
- Rekurzivnim postupkom.

7.4.2.1. Formiranje sortirane jednostruko spregnute liste
iterativnim postupkom
Formiranje sortirane jednostruko spregnute liste iterativnim postupkom
(korienjem ciklusa) uradiemo pomou funkcije formsortlistu. Funkciji se po referenci
mora proslediti pokaziva glava kako bi se moglo pristupiti listi, a prenos je po referenci
jer se novi cvor moe uvezati na poetak liste.
U okviru funkcije koriste se tri pomona lokalna pokazivaa: novi, ispred i iza.
Pokaziva novi prihvatie adresu novoformiranog objekta koga treba uvezati u listu.
Pokazivai iza i ispred koriste se u sluaju kada se element uvezuje negde u sredinu ili na
kraj liste. Ako se element uvezuje negde u sredinu liste, prvo se mora utvrditi pozicija
gde je element potrebno uvezati, tj pokaziva ispred pokazuje na vor koji je ligiki
sledei u odnosu na onog koji se uvezuje, a pokaziva iza pokazuje na vor koji je logiki
prehodnik u odnosu na vor koji se uvezuje. U sluaju da je potrebno uvezati vor na kraj
liste, pokaziva ispred imae vrednost NULL (jer nema logikog sldbenika), a pokaziva
iza pokazivae na poslednji element liste. Kada pokazivai iza i ispred sadre potrebne
adrese, tada je lako izvriti vezivanje novog elementa.

void formsortlistu(Tcvor **glava)
{
Tcvor *novi, *iza=NULL,* ispred=NULL;
novi=formcvor();

ispred=*glava;
while(ispred!=NULL&&novi->info.pod>ispred->info.pod)
{
iza=ispred;
ispred=ispred->sledeci;
}
286
novi->sledeci=ispred;
if(*glava==ispred) *glava=novi;
else iza->sledeci=novi;
}

U ovom primeru smatralo se da informacioni sadraj vora liste sadri podatak pod
koji e uestvovati u ispunjavanju uslova kriterijuma sortiranja. Moe vie podataka
uestvovati u kriterijumima sortiranja, ali tada je potrebno modifikovati datu funkciju u
while uslovu. Iteratifni postupak formiranja jednostruko spregnute liste moe se opisati
kroz etiri sluaja.

Prvi sluaj:
U prvom sluaju lista je prazna, te se novi vor dodaje na poetak liste.



Drugi sluaj:
U drugom sluaju postoji lista, a element koji se dodaje u listi treba da se uvee na
poetak liste. U ovom sluaju while ciklus se nije izvrio ni jednom te pokaziva iza
pokazuje na prvi cvor liste, gde i pokaziva glava, a kako liste ima to im je vrednost
razliita od NULL.




287

Trei sluaj:
U ovom sluaju vor treba uvezati na kraj liste. To se zakljuilo na osnovu vrednosti
pokazivaa iza i ispred nakon zavretka while ciklusa. Pokaziva iza pokazivae na rep
liste, a pokaziva ispred imae vrednost NUUL.


etvrti sluaj:
U ovom sluaju nakon zavretka while ciklusa pokazivai iza i ispred su razliiti od
NULL, a to je znak da je novi element potrebno uvezati negde na sredinu liste (nije
poetak, a nije ni kraj liste). Pokaziva ispred pokazivae na vor koji je logiki
sledbenik u odnosu na element koji se uvezuje u listu, a pokaziva iza pokazivae na vor
koji je logiki prethodnik u odnosu na element koji se uvezuje u listu.


288



7.4.2.2. Formiranje sortirane jednostruko spregnute liste
rekurzivnim postupkom

Rekurzivni postupak znai da je funkcija kojom se formira sortirana jednostruko
spregnuta lista rekurzivna (poziva sama sebe). Funkcija formsortlistrek je rekurzina i u
sebi poziva funkciju dodajnapocetakliste koja je malo modifikovana. Formiran je ve
objekat koji treba da se uvee u listu a na njega pokazuje pokaziva novi.

void dodajnapocetakliste(Tcvor **glava, Tcvor *novi)
{
if(*glava==NULL) *glava=novi;
else{
novi ->sledeci=*glava;
*glava=novi;
}
}


void formsortlistrek(Tcvor **glava, Tcvor *novi)
{
if(*glava==NULL || (*glava)->info.pod>novi->info.pod)
dodajnapocetakliste(*glava, novi);
else formsortlistrek((*glava)->sledeci,novi);
}

Prilikom rekurzivne realizacije formiranja jednostruko spregnute liste u sutini se
vri uvek dodavanje na poetak liste, na koga pokazuje pokaziva glava koji se nalazi u
aktivacionom zapisu na STEK-u.

Prvi sluaj:
U prvom sluaju lista je prazna, te se novi element uvezuje na stvarni poetak liste.
Izvrseno je prosledjivanje pokazivaa glava po referenci na stek, te se prvi element liste
vezuje na poetak liste
289


Drugi sluaj:
U drugom sluaju element se ne uvezuje na stvarni poetak liste. Kako se poziva
rekurzivna funkcija, to e kada se zadovolje uslovi iskakanja iz rekurzije, pokaziva
glava iz poslednjeg aktivacionog zapisa pokazivati na logikog sledbenika u odnosu na
element koga treba uvezati u listu. Znai da e se izvriti uvezivanje na poetak liste u
odnosu na pokaziva glava iz poslednjeg aktivacionog zapisa.









290





Nakon uvezivanja zavrava se poslednje pozvana rekurzivna funkcija, a kako
ispod nje nema naredbi zavrie se prethodno pozvana rekurzivna funkcija, itd. Znai
brisae se jedan po jedan aktivacioni zapisa sa steka.








291







Primer:
U tekstualnoj datoteci POLINOM.TXT nalaze se polinomi. Svaki red datoteke
sadri jedan polinom. Polinom je opisan sa nizom ureenih parova
N n N k n k x a
k
k
e A e A e ] .. 1 [ ), , ( . Nacrtati najjednostavniji i ujedno najefikasniji
strukturni dijagram (uz objanjenje zato ba on) i na osnovu njega napisati C program
koji na osnovu datoteke izraunava rezzultujui polinom, kao zbir svih polinoma koje
sadri datoteka. Na kraj datoteke dodati liniju kojom se podvlai crta, a ispod crte
tampati i rezultujui polinom.

Reenje

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>

typedef struct cvor{
int ko;
int step;
struct cvor *sledeci;
}Tcvor;

void dodaj(Tcvor **glava, char *s);
void upis(Tcvor **glava,int ko,int step);
void ispis(Tcvor **glava,FILE *dat);

292
void main(void)
{
textmode(3);
textcolor(9);
textbackground(0);
clrscr();

Tcvor *glava=NULL;
FILE *dat;
char s[81];

if((dat=fopen("POLINOM.TXT","r+"))==NULL)
{
gotoxy(5,5);
printf("Ne moze otvoriti datoteku!");
}

/* Ucitava se red po red datoteke i vrsi sabiranje polinoma. Sabiranje vise polinoma vrsi
se ne polinom po polinom, vec clan po clan polinoma. Na ovaj nacin polinom ne mora
biti u datoteci sortiran po opadajucim vrednostima stepena. Rezultujuci polinom
predstavljace ce sortiranu jednostruko spregnutu listu po stepenima polinoma u
opadajucem redosledu. Svaci cvor liste predstavljace jedan clan polinoma. Funkcija dodaj
dobija string koji sadrzi jedan polinom, ali se lista formira tako sto se iz stringa izdvaja
clan po clan polinoma i ubacuje u listu ako takvog stepena nema, ili se sabira sa
odgovarajucim clanom koji ima isti stepen. */

while(fgets(s,80,dat)!=NULL) dodaj(&glava,s);

/* Ispisuje se rezultujuci polinom u datoteci. */
ispis(&glava,dat);
fclose(dat);

printf("\n\n\t\tPosao je obavljen!!");
getch();
}

void dodaj(Tcvor **glava, char *s)
{
char prvis[20],drugis[20];
int i,j,prvi=0,drugi=0,max;

max=strlen(s);
i=0;
while(i<max-2)
{
prvis[0]=drugis[0]='\0';
i++,j=0;
while((s[i]==','||s[i]=='('||s[i]==')')&&i<strlen(s)) i++;
while((s[i]!=',')&&i<strlen(s)) prvis[j]=s[i],i++,j++;
prvis[j]='\0';

293
/* Promenljiva prvi sadrzi koeficijent, a promenljiva drugi stepen jednog clana
polinoma. */

prvi=atoi(prvis);
j=0,i++;
while(s[i]!=')') drugis[j]=s[i],i++,j++;
drugis[j]='\0';
drugi=atoi(drugis);

/* Ako je koeficijent clana polinoma nula nece se promeniti rezultat. */
if(prvi!=0) upis(&(*glava),prvi,drugi);
}
}

void upis(Tcvor **glava,int ko,int step)
{
Tcvor *novi=NULL,*tek=*glava,*pret=*glava;
novi=(Tcvor *)malloc(sizeof(Tcvor));
novi->ko=ko;
novi->step=step;
novi->sledeci=NULL;

if(*glava==NULL) *glava=novi;
else{
/* Koristi se ista tehnika kao i kod formiranja sortirane liste. */
while((novi->step < tek->step )&&tek!=NULL) pret=tek, tek=tek->sledeci;

/* Ako postoji polinom sa istim stepenom sabiraju im se koeficijenti. */
if((novi->step == tek->step)&&tek!=NULL) tek->ko=tek->ko+novi->ko;
else{
/* Ako takvog stepena nema cvor se uvezuje u listu. */
novi->sledeci=tek;
if(tek==*glava) *glava=novi;
else pret->sledeci=novi;
}
}
}

void ispis(Tcvor **glava,FILE *dat)
{
Tcvor *tek=*glava;
int i=0;

/* Prvo se na kraju datoteke doda jedan red sa crticama, a ispod ispise SAB = */
fprintf(dat,"\n");
for(i=1;i<=39;i++) fprintf(dat,"-");
fprintf(dat,"\nSAB = ");




294
/* Rezultujuci polinom se nalazi u sortiranoj listi. Uzima se clan po clan polinoma i
ispisuje u istom formatu kao sto su i ostali polinomi u datoteci. Nakon upisa cvor liste se
brise. */

while(*glava!=NULL)
{
tek=*glava;
if((*glava)->ko!=0) fprintf(dat,"(%d,%d)",(*glava)->ko,(*glava)->step);
*glava=tek->sledeci;
tek->sledeci=NULL;
free(tek);
if(*glava!=NULL&&(*glava)->ko) fprintf(dat,",");
}
}

Test primer:

POLINOM.TXT (PRE STARTOVANJA PROGRAMA)

(2,5),(2,1),(3,0)
(1,4),(9,0)


POLINOM.TXT (POSLE STARTOVANJA PROGRAMA)

(2,5),(2,1),(3,0)
(1,4),(9,0)
---------------------------------------
SAB = (2,5),(1,4),(2,1),(12,0)






















295
7.5. TESTOVI IZ DATOTEKA I DINAMIKIH STRUKTURA
PODATAKA

TEST 3
GRUPA 1

Zadatak 1
Napisati deo C koda koji otvara tekstualnu datoteku za auriranje (itanje i pisanje),
dodajui nove elemente na njen kraj. Naziv datoteke bez putanje unosi se sa tastature.

//Napisati kod




Zadatak 2
Napisati deo C koda koji u tekstualnoj datoteci utvruje koliko ima velikih slova. Naziv
datoteke bez putanje uneti sa tastature.

//Napisati kod.




Zadatak 3
U sledeem delu koda postoje greke. Prepraviti deo koda tako da ispravno radi, a potom
objasniti kakvih greaka je bilo. Smatrati da je datoteka uspeno otvorena, i da je potrebno svaki
red datoteke smestiti u niz stringova.

//Deo koda koga treba ispraviti

char c[81*25], *s2[25];
unsigned i;
FILE *dat;

for(i=0;i<25;i++) s2[i]=c;
i=0;
while(fgets(c,80,dat)!=NULL)
{
strcpy(s2[i],c);
s2[i+1]=s2[i]+strlen(s2[i]);
i++;
}

Zadatak 4
Ako je poznato da funkcija utvrdi iji je prototip:
unsigned utvrdi(FI LE *dat, char *s);
u stringu s, koji predstavlja jedan red datoteke, utvruje prvu najduu re i vraa indeks
poetka najdue rei u stringu s. Pokaziva na datoteku je dat. Napisati deo koda koji
296
korienjemm funkcije utvrdi, u svakom redu prvu najduu re formatira tako to sva slova te
rei pretvaraju u velika slova.

//Napisati deo koda

Zadatak 5
Napisati funkciju vreme koja na osnovu celobrojnog podatka sekunde formira i vraa
podatak tipa Tsat. Tip podatka Tsat sastoji se od polja: sek, min i sat koji su tipa int.
//Prototip funkcije

//Definisanje funkcije.




//Pozicv funkcije

Zadatak 6
Napisati funkciju rednaveza koja na osnovu niza struktura x izraunava i vraa podatak
koji predstavlja ekvivalentntnu impedansu redne veze impedansi u kompleksnom obliku. Svaki
element niza predstavlja jednu impedansu redne veze i tipa je Tkom. Tip podataka Tkom sastoji
se od dva polja: realni i imaginarni koji su tipa float.
//Prototip funkcije

//Definisanje funkcije.





//Pozicv funkcije

Zadatak 7
Napisati deo C koda koji omoguava smetanje niza struktura X u binarnu datoteku
UCENICI.DAT uz brisanje predhodnog sadraja datoteke. Elemente niza ine podaci tipa
Tucenik sa poljima: prezime, ime i prosecna_ocena. Promenljiva prosecna_ocena je tipa
double, a promenljive prezime i ime su stringovi od maksimalno 30 karaktera.

//Napisati deo koda





Zadatak 8
Ako u dinamikoj zoni podataka postoje dve jednostruko spregnute liste, napisati deo C
koda koji omoguava nadovezivanje druge liste na kraj prve. Pokaziva prvi je pokaziva na
prvi vor prve liste, a pokaziva drugi je pokaziva na prvi vor druge liste. vorovi liste su tipa
Tcvor i sadre u sebi pokaziva sledeci.

//Napisati deo koda
297
Zadatak 9
Ako pored pokazivaa na poetak liste glava, postoji i pokaziva na rep liste rep, napisati
funkciju uvezinakraj koja omoguava ulanavanje elementa na koji pokazuje pokaziva pok na
kraj liste. vorovi liste su tipa Tcvor koji u sebi sadri pokaziva sledeci.
//Prototip funkcije

//Definisanje funkcije.






//Pozicv funkcije

Zadatak 10
U sledeoj funkciji postoje greke. Prepraviti funkciju tako da ispravno radi, a potom
objasniti kakvih greaka je bilo. vorovi liste su tipa Tcvor a pokaziva na prvi vor liste je
glava.

void dodajnapocetakliste(Tcvor *glava)
{
Tcvor *novi = NULL;
novi = formcvor();
if(glava==NULL) glava=novi;
else{
glava=novi;
novi -> sledeci=glava;
}
}

//Ispravljeni kod funkcije uz objanjenja





REENJA SA TESTA 3
GRUPA 1


Zadatak 1
Napisati deo C koda koji otvara tekstualnu datoteku za auriranje (itanje i pisanje),
dodajui nove elemente na njen kraj. Naziv datoteke bez putanje unosi se sa tastature.

//Napisati kod
FILE *dat;
char ime[13];

printf("Unesite ime datoteke bez putanje: ");
gets(ime);
298
if((dat=fopen(ime, "a"))==NULL)
{
printf("Datoteka %s se ne moze otvoriti!!");
getch();
return;
}

Zadatak 2
Napisati deo C koda koji u tekstualnoj datoteci utvruje koliko ima velikih slova. Naziv
datoteke bez putanje uneti sa tastature.

//Napisati kod.
FILE *dat;
char ime[13],c;
unsigned br=0;

printf("Unesite ime datoteke bez putanje: ");
gets(ime);
if((dat=fopen(ime, "r"))==NULL)
{
printf("Datoteka %s se ne moze otvoriti!!");
getch();
return;
}

while((c=fgetc(dat))!=EOF)
{
if(isupper(c)) br++;
}

Zadatak 3
U sledeem delu koda postoje greke. Prepraviti deo koda tako da ispravno radi, a potom
objasniti kakvih greaka je bilo. Smatrati da je datoteka uspeno otvorena, i da je potrebno svaki
red datoteke smestiti u niz stringova.

//Deo koda koga treba ispraviti //Ispravljeni deo koda

char c[81*25], *s2[25]; char c[81*25], *s2[25], s[81], *pom=c;
unsigned i; unsigned i;
FILE *dat; FILE *dat;
s2[0]=pom;
for(i=0;i<25;i++) s2[i]=c; for(i=1;i<25;i++) s2[i]=NULL;
i=0; i=0;
while(fgets(c,80,dat)!=NULL) while(fgets(s,80,dat)!=NULL)
{ {
strcpy(s2[i],c); strcpy(s2[i],s);
s2[i+1]=s2[i]+strlen(s2[i]); s2[i+1]=s2[i]+strlen(s2[i])+1;
i++; i++;
} }


299
Zadatak 4
Ako je poznato da funkcija utvrdi iji je prototip:
unsigned utvrdi(FI LE *dat, char *s);
u stringu s, koji predstavlja jedan red datoteke, utvruje prvu najduu re i vraa indeks
poetka najdue rei u stringu s. Pokaziva na datoteku je dat. Napisati deo koda koji
korienjemm funkcije utvrdi, u svakom redu prvu najduu re formatira tako to sva slova te
rei pretvaraju u velika slova.

//Napisati deo koda
FILE *dat;
char s[81];
unsigned i,j;

while(fgets(s,80,dat)!=NULL)
{
i=utvrdi(dat,s);
while(s[i]!= '\0'&& (!isalnum(s[i])))
{
if(isalpha(s[i]))
{
if(!islower(s[i])) s[i]=toupper(s[i]);
}
i++;
}
}

Zadatak 5
Napisati funkciju vreme koja na osnovu celobrojnog podatka sekunde formira i vraa
podatak tipa Tsat. Tip podatka Tsat sastoji se od polja: sek, min i sat koji su tipa int.
//Prototip funkcije
Tsat vreme(int sekunde);

//Definisanje funkcije.
Tsat vreme(int sekunde)
{
Tsat pom;
pom.sat=sekunde/3600;
pom.min=(sekunde%3600)/60;
pom.sek=sekunde%60;

return pom;
}

//Pozicv funkcije
Tsat x;
unsigned sekunde;

x=vreme(sekunde);



300
Zadatak 6
Napisati funkciju rednaveza koja na osnovu niza struktura x koja ima n elemenata,
izraunava i vraa podatak koji predstavlja ekvivalentntnu impedansu redne veze impedansi u
kompleksnom obliku. Svaki element niza predstavlja jednu impedansu redne veze i tipa je Tkom.
Tip podataka Tkom sastoji se od dva polja: realni i imaginarni koji su tipa float.

//Prototip funkcije
Tkom rednaveza(Tkom x[MAX], int n);

//Definisanje funkcije.
Tkom rednaveza(Tkom x[MAX], int n)
{
unsigned i=0;
Tkom pom={0,0};
for(i=0;i<n;i++)
{
pom.realni+=x[i].realni;
pom.imaginarni+=x[i].imaginarni;
}
return pom;
}

//Pozicv funkcije
Tkom x[MAX], ekvlredna;
nnsigned n;

ekvlredna=rednaveza(x,n);

Zadatak 7
Napisati deo C koda koji omoguava smetanje niza struktura X od n elemenata u binarnu
datoteku UCENICI.DAT uz brisanje predhodnog sadraja datoteke. Elemente niza ine podaci
tipa Tucenik sa poljima: prezime, ime i prosecna_ocena. Promenljiva prosecna_ocena je tipa
double, a promenljive prezime i ime su stringovi od maksimalno 30 karaktera.

//Napisati deo koda
FILE *dat;
unsigned i,n;
Tucenik x[MAX];

dat=fopen("UCENICI.DAT", "wb");

for(i=0;i<n;i++) fwrite(&x[i],sizeof(Tucenik),1,dat);

Zadatak 8
Ako u dinamikoj zoni podataka postoje dve jednostruko spregnute liste, napisati deo C
koda koji omoguava nadovezivanje druge liste na kraj prve. Pokaziva prvi je pokaziva na
prvi vor prve liste, a pokaziva drugi je pokaziva na prvi vor druge liste. vorovi liste su tipa
Tcvor i sadre u sebi pokaziva sledeci.

//Napisati deo koda
Tcvor *pok=prvi;
301
if(pok==NULL) prvi=drugi;
else{
if(drugi!=NULL)
{
while(pok->sledeci!=NULL) pok=pok->sledeci;
pok->sledeci=drugi;
drugi=NULL;
}
}

Zadatak 9
Ako pored pokazivaa na poetak liste glava, postoji i pokaziva na rep liste rep, napisati
funkciju uvezinakraj koja omoguava ulanavanje elementa na koji pokazuje pokaziva pok na
kraj liste. vorovi liste su tipa Tcvor koji u sebi sadri pokaziva sledeci.
//Prototip funkcije
void uvezinakraj(Tcvor *glava, Tcvor **rep, Tcvor *pok);

//Definisanje funkcije.
void uvezinakraj(Tcvor **glava, Tcvor **rep, Tcvor *pok)
{
if(*glava==NULL) *glava=*rep=pok;
else{
rep->sledeci=pok;
pok->sledeci=NULL;
}
}

//Pozicv funkcije
Tcvor *glava, *rep, *pok;

uvezinakraj(&glava,&rep,pok);


Zadatak 10
U sledeoj funkciji postoje greke. Prepraviti funkciju tako da ispravno radi, a potom
objasniti kakvih greaka je bilo. vorovi liste su tipa Tcvor a pokaziva na prvi vor liste je
glava.

void dodajnapocetakliste(Tcvor *glava) void dodajnapocetakliste(Tcvor **glava)
{ {
Tcvor *novi = NULL; Tcvor *novi = NULL;
novi = formcvor(); novi = formcvor();
if(glava==NULL) glava=novi; if(*glava==NULL) *glava=novi;
else{ else{
glava=novi; novi -> sledeci=*glava;
novi -> sledeci=glava; *glava=novi;
} }
} }



302
TEST 3
GRUPA 2

Zadatak 1
Napisati deo C koda koji otvara tekstualnu datoteku za auriranje (itanje i pisanje),
odbacujui postojei sadraj ako postoji, ili kreira novu datoteku ako ona ne postoji. Naziv
tekstualne datoteke bez putanje unosi se sa tastature ili iz komandne linije.

//Napisati kod



Zadatak 2
Ako je poznato da funkcija brojireci utvruje broj rei u jednom redu tekstualne datoteke.
Napisati deo C koda koji tampa tabelarni prikaz pojave rei po redovima u datoteci, oblika:

R.BR. REDA BROJ RECI
1 22
2 18
. .
. .
//Napisati kod.





Zadatak 3
U sledeem delu koda postoje greke. Prepraviti deo koda tako da ispravno radi, a potom
objasniti kakvih greaka je bilo. Smatrati da je datoteka uspeno otvorena, i da je potrebno svaki
red datoteke smestiti u niz stringova.

char s[100],c;
unsigned i=0,br=0;
FILE *dat;

while(fgets(s,150,dat)!=NULL)
{
while(s[i]!='\0') if(s[i]==c) br++;
i++;

}

Zadatak 4
Napisati funkciju utvrdi koja na osnovu niza pokazivaa na stringove X i broja lanova
niza n utvruje koji red datoteke sadri najvie rei. U nizu stringova X predhodno je ve
smetena tekstualna datoteka, a n je broj redova datoteke.
Funkcija vraa redni broj reda datoteke koji sadri najvie rei. U sluaju da vie redova
sadri najdue rei iste duine, funkcija vraa red koji je blii kraju datoteke.

//Prototip funkcije
303
//Definisanje funkcije.






//Pozicv funkcije


Zadatak 5
Napisati deo C koda koji definie tri podatka koji su stringovi. Omoguiti unos dva stringa
sa tastature, a potom izvriti zamenu stringova bez korienja funkcija za kopiranje stringova ili
ciklusa za prolaske kroz stringove.

//Napisati deo koda





Zadatak 6
Ako se u svakom redu tekstualne datoteke nalaze podaci o jednom ueniku: prezime, ime i
prosek, meusobno razdvojeni sa jednom prazninom, napisati deo C koda koji na osnovu
tekstualne datoteke formira niz X, pri emu je svaki element niza tipa Tucenik sa poljima:
prezime, ime i prosek. Promenljive prezime i ime su stringovi od maksimalno 30 karaktera, a
prosek je tipa float.

//Napisati deo koda


.
Zadatak 7
Napisati deo C koda koji omoguava ukljuivanje mia u program pod DOS-om
ukljuivanjem biblioteke MIS.H. Ako se klikne levim tasterom mia na ekranu se ispie veliko
slovo A.

//Napisati deo koda



Zadatak 8
Ako u dinamikoj zoni podataka postoje dve sortirane jednostruko spregnute liste po
rastuem kriterijumu, napisati deo C koda koji omoguava prevezivanje pokazivaa jedne i druge
liste tako da nastane jedna lista koja e ostati sortirana po istom kriterijumu sortiranja. Pokaziva
prvi je pokaziva na prvi vor prve liste, a pokaziva drugi je pokaziva na prvi vor druge liste.
vor liste je tipa Tcvor i pored pokazivaa sledeci sastoji se i od podatka broj. Obratite panju
da neka od listi moda nema elemenata.

//Napisati deo koda

304
Zadatak 9
Ako pokaziva tek pokazuje na vor jednostruko spregnute liste koga treba izbrisati iz liste,
napisati deo C koda koji omoguava brisanje tog vora iz liste. Pokaziva na poetak liste je
glava. vorovi liste su tipa Tcvor koji u sebi sadri pokaziva sledeci.

//Napisati deo koda






Zadatak 10
U sledeoj funkciji postoje greke. Prepraviti funkciju tako da ispravno radi, a potom
objasniti kakvih greaka je bilo. vorovi liste su tipa Tcvor a pokaziva na prvi vor liste je
glava.

void formsortlistu(Tcvor *glava, Tcvor *novi)
{
Tcvor iza=NULL, ispred=NULL;

novi= (Tcvor *)malloc(sizeof(Tcvor));
scanf("%lf",novi->info.pod);
iza=glava;
while(iza!=NULL&&novi->info.pod>iza->info.pod)
{
iza=ispred;
ispred=ispred->sledeci;
}
novi->sledeci=iza;
if(glava==iza) glava=novi;
else iza->sledeci=novi;
}

//Ispravljeni kod funkcije uz objanjenja





TEST 3
GRUPA 3

Zadatak 1
Napisati deo C koda koji otvara tekstualnu datoteku za auriranje (itanje i pisanje)
postavljajui pokaziva na poetak datoteke. Naziv datoteke bez putanje unosi se sa tastature ili iz
komandne linije.

//Napisati kod


305


Zadatak 2
Napisati funkciju ucitaj koja sadraj tekstualne datoteke (koja je ve uitana) i na koji
pokazuje pokaziva dat, prepisuje u string s. Funkcija vraa broj slova koji se nalazi u datoteci.
//Prototip funkcije

//Definisanje funkcije.






//Pozicv funkcije


Zadatak 3
Napisati deo C koda koji pravi inverziju u tekstualnoj datoteci. Svako malo slovo u datoteci
pretvara u veliko i veliko u malo slovo. Ostali karakteri ostaju nepromenjeni. Naziv datoteke se
nalazi u promenljivoj imedat.

//Napisati kod






Zadatak 4
Napisati funkciju impedansa koja na osnovu napona i struje u kompleksnom obliku
izraunava i vraa impedansu, a prenosom po referenci prividnu snagu u kompleksnom obliku.
Kompleksan broj je opisan sa tipom podataka Tkom. Tip podataka Tkom sastoji se od dva polja:
real i imag koji su tipa double.

//Napisati kod






Zadatak 5
Ako je poznat niz X od n elemenata, pri emu su elementi niza tipa Tucenik, napisati deo
C koda koji sortira niz u opadajuem redosledu po broju osvojenih bodova, a drugi kriterijum je
po abecednom redosledu ako imaju isti broj bodova. Tip podataka Tucenik sastoji se od polja:
prezime, ime i br_bodova.

//Napisati kod


306

Zadatak 6
U sledeem delu koda postoje greke. Prepraviti deo koda tako da ispravno radi, a potom
objasniti kakvih greaka je bilo. Svako slovo u datoteci koje je indentino sa slovom zapisanim u
promenljivoj c, zameniti sa slovom zapisanim u promenljivoj d.

char c,d,car;
long poz;
FILE *dat;

do{
poz=ftell(dat);
car=fgetc(dat);
if(car == c)
{
fseek(dat,poz,SEEK_SET);
fputc(d,dat);
printf("%c",d);
}else printf("%c",car);
}while(car!=EOF);

Zadatak 7
Napisati deo C koda koji iz binarne datoteke PRIHOD.DAT uitava k binarnih 32-bitnih
rei i formira niz od k elemenata. Svaki element niza je tipa Tpodatak sa poljima:
broj_proizvoda, dan, mesec i godina.

Binarna re je oblika:
0 11 bita broj proizvoda
12 16 bita dan
17 20 bita mesec
21 32 bita godina

//Napisati kod







Zadatak 8
Ako se u dinamikoj zoni podataka nalazi jednostruko spregnuta lista koja je sortirana u
opadajuem redosledu, napisati deo koda koji izvrava prevezivanje vorova liste, tako da lista
budec sortirana u rstuem redosledu. Pokaziva prvi je pokaziva na prvi vor liste. vor liste je
tipa Tcvor i pored pokazivaa sledeci sastoji i od polja broj. Obratite panju da neka od listi
moda nema elemenata. .

//Napisati kod



307

Zadatak 9
Ako se u dinamikoj zoni podataka nalazi jednostruko spregnuta lista, pri emu je pok
pokaziva na poetak liste. Napisati funkciju broj koja utvruje i vraa koliko lista sadri
elemenata. vorovi liste su tipa Tcvor koji u sebi sadri pokaziva sledeci.
//Prototip funkcije

//Definisanje funkcije.




//Pozicv funkcije


Zadatak 10
U sledeoj funkciji postoje greke. Prepraviti funkciju tako da ispravno radi, a potom
objasniti kakvih greaka je bilo. vorovi liste su tipa Tcvor a pokaziva na prvi vor liste je
glava. U okviru funkcije brisanjeelementa poziva se funkcija trazi koja utvruje da li postoji
vor sa informacionim sadrajem koji sadri kljuc traenja.

unsigned brisanjeelementa(Tcvor *glava, Tslog kljuc)
{
Tcvor *tek, *pret;
tek=pret=NULL;

tek= trazi(glava,kljuc);
if(tek==NULL) return 0;

if(tek==glava)
{
tek->sledeci=NULL;
glava=tek->sledeci;
}else{
pret=glava;
while(pret->sledeci!=tek) tek=tek->sledeci;
free(tek);
pret->sledeci=tek->sledeci;
tek->sledeci=NULL;
}

return 1;
}

//Ispravljeni kod funkcije uz objanjenja






308

7.6. STEK
Realizacija stek-a pomou niza
Realizacija stek-a pomou jednostruko spregnute liste


Stek je poludinamika struktura podataka. Moe se realizovati pomou niza ili
jednostruko spregnute liste. Kod steka je dostupna samo poslednje dodata vrednost
(za koju se kae da je na vrhu steka). Sa steka se uklanja poslednji dodani element.
Na steku su definisane dve operacije:
- dodavanje elementa na stek (push), i
- skidanje elementa sa steka (pop).


Prilikom realizacije steka jednostruko spregnutom listom,
stek je opisan sa vorovima liste i pokazvaa na prvi vor liste
koji se zove pokaziva na vrh steka. Funkcijom push novi
objekat se dodaje na stek dodavanjem na poetak liste. Prilikom
korienja funkcije pop funkcija fraa kao rezultat podatke sa
objekta koji je prvi lan liste i brie prvi vor liste uz oslobaanje
memorije koju je taj vor zauzeo.




Primer 1:
Napisati C program koji vri auriranje tekstualne datoteke REDOVI.TXT
primenom steka (ealizovanog pomou niza). U svakom redu datoteke nalaze se podaci o
jednom ueniku. Nije potrebno obraivati te podatke ve treba datoteku aurirati u
inverznom poretku po redovima.

Na primer:

REDOVI.TXT Preureena datoteka REDOVI.TXT

Beg Marijan 5.00 Prljevi Slobodan 4.50
Makan Dalibor 4.93 Savin Nikola 2.93
Savin Nikola 2.93 Makan Dalibor 4.93
Prljevi Slobodan 4.50 Beg Marijan 5.00

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>

info


vrh
info

info
NULL
309
/* Definise se struktura Tredovi koja ima samo jedno polje. */
typedef struct redovi{
char s[81];
}Tredovi;


/* Prototipovi funkcija. */
unsigned push(FILE *dat, Tredovi niz[], int *n);
unsigned pop(FILE *dat, Tredovi niz[], int *n);


void main(void)
{

/* Deklaracija promenljivih. */
FILE *dat;
int vrh=0,i;
Tredovi niz[100]; /* Promenljiva niz je niz struktura. */

/* Inicijalizacija niza. */
for(i=0;i<100;i++) strcpy(niz[i].s,"");

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

/* Otvaranje datoteke za citanje. */
if((dat=fopen("REDOVI.TXT","r"))==NULL)
{
printf("Datoteka REDOVI.TXT se ne moze otvoriti!!");
getch();
return;
}

printf("Datoteka REDOVI.TXT je uspesno otvoren!!");

/* Smestanje datoteke na stek red po red funkcijom push. */
while(push(dat,niz,&vrh));
fclose(dat);

/* Datoteka se ponovno otvara sada za pisanje i time se predhodni sadrzaj datoteke brise.
*/

dat=fopen("REDOVI.TXT","w");

/* Uzimaju se podaci iz niza u suprotnom redosledu. /*
while(pop(dat,niz,&vrh));

fclose(dat);
printf("\n\nU datoteku REDOVI.TXT upisani su redovi u obrnutom redosledu!!");
310

gotoxy(1,25);
getch();
}


/* Funkcija omogucava ucitavanje jednog reda iz datoteke i upisivanje u niz. Funkcija
vraca jedan ako je uspesno dodala element na stek ili 0 u suprotnom. */

unsigned push(FILE *dat, Tredovi niz[], int *vrh)
{
char s[81]="";

if(fgets(s,80,dat)!=NULL)
{
/* Potrebno je da poslednji karakter stringa bude '\n' da ne bi bilo iznenadjenja
prilikom formiranja nove datoteke. */

if(s[strlen(s)-1]!='\n') strcat(s,"\n");

/* Vrh steka predstavlja indeks vrh. */
strcpy(niz[*vrh].s,s);
(*vrh)++;

return 1;
}

return 0;
}

/* Funkcija pop omogucava uzimanje podatka sa steka i to samo onog koji je poslednji unet
na stek. Funkcija vraca 0 ako je stek prazan ili 1 u suprotnom. */
unsigned pop(FILE *dat, Tredovi niz[], int *n)
{

(*n)--;
if((*n)<0) return 0;

/* Upis reda u datoteku. */
fprintf(dat,"%s",niz[*n].s);

return 1;
}


Primer 2:
Napisati C program koji vri auriranje tekstualne datoteke REDOVI.TXT
primenom steka (realizovanog pomou jednostruko spregnute liste). U svakom redu
datoteke nalaze se podaci o jednom ueniku. Nije potrebno obraivati te podatke ve
treba datoteku aurirati u inverznom poretku po redovima.
311

Na primer:

REDOVI.TXT Preureena datoteka REDOVI.TXT

Beg Marijan 5.00 Prljevi Slobodan 4.50
Makan Dalibor 4.93 Savin Nikola 2.93
Savin Nikola 2.93 Makan Dalibor 4.93
Prljevi Slobodan 4.50 Beg Marijan 5.00

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

/* Definise se struktura Tredovi koja ima samo jedno polje. */
typedef struct cvor{
char s[81];
struct cvor *sledeci;
}Tcvor;

/* Prototipovi funkcija. */
unsigned push(FILE *dat, Tcvor **vrh);
unsigned pop(FILE *dat, Tcvor **vrh);

void main(void)
{

/* Deklaracija promenljivih. */
FILE *dat;
Tcvor *vrh=NULL;


textmode(3);
textbackground(0);
textcolor(15);
clrscr();

/* Otvaranje datoteke za citanje. */
if((dat=fopen("REDOVI.TXT","r"))==NULL)
{
printf("Datoteka REDOVI.TXT se ne moze otvoriti!!");
getch();
return;
}
printf("Datoteka REDOVI.TXT je uspesno otvoren!!");


312
/* Smestanje datoteke na stek red po red funkcijom push. */
while(push(dat,&glava));
fclose(dat);

/* Datoteka se ponovno otvara sada za pisanje i time se predhodni sadrzaj datoteke brise.
*/

dat=fopen("REDOVI.TXT","w");

/* Uzimaju se podaci sa pocetka liste. */
while(pop(dat,&vrh));

fclose(dat);
printf("\n\nU datoteku REDOVI.TXT upisani su redovi u obrnutom redosledu!!");

getch();
}

/* Funkcija omogucava ucitavanje jednog reda iz datoteke i upisivanje u niz. Funkcija
vraca jedan ako je uspesno dodala element na stek ili 0 u suprotnom. */
unsigned push(FILE *dat, Tcvor **vrh)
{
char s[81]="";
Tcvor *novi;

if(fgets(s,80,dat)!=NULL)
{
if(s[strlen(s)-1]!='\n') strcat(s,"\n");

novi=(Tcvor *)malloc(sizeof(Tcvor));
strcpy(novi->s,s);
novi->sledeci=NULL;

/* Vrh steka je vrh pokazivac na pocetak liste. */
if(*vrh == NULL) *vrh=novi;
else{
novi->sledeci=*vrh;
*vrh=novi;
}

return 1;
}
return 0;
}

/* Funkcija pop omogucava uzimanje podatka sa steka i to samo onog koji je poslednji unet
na stek. Funkcija vraca 0 ako je stek prazan ili 1 u suprotnom. */
unsigned pop(FILE *dat, Tcvor **vrh)
{
Tcvor *tek;

313
if(*vrh==NULL) return 0;

/* Upis reda u datoteku. */
fprintf(dat,"%s",(*vrh)->s);

/* Brise se prvi cvor iz liste i oslobadja zauzeta memorija. */
tek=*vrh;
*vrh=tek->sledeci;
tek->sledeci=NULL;
free(tek);

return 1;
}

Primer 3:
Zadata je tekstualna datoteka PRIMER.TXT. Korienjem dinamike strukture podataka
STEK formirati izlaznu datoteku IZLAZ.TXT gde e biti zapisana datoteka PRIMER.TXT u
invernom poretku po pasusima. Izmeu pasusa postoji prazan red.
Reenje:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

/* Definisanje cvora steka. */
typedef struct stek{
char rec[3000];
struct stek *sled;
}Tcvor;

void push(Tcvor **vrh,char *s); /* Dodavanje cvora na stek. */
char *pop(Tcvor **vrh); /* Uzimanje podatka sa steka uz oslobadjanje zauzete memorije. */

void main(void)
{
FILE *dat;
Tcvor *vrh=NULL;
int br=0;
char s1[101]="",s[3000]="", *pok;

textmode(3);
textbackground(0);
textcolor(15);
clrscr();

if((dat=fopen("PRIMER.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka %s se ne moze otvoriti!!");
return;
}
314

/* Ucitava se red po red iz tekstualne datoteke. Ako je red prazan kraj je pasusa i
formirani string s se upisuje na sek. Promenljivom br brojimo koliko datoteka sadrzi
pasusa. Ako red nije prazan nadoveyuje se na kraj stringa s. */

while(fgets(s1,100,dat)!=NULL)
{
if(!strcmp(s1,"\n"))
{
br++;
push(&vrh,s);
printf("%s",vrh->rec);
getch(); clrscr(); strcpy(s,"");
}else strcat(s,s1);
}
fclose(dat);

/* Otvara se datoteka za pisanje i upisuju se pasusi sacuvani na steku. */
dat=fopen("IZL.TXT","w");
while((pok=pop(&vrh))!=NULL) fprintf(dat,"%s\n",pok), pok=NULL;
}

void push(Tcvor **vrh,char *s)
{
Tcvor *novi;

novi=(Tcvor *)malloc(sizeof(Tcvor));
strcpy(novi->rec,s); novi->sled=NULL;

if((*vrh)==NULL) *vrh=novi;
else{
novi->sled=*vrh;
*vrh=novi;
}
}

char *pop(Tcvor **vrh)
{
Tcvor *tek;
char *pok;

if(*vrh==NULL) return NULL;
tek=*vrh;
*vrh=(*vrh)->sled;
pok=tek->rec;
free(tek);

return pok;
}

315
7.7. STEK I REKURZIJA

Algoritamske tehnike mogu se podeliti u dve grupe: iterativnu i rekurzivnu.
Svaki problem moe se reiti iterativnom ili rekurzivnom tehnikom. Koja e se
tehnika primeniti zavisi od problema koji se reava.
Jedan od tipinih zadataka gde se rekurzija koristi je pretraivanje sa vraanjem.
Primer korienja tehnike pretraivanje sa vraanjem je lavirint, koji ima jedan ulaz, a
vie izlaza, te je potrebno prikazati sve puteve izlaska iz lavirinta.

Primer:
U tekstualnoj datoteci LAVIRINT.TXT nalazi se mapa lavirinta. U prvom redu su
dimenzije matrice lavirinta, a u sledeim redovima je matrica lavirinta. Elemente lavirinta
ine brojevi od 0-3, ija su znaenja:

0 - hodnik;
1 - zid;
2 - ulaz u lavirint; i
3 - izlaz iz lavirinta

Lavirint ima samo jedan ulaz koji se nalazi na krajevima matrice, i vie izlaza koji
se nalaze takoe na krajevima matrice (prva vrsta, zadnja vrsta, prva kolona, zadnja
kolona). Potrebno je prikazati sve mogue puteve izlaska iz lavirinta. Sa pritiskom na bilo
koji taster prikazuje se sledei put izlaska (sledee reenje).
Zadatak reiti rekurzivnom tehnikom.


Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>

#define MAXX 70
#define MAXY 15

/* Prototipovi funkcija. */
void maska(int m[MAXX][MAXY], int *vr, int *kol, int *startx, int *starty, int *poci,
int *pocj);
void crtaj(int m[MAXX][MAXY], int vr, int kol, int startx, int starty);
void nadji(int m[MAXX][MAXY], int i, int j, int vr, int kol, int startx, int starty);
int moze(int m[MAXX][MAXY], int i, int j, int vr, int kol);
void pisi(int m[MAXX][MAXY], int vr, int kol, int startx, int starty);


void main(void)
{
316
/* Matrica lavirinta je m, vr je broj vrsta, kol je broj kolona, poci i pocj su indeksi u
matrici gde je ulaz, a startx i starty cine pocetnu poziciju na ekranu. */

int i,j,vr=0,kol=0,m[MAXX][MAXY],poci,pocj;
int startx=0,starty=0;

for(i=0;i<MAXX;i++)
{
for(j=0;j<MAXY;j++) m[i][j]=0;
}

textmode(3);
textcolor(15);
textbackground(15);
clrscr();
textcolor(4);
_setcursortype(_NOCURSOR);

gotoxy(36,2);
cprintf("LAVIRINT");

/* Crta se lavirint na ekranu. */
maska(m,&vr,&kol,&startx,&starty,&poci,&pocj);
textcolor(2);

/* Prikazuju se sva moguca resenja. */
nadji(m,poci,pocj,vr,kol,startx,starty);
}

/* Funkcija crta lavirint. Nema povratnu vrednost. Formira matricu ucitavanjem podataka iz
datoteke. */
void maska(int m[MAXX][MAXY], int *vr, int *kol, int *startx, int *starty,
int *poci, int *pocj)
{
FILE *dat;
char s[81],*pok;
int i,j;

if((dat=fopen("LAVIRINT.TXT","r"))==NULL)
{
gotoxy(35,12);
printf("Datoteka LAVIRINT.TXT se ne moze otvoriti!!");
return;
}

/* Ucitava se prvi red datoteke i utvrdjuje broj vrsta i kolona. */
fgets(s,80,dat);
pok=strtok(s," ");
*vr=atoi(pok);
pok=strtok(NULL,"\n");
*kol=atoi(pok);
317

/* Odredjuju se startne pozicije gornjeg ugla lavirinta tako da lavirint bude uvek na
sredini ekrana. */

*startx=41-3*(*kol)/2;
*starty=12-(*vr)/2;

/* Formira se matrica lavirinta ucitavanjem podataka iz datoteke. */
for(i=0;i<*vr;i++)
{
fgets(s,81,dat);
for(j=0;j<*kol;j++)
{
m[i][j]=s[j]-48;
if(m[i][j]==2) *poci=i, *pocj=j;
}
}
fclose(dat);

/* Pozova se funkcija crtaj koja na osnovu matrice lavirinta crta lavirint. */
crtaj(m,*vr,*kol,*startx,*starty);
}

/* Funkcija crtaj na osnovu matrice lavirinta prikazuje lavirint na ekranu. */
void crtaj(int m[MAXX][MAXY], int vr, int kol, int startx, int starty)
{
int i,j;

for(i=0;i<vr;i++)
{
gotoxy(startx,starty+i);
for(j=0;j<kol;j++)
{
if(m[i][j]==1)
{
textbackground(0);
textcolor(1);
cprintf("");
}

if(m[i][j]==0)
{
textbackground(0);
textcolor(15);
cprintf(" ");
}
if(m[i][j]==2)
{
textbackground(0);
textcolor(2);
318
cprintf(" $ "); /* Sa karakterom $ oznacice se covek u lavirintu.
*/
}
if(m[i][j]==3)
{
textbackground(0);
textcolor(2);
cprintf("IZL");
}
}
}

}

/* Funkcija nadji je glavna funkcija jer utvrdjuje i prikazuje na ekranu sve puteve izlaska iz
lavirinta. Rekurzivna je funkcija, nema unutar lokalnih promenljivih kako se stek ne bi
opteretio.*/

void nadji(int m[MAXX][MAXY], int i, int j, int vr, int kol, int startx, int starty)
{
/* Ako se u matrici upise vrednost 4 znaci da je covek na toj poziciji bio. */
if(m[i][j]==0) m[i][j]=4;

/* Ako se nadje na granici lavirinta i tu je ujedno izlaz funkcijom pisi ispisuje se resenje.
*/

if((i==0||i==vr-1||j==0||j==kol-1)&&m[i][j]==3) pisi(m,vr,kol,startx,starty);
else{

/* Redom se proverava i pomera gde moze, te zbog rekurzije sa gornjim if-om
upisuje 4 da je tu bio ako je mogao da bude. */

if(moze(m,i+1,j,vr,kol)) nadji(m,i+1,j,vr,kol,startx,starty);
if(moze(m,i-1,j,vr,kol)) nadji(m,i-1,j,vr,kol,startx,starty);
if(moze(m,i,j+1,vr,kol)) nadji(m,i,j+1,vr,kol,startx,starty);
if(moze(m,i,j-1,vr,kol)) nadji(m,i,j-1,vr,kol,startx,starty);
}
/* Ako nije ulaz ili izlaz znaci da je bio po drugi put, to je taj deo puta slep i upisuje se 0
kao da tu i nije bio. */

if(m[i][j]!=2&&m[i][j]!=3) m[i][j]=0;
}

/* Funkcija moze utvrdjuje da li se covek moze naci na toj poziciji, te ako moze vraca 1 a u
suprotnom 0. */
int moze(int m[MAXX][MAXY], int i, int j, int vr, int kol)
{
return i>=0&&i<vr&&j>=0&&j<kol&&(m[i][j]==0||m[i][j]==3);
}


319
/* Funkcija pisi prikazuje nadjeni put izlaska iz lavirinta. */
void pisi(int m[MAXX][MAXY], int vr, int kol, int startx, int starty)
{
int i,j;

/* Prolazi se kroz matricu lavirinta i tamo gde se u matrici nalazi broj 4 znaci da je tu
covek bio te se ispisuje crveni $. */
for(i=0;i<vr;i++)
{
for(j=0;j<kol;j++)
{
if(m[i][j]==4)
{
gotoxy(startx+1+3*j,starty+i);
textcolor(4);
cprintf("$");
}
}
}
while(!kbhit()); /* Dok ne pritisnes taster gledaj resenje. */

/* Sada je potrebno izbrisati predhodno resenje. */
textbackground(0);
for(i=0;i<vr;i++)
{
for(j=0;j<kol;j++)
{
gotoxy(startx+1+3*j,starty+i);
if(m[i][j]==4) cprintf(" ");
}
}
getch();
}

Test primer programa:


320
7.8 DINAMIKA STRUKTURA PODATAKA RED

Red je dinamika struktura podataka ija je struktura slina steku. Osnovna
razlika izmeu ove dve strukture je to se redovi indentifikuju sa dva pokazivaa:
glava koji pokazuje na logiki prvi vor liste i rep koji pokazuje na logiki poslednji
vor liste (rep liste). Kod steka elemenat se moe uzimati i dodavati samo sa vrha
steka. Kod redova element se dodaje na kraj reda, a uzima sa vrha reda. Koristi se
kada je potrebno zadrati hronoloki redosled unosa elemenata.










Za razliku od jednostruko spregnute liste omogueno je lake dodavanje elementa
na kraj liste. Prilikom dodavanja elementa na kraj jednostruko spregnute liste moralo se
sa pomonim pokazivaem doi do repa liste, prolaskom kroz celu listu, kako bi se
element vezao na kraj liste.

Primer 1:
Zadata je tekstualna datoteka RECI.TXT pri emu se u svakom redu datoteke
nalazi tano jedna re. Jedna re moe se pojavljivati u vie redova datoteke. Formirati
dinamiku strukturu podataka RED, a potom na osnovu nje formirati izlaznu datoteku
IZL.TXT pri emu se u svakom redu datoteke nalazi po jedna re i broj njenog
pojavljivanja u datoteci RECI.TXT.

Reenje

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

typedef struct info{
char rec[30];
unsigned brojpojava;
}Tslog;

typedef struct cvor{
Tslog info;
struct cvor *sled;
}Tcvor;

321
void main(void)
{
FILE *dat;
Tcvor *glava=NULL, *rep=NULL, *novi, *tek;
char s[30];

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

if((dat=fopen("RECI.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka se ne moze otvoriti!!");
return;
}

/* Ucitava se red po red iz datoteke. */
while(fgets(s,30,dat)!=NULL)
{
/* Ako je poslednji karakter '\n' brise se iz stringa, radi kasnijeg ispravnog
prikaza redova u datoteci. */
if(s[strlen(s)-1]=='\n') s[strlen(s)-1]='\0';

/* Utvrdjuje se da li takve reci ima u listi. */
tek=glava;
while(tek!=NULL&&strcmp(s,tek->info.rec)) tek=tek->sled;

/* Ako reci nema formira se novi cvor reda, a u suprotnom brojac reci se
povecava za jedan. */

if(tek==NULL)
{
novi=(Tcvor *)malloc(sizeof(Tcvor));
strcpy(novi->info.rec,s);
novi->info.brojpojava=1;
novi->sled=NULL;

if(glava==NULL) glava=novi, rep=novi;
else rep->sled=novi, rep=novi;
}else tek->info.brojpojava++;
}
fclose(dat);

/* Otvara se izlazna datoteka i podaci se iz reda upisuju u datoteku uz brisanje cvorova
reda i oslobadjanje zauzete memorije. */

dat=fopen("IZL.TXT","w");
tek=glava;


322
while(tek!=NULL)
{
fprintf(dat,"%s\t\t%d\n",tek->info.rec,tek->info.brojpojava);
tek=tek->sled;
free(glava);
glava=tek;
}
fclose(dat);

printf("\n\n\t\tPosao je obavljen!!");
getch();
}

Primer 2:
Zadata je tekstualna datoteka RACUNI.TXT. U svakom redu datoteke nalazi se po
jedan raun u formatu:

ifra # Prezime # Ime # Uplata-isplata(U/I) # iznos uplate

U datoteci se moe nalaziti vie uplata i isplata sa istom ifrom. Na osnovu ulazne
datoteke formirati dinamiku strukturu podataka RED.
Nakon formiranja reda (ne moe vie lanova reda imati istu ifru), izvriti njegovo
sortiranje u rastuem redosledu, ali bez korienja dodatnih vorova i objekata.
Na osnovu dinamike strukture, formirati izlaznu datoteku IZRAC.TXT u kojoj e
biti prikazani podaci sortirani u rastuem redosledu po kriterijumu stanje na raunu.

Reenje

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

typedef struct slog{
char sifra[5];
char prezime[20];
char ime[20];
double iznos;
}Tslog;

typedef struct cvor{
Tslog info;
struct cvor *sled;
}Tcvor;

/* definisanje prototipova funkcija. */
void ubaci(Tcvor **glava, Tcvor **rep, char *s);
void uredi(Tcvor **glava, Tcvor **rep);
void formdat(Tcvor **glava, Tcvor **rep);
323

void main(void)
{
FILE *dat;
Tcvor *glava=NULL, *rep=NULL;
char s[100];

textmode(3);
textbackground(0);
textcolor(15);
clrscr();


if((dat=fopen("RACUNI.TXT","r"))==NULL)
{
printf("Datoteka RACUNI.TXT se ne moze otvoriti!!");
return;
}

/* Ucitava se red po red datoteke i uvezuje u red. */
while(fgets(s,100,dat)!=NULL) ubaci(&glava,&rep,s);
fclose(dat);

/* Vrsi se preuredjivanje reda tako da postane sortiran u opadajucem redosledu. */
uredi(&glava,&rep);

/* Formira se izlazna datoteka uz brisanje cvorova reda i oslobadjanje zauzete
memorije. */
formdat(&glava,&rep);

printf("\n\n\t\tPosao je obavljen!!");
getch();
}

void ubaci(Tcvor **glava, Tcvor **rep, char *s)
{
Tcvor *novi, *tek;
Tslog pom; /* Promenljiva pom je pomocna promenljiva i sluzi za privremeno smestanje
podataka jednog racuna. */
char *pok=s, ui[2];

/* Izdvajaju se podaci jednog racuna iz stringa. */
pok=strtok(s,"#"); strcpy(pom.sifra,pok);
pok=strtok(NULL,"#"); strcpy(pom.prezime,pok);
pok=strtok(NULL,"#"); strcpy(pom.ime,pok);
pok=strtok(NULL,"#"); strcpy(ui,pok);
pok=strtok(NULL,"#"); pom.iznos=atof(pok);

/* Utvrdjuje se da li postoji u listi takva sifra. */
tek=*glava;
while(tek!=NULL&&strcmp(tek->info.sifra,pom.sifra)) tek=tek->sled;
324

if(tek==NULL)
{
/* Ako sifra ne postoji, formira se objekat i uvezuje u red. */
novi=(Tcvor *)malloc(sizeof(Tcvor));
novi->info=pom;

/* Kako ranije nije bilo objekta sa takvom sifrom, u slucaju da je vrsena isplata,
stanje na njegovom racunu bice u minusu. */

if(!strcmp(ui,"I")) novi->info.iznos*=-1;
novi->sled=NULL;

/* Vrsi se uvezivanje cvora u red. */
if(*glava==NULL) *glava=novi, *rep=novi;
else (*rep)->sled=novi, *rep=novi;
}else{
/* Ako postoji takva sifra, nastaje promena stzanja racuna, pri emu se prilikom
uplate stanje na racunu uvecava, a prilikom isplate umanjuje. */

if(!strcmp(ui,"U")) tek->info.iznos+=pom.iznos;
else tek->info.iznos-=pom.iznos;
}
}

void uredi(Tcvor **glava, Tcvor **rep)
{
Tcvor *glava1=NULL, *rep1=NULL, *pret, *tek;
double min;

/* Prevezivacemo pokazivace tako da ce nastati novi red. Pronalazimo u ciklusu cvor
reda koji ima najmanje stanje na racunu i njega uvezujemo u novi red, a izbacujemo bez
fizikog brisanja iz starog reda. Kada stari red ne bude imao cvorova novonastali red bice
sortirani red u rastucem redosledu. */

while(*glava!=NULL)
{
/* Pomocu pokazivaca tek prolazimo kroz red, a nakon prolaska pokazivac pret
ce pokazivati na cvor sa najmanjim stanjem u redu. */

tek=pret=*glava;
min=tek->info.iznos;
while(tek!=NULL)
{
if(tek->info.iznos < min)
{
min=tek->info.iznos;
pret=tek;
}
tek=tek->sled;
}
325

/* Sada se taj cvor uvezuje u novi red, gde je pokazivac na prvi cvor glava1, a
pokazivac na rep rep1. */

if(glava1==NULL) glava1=pret, rep1=pret;
else rep1->sled=pret, rep1=pret;

/* Vrsi se izbacivanje cvora iz stare liste. Mogu se razdvojiti tri slucaja: Izbacuje
se prvi cvor reda, izbacuje se poslednji logicki cvor reda i izbacuje se cvor reda
koji nije logicki prvi a ni logicki poslednji cvor. */

if(pret==*glava)
{
/* Izbacuje se logicki prvi cvor reda. */
*glava=(*glava)->sled;
pret->sled=NULL;

}else{
/* Izbacuje se logicki poslednji cvor reda. */
if(pret==*rep)
{
*rep=*glava;
while((*rep)->sled!=pret) *rep=(*rep)->sled;
(*rep)->sled=NULL;
}else{
/* Izbacuje se cvor reda koji nije logicki prvi niti logicki
poslednji cvor reda. */

tek=*glava;
while(tek->sled!=pret) tek=tek->sled;
tek->sled=pret->sled;
pret->sled=NULL;
}
}
}

/* Sada postoji samo novi red, te je potrebno pokazivace koji spolja opisuju red promeniti
tako da ispravno pokazuju na prvi, odnosno poslednji cvor reda. */

*glava=glava1, *rep=rep1;
}

void formdat(Tcvor **glava, Tcvor **rep)
{
FILE *dat;
Tcvor *tek;

/* Prolazi se kroz red i vrsi upisivanje podataka u izlaznu datoteku uz oslobadjanje
zauzete memorije. */
dat=fopen("IZRAC.TXT","w");

326
tek=*glava;
while(tek!=NULL)
{
fprintf(dat,"%5s%20s%20s\t%10.3f\n",
tek->info.sifra,tek->info.prezime,tek->info.ime,tek->info.iznos);
*glava=tek->sled;
tek->sled=NULL;
free(tek);
tek=*glava;
}
*rep=NULL;
}

Test programa:

RACUNI.TXT

12#Maric#Mirko#U#4000.00
123#Petrovic#Milos#I#1500.00
12#Maric#Mirko#I#2000.00
123#Petrovic#Milos#U#1000.00
21#Kozic#Luka#U#10000.00
18#Markovic#Milos#I#5000.00

IZRAC.TXT

18 Markovic Milos -5000.000
123 Petrovic Milos -500.000
12 Maric Mirko 2000.000
21 Kozic Luka 10000.000





















327
7.9 DINAMIKA STRUKTURA PODATAKA
DVOSTRUKO SPREGNUTA LISTA

esto je potrebno od jednog vora liste doi do njegovog logikog predhodnika.
Kod jednostruko spregnute liste bilo bi potrebno prei sve lanove liste od prvog vora
do predhodnika. Zbog toga je korisno da svaki vor, pored pokazivaa na sledei vor,
poseduje i pokaziva na predhodni vor liste. Kada vor liste poseduje dva pokazivaa,
jedan na predhodni, a drugi na sledei vor liste, kaemo da je u pitanju dvostruko
spregnuta lista.
Kod dvostruko spregnute liste jako je jednostavno kretati se kroz listu u jednom i
drugom smeru. Dvostruko spregnuta lista poseduje i dva spoljanja pokazivaa,
pokaziva na prvi vor liste za prolazak s leva u desnu i pokaziva na poslednji vor liste
za prolazak s desna na levo.
Prilikom umetanja ili brisanja vora liste nije potrebno posedovati i dodatne
pokazivae. Prilikom umetanja novog vora u listu, osim pokazivaa koji pokazuje na
objekat koji se umee u listu i jednog koji pokazuje na vor liste ispred (ili iza) koga
treba umetnuti novi vor, nisu potrebni dodatni pokazivai. Prilikom brisanja potrebno je
imati samo pokaziva na vor koji treba da se izbrise iz liste.
.









Primer 1:
Zadata je tekstualna datoteka BROJEVI.TXT koja u svakom redu sadri po jedan
racionalan broj. Na osnovu sadraja datoteke formirati dvostruko spregnutu listu.
vor liste je definisan na sledei nain:

typedef struct cvor{
int broj;
unsigned brojpojava;
struct cvor *sled;
struct cvor *pret;
}Tcvor;

Polje brojpojava predstavlja broj pojavljivanja datog broja u datoteci. Na osnovu
dvostruko spregnute liste formirati izlazne tekstualne datoteke RAS.TXT i OPA.TXT.
Datoteka RAS.TXT sadri brojeve sortirane u rastuem redosledu. Datotek OPA.TXT
sadri date brojeve sortirane u opadajuem redosledu.
Svaki red datoteka RAS.TXT i OPA.TXT u jednom redu sadre tano jedan broj.



poc
info

NULL
info


info


info
NULL


kraj
328
Reenje

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

typedef struct cvor{
int br;
unsigned brpojava;
struct cvor *sled;
struct cvor *pret;
}Tcvor;

void main(void)
{
FILE *dat;
Tcvor *poc=NULL, *kraj=NULL, *novi, *tek;
char s[30];
int i;

textmode(3);
textcolor(15);
textbackground(0);
clrscr();

if((dat=fopen("BROJEVI.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka BROJEVI.TXT se ne moze otvoriti!!");
return;
}

while(fgets(s,30,dat)!=NULL)
{
if(poc==NULL)
{
novi=(Tcvor *)malloc(sizeof(Tcvor));
novi->sled=NULL;
novi->pret=NULL;
novi->brpojava=1;
novi->br=atoi(s);
poc=novi;
kraj=novi;
}else{
tek=poc;
while(tek!=NULL&&tek->br>=atoi(s)) tek=tek->sled;

if(tek!=NULL)
{
if(tek->br==atoi(s)) tek->brpojava++;
else{
novi=(Tcvor *)malloc(sizeof(Tcvor));
329
novi->brpojava=1;
novi->br=atoi(s);
if(tek==poc)
{
novi->sled=tek;
tek->pret=novi;
poc=novi, novi->pret=NULL;
}else{
novi->sled=tek;
novi->pret=tek->pret;
tek->pret->sled=novi;
tek->pret=novi;
}
}
}else{
novi=(Tcvor *)malloc(sizeof(Tcvor));
novi->sled=NULL;
novi->brpojava=1;
novi->br=atoi(s);
novi->pret=kraj;
kraj->sled=novi;
kraj=novi;
}
}
}
fclose(dat);

dat=fopen("OPA.TXT","w");
tek=poc;
while(tek!=NULL)
{
for(i=1;i<=tek->brpojava;i++) fprintf(dat,"%d\n",tek->br);
tek=tek->sled;
}
fclose(dat);

dat=fopen("RAS.TXT","w");
tek=kraj;
while(tek!=NULL)
{
for(i=1;i<=tek->brpojava;i++) fprintf(dat,"%d\n",tek->br);
tek=tek->pret;
free(kraj);
kraj=tek;
}
fclose(dat);

printf("\n\n\tPosao obavljen!!");
getch();
}

330
Primer 2:
Zadate su tri binarne datoteke UCENIK.DAT, ISPITI.DAT i
POLAGANJE.DAT. Datoteka UCENIK.DAT je u formatu: evidencioni broj
(unsigned), ime i prezime (od maksimalno 30 karaktera). Datoteka ISPITI.DAT je u
formatu: ifra ispita (unsigned) i naziv ispita od maksimalno 50 karaktera. Datoteka
POLAGANJE.DAT je u formatu: evidencioni broj (unsigned), ifra ispita (unsigned)
datum ispita (u obliku dd.mm.gggg) i ocena (unsigned).
Datoteka POLAGANJE.DAT slui za uvanje podataka o polaganju svih
vandrednih uenika za bilo koje ispite u nekom proizvoljnom vremenskom periodu.
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program koji za izabranog studenta na osnovu
evidencionog broja tampa na ekranu tabelarni prikaz poloenih ispita. U svakom redu po
jedan ispit: Redni broj ispita, ifra i naziv ispita, Datum polaganja ispita i ocena.
Program ne vri kontrolu podataka iz binarnih datoteka, jer se smatra da su podaci
ispravni.

Reenje

U programu je koriscena dinamicka struktura podataka multilista. Formirana je
jednostruko spregnuta lista ciji cvorovi osim informacionog sadrzaja poseduju i dva
pokazivaca: pokazivac na naredni cvor jednostruko spregnute liste i pokazivac na prvi
cvor liste koja izbija iz glavne liste. Glavna lista sadrzi podatke o vandrednim ucenicima.
Liste koje iz datog vora liste ucenika izbijaju sadrze podatke o polozenim ispitima tog
ucenika. Svaki cvor tih lista odnosi se na podatke vezane za polozeni ispit datog ucenika.

#include<stdio.h>
#include<conio.h>
#include<alloc.h>

#define ESC 27

typedef struct{
unsigned evbroj;
char ime_prezime[30];
}Tucenik; /* Struktura vanrednog ucenika. */

typedef struct{
unsigned evbroj;
unsigned sifra;
char datum[12];
unsigned ocena;
}Tpolaganje; /* Struktura polozenog ispita. */

typedef struct cvorp2{
Tpolaganje info;
struct cvorp2 *dole;
}Tcvorp2; /* Struktura cvora polozenog ispita. */

331
typedef struct cvorp1{
Tucenik info;
struct cvorp1 *sledeci;
struct cvorp2 *dole;
}Tcvorp1; /* Struktura cvora vandrednog ucenika. */

typedef struct{
unsigned sifra;
char naziv[30];
}Tispit; /* Struktura ispita. */

int unos_ceo(void); /* Funkcija omogucava unos celog broja uz kontrolu, a sa ESC se prekida
formiranje broja i vraca vrednost -1 sto oznacava da broj nije formiran. Kraj formiranja broja je
pritisak na taster ENTER. */

Tcvorp1 *trazi(Tcvorp1 *tek,unsigned evbroj); /* Trazi se ucenik na osnovu evidencionog broja.
*/

void main(void)
{
FILE *polaganje,*ucenik,*ispit;
Tcvorp1 *glava;
Tcvorp1 *novi=NULL,*tek=NULL,*pret=NULL;
Tcvorp2 *novi2=NULL,*tek2=NULL,*pret2=NULL;
Tucenik s;
Tpolaganje p;
Tispit t;
char c;
int i, evbroj, kon;

textmode(3);
textbackground(15);
textcolor(1);

do{
clrscr();
cprintf(" Polozeni ispiti za ucenika ");
cprintf(" Ev. broj:");
textbackground(2);
cprintf(" ");
textbackground(15);
cprintf(" Ime i prezime:");
textbackground(2);
cprintf(" ");
textbackground(15);
cprintf(" ");
textbackground(4);
cprintf(" R.br Ispit Datum Ocena ");
textbackground(15);
gotoxy(21,2);
textbackground(2);
332
/* Unosi se evidencionalni broj ucenika. */
evbroj=unos_ceo();

if(evbroj==-1) return;
textbackground(15);
glava=NULL;
ucenik=fopen("UCENIK.DAT","r+b");

/* Ucitavaju se podaci o ucenicima iz binarne datoteke. */
while(fread(&s,sizeof(s),1,ucenik))
{
/* Formira se cvor o uceniku. */
if(s.evbroj==evbroj) gotoxy(48,2),puts(s.ime_prezime);
novi=(Tcvorp1*)malloc(sizeof(Tcvorp1));
novi->sledeci=NULL;
novi->dole=NULL;
novi->info=s;

/* Vrsi se uvezivanje cvora na kraj liste. */
if(glava==NULL) glava=novi;
else{
tek=pret=glava;
while(tek!=NULL) pret=tek, tek=tek->sledeci;
pret->sledeci=novi;
}
}
fclose(ucenik);

/* Otvara se datoteka sa polozenim ispitima. */
polaganje=fopen("POLAGANJE.DAT","r+b");
while(fread(&p,sizeof(p),1,polaganje))
{
/* Formira se cvor o polozenom ispitu. */
novi2=(Tcvorp2*)malloc(sizeof(Tcvorp2));
novi2->dole=NULL;
novi2->info=p;

/* Vrsi se uvezivanje cvora na kraj liste polozenih ispita. */
tek=glava;
while(tek!=NULL)
{
/* Pronalazi se ucenik sa istim evidencionim brojem. */
if(novi2->info.evbroj==tek->info.evbroj)
{
if(tek->dole==NULL) tek->dole=novi2;
else{

/* Prolazimo kroz listu polozenih ispita.
Moramo koristiti pokazivace tek2 i pret2 koji
mogu da pokazuju na cvorove polozenih ispita.
Sttruktura cvora polozenog ispita i struktura
333
cvora ucenik su razliciti. Vezivanje cvora se vrsi
na kraj liste.*/

tek2=pret2=tek->dole;
while(tek2!=NULL)
{
pret2=tek2;
tek2=tek2->dole;
}
pret2->dole=novi2;
}
}
tek=tek->sledeci;
}
}
fclose(polaganje);

i=0;
tek=glava;
printf("\n\n");
tek=trazi(tek,evbroj); /* Trazi se ucenik na osnovu evedencionog broja. */

ispit=fopen("ISPIT.DAT","r+b");
if(tek!=NULL)
{
pret2=tek->dole;
while(pret2!=NULL)
{
i++;
printf(" %d %u %s %u\n",
i,pret2->info.sifra,pret2->info.datum,pret2->info.ocena);

/* Pozicioniramo se na pocetak datoteke ispiti i trazimo naziv
ispita koji odgovara datoj sifri. */
fseek(ispit,0,SEEK_SET);
kon=1;
while(fread(&t,sizeof(t),1,ispit))
{
if(t.sifra==pret2->info.sifra && kon==1)
{
gotoxy(19,4+i);
puts(t.naziv);
kon=0;
}
}
pret2=pret2->dole;
}
}else{
gotoxy(23,13);
printf(" Zadati kriterijumi nisu pronadjeni");
gotoxy(23,14);
334
printf("Za izlazak iz programa pritisni 'ESC'");
}
fclose(ispit);
c=getch();
}while(c!=ESC);
}

/* Funkcija unos_ceo omogucava unos celog broja. */
int unos_ceo(void)
{
unsigned xu, yu;
char c;
int x, pom=1;

/* Sa unosom broja pocinjemo od trenutne pozicije na ekranu. */
xu=wherex();
yu=wherey();

x=0;
do{
c=getch();
if(c==ESC) return -1;

/* U slucaju da je predznak negativan promenljiva pom dobija vrednost -1. */
if(c=='-'&&x==0) pom=-1, putch(c);

/* Cifra je ako je karakter veci od 48 a manji od 57, jer su to redni brojevi koji
odgovaraju decimalnim ciframa iy ASCII tabele. Prva cifra ne moye da bude 0.*/
if((c>48&&c<=57)||(c==48&&x!=0))
{
x=x*10+c-48;
putch(c);
}

/* Znajuci da ako broj predje granicu 32767 automatski
postaje negativan, utvrdjujemo da li se to desilo I usled
prekoracenja vracamo korisnika na ponovni unos. */
if(x<0)
{
x=0;
pom=1;
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
}
}while(c!='\r' || x==0);

/* Vracamo dobijeni broj pomnozen sa zapamcenim predznakom. */
return x*pom;
}

335
/* Funkcija trazi trazi ucenika u listi ucenika na osnovu evidencionalnog broja. */
Tcvorp1 *trazi(Tcvorp1 *tek,unsigned evbroj)
{
while(tek!=NULL&&(tek->info.evbroj)!=evbroj) tek=tek->sledeci;
if(tek==NULL)
{
return NULL;
}else{
return tek;
}
}

Test primer programa:




Primer 3:
Tekstualna datoteka LETOVI.TXT sadri spisak svih avionskih linija jedne avio
kompanije. Svaka linija teksta sadri sledea polja: broj leta, ime grada iz kojeg avion
polee, ime grada do koga avion leti i cenu leta, pri emu su pojedina polja razdvojena sa
znakom #:
broj leta # poletni grad # odredini grad # cena leta

Moe postojati vie letova iji poletni grad je isti. Takoe moe postojati vie letova
sa istim odredinim gradom.
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program koji omoguava:

- Ispisivanje letova ove avio kompanije, sortirane po gradovima iz koje avion
polee. Svaki ispis treba da sadri: ime grada iz kojeg avion polee, ime
odredinog grada, broj leta i cenu leta.
- Za zadati grad, ispisuje brojeve svih linija koje kreu iz tog grada, kao i
odredite svake od tih linija.
336
- Za zadate gradove A i B odrediti broj direktnog leta i cenu leta od grada A
do grada B ako takav let postoji, i
- Za zadate gradove A i B odrediti niz letova kojima se stie iz grada A do
grada B sa minimalnim brojem sletanja, kao i ukupnu cenu ovakvog leta.
U analizu dolazi maksimalno tri sletanja.

Reenje

U programu je koriscena dinamicka struktura podataka multilista. Formirana je
jednostruko spregnuta lista ciji cvorovi osim informacionog sadrzaja poseduju i dva
pokazivaca: pokazivac na naredni cvor jednostruko spregnute liste i pokazivac na prvi
cvor liste odredisnih gradova. Iz svako grada odakle se polece izbija lista koja sadrzi
cvorove koji opisuju odredisne gradove do kojih postoji direktan let od tog poletnog
grada.

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>

typedef struct cvor{
char grad[20];
int cena,broj;
struct cvor *sledeci, *dalje;
}Tcvor;

/*Funkcija trazi objekat u glavnoj listi za grad poletanja*/
Tcvor *trazi(Tcvor *glava, char kljuc[]);

/*funkcija trazi grad sletanja u listi grada poletanja*/
Tcvor *trazikroz(Tcvor *glava, char kljuc[]);

void main(void)
{
Tcvor *glava,*pok,*pret,*tek,*taj,*p1,*p2,*p3,*p4,*p5;
int i,j,broj,cena,a,x,y,x1,y1,pomx,pomy,pomx1,pomy1,kon;
FILE *dat;
char pom[70],iz[20],u[20],br[5],cn[5];

glava=NULL;

textmode(3);
textcolor(BLUE);
textbackground(WHITE);
clrscr();

if((dat=fopen("letovi.txt","r"))==NULL)
{
337
printf("\n\tDatoteka se ne moze otvoriti!!!");
return;
}else{
while(fgets(pom,80,dat)) /*Ucitavanje reda datoteke u sring pom*/
{
/* Izdvajanje podataka iz stringa pom*/
i=0,j=0;
while(pom[i]!='#') br[j]=pom[i], i++, j++;
br[j]='\0', i++, j=0;

while(pom[i]!='#') iz[j]=pom[i], i++, j++;
iz[j]='\0', i++, j=0;
while(pom[i]!='#') u[j]=pom[i], i++, j++;
u[j]='\0', i++, j=0;

while(pom[i]!='\n') cn[j]=pom[i], i++, j++;
cn[j]='\0', i++, j=0;

/*Pretvara stringove u celobrojne podatke*/
broj=atoi(br);
cena=atoi(cn);

/*Ako lista ne postoji*/
if(glava==NULL)
{
/* Formirati cvor sa poletnim grad. */
glava=(Tcvor*)malloc(sizeof(Tcvor));

strcpy(glava->grad,iz);
glava->sledeci=NULL;

/* Formirati cvor sa odredisnim gradom. */
glava->dalje=(Tcvor*)malloc(sizeof(Tcvor));
pok=glava->dalje;
strcpy(pok->grad,u);
pok->broj=broj;
pok->cena=cena;
pok->dalje=NULL;
}else{

/*Ako lista postoji, trazi u glavnoj listi grad poletanja*/
taj=trazi(glava,iz);

if(taj==NULL)
{
/* Takvog poletnog grada nema. Formirati cvor na kraju liste
Poletnih gradova. */
tek=pret=glava;
while(tek!=NULL) pret=tek, tek=tek->sledeci;

pret->sledeci=(Tcvor*)malloc(sizeof(Tcvor));
338
pok=pret->sledeci;
strcpy(pok->grad,iz);
pok->sledeci=NULL;

/* Upisati prvi odredisni grad direktnog leta. */
pok->dalje=(Tcvor*)malloc(sizeof(Tcvor));
pok=pok->dalje;
strcpy(pok->grad,u);
pok->broj=broj;
pok->cena=cena;
pok->dalje=NULL;
}else{
/* Postoji takav poletni grad. Prolazimo kroz listu odredisnih
gradova i formiramo novi cvor na kraju liste. */

pret=tek=taj;
while(tek!=NULL) pret=tek, tek=tek->dalje;
pret->dalje=(Tcvor*)malloc(sizeof(Tcvor));
pok=pret->dalje;
pok->dalje=NULL;
strcpy(pok->grad,u);
pok->broj=broj;
pok->cena=cena;
}
}
}

i=0;
/*Pocetak while ciklusa za ponavljanje celokupnog menija*/
while(a!=5)
{
delay(100);
if(i!=0) getch();

if(i==0) i++;
clrscr();
textcolor(YELLOW);
textbackground(BLACK);
clrscr();
printf("\n\n\n\n\n\n\n ");
textcolor(BLUE);
cprintf("- O P C I J E -");
printf("\n 1-Svi letovi kompanije\n 2-Letovi iz grada");
printf("\n 3-Trazenje direktnog leta\n 4-Letovi sa vise sletanja\n 5-I Z L A Z");
printf("\n O P C I J A: ");
textbackground(RED);
x=wherex(), y=wherey();
cprintf(" ");



339
/*Unos opcije*/
do{
gotoxy(x+1,y);
a=getche()-48;
}while(a<=0&&a>5);

/*Selekcija vrednosti a*/
switch(a)
{
case 1: pok=glava;
printf("\n\t");
gotoxy(35,3);
cprintf(" L E T");
cprintf(" broj leta"),x=wherex()-5,y=wherey();
cprintf(" cena leta"),x1=wherex()-6,y1=wherey();
y++,y1++,i=4;

while(pok!=NULL)
{
strcpy(iz,pok->grad);
tek=pok->dalje;
while(tek!=NULL)
{
gotoxy(35,i++);
printf("%s - %s",iz,tek->grad);
gotoxy(x,y++),printf("%d",tek->broj);
gotoxy(x1,y1++),printf("%d",tek->cena);
tek=tek->dalje;
}
pok=pok->sledeci;
}
break;
case 2: printf("\n\n\tGrad: ");
scanf("%s",&iz);
pok=trazi(glava,iz);
gotoxy(30,3);
cprintf(" L E T");
cprintf(" broj leta"),x=wherex()-5,y=wherey();
cprintf(" cena leta"),x1=wherex()-5,y1=wherey();
y++,y1++;

tek=pok->dalje; i=4;
while(tek!=NULL)
{
gotoxy(30,i++);
printf("%s - %s",iz,tek->grad);
gotoxy(x,y++),printf("%d",tek->broj);
gotoxy(x1,y1++),printf("%d",tek->cena);
tek=tek->dalje;
}
break;
340
case 3: printf("\n\n\tPoletanje: ");
scanf("%s",&iz);
printf("\tSletanje: ");
scanf("%s",&u);
pok=trazi(glava,iz);
tek=trazikroz(pok,u);
gotoxy(30,3);
cprintf(" L E T");
cprintf(" broj leta"),x=wherex()-5,y=wherey();
cprintf(" cena leta"),x1=wherex()-6,y1=wherey();
y++,y1++;

if(tek==NULL)
{
gotoxy(30,4);
printf(" ---------N E M A L E T O V A--------");
}else{
gotoxy(30,4);
printf("%s - %s",iz,tek->grad);
gotoxy(x,y),printf("%d",tek->broj);
gotoxy(x1,y1++),printf("%d",tek->cena);
}
break;
case 4: printf("\n\n\tPoletanje: ");
scanf("%s",&iz);
printf("\tSletanje: ");
scanf("%s",&u);

if(strcmp(iz,u))
{
gotoxy(30,i=3);

/*Ispitivanje da li postoji direktan let*/
gotoxy(30,i++);
cprintf(" L E T");
cprintf(" broj leta"),x=wherex()-5,y=wherey();
cprintf(" cena leta "),x1=wherex()-6,y1=wherey();
y++,y1++;

/*Funkcije trazi i trazikroz ce se pozivati maksimalno onoliko
puta koliko postoji gradova u glavnoj listi*/
p1=trazi(glava,iz);
p2=trazikroz(p1->dalje,u);
if(p2!=NULL)
{
gotoxy(30,y++);
printf("%s - %s",iz,p2->grad);
gotoxy(x,y-1),printf("%d",p2->broj);
gotoxy(x1,y1++),printf("%d",p2->cena);
}else{
gotoxy(30,y++);
341
printf("-----N E M A D I R E K T N I H L E T O V A----");
gotoxy(30,y+=2);

/*Ispitivanje da li postoji let sa jednim sletanjem*/
gotoxy(30,y++);
cprintf(" L E T");
cprintf(" broj leta"),
pomx=x=wherex()-5,pomy=y=wherey();
cprintf(" cena leta "),
pomx1=x1=wherex()-6,pomy1=y1=wherey();
y++,y1++;
p2=p1->dalje;
kon=0;
while(p2!=NULL)
{
p3=trazikroz(trazi(glava,p2->grad)->dalje,u);
if(p3!=NULL)
{
kon=1;
gotoxy(30,y++);
printf("%s - %s",iz,p2->grad);
gotoxy(x,y-1);
printf("%d",p2->broj);
gotoxy(x1,y1++);
printf("%d",p2->cena);
gotoxy(30,y++);
printf("%s - %s",p2->grad,p3->grad);
gotoxy(x,y-1),printf("%d",p3->broj);
gotoxy(x1,y1++);
printf("%d",p3->cena);
gotoxy(30,y++);
printf("------------------");
y1++;
gotoxy(30,y++);
printf("Ukupna cena: ");
printf("%d",p2->cena+p3->cena);
y1++;
}
p2=p2->dalje;
}
gotoxy(30,y+=2);

if(kon==0)
{
x=pomx, y=pomy+1, x1=pomx1, y1=pomy1+1;
/*Proveravanje da li postoji let sa dva sletanja*/
p2=p1->dalje;
while(p2!=NULL)
{
/* Trazimo grad sa prvim sletanjem. */
p3=trazi(glava,p2->grad);
342
while(p3!=NULL)
{
p3=p3->dalje;
/* Trazimo grad sa drugim sletanjem. */
p4=trazikroz(trazi(glava,p3->grad)->dalje,u);
if(p4!=NULL)
{
kon=2;
gotoxy(30,y++); printf("%s - %s",iz,p2->grad);
gotoxy(x,y-1); printf("%d",p2->broj);
gotoxy(x1,y1++); printf("%d",p2->cena);
gotoxy(30,y++);
printf("%s - %s",p2->grad,p3->grad);
gotoxy(x,y-1),printf("%d",p3->broj);
gotoxy(x1,y1++); printf("%d",p3->cena);
gotoxy(30,y++);
printf("%s - %s",p3->grad,p4->grad);
gotoxy(x,y-1),printf("%d",p4->broj);
gotoxy(x1,y1++); printf("%d",p4->cena);
gotoxy(30,y++),printf("-----------------"),y1++;
gotoxy(30,y++); printf("Ukupna cena: "),y1++;
printf("%d",p2->cena+p3->cena+p4->cena);
}
p3=p3->dalje;
}
p2=p2->dalje;
}
}
/*Ako je p4=0 ne postoje letovi sa vise sletanja*/
if(kon==0)
{
gotoxy(30,y++);
printf("Nema sa manje od 3 sletanja u tom pravcu!");
}else{
gotoxy(45,6);
printf("LETOVI SA %d SLETANJA",kon);
gotoxy(1,25);
}
}
}
break;
}
}
}
}
Tcvor *trazi(Tcvor *glava, char kljuc[])
{
Tcvor *pot=glava;
while(pot!=NULL&&strcmp(pot->grad,kljuc)) pot=pot->sledeci;
return pot;
}
343

Tcvor *trazikroz(Tcvor *glava, char kljuc[])
{
Tcvor *pol;
pol=glava;
while(pol!=NULL&&strcmp(pol->grad,kljuc)) pol=pol->dalje;
return pol;
}

Test primer programa:























344
7.10. ZADACI IZ DINAMIKIH STRUKTURA PODATAKA

Zadatak 1 (2)
Zadata je tekstualna datoteka TEKST.TXT. Nacrtati najjednostavniji i ujedno
najefikasniji strukturni dijagram (uz objanjenje zato ba on) i na osnovu njega napisati
C program koji modifikuje datoteku TEKST.TXT tako to se polazna datoteka
transformie u datoteku iji su redovi ispisani u obrnutom poretku.

Zadatak 2 (2)
U tekstualnoj datoteci SPISAK.TXT nalazi se spisak graana gde je u jednoj liniji
teksta prezime, ime i teina. Podaci su razdvojeni sa praznim mestima i/ili tabulatorima.
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program koji brzo daje odgovor na upit teina
za zadatog graanina.

Zadatak 3 (2)
U tekstualnoj datoteci iji se naziv unosi sa tastature postoji dva reda zapisa, pri
emu se prvi red odnosi na prvi polinom P, a drugi red na drugi polinom Q. Polinom je
opisan sa nizom ureenih parova N n N k n k x a
k
k
e A e A e ] .. 1 [ ), , ( . Nacrtati
najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje zato ba on) i
na osnovu njega napisati C program koji na osnovu datoteke izraunava i u treem redu
ispisuje polinom R u formati koji je gore naveden, pri emu je R = P+Q.

Zadatak 4 (2)
Zadata je tekstualna datoteka IMENA.TXT u kojoj se u svakom redu nalazi tano
jedno ime i prezime meusobno razdvojeni blanko mestima i/ili tabulatorima. Nacrtati
najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje zato ba on) i
na osnovu njega napisati C program koji na ekranu i u datoteci IZVESTAJ.TXT tampa
izvetaj sledeeg izgleda:

R. Br. Prezime Broj pojava
1 Arsic 12
2 Bajic 3
3 Dragas 10, itd ...

Izvetaj je sortiran po abecednom redosledu.

Zadatak 5 (2)
Zadata je tekstualna datoteka BROJEVI.TXT koja u svakom redu sadri uopteno
jedan realan podatak Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram
(uz objanjenje zato ba on) i na osnovu njega napisati C program koji iz datoteke brie
one brojeve koji su negativni i imaju vrednost veu od srednje vrednosti brojeva iz
datoteke. Za izraunavanje srednje vrednosti koristiti funkciju srednjavrednost iji je
prototip: double srednjavrednost(Tcvor **glava); gde je glava pokaziva na prvi
elemenat liste.

345
Zadatak 6 (2)
Zadata je tekstualna datoteka BROJEVI.TXT koja u svakom redu sadri uopteno
jedan realan podatak Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram
(uz objanjenje zato ba on) i na osnovu njega napisati C program koji preureuje
datoteku tako da se prvo ispisuju negativni brojevi sortirani u opadajuem redosledu, a
potom pozitivni brojevi sortirani u rastuem redosledu. U svakom redu nalazi se samo
jedan broj.

Zadatak 7 (2)
Zadata je tekstualna datoteka SPISAK.TXT koja sadri spisak imena i prezimena.
U svakom redu datoteke nalazi se tano jedno ime i prezime meusobno razdvojeni
prazninama i/ili tabulatorima. Datoteka je sortirana po abecednom kriterijumu. U datoteci
BRISI.TXT nalazi se u istom formatu kao u datoteci SPISAK.TXT spisak imena i
prezimena koje treba izbaciti iz datoteke SPISAK.TXT. Nacrtati najjednostavniji i
ujedno najefikasniji strukturni dijagram (uz objanjenje zato ba on) i na osnovu njega
napisati C program koji efikasno reava dati problem.


Zadatak 8 (3)
Binarna datoteka KRUGOVI.DAT je formata: x (double), y (double) i r (double).
Sa x i y oznaen je centar kruga a r je poluprenik kruga. Nacrtati najjednostavniji i
ujedno najefikasniji strukturni dijagram (uz objanjenje zato ba on) i na osnovu njega
napisati C program koji iz datoteke izbacuje sve one krugove koji se nalaze unutar
krugova sa najveim poluprenicima.

Zadatak 9 (3)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program za voenje evidencije robe neke
tehnike prodavnice. Roba je okarakterisana: nazivom (do 30 karaktera), ifrom (do 15
karaktera), koliinom u magacinu i cenom po komadu.

Program treba da omogui sledee funkcije:
1) Unos nove robe;
2) Brisanje robe iz evidencije (ako je koliina te robe 0);
3) Promena cene robe (pojedinano ili linearno za svu robu);
4) Prikaz podataka po ifri za zadatu robu;
5) Trajno uvanje podataka o robi u binarnoj datoteci ROBA.DAT.


Zadatak 10 (3)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program za praenje glasanja na muzikom
festivalu. Svaka pesma dobija ocenu irija od 0 do 10 i ocenu publike od 0 do 10.
Program treba da omogui unos naziva pesme, naziv izvoaa, broj osvojenih bodova,
kao i izlistavanje rezultata po opadajuem redosledu broja bodova.

346
Zadatak 11 (3)
Zadata je tekstualna datoteka TEKST.TXT. Nacrtati najjednostavniji i ujedno
najefikasniji strukturni dijagram (uz objanjenje zato ba on) i na osnovu njega napisati
C program koji modifikuje datoteku TEKST.TXT tako to se polazna datoteka
transformie u datoteku ije su reenice ispisane u obrnutom poretku.

Zadatak 12 (3)
Data je binarna datoteka ije ime se unosi sa tastature u formatu: oznaka (string od
6 karaktera), koliina (float) i datum (string oblika dd.mm.gggg). Oznaka predstavlja
ureaj koji proizvodi neki proizvod. Koliina predstavlja proizvedenu koliinu na tom
ureaju u toku dana koji je oznaen sa datum. Nacrtati najjednostavniji i ujedno
najefikasniji strukturni dijagram (uz objanjenje zato ba on) i napisati C program koji
sekvencijalno uitava binarnu datoteku i na osnovu nje formira tekstualnu datoteku sa
isim imenom kao i ulazna datoteka uz ekstenziju TXT. U izlaznu datoteku ulaze samo
one oznake koje su imale najveu koliinu. U svakom redu datoteke nalaze se podaci
oblika (oznaka, koliina i datum) razdvojenih sa jednim tabulatorom.

Zadatak 13 (3)
Zadata je binarna datoteka PROMENE.DAT u formatu: pr_sifra (unsigned),
pr_kolicina (float), pr_cena (unsigned) i pr_smer (float).
Napisati C program koji sekvencijalno ita datoteku PROMENE.DAT i formira
najjednostavniju i ujedno najefikasniju strukturu. Objekat strukture poseduje polja:
st_sifra, st_kolicina, st_cena i st_vrednost.


=
1 0
_ _ _
smerom sa sifre
te promene sve za
smerom sa sifre
te promene sve za
kolicina pr kolicina pr kolicina st

st_cena je najvea cena u svim strukturama promene za tu ifru.
st_vrednost = st_cena * st_kolicina

Na kraju tampati niz struktura u proizvoljnom formatu, ali tako, da se posle
tampanja poslednjeg elementa strukture odtampa ukupna vrednost sve robe u
magacinu.

Zadatak 14 (3)
U tekstualnoj datoteci TELEFONI.TXT u svakom redu nalazi se zapisan po tano
jedan broj telefona (izmeu brojeva mogu postojati praznine, tabulatori i crtice). Korisnik
je dobio ogroman telefonski raun te od pote zatrai da za dati mesec dobije izvetaj
telefonskih poziva. Pota molbu ne prihvati (vlasnik telefona nije u zemlji), ali mu
drugarica iz pote prosledi binarnu datoteku naziva prezime (ime datoteke) i ekstenzija
DAT. Format datoteke je: broj telefona (string og maksimalno 15 karaktera) i broj
impulsa (unsigned).
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program koji e utvrditi da li postoji neki
sumnjivi brojevi telefona i da se utvrdi sa kojim telefonskim brojevima je napravljen
najvei broj impulsa datog meseca.
347
Zadatak 15 (4)
U datotekama MATRICAxx.TXT nalaze se veoma velike matrice. Oznaka xx je
broj (01,02,...,10,...) datoteke. Svaki red datoteke sastoji se od tri podatka (vrsta, kolona i
vrednost na toj poziciji) meusobno razdvojeni sa po jedniim praznim mestom. Matrica
je retka, tj. mnogo njenih elemenata ima vrednost nula. Nacrtati najjednostavniji i
ujedno najefikasniji strukturni dijagram sa to manje elemenata (uz objanjenje zato ba
on) i na osnovu njega napisati C program koji sekvencijalno uitava tekstualne datoteke,
formira odgovarajuu strikturu i na osnovu nje izlazne matrice IZLAZxx.TXT koje
pretstavljaju rezultujue matrice zapisane u formatu ulaznih matrica. Svaka datoteka
IZLAZxx.TXT sadrae po jednu matricu koja je nastala kao rezultat zbira matrica istih
dimenzija (jer se matrice mogu sabrati ako imaju jednak broj vrsta i kolona).

Zadatak 16 (4)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program koji automatizuje finalno takmienje
u streljatvu n kome uestvuje 10 finalnih strelaca, najboljih po plasmanu iz
predtakmienja. Svaki strelac ima 10 hitaca koji se ocenjuju u opsegu od 0.0 do 11.0
bodova. Svaki strelac je okarakterisan sledeim atributima: takmiarski broj, ime i
prezime, broj bodova iz predtakmienja i bodovima finalnih hitaca. Program treba da
omogui sledee funkcije:

1) Unos optih podataka o akmiaru (prva tri atributa), tj. prijavljivanje;
2) Unos bodova svakog takmiara po obavljenom hicu. Prvi unos treba
automatski da zabrani prijavljivanje takmiara;
3) Lista takmiara ureena po rastuem ukupnom broju bodova u obliku tabele
sa 13 kolona: Takm. broj, Prezime i ime, Hitac1, Hitac2,...,Hitac10 i
Ukupno; i
4) Podatke uvati u binarnoj datoteci iji naziv unosi korisnik sa tastature.


Zadatak 17 (4)
Data je tekstualna datoteka iji naziv se unosi sa tastature. Nacrtati najjednostavniji
i ujedno najefikasniji strukturni dijagram (uz objanjenje zato ba on) i na osnovu njega
napisati C program koji na osnovu unesene rei utvruje koliko se ta re pojavljuje u
datoteci i u kojim sve redovima se nalazi i koliko puta.

Zadatak 18 (4)
Datoteka DELOVI.DAT sadri podatke o delovima automobila u formatu: ifra
dela, naziv dela, marku automobila za koji je namenjen i cenu dela. Nacrtati
najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje zato ba on) i
na osnovu njega napisati C program koji za zadati automobil izlistava sve njegove
raspoloive delove automobila, i da se za zadati deo izlistaju sve marke automobila za
koji je deo namenjen.
Potrebno je realizovati postupke za postavljanje dva navedena upita i postupke za
dodavanje novog i uklanjanje postojeeg dela iz strukture.

348
Zadatak 19 (4)
U tekstualnoj datoteci iji naziv se unosi sa tastature nalaze se podaci: prezime, ime,
prosena ocena, broj opravdanih izostanaka i broj neopravdanih izostanaka. Podaci su
razdvojeni sa po jednim praznim mestom. Nacrtati najjednostavniji i ujedno najefikasniji
strukturni dijagram (uz objanjenje zato ba on) i na osnovu njega napisati C program
koji daje prikaz podataka po sledeim kriterijumima:
- Rastui poredak po prosenoj oceni, a drugi kriterijum sortiranja je
alfanumeriki poredak po prezimenu i imenu uenika; i
- Opadajui poredak po broju neopravdanih izostanaka, drugi kriterijum je
vei broj izostanaka, a trei kriterijum je alfanumeriki kriterijum po
prezimenu i imenu uenika.

Zadatak 20 (4)
Zadate se tri tekstualne datoteke POREZI.TXT, ROBA.TXT i PRODAJA.TXT.
U datoteci POREZI.TXT u svakom redu nalazi se tri podatka meusobno
razdvojena sa jednim praznim mestom: ifra poreza (dve cifre), stopa saveznog poreza
(tri cela i dva decimalna mesta) i republika stopa poreza (tri cela i dva decimalna mesta).
U datoteci ROBA.TXT u svakom redu nalazi se tri podatka meusobno razdvojena
sa jednim praznim mestom: ifra robe (12 cifara), cena robe (pet celih i dva decimalna
mesta) i ifra poreza kojem podlee ta roba (dve cifre).
U datoteci PRODAJA.TXT u svakom redu nalazi se tri podatka meusobno
razdvojena sa jednim praznim mestom: ifra robe koja je prodata (12 cifara), datum kada
je roba prodata u formatu dd.mm.gggg i koliina te robe prodate tog datuma (tri cela i dva
decimalna mesta)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program koji izraunava proseke obaveza za
zadati period i tampa izvetaj sledeeg izgleda:


R.BR. SIFRA POREZA SAVEZNI POREZ REPUBLICKI POREZ
1 xx xxxxxxx.xx xxxxxxx.xx
2 xx xxxxxxx.xx xxxxxxx.xx
3 xx xxxxxxx.xx xxxxxxx.xx, itd...



Zadatak 21 (4)
Data je tekstualna datoteka BANKA.TXT koja u svakom redu sadi tri podatka
meusobno razvojena sa po jednim praznim mestom: raun (xxx xxx xxx), smer (ima
vrednost 1 ako je uplata ili 0 ako je isplata) i iznos (realan broj na dve decimale). Napisati
C program koji sekvencijalno ita datoteku BANKA.TXT i formira dvostruko spregnutu
listu na sledei nain:
- Ako smo proitali podatke jednog objekta iji atribut raun nije u listi,
uveite ga na kraj.
- Ako smo proitali podatke jednog objekta iji atribut raun se nalazi u listi,
uvezati ga iza poslednjeg vora sa tim raunom.
349
Koristei se sadrajem liste, odtanpati sledei izvetaj:


RACUN ZBIR
xxx xxx xxx xxxxxxx.xx
xxx xxx xxx xxxxxxx.xx
xxx xxx xxx xxxxxxx.xx, itd...


Zadatak 22 (4)
Data je binarna datoteka TEKST.DAT koja je formatizovana sa podacima koji se
sastoje od dva polja: ifra (8 cifara, a u datoteci se moe nalaziti vie podataka sa istom
ifrom) i ekst (string od 20 karaktera).
Napisati C program koji sekvencijalno ita datoeku i formira jednostruko spregnutu
listu sortiranu u rastuem redosledu ifre, tako da su svi duplikati jedne ifre vezani u
listu iji je poetak u sortiranoj listi. Ta lista duplikata treba da je formirana po principu
umetanja na poslednje mesto u listi.
Na kraju odtampati izvetaj sledeeg izgleda:

SIFRA TEKST NAPOMENA
xxxxxxxx xxxxxxxxxxxxxxxxxxxx IMA DUPLIKATE
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx

xxxxxxxx xxxxxxxxxxxxxxxxxxxx IMA DUPLIKATE
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx

xxxxxxxx xxxxxxxxxxxxxxxxxxxx NEMA DUPLIKATE

xxxxxxxx xxxxxxxxxxxxxxxxxxxx IMA DUPLIKATE
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx, itd...

Zadatak 23 (5)
Date su binarne datoteke GRADJANI.DAT i RACUNI.DAT. Datoteka
GRADJANI.DAT je formata: prezime i ime graanina (do 40 karaktera), JMBG (13
karaktera) i dabine koje graanin treba da plati. Datoteka RACUNI.DAT sadri podatke
o iro i tekuim raunima graana i to: JMBG, broj rauna i stanje na raunu. Jedan
graanin moe da ima vie iro ili tekuih rauna, a moe uopte da nema rauna.
Program treba da formira sledeu strukturu:
Lista graana dodavanjem na poetak;
Lista rauna za svakog graanina u listi graana;
350
Iz tako dobijene strukture izvriti izbacivanje graana koji imaju vie novca na
raunima, nego to je iznos njihovih dabina; i
Smetanje ostataka liste u tekstualnu datoteku DUZNICI.TXT, pri emu svaki red
datoteke sadri podatke: ime, prezime, JMBG i iznos duga. Podaci su razdvojeni sa
jednim praznim mestom.

Zadatak 24 (5)
U Sremskim Karlovcima svake godine odravaju se dani vina. Ove godine reeno je
da se putem SMS poruka izvri takmienje. Poruke se upisuju u datoteku
PORUKE.TXT. Svaki red datoteke sadri jednu poruku u formatu:

ifra vina # Broj mobilnog telefona # Ocena (1..5)

U datoteci TAKMICARI.TXT nalaze se prijavljeni takmiari, pri emu svaki red
datoteke sadri podatke jednog takmiara, u formatu:

ifra # Naziv vina

Ucitati podatke iz datoteka i formirati najjednostavniju i ujedno najefikasniju
dinamiku strukturu podataka, kojom e se najefikasije utvrditi rang lista vina. Rang lista
se formira u izlaznoj datoteci POBEDNICI.TXT.

Pravila ocenjivanja:
- Odbacuju se poruke sa neispravnom ifrom vina;
- Odbacuju se poruke sa neispravnom ocenom;
- Za jednu ifru vina sa jednog mobilnog telefona prihvataju se maksimalno
prve tri poruke.

Izlazna datoteka je sortirana u opadajuem redosledu: Prvi kriterijum sortiranja je
broj glasova, a drugi prosena ocena.
Svaki red izlazne datoteke odnosi se na jedno vino i zapis je u formatu:

ifra # Naziv vina # Prosena ocena # Broj osvojenih glasova

Zadatak 25 (5)
Mali Perica je poeo da skija. Perica je egzibicionista i ne skija po stazama, ve
skija kako stigne. Zbog toga, sluba spasavanja je reila da napravi program koji e
simulirati kretanje Perice od poetne pozicije do cilja. Program prikazuje sva mogua
reenja. Mapa terena se nalazi u datoteci MAPA.TXT. Prvi red datoteke ine dva broja
(broj vrsta i broj kolona mape) meusobno razdvojena blanko mestima. U narednim
redovima nalazi se mapa terena pri emu su elementi mape (predstavlja visinu terena)
razdvojeni praznim mestima. Ispod mape terena nalazi se red u kome su dva broja
meusobno razdvojeni praznim mestima koji oznaavaju startno mesto od koje Perica
poinje da skija.
351
Perica se sputa samo u pravcu jedne koordinate (ne dijagonalno), i to iskljuivo sa
mesta koje ima veu visinu na mesto nie visine. Potencijalni cilj su ona mesta koja na
mapi imaju najmanju visinu.

Zadatak 26 (5)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program za elektronsko voenje kolske
biblioteke. Svaki lan biblioteke je okarakterisan sa:

7) Prezime i ime,
8) lanski broj,
9) Adresa stanovanja,
10) Razred,
11) Telefon, i
12) Broj uzetih knjiga.

Program treba da omogui:

h) Upis novog lana, pri emu automatski dobija lanski broj,
i) Brisanje pojedinog lana iz biblioteke pod uslovom da je vratio sve knjige
koje je iz biblioteke zaduio,
j) Izmene pojedinih podataka o lanu,
k) Ispis podataka o svim lanovima po kriterijumu broja zaduenih knjiga,
l) Utvivanje koji razred ima najvie neurednih korisnika biblioteke,
m) Na kraju kolske godine prikaz svih lanova etvrte godine koji nisu vratili
knjige, i
n) Automatso preimenovanje oznake svih odeljenja kole na poetku kolske
godine.

Program treba da obezbedi trajno uvanje podataka u tekstualnoj datoteci
BIBLIOTEKA.TXT.


Zadatak 27 (5)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program koji prihvata podatke o posetiocima
nekog preduzea gde je svaki posetioc okarakterisan sa: prezimenom i imenom (do 30
karaktera), JMBG (13 karaktera) i vremenom ulaska i naputanja preduzea.

Program treba da omogui sledee funkcije:
1. Unos podataka o posetiocu pri ulasku i izlasku iz preduzea;
2. Prikaz svih podataka o posetama za datog zaposlenog, tabela sa kolonama:
ULAZAK, IZLAZAK, PREZIME I IME;
3. Prikaz svih poseta koji jo nisu izali iz preduzea, tabela sa kolonama:
ULAZAK, PREZIME I IME, POSETA ZA;
352
4. Prikazati na ekranu ime i prezime najveeg zabuanta. Najvei zabuant je
onaj radnik koji je najvei interval vremena proveo u razgovoru sa svojim
posetiocima. U sluaju da je njih vie imalo isti maksimalni vremenski
interval trajanja posete, najvei zabuant postaje onaj radnik koga je u toku
dana posetilo najvie posetilaca.
5. Trajnjo uvanje podataka o svim posetama u tekstualnoj datoteci pod
nazivom PORTddmmgg.TXT gde je dd dan, mm mesec, a gg godina
evidencije.

Zadatak 28 (5)
Date su tekstualne datoteke PROIZVODI.TXT, AUTOMOBILI.TXT i
KUPCI.TXT koje sadre podatke o proizvoaima automobila i kupcima jedne auto
kue. Datoteke sadre sledee podatke:

PROIZVODI.TXT
- Naziv proizvoaa automobila (od maksimalno 40 karaktera);
- Mesto (od maksimalno 20 karaktera).

AUTOMOBILI.TXT
- Tip automobila (od maksimalno 30 karaktera);
- Naziv proizvoaa (od maksimalno 40 karaktera);
- Cena (od maksimalno 10 karaktera); i
- Koliina na lageru (od maksimalno 5 karaktera)

KUPCI.TXT
- Ime kupca (od maksimalno 30 karaktera);
- Tip automobila (od maksimalno 30 karaktera); i
- Ve uplaeni iznos (od maksimalno 10 karaktera).

Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objanjenje
zato ba on) i na osnovu njega napisati C program koji omoguava kreiranje sledeih
izvetaja:
1) Spisak svih tipova automobila iz programa ove auto kue. Za svaki tip
automobila potrebno je navesti sledee podatke: proizvoa, sedite
proizvoaa, cena automobila, broj prodatih automobila (broj kupaca tog
tipa automobila) i ukupan broj automobila na lageru.

2) Spisak svih kupaca. Za svakog kupca navesti spisak svih automobila koje
kupuje, ukupno uplaen iznos kao i ukupan iznos koji duguje auto kui.


Zadatak 29 (5)
U tekstualnoj datoteci BEGUNAC.TXT nalazi se mapa zamka. Na ulazu u zamak
nalazi se begunac. Postoji vie puteva u zamku kojim je begunac mogao pobei policiji,
kao i vie izlaza iz zamka. U samom zamku na jednom mestu policija je postavila zasedu.

353
Mapa zamka sastoji se od brojeva ije vrednosti mogu biti:
1 Zid zamka;
2 Hodnik u zamku;
3 Mesto gde se nalazi policija; i
4 Poloaj begunca.

Program treba da utvrdi kolika je verovatnoa da e begunac pobei iz zamka.
U datoteci POBEGAO.TXT upisati koordinate kretanja begunca da bi pobegao
iz zamka. Potrebno je u datoteci upisati sve putanje kojima je begunac mogao pobei iz
zamka. Putanju ine redni brojevi koji opisuju poloaj elementa u matrici.
Na ekranu prikazati najoptimalniji put izlaska iz zamka. Najoptimalniji put
izlaska iz zamka je onaj koji ima najmanje polja koji pretstavljaju hodnik i ujedno
najmanje promene smera kretanja.
Program treba da pomogne policiji u postavljanju jo jedne zasede, a koji je
udaljen vie od tri polja (koga ine hodnik ili zid), a postavlja se na polje gde je hodnik,
tako da begunac bude sigurno uhvaen.
Prikazati simulaciju kretanja begunca, prilikom beanja kroz zamak. Nakon svakog
prikaza prolaska do izlaza, za nastavak pritisnuti taster SPACE. Ako je mogue sa 100%
sigurnosti uhvatiti begunca, prikazati poloaj druge policijske zasede, na iscrtanom
zamku

Zadatak 30 (5)
Napisati C program koji predstavlja igricu "milioner". U datoteci PITANJA.TXT
nalaze se pitanja na koje igrac daje odgovor. Svako pitanje je odgovarajue teine.
Izmeu formata zapisa pitanja nalazi se prazan red. Format zapisa pitanja prostire se
u reda. Prvi red sadri broj koji predstavlja teinu pitanja i samo pitanje, razdvojeni
znakom #. U naredna etiri reda nalaze se ponueni odgovori (A, B, C i D). U narednom
redu nalaze se etiri cifre razdvojene praznim mestima, koje predstavljaju procente.
U poslednjem redu formata pitanja nalazi se redni broj tacnog odgovora.
Pri startovanju igrice na ekranu se nalaze opcije sa iznosom novca koju ce dobiti
ukoliko odgovori tano na postavljeno pitanje. Svaka naredna opcija nosi vie novca i
ima veu teinu pitanja. Opcija na kojoj se trenutno nalazi igrac je crvene boje, dok su
sve ostale plave boje. Sa desne strane od postavljene opcije nalazi se postavljeno pitanje,
a ispod njega poneena etiri odgovora (ispred odgovora je slovo A..D). Igrac moe
pritiskom na odgovarajue slovo dati odgovor ili zatraiti pomo. Ako da odgovor na
pitanje pritiskom na odgovarajue slovo, raunar mu saoptava da li je odgovor taan te
ako jeste moe odgovarati na sledee pitanje vee teine i saoptava mu se koliko ima
trenutno novca. Ako je odgovorio pogreno kraj je igre. Igrau su na raspolaganju i tri
pomoi: pomo raunara1 (briu se dva od etiri ponuena odgovora), pomo raunara2
(brie se jedno od etiri ponuena odgovora) i pomo prijatelja (na osnovu etiri uitana
broja koja su predstavljala procente, prikazuju se procentualna zastupljenost odgovora A,
B, C i D od strane puublike). Pomoi su numerisane sa brojevima 1, 2 i 3. Igra u toku
igre moe ako hoe iskoristiti ponuene pomoi, ali svaku pomo samio jednom u toku
cele igre.
Igra se moe u toku trajanja programa igrati vie puta, ali se ne smeju ponavljati
pitanja od predhodnih odigranih partija.

You might also like