Professional Documents
Culture Documents
CIII Novi
CIII Novi
POGLAVLJE
FUNKCIJE
1
1.1. POJAM I DEFINICIJA FUNKCIJE
Definicija potprograma:
2
Na primer: y e 3 x 2 4 x 5
Definicija funkcije:
Osobine funkcija:
3
1.2. DEFINISANJE FUNKCIJE
Definisanje funkcije
Funkcija se definiše naredbom za definisanje funkcije:
tip - predstavlja osnovni tip vrednosti funkcije (svi standardni prosti tipovi).
Vrednost funkcije može da bude samo jedan podatak. Za tip vrednosti funkcije
ne može da bude niz. Za funkcije koje ne stvaraju vrednost funkcije kao
oznaka tipa treba da se koristi službena reč void. Ako se izostavi oznaka tipa
podrazumeva se tip int.
4
prekidanje izvršavanja programskog toka u funkciji, bez obzira na kom mestu
se nalazi u telu funkcije. Kod funkcija tipa void naredba return ne sme da
sasdrži izraz.
Primer 1:
Definisati C funkciju hipotenuza koja na osnovu kateta a i b izračunava hipotenuzu
pravouglog trougla.
Rešenje
prvi način:
drugi način:
c=sqrt(a*a+b*b);
return c;
}
Primer 2:
Definisati C funkciju slika koja na osnovu neparnog broja zvezdica n iscrtava sliku
sledećeg izgleda:
*
***
*****
******* Za n = 7 napravljena je ova slika
****** gde je n neparan broj i predstavlja
***** gornju katetu trougla zvezdica.
****
***
**
*
5
Rešenje
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");
}
}
6
1.3. POZIVANJE FUNKCIJA
Izraz za pozivanje funkcije može se koristiti kao operand u složenijem izrazu, tada
se vrednost funkcije koristi u izračunavanju tog izraza. Kako je operator poziva funkcije
() visokog prioriteta, to obezbeđuje da se izračunavanje vrednosti funkcije (pozivanje
funkcije) izvrši pre bilo kog susednog operatora u izrazu. Ukoliko funkcija nema svoju
vrednost (tip void) može da se koristi samo kao drugi operand operatora zarez ili kao
drugi ili treći operand trinarnog operatora. Funkcija koja nema svoju vrednost najčešće se
koristi kao operand izraza u prostoj naredbi (fun(...);).
Primer 1:
Napisati C program koji na osnovu unetih kateta pravouglog trougla a i b
izračunava dužinu hipotenuze. Dužinu hipotenuze računati funkcijom hipotenuza čija je
sintaksa: float hipotenuza(float a, float b);
Rešenje
prvi način:
#include <stdio.h>
#include <conio.h>
#include <math.h>
7
float hipotenuza(float a, float b)
{
return sqrt(a*a+b*b);
}
void main(void)
{
float a,b;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
printf("\n\n\n\n\n\n\n");
printf("\n\n\n\n\n\n\n\tHIPOTENUZA PRAVOUGLOG TROUGLA JE:\n\t\t");
printf("c = %.3f",hipotenuza(a,b));
gotoxy(1,25);
getch();
}
drugi način:
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main(void)
{
float a,b,c;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
printf("\n\n\tUNESITE KATETE PRAVOUGLOG TROUGLA:\n\t\ta = ");
scanf("%f",&a);
printf("\t\tb = ");
scanf("%f",&b);
8
c = hipotenuza(a,b); /* Prilikom poyiva 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 PRAVOUGLOG TROUGLA JE:\n\t\t");
printf("c = %.3f",c);
gotoxy(1,25);
getch();
}
Primer 2:
Napisati C program koji korišćenjem unetog neparnog prirodnog broja n, pozivom
funkcije slika prikazuje na ekranu sliku od zvezdica sledećeg izgleda:
*
***
*****
******* Za n = 7 napravljena je ova slika
****** gde je n neparan broj i predstavlja
***** gornju katetu trougla zvezdica.
****
***
**
*
Rešenje
#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++) cprintf(" ");
for(j=1;j<=2*i-1;j++) cprintf("* ");
printf("\n");
}
9
for(i=1;i<=n-1;i++)
{
for(j=1;j<=i;j++) printf(" ");
for(j=1;j<=n-i;j++) printf("* ");
printf("\n");
}
}
void main(void)
{
unsigned xn,yn;
int n;
textmode(3);
textcolor(0);
textbackground(15);
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);
gotoxy(1,25);
getch();
}
10
1.4. PREDAJA PARAMETARA
Primer 1:
Napisati C program koji na osnovu dužine stranice kvadrata izračunava obim i
površinu kvadrata. Za izračunavanje obima kvadrata koristiti funkciju obim, a površine
kvadrata funkciju povrsina.
Rešenje
#include <stdio.h>
#include <conio.h>
11
/* Funkcija izracunava povrsinu kvadrata. */
double povrsina(double x)
{
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;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
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 rezerviše pet zona memorije, koji
su delovi RAM memorije. Za sada posmatraćemo 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 fizički nije ista
memorijska lokacija kao stvarni argument, koji se nalazi u ZONI PODATAKA. */
gotoxy(1,25);
getch();
}
12
Primer 2:
Napisati C program koji korišćenjem funkcije suma izračunava zbir prvih n
članova beskonačnog periodičnog niza periode p.
Beskonačni niz ima sledeći oblik:
U funkciji suma koristiti funkciju zbir koja može na osnovu unetog broja k da
sabira celu periodu (ako je k=p) ili deo periode (ako je k<p) beskonačnog niza.
Zadatak rešiti bez korišćenja nizova.
Rešenje
#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. */
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;
}
13
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
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.*/
/* 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();
gotoxy(1,25);
getch();
}
14
1.5. PROTOTIPOVI FUNKCIJA
Ovaj prototip ukazuje prevodiocu da će se kasnije koristiti funkcija zbir koja vraća
podatak tipa int i da funkcija zbir ima dva argumenta tipa int. Njega uopšte ne zanimaju
promenljive n i p. Iz tih razloga dozvoljeno je pisanje prototipa funkcije i u sledećem
obliku.
int zbir(int , int );
Posmatraćemo primer 2 sa časa 6. Ako bismo izvršili zamene mesta definisanja
funkcija zbir i zbirdeo program bi imao grešaka, jer se u funkciji zbir poziva funkcija
zbirdeo koju prevodilac „ne poznaje“. Korišćenjem prototipova funkcija ne moramo
voditi računa o rasporedu definicija funkcija, a definisanje funkcija se izvode u
proizvoljnom poretku ispod tela main funkcije.
Primer:
Napisati C program koji korišćenjem funkcije suma izračunava zbir prvih n
članova beskonačnog periodičnog niza periode p.
Beskonačni niz ima sledeći oblik:
U funkciji suma koristiti funkciju zbir koja može na osnovu unetog broja k da
sabira celu periodu (ako je k=p) ili deo periode (ako je k<p) beskonačnog niza.
Zadatak rešiti bez korišćenja nizova.
Rešenje
#include <stdio.h>
#include <conio.h>
15
void main(void)
{
int p, n;
unsigned xn=-1, yn=-1, xp=-1, yp=-1;
textmode(3);
textcolor(0);
textbackground(15);
clrscr();
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;
}
/* 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;
}
16
/* 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;
}
17
1.6. REKURZIVNE FUNKCIJE
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.
Rešenje
#include <stdio.h>
#include <conio.h>
void main(void)
{
int n, xn, yn;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
do{
gotoxy(xn,yn);
printf(" ");
18
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0);
/*U ovom redu se vidi da je prikaz rekurzivna funkcija jer u okviru svog tela
poziva sama sebe. */
if(k<n) prikaz(k+1,n);
printf("%d\t",k);
}
STEK
k: 1,Aktivaciono
n: 3 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 povećava za 1 na sledeću lokaciju.
STEK
k: 1,Aktivaciono
n: 3 Aktivacioni zapis 1.
k: 2, n: 3
Aktivacioni zapis 2.
Pok na stek
19
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,Aktivaciono
n: 3 Aktivacioni zapis 1.
k: 2, n: 3
Aktivacioni zapis 2.
k: 3, n: 3
Aktivacioni zapis 3.
Pok na stek
STEK
k: 1,Aktivaciono
n: 3 Aktivacioni zapis 1.
k: 2, n: 3
Aktivacioni zapis 2.
Pok na stek
STEK
k: 1,Aktivaciono
n: 3 Aktivacioni zapis 1.
Pok na stek
20
Nakon završetka funkcije prikaz sa parametrima koji odgovaraju aktivacionom
zapisu 1 vraćamo se u glavni program.
Primer 2:
Napisati C program koji korišćenjem rekurzivne funkcije suma izračunava zbir
elemenata niza A od n članova n<31.
Rešenje
#include <stdio.h>
#include <conio.h>
#define MAX_NIZ 30
void main(void)
{
int a[MAX_NIZ], n, pom;
unsigned i, j, xn, yn, xu, yu;
/*Inicijalizacija niza. */
for(i=0;i<MAX_NIZ;i++) a[i]=0;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
21
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_NIZ);
22
2. POGLAVLJE
POKAZIVAČI
23
2.1. POKAZIVAČI
Definicija pokazivača:
Pokazivač je promenljiva koja sadrži adresu druge promenljive ili funkcije.
tip *pok;
pok = NULL;
tip *pok=NULL;
24
Pokazivačka promenljiva pokazivaće na drugu promenljivu ako sadrži njenu adresu.
To se postiže na sledeći način.
pok = &prom;
U ovom slučaju pokazivačka promenljiva pok mora prethodno biti deklarisana tako
da pokazuje na promenljive tipa tip, a da je i promenljiva prom takođe 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 dešava sa memorijskim lokacijama gde su smeštene 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();
25
Rešenje
#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();
x[i] *(x + i)
Primer 2:
Napisati C program koji isključivo korišćenjem pokazivača izračunava zbir
pozitivnih elemenata niza X od n elemenata n<31.
Rešenje
26
#include <stdio.h>
#include <conio.h>
#define MAX 30
void main(void)
{
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
/* 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);
27
gotoxy(1,25);
getch();
}
Generički pokazivači:
Pored pokazivača na podatke poznatih tipova, postoje i generički pokazivači
kod kojih nije određen tip pokazivačkih podataka. Deklaracija generičkog
pokazivača vrši se stavljanjem rezervisane reči void umesto opisa tipa pokazivačkih
podataka.
void *pok;
Na primer:
int x, y, *pok1=NULL, *pok2=NULL;
void *pok3=NULL;
x=0;
y=5;
28
2.2. PREDAJA PARAMETARA PO REFERENCI
BOČNI EFEKTI
Prenos parametara po referenci najlakše možemo objasniti kroz jedan prost zadatak.
Primer 1:
Napisati C program koji korišćenjem funkcije zameni vrši zamenu vrednosti dve
promenljive. Prototip funkcije zameni je void zameni(int a, int b);
Rešenje
#include <stdio.h>
#include <conio.h>
/* Prototip funkcije. */
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);
/* Poziv funkcije */
zameni(a,b);
gotoxy(1,25);
getch();
}
pom=a;
29
a=b;
b=pom;
}
Ako istestiramo ovaj program videćemo da program ne radi ispravno. Ispisaće iste
vrednosti kao i pre poziva funkcije zameni. Problem leži u tome što formalni parametri a
i b respektivno pozivom funkcije zameni dobijaju stvarne vrednosti promenljivih a i b.
Formalni parametri nalaze se na steku i više nikakve veze nemaju sa promenljivama a i b
iz ZONE PODATAKA. Zamena će biti izvršena između formalnih promenljivih a i b.
Posle završetka funkcije sadržaj steka se briše, a time i sadržaj formalnih parametara.
Podaci a i b iz zone podataka ostali su nepromenjeni.
#include <stdio.h>
#include <conio.h>
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);
30
printf("\n\tb = %d",b);
gotoxy(1,25);
getch();
/*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. */
Primer 2:
Napisati šta radi sledeći program i objasniti šta radi funkcija pronadji.
#include <stdio.h>
#include <conio.h>
#define MAX 50
31
void main(void)
{
int i,j,k,n,x[MAX];
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;
for(i=0;i<n-1;i++) pronadji(x,0,n-i-1);
pom=*(x+a);
for(i=a;i<k;i++) *(x+i)=*(x+i+1);
*(x+k)=pom;
}
Rešenje
Program na osnovu unetog broja n formira niz od n elemenata čiji članovi imaju
vrednost jednaku rednom broju člana niza. Korišćenjem funkcije pronađi niz se
modifikuje tako da postaje zapisan u inverznom poretku i takav se ponovno štampa na
ekranu.
Funkcija pronadji vrši rotaciju niza X između indeksa a i k za jedno mesto u levo.
32
Primer 3:
Napisati šta radi sledeći program i objasniti šta radi funkcija utvrdi.
#include <stdio.h>
#include <conio.h>
#define MAX 50
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;
for(i=0;i<n;i++) uradi(x,&a,i);
uradi(x,&a,0);
pom=*a;
*a=*(x+k);
*(x+k)=pom;
}
33
Rešenje
Program na osnovu unetog broja n formira niz od n elemenata čiji članovi imaju
vrednost jednaku rednom broju člana niza. Korišćenjem funkcije uradi niz se modifikuje
tako da postaje zarotiran za jedno mesto u desno i takav se ponovno štampa na ekranu.
Funkcija uradi vrši 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) aritmetičku, ili
b) geometrijsku progresiju
Rešenje
#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(0);
textbackground(15);
clrscr();
34
printf(" ");
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0||n>MAX);
/*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;
35
/*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;
return 0;
}
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 sledećim pravilima.
Niz C imaće isti broj elemenata kao i niz B,
I-ti element niza C dobija se sabiranjem
odgovarajućih 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 kreće sa leva na desno, a ako je negativna sa desna na levo,
Ako je vrednost elementa niza B nula, tada je
odgovarajuća 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
počev od prvog elementa iz niza A, dok se ostali dobijaju sabiranjem od trenutne pozicije
gde se sa sabiranjem završilo prilikom dobijanja predhodnog elementa, i
Ako se dođe do kraja ili početka 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
36
Niz C imaće sledeći izgled C = 18 75 55 7 13
Rešenje
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define MAX_NIZ 30
/*Prototipovi funkcija. */
int sabdesno(int *s,int n,int a[],unsigned *k,unsigned *j);
int sablevo(int *s,int a[],unsigned *k,unsigned *j);
void main(void)
{
int s,n,a[MAX_NIZ], m,p,b[MAX_NIZ],c[MAX_NIZ];
unsigned i,j,k,xn,yn,xm,ym,xu,yu;
for(i=0;i<MAX_NIZ;i++) a[i]=b[i]=c[i]=0;
textmode(3);
textcolor(0);
textbackground(15);
clrscr();
do{
gotoxy(xn,yn);
printf(" ");
gotoxy(xn,yn);
scanf("%d",&n);
}while(n<=0||n>MAX_NIZ);
gotoxy(xu+5*j,yu);
scanf("%4d",&a[i]);
j++;
}
37
gotoxy(xm,ym);
printf(" ");
gotoxy(xm,ym);
scanf("%d",&m);
}while(m<=0||m>MAX_NIZ);
gotoxy(xu+5*j,yu);
scanf("%4d",&b[i]);
j++;
}
if(b[i]<0) p=-1;
else{
if(b[i]>0) p=1;
else p=0;
}
while(p!=0)
{
if(p==1) p=sabdesno(&s,n,a,&k,&j);
else p=sablevo(&s,a,&k,&j);
}
38
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);
getch();
}
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;
}
return p;
}
if(*k>(*j)+1)
{
(*k)-=(*j)+1;
p=(*j)+1;
for(i=1;i<=p;i++)
{
*s+=a[*j];
39
(*j)--;
}
*j=0;
p=1;
}else{
for(i=1;i<=*k;i++) *s+=a[*j],(*j)--;
(*j)++;
p=0;
}
return p;
}
40
2.3. FUNKCIJE KOJE VRAĆAJU POKAZIVAČE
POKAZIVAČI NA FUNKCIJE
Primer 1:
Napisati C program koji omogućava izbacivanje iz niza X od n elemenata (n<51),
sve one elemente koje imaju određenu vrednost. Izbacivanje elemenata vršiti funkcijom
izbaciizniza koja vraća broj izbačenih elemenata. U funkciji izbaciizniza koristiti
funkciju trazi koja utvrđuje da li u nizu ima elementa koga treba izbaciti i vraća adresu
elementa niza gde je pronađen ili NULL u suprotnom. Na ekranu štampati sažeti niz ili
poruku da je niz ostao nepromenjen.
Rešenje
#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;
41
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
/* 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. */
42
unsigned i, k, br=0;
int *p=NULL;
while((p=trazi(izbaci,x,*n))!=NULL)
{
br++;
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. */
while(x[i]!=izbaci&&i<n) i++;
Pokazivači na funkcije
Pokazivači pored toga što mogu da sadrže adresu podatka, mogu da sadrže i
adresu programskog koda.
tip (*indentifikator_pokazivača)(niz_tipova_argumenata);
43
Priliko deklaracije zagrade u okviru kojih se nalazi pokazivač su neophodne, jer u
suprotnom umesto pokazivača na funkcije imali bi smo funkciju koja vraća pokazivač.
Zagrade omogućavaju da se prvo izvrši indirektno adresiranje pokazivača, čime dolazimo
do adrese funkcije, a u drugoj zagradi nalaze se argumenti nad kojima će se funkcija
izvršiti. Postoje dva slučaja kada se pokazivači najčešće koriste. Prvi je da pokazivač
zapamti adresu jedne od funkcija koja je izabrana, a da se naknadnim pozivanjem
pokazivača na funkciju odabrana funkcija izvrši. Drugi slučaj je da pokazivač na funkciju
predstavlja argument neke funkcije. Na taj način se adresa jedne funkcije pomoću
pokazivača na funkciju prenosi drugoj funkciji.
Primer 2:
Napisati C program koji omogućava unos niza od n, n<11 tačaka i tabelarni prikaz
vrednosti jedne od tri funkcije, na osnovu niza tačaka. Funkcije su:
ex
y x 2 log* ( x 2 1), y x 2 1, i y
log( x 2 4)
Rešenje
#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);
void main(void)
{
int i,n=0;
double x[MAX];
char odluka;
for(i=0;i<MAX;i++) x[i]=0;
textmode(3);
textcolor(0);
textbackground(15);
clrscr();
44
/* Vrsi se izbor jedne od tri ponuđene funkcije. */
printf("\nIzaberi jednu od tri sledece funkcije:\n");
printf("\t1: y = x²log(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);
45
/* Funkcija fun1 je prva funkcija iz izbora. */
double fun1(double x)
{
return x*x*log(x*x+1);
}
/* 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");
for(i=0;i<n;i++) printf("\t%2d.%20.3f%20.3f\n",i+1,x[i],(*pok)(x[i]));
}
46
2.4. FORMIRANJE SOPSTVENE BIBLIOTEKE FUNKCIJA
#include <imedatoteke.h>
#include “imedatoteke.h“
Primer 1:
Napisati C program TEST1.C koji omogućava unos niza X od n elemenata i
njegovo sortiranje u rastućem redosledu i program TEST2.C koji formira niz Y od m
elemenata u opadajućem redosledu n<31 i m<41. Prilikom realizacije programa koristiti
funkcije unos_ceo koja omogućava unos celog broja tipa int, ali da se prilikom unosa
broja omogući zaštita unosa (ne dozvoljava unos drugih karaktera osim dekadnih cifara).
U hederu NIZ.H se pored opisane funkcije nalaze i funkcije:
unos_niza - koja omogućava unos niza pozivajući funkciju unos_ceo,
unos_brc - koja omogućava unos broja članava niza uz zaštitu unosa pozivajući
funkciju unos_ceo,
sort - koja vrsi sortiranje niza u rastućem ili opadajućem redosledu u određenom
intervalu, i
ispis_niza - koja omogućava ispis niza na ekranu.
Rešenje
47
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);
/* 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);
}
}while(c!='\r' || x==0);
48
/* Vracamo dobijeni broj pomnozen sa zapamcenim predznakom. */
return x*pom;
}
return n;
}
/* 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++)
{
for(j=i+1;j<=q;j++)
49
{
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;
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>
#include "niz.h"
#define MAX 30
void main(void)
50
{
/* Deklaracjia promenljivih. */
int x[MAX], n, i;
/* Inicijalizacija niza X. */
for(i=0;i<MAX;i++) x[i]=0;
textmode(3);
textbackground(15);
textcolor(0);
clrscr();
getch();
TEST2.C
51
#include <stdio.h>
#include <conio.h>
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(15);
textcolor(0);
clrscr();
m=unos_brc(MAX_NIZ);
printf("\n\n");
unos_niza(y,m);
Primer 2:
52
Zadat je celobrojan niz X od n elemenata n<51 i celobrojni podatak p. Napisati C
program koji korišćenjem što većeg 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 veći ili jednak od 2 a manji ili jednak od n.
Deo niza koga obrazuje najveći interval i ujedno je zbir njegovih indeksa najveći, sa
gore navedenom osobinom, sortirati u rastućem redosledu a potom prikazati na ekranu
novonastali niz, kao i broj zamena elemenata niza koji se izvršio 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.
Rešenje
#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(15);
textcolor(0);
clrscr();
53
/* Unos koliko ce niz imati elemenata uz ogranicenje da ne bude vece od dimenzije niza.
*/
n=unos_brc(MAX_NIZ);
printf("\n\n");
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. */
54
/* 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;
55
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;
}
56
2.5. ZADACI IZ FUNKCIJA
Zadatak 1 (2)
Napisati C program koji na osnovu unetog prirodnog broja n i racionalnog broja x
izračunava i štampa sumu zaokruženu na četiri decimale. Sumu računati pozivom
funkcije suma čija je sintaksa: double suma(int n, double x);
Suma je zadata oblikom:
x x2 x3 xn
S 1 ... n
x 1 x2 1 2 x3 1 2 3 x 1 2 3 ... n
Zadatak 2 (2)
Napisati C program koji na osnovu unetih prirodnih brojeva n i x izračunava i
štampa sumu zaokruženu na tri decimale. Sumu računati pozivom funkcije suma.
Suma je zadata oblikom:
3 x 3 (1 2) 4 x 4 (1 2 3) n x n (1) n (1 2 3 ... n 1)
S 1 x ...
2 x2 1 2 3 2 x3 1 2 3 4 (n 1) x n1 1 2 3 ... n
Zadatak 3 (2)
Napisati C program koji korišćenjem unetog prirodnog neparnog broja n (2<n>12),
pozivom funkcije slika prikazuje na ekranu sliku od zvezdica sledećeg 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 unutrašnjosti kvadrata nalazi se deltoid čija manja dijagonala ima n zvezdica.
57
Zadatak 4 (2)
Napisati C program koji na osnovu unetog prirodnog broja n izračunava zbir
kvadrata prvih n prirodnih brojeva. Za izračunavanje zbira koristiti funkciju zbir.
Zadatak 5 (2)
Napisati C program koji na osnovu unetog prirodnog broja n izračunava
korišćenjem funkcije zbir, zbir prvih n članova niza:
Zadatak 6 (2)
Napisati C program koji na osnovu unesenih stranica kvadra a, b i c pozivom
funkcije kvadar izračunava i vraća površinu kvadra a po referenci određuje zapreminu
kvadra.
Zadatak 7 (2)
Napisati C program koji korišćenjem funkcije suma izračunava 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 sledećem pravilu: z[i] = max(x[i],y[i]), i=[1..n]
Odgovarajući element niza Z dobija se pozivom funkcije max.
Zadatak 9 (2)
Napisati C program koji pozivom funkcije trazi, utvrđuje da li se u celobrojnom
nizu X od n (n<31) elemenata nalazi broj p. Ako se broj p nalazi u nizu funkcija vraća 1
a u suprotnom 0.
Zadatak 10 (2)
Napisati C program koji korišćenjem funkcije minmax određuje po referenci
vrednosti minimalnog i maksimalnog elemenata celobrojnog niza X. Niz X ima n
elemenata (n<41). Funkcija nema povratne vrednosti.
Zadatak 11 (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
izračunavanje zbira prethodnika koristiti funkciju zbir.
Zadatak 12 (3)
Napisati C program koji korišćenjem funkcije min određuje po referenci vrednosti
minimalnog elemenata celobrojnog niza X, a vraća broj minimalnih elemenata niza. Niz
X ima n elemenata (n<41).
Zadatak 13 (3)
58
Napisati C program koji vrši konverziju dekadnog broja n (n<250) u njegov binarni
ekvivalent i vrši njegov binarni ispis na ekranu. Pretvaranje i ispis realizovati funkcijom
bin_ispis.
Zadatak 14 (3)
Napisati C program koji na osnovu unetog prirodnog broja n izračunava pozivom
funkcije zbir, zbir prvih n članova niza:
1, 1, 2, 5, 7, 74, ...
Prva dva člana niza imaju vrednost 1, a počev od trećeg svaki sledeći član dobija se
kao zbir kvadrata predhodna dva člana.
Zadatak 15 (3)
Napisati C program koji na osnovu unetog prirodnog broja n korišćenjem funkcije
prost utvrđuje i na ekranu štampa sve proste brojeve koji se nalaze na intervalu 1..n.
U funkciji prost pozivati funkciju utvrdi koja utvrđuje da li je broj k sa intervala
1..n prost, te vraća 1 ako jeste ili 0 u suprotnom.
Zadatak 16 (3)
Eksponencijalna funkcija y e x može se izračunati razvojem u Maklorenov red,
kao:
x2 x3 xk
ex 1 x ...
1 2 1 2 3 1 2 3 ... k
Zadatak 17 (3)
Napisati C program koji korišćenjem funkcije datum na osnovu rednog broja dana
u godini ispisuje datum koji odgovara tom rednom broju. Funkcija vraća 1 ako je redni
broj korektan, a u suprotnom 0. Funkcijom korišćenjem bočnog efekta odrediti dan i
redni broj meseca.
Zadatak 18 (3)
Zadat je celobrojan niz A od n elemenata n<100. Napisati C program koji za uneto
k, vrši pozivom funkcije rotiraj rotiranje niza za k elemenata. Ako je k>0 vrši se
rotiranje za k elemenata u desno, ako je k<0 za k elemenata u levo, a za k=0 ne vrši se
rotacija niza. Funkcija vraća 0 ako nije vršila rotaciju niza, a u suprotnom vraća 1.
Zadatak 19 (3)
59
Brojčano su dati dan, mesec i godina. Ispisati dan u mesecu, naziv datog meseca,
godinu i dan u godini. Za izračunavanje dana u godini napisati funkciju reddan.
Na primer:
Dan: 15
Mesec:3 => 15 mart 1987 dan 74
Godina:1987
Zadatak 20 (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 između maksimalnog i minimalnog
elementa niza A.
Niz B formirati funkcijom formb u okviru koje se pozivaju funkcije minimum i
maksimum za traženje minimalnog odnosno maksimalnog elementa niza A.
Zadatak 21 (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:
pri čemu je br[i] broj elemenata niza B koji imaju vrednost veću od a[i] a dobija se
korišćenjem 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 korišćenjem funkcije suma.
.
Zadatak 22 (4)
Napisati C program koji na osnovu unetog prirodnog broja n sa intervala 1..n traži
korišćenjem funkcije trazi_del broj koji ima najviše delilaca. Štampati sve brojeve u
slučaju da ima više takvih brojeva.. Funkcija trazi_del na osnovu prirodnog broja k
utvrđuje i vraća broj delilaca broja k.
Zadatak 23 (4)
Napisati C program koji po izboru korisnika vrši sortiranje celobrojnog niza X od n
(n<41) elemenata u rastućem ili opadajućem redosledu. Sortiranje niza vrši se pozivom
samo jedne funkcije pod imenom sort. Prenosom po vrednosti prosleđuje se da li će se
sortirati u rastućem ili opadajućem redosledu.
Zadatak 24 (2)
Napisati C program koji kojim se ispituje koliko elemenata niza X od n (n<41)
elemenata je deljivo sa brojem a a nije deljivo sa brojem b. Brojevi a i b su celobrojni.
Funkcija odredi ima prototip unsigned odredi(int a[], int m, int p, int q);
Funkcija u nizu a od m elemenata utvrđuje koliko elemenata je deljivo sa brojem p
a nije sa brojem q.
Zadatak 25 (4)
60
Napisati C program koji korišćenjem funkcije utvrdi utvrđuje broj različitih
elemenata u celobrojnom nizu X od n elemenata (n<41).
Zadatak 26 (3)
Zadat je niz X od n (n<41) elemenata. Napisati C program koji iz niza izbacuje
elemente koji imaju osobinu da im je vrednost jednaka sa vrednosti prethodnog elementa
niza. Funkcija sazmi vrši sažimanje niza poozivajući funkciju utvrdi. Fdunkcija utvrdi
vraća adresu pronađenog elementa niza, sa osobinom da mu je vrednost jednaka
prethodnom elementu niza.
Zadatak 27 (2)
Zadat je niz X od n (n<41) elemenata. Napisati C program koji na osnovu niza X
formira niz Y. Elementi niza Y dobijaju se tako što se elementima prve polovine niza
oduzima polovina minimuma, a elementima druge polovine niza dodaje polovina
maksimuma. Ako niz ima neparan broj elemenata tada prva polovina niza ima više
elemenata.
Funkcija minmax po referenci određuje indeks prvog minimuma i imdeks
poslednjeg maksimuma niza.
Zadatak 28 (4)
Zadat je niz X od n (n<41) elemenata. Napisati C program koji pozivom funkcije
ciklpom cikličnim pomakom u levo prvi maksimum premešta na prvu poziciju u nizu.
Funkcija ciklpom poziva funkciju max koja vraća adresu prvog maksimuma.
Zadatak 29 (4)
Zadat je niz X od n (n<41) elemenata. Napisati C program kojim se iz niza izbacuju
svi elementi niza sa osobinom da im je vrednost tri puta veća od minimuma a nisu
maksimumi, Za odrešivanje minimuma i maksimuma niza koristiti funkciju minmax koja
vraća minimum a po referenci određuje maksimu. Funkcija izbaci na osnovu prosleđene
adrese elementa niza izbacuje element niza koji se na toj adresi nalazi.
Zadatak 30 (4)
Zadat je niz X od n (n<41) elemenata. Napisati C program koji na osnovu unesenih
rednih brojeva i i j (i<n i j<i) vrši rotiranje niza za jedno mesto i određuje srednju
vrednost ostatka niza, bez elemenata sa tim rednim brojevima. Funkcijum rot vršiti
rotiranje niza za jedno mesto u desno ili u levo, na oslovu prosleđenog parametra
funkciji. Funkcija sredvre određuje srednju vrednost ostatka niza.
Zadatak 31 (4)
Zadat je niz X od n (n<41) elemenata. Napisati C program koji utvrđuje da li je niz
X monotono rastući. Funkcija utvrdi vraća 1 ako je niz strogo monotono rastući ili 0 u
suprotnom. Ako niz nije monotono rastući pozivom funkcije sort izvršiti njegovo
sortiranje u rastućem redosledu.
Zadatak 32 (4)
61
Napisati C program za poređenje dva niza celih brojeva A i B od po n elemenata
n<100. Poređenje dva niza vršiti funkcijom poredi koja vraća -1 ako je niz A manji od
niza B, 0 ako je niz A jednak nizu B ili 1 ako je niz A veći od niza B.
Zadatak 33 (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 sledeći način:
VREDNOST TIP
**** minimum
**** maksimum
Funkcija ekstremi vraća 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 izveštaj imati sledeći izgled:
VREDNOST TIP
5 maksimum
3 minimum
6 maksimum
1 minimum
23 maksimum
Zadatak 34 (4)
Zadat je niz X od n elemenata (n<51). Napisati C program koji pozivom funkcije
sazmi izbacuje iz celobrojnog niza svaku pojavu odgovarajućeg broja broj. Ako broja
nema u nizu funkcija vraća 0, a u suprotnom koliko je elemenata niza imalo tu vrednost.
Zadatak 35 (5)
62
Zadat je niz X od n elemenata (n<51). Napisati C program koji sve maksimalne
elemente prebacuje na početak niza a minimalne na kraj niza. Modifikovanje niza vršiti
funkcijom mod u okviru koje se poziva funkcija minmax. Funkcija minmax ima prototip
unsigned minmax(int a[], int m, char tip, int *ekstrem);
Parametar tip može imati vrednosti 0 (traži se minimum) ili 1 (traži se maksimum).
Po referenci određuje se vrednost određenog ekstrema, a funkcija vraća broj pojavljivanja
određenog ekstrema.
Zadatak 36 (5)
Zadat je niz X od n elemenata (n<51). Napisati C program koji određuje sumu
elemenata niza pre prvog ekstrema i srednju vrednost posle drugog ekstrema.
Funkcija minmax po referenci određuje vrednosti minimuma i maksimuma, a vraća
broj ekstrema. Funkcija ekstrem pronalazi prvi ekstrem od početka niza i vraća njegovu
adresu. Funkcija suma izračunava zbir elemenata niza do prvog ekstrema. Funkcija
sredvred određuje srednju vrednost dela niza od drugog ekstrema.
Zadatak 37 (5)
Zadat je niz X od n elemenata (n<51). Napisati C program koji određuje prvi
interval elemenata kod koga svi elementi imaju veću vrednost od unetog racionalnog
broja a. Interval mora imati najmanje tri elementa. Funkcija interval vraća dužinu
intervala ako postoji ili 0 u suprotnom, dok se bočnim efektom određuju indeksi početka
i kraja intervala.
Zadatak 38 (4)
Napisati C program koji pozivom funkcije trazi, utvrđuje da li se u celobrojnom
nizu X od n (n<31) elemenata nalazi broj p. Ako se broj p nalazi u nizu funkcija vraća 1
a u suprotnom 0. Koristeći funkciju trazi u funkciji izbaci, izbaciti svako višestruko
pojavljivanje broja p u nizu X. U nizu ostaviti onaj broj p koji je imao najveći indeks.
Funkcija izbaci vraća broj izbačenih elemenata iz niza X, ili 0 ako ni jedan element nije
izbačen iz niza.
Zadatak 39 (4)
Zadat je niz X od n (n<41) elemenata. Napisati C program koji određuje vrednost
zbira dela niza između pozicija minimalnog i maksimalnog elementa ili maksimalnog i
minimalnog elementa i srednju vrednost ostatka niza.
Za formiranje niza X od n elemenata koristiti funkciju unos. U nizu X nema
ponavljanja elemenata.
Funkcija uradi izračunava i po vrednosti vraća zbir elemenata niza između pozicija
minimalnog i maksimalnog elementa, a bočnim efektom srednju vrednost ostatka niza.
Funkciji po referenci proslediti vrednost logičke promenljiva koja nakon završetku
funkcije dobija vrednost 1 ako je izračunata srednja vrednost ili 0 ako se srednja vrednost
ne može izračunati.
Funkcijom minmax odrediti po referenci pozicije minimalnog i maksimalnog
elementa niza. Funkcija minmax nema povratne vrednosti..
Zadatak 40 (5)
63
Zadat je niz X od n (n<51) elemenata. Napisati C program koji određuje najveći
rastući interval niza. Ako ima više takvih intervala ispisati ih sve na ekranu, i za svaki
utvrditi da li sadrži maksimalni element niza. Određivanje najvećih rastućih intervala niza
vrši se pozivom funkcije interval koja vraća dužinu podniza ili -1 ako rastućeg intervala
nema, dok se početak i kraj intervala određuje po referenci.
Funkcija max utvrđuje vrednost maksimalnog elementa niza, a funkciju pronadji
(pozivom funkcije max) pripadnost maksimalnog elementa najvećem rastućem intervalu.
Rastući interval mora imati barem dva člana niza.
Zadatak 41 (5)
Napisati C program koji pozivom funkcije period utvrđuje da li je celobrojan niz X
od n (n<51) elemenata periodičan. Funkcija vraća 0 ako niz nije periodičan, ili broj
p 0 koji predstavlja traženi period.
Zadatak 42 (5)
Novac kojim raspolaže (trenutno se nalazi u kasi) služba platnog prometa jedne
banke zadata je nizom novac. Prvi član niza sadrži broj novčanica apoena 1000, drugi
broj novačanica apoena 500, treći broj novčanica apoena 200, sledeći 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 služba isplatiti klijenta od N dinara
a da pri tome utoši što manje novčanica sa manjim apoenima. Problem rešiti funkcijom
isplata koja vraća vrednost 1 ako je moguće isplatiti klijenta, a 0 u suprotnom.
Korišćenjem bočnog efekta i niza novac, ispisati kako je izvršena isplata, kao i koliko je
novca po apoenima ostalo u banci.
Zadatak 43 (5)
Napisati C program koji omogućava ispis ASCII tabele na ekranu, a zatim za unos
nekog rednog broja označiti odgovarajući znak na ekranu. Oznaku odgovarajućeg znaka
sa ekrana vrši se pozivom funkcije oznaci.
Zadatak 44 (5)
64
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 moguće slučajeve.
Funkcija rastavi za dato k, p i n utvrđuje da li je moguće rastaviti i vraća 1 ako
može ili 0 u suprotnom.
Zadatak 45 (5)
Dopuniti C program (zadatak 9 iz poglavja nizovi) tako da igra samo jedan igrač, a
da je drugi igrač računar. Računar uvek igra kao "X". Programski igra računara je
realizovana funkcijom kompot. Funkcija vraća poziciju u nizu gde treba upisati broj 2
(što označava da digrao računar). Pozicija mora biti korektna,tj na toj poziciji nalazi se u
nizu vrednost 0. Po mogućućstvu funkcija kompot treba da vraća takve poteze da na kraju
igre pobednik uvek bude računar, ili je igra završena nerešeno.
Zadatak 46 (2)
Napisati C program koji na osnovu unetog prirodnog broja n korišćenjem
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 47 (2)
Napisati C program koji na osnovu unetog prirodnog broja n korišćenjem
rekurzivne funkcije faktorijal izračunava faktorijal prirodnog broja n. Faktorijel
prirodnog broja n računa se po formuli:
n! n (n 1) (n 2) ... 3 2 1
Zadatak 48 (3)
Napisati C program koji korišćenjem rekurzivne funkcije zbir izračunava zbir cifara
dekadnog prirodnog broja n.
Zadatak 49 (3)
Zadat je niz X od n elemenata (n<51). Napisati C program koji korišćenjem
rekurzivne funkcije zbir izračunava zbir elemenata niza X.
Zadatak 50 (3)
65
Napisati C program koji na osnovu unetog prirodnog broja n izračunava zbir prvih
n brojeva Fibonačijevog niza.
Fibonačijev niz ima sledeći izgled: 1 1 2 3 5 8 13 21 34 55 ...
Za računanje vrednosti k-tog člana Fibonačijevog niza koristiti rekurzivnu funkciju
fib.
Zadatak 51 (4)
Napisati C program koji izračunava korišćenjim rekurzivne funkcije rekdet
determinantu Dp oblika:
n m 0 0 . . . 0 0
k n m 0 . . . 0 0
0 k n m . . . 0 0
. . . . . . . . .
Dp . . . . . . . . . p , n , m, k N
. . . . . . . . .
. . . . . . . . .
0 0 0 0 . . . n m
0 0 0 0 . . . k n pxp
Zadatak 52 (4)
Formirati heder MOJEFUN.H gde će se nalaziti tvoje najčešće korišćene funkcije.
Formirati funkciju un_ceo koja onemogućava unos znaka koji nije cifra (0..9), a
završava se unosom kada se pritisne taster ENTER. Funkcija vraća uneti broj koji se
ispisuje na ekranu, a kursor se nalazi posle zadnje unete cifre. Demonstrirati korišćenje
funkcije pisanjem glavnog C programa (sadrži main funkciju).
Zadatak 53 (4)
Formirati funkciju un_rac i smestiti je u heder MOJEFUN.H koja onemogućava
unos znaka koji nije cifra (0..9) ili decimalna tačka, a završava se unosom kada se pritisne
taster ENTER. Funkcija vraća uneti broj koji se ispisuje na ekranu, a kursor se nalazi
posle zadnje unete cifre. Demonstrirati korišćenje funkcije pisanjem glavnog C programa
(sadrži main funkciju).
Zadatak 54 (4)
Formirati funkcije unos_niza i ispis_niza. Prilikom unosa niza koristiti funkciju
un_ceo koja se nalazi se u hederu MOJEFUN.H i smestiti je u heder NIZ.H.
Demonstrirati korišćenje funkcija pisanjem glavnog C programa (sadrži main funkciju).
Zadatak 55 (3)
Formirati funkcije minimum, maksimum i sort_niz i smestiti ih u heder NIZ.H.
Funkcija sort_niz može da sortira u rastućem ili opadajućem redosledu.
66
Demonstrirati korišćenje funkcija pisanjem glavnog C programa (sadrži main
funkciju).
Zadatak 56 (3)
Zadat je celobrojan niz X od n elemenata pri čemu je n paran broj i n<100. Napisati
C program koji korišćenjem funkcija unos_niza, ispis_niza i sort_niz koji se nalaze u
hederu NIZ.H, prvu polovinu zadatog niza sortira u opadajućem redosledu, a drugu
polovinu u rastućem redosledu.
Zadatak 57 (3)
Napisati C program koji korišćenjem raspoloživih funkcija iz hedera MOJEFUN.H
i NIZ.H omogućava unos racionalnog niza X od n elemenata (n<41) i utvrđuje koliko
elemenata niza ima vrednost veću od minimuma a manju od maksimuma niza.
Zadatak 58 (4)
Napisati funnkcije unos_dug_broja i ispis_dug_broja. Dugačak ceo broj se smešta
u niz pri čemu svaki element niza počev od drugog sadrži broj koji predstavlja cifru od 0
do 9, dok prvi element sadrži redni broj predznaka (+ ili -) iz ASCII tabele. Funnkcije
smestiti u heder MOJEFUN.H. Demonstrirati korišćenje funkcija pisanjem glavnog C
programa (sadrži main funkciju).
Zadatak 59 (5)
Napisati C program koji će korišćenjem funkcija saberi, oduzmi, ili mnozi po
izboru korisnika vrši sabiranje, oduzimanje ili množenje dva dugačka cela broja. Dugački
brojevi se nalaze smešteni u dva niza. Svaki element niza počev od drugog sadrži broj
koji predstavlja cifru od 0 do 9, dok prvi element sadrži redni broj predznaka (+ ili -) iz
ASCII tabele Takođe za unos cifre koristiti funkciju unceo koja omogućava unos znaka
iz intervala 0..9 i vraća ceo broj (0..9) ili -1 ako je pogrešno unet znak. Rezultat je takođe
dugačak ceo broj čije su cifre smeštaju u niz, po gore navedenom pravilu.
Sve napisane funkcije treba smestiti u hederu MOJEFUN.H.
Zadatak 60 (5)
Dopuniti "Zmijicu" iz 60 zadatka oblasti nizovi, tako da se koriste funkcije.
Program mora imati četiri nivoa:
Prvi nivo je zadatak 60 iz prošle glave stim
što igrač ima tri života, a igrač gubi život kada "Zmijica" sa glavom naiđe na samu sebe.
Drugi nivio dobija veliki vertikalni tunel, a
ako se naiđe na zid tunela gubi se život.
Treći nivo ima dva tunela: jedan
horizontalni i jedan vertilkalni, a "Zmijica" se dosta brže kreće nego što je to bio uslučaj
u prva dva nivoa.
Četvrti nivo ima dva tunela horizontalni i
vertikalni, "Zmijica" se još brže kreće, a posle svake pojedene hrane mora proći kroz
jedan od dva tunela, jer ako opet pojede hranu a nije prošla kroz tunel zmijica gine.
67
68
3. POGLAVLJE
VIŠEDIMENZIONALNI NIZOVI
69
3.1. VIŠEDIMENZIONALNI 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.
tip imeniza[MAX][MAX][MAX][MAX]…[MAX];
Na primer:
int matrica[3][4], trodniz[3][6][4];
Na primer ako posmatramo igricu minsko polje. Tada se svako polje može 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.
70
Sa pojmom matrica susrećete se i u matematici prilikom rešavanja sistema
jednačina. Opisana je sa dve dimenzije pri čemu se prva uvek odnosi na vrstu, a druga na
kolonu.
Na primer:
2 4 0 1
A 4 6 7 3
2 1 3 5 3 x 4
Matrica A ima tri vrste i četiri kolone. Deklaracija matrice A i ujedno njena inicijalizacija
s tim da matrica ima ovakav izgled je:
Za slučaj da smo hteli inicijalizovati matricu a da pri tome ne napišemo sve elemente, ne
obuhvaćenim elementima automatski bi se dodelila vrednost nula. Za slučaj da smo
deklarisali i inicijalizovali sa:
2 4 0 0
A 4 6 7 3
2 1 3 0 3 x 4
Na primer:
int a[3][4];
A00 A01 A02 A03 A10 A11 A12 A13 A20 A21 A22 A23
Iz primera se lako vidi kako je izvršena linearizacija matrice u memoriji.
71
Kao i kod jednodimenzionalnog niza ili vektora tako i kod višedimenzionalnih
nizova postoji prisna veza između pokazivača i niza.
Pristup odgovarajućem podatku matrice može se vršiti pomoću indeksa ili
pokazivača 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 može 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}};
Prvi način:
s=a[2][1]; - nakon ove naredbe dodele promenljiva s ima vrednost 1.
Drugi način:
int i=1, j=0;
s=a[i][j]; - nakon ove naredbe dodele s je 4.
Na primer:
int a[MAXV][MAXK];
Prototip funkcija koja koristi matricu a kao parametar imala bi sledeći izgled:
72
3.2. PROLASCI KROZ VŠEDIMENZIONALNI NIZ
Primer 1:
Zadata je matrica A dimenzije mxn ( m N , n N , m 10, n 10 ).. Napisati C
program koji izračunaa zbir elemenata matrice prolazeći kroz matricu vrsta po vrsta.
Rešenje
#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();
73
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&m);
}while(m<=0||m>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. */
/* 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();
}
74
Primer 2:
Zadata je matrica A dimenzije mxn ( m N , n N , m 10, n 10 ). Napisati C
program koji izračunva zbir elemenata matrice prolazeći kroz matricu kolona po kolona.
Rešenje
#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. */
75
/* 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. */
/* 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 ( n N , n 12) . 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 proširili za prvih n-1 kolonu. Iz razloga zanimljivosti
zadatka ne sme se vršiti proširivanje matrice.
Rešenje
#include<stdio.h>
#include<conio.h>
#define MAX 9
76
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();
77
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 N , n N , m 10, n 10 ). Napisati C
program koji bez korišćenja pomoćnih nizova ili matrica sažima matricu izbacivanjem
odgovarajuće i-te vrste i j-te kolone, pri čemu se i i j unose sa ulaza i
i [1..m], j [1..n] .
Rešenje
#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;
textmode(3);
textcolor(9);
textbackground(0);
clrscr();
78
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&m);
}while(m<=0||m>MAX);
79
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&q);
}while(q<=0||q>n);
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--;
}
80
3.3. VIŠEDIMENZIONALNI NIZOVI I FUNKCIJE
Primer 1:
Zadata je matrica A dimenzije mxn ( m N , n N , m 10, n 10 ). 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 različitu od minimalne i maksimalne vrednosti vrste.
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
Rešenje
#include<stdio.h>
#include<conio.h>
#define MAX 9
81
/* Prototipovi funkcija gde se vidi da se u prvoj dimenziji ne mora nista pisati, dok se u
drugoj dimenziji morala napisati dimenzija. */
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;
textmode(3);
textcolor(0);
textbackground(15);
clrscr();
82
printf(" ");
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 način 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();
}
/* 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];
}
83
return min;
}
for(j=1;j<n;j++)
{
if(a[i][j]>max) max=a[i][j];
}
return max;
}
/* 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;
}
84
Primer 2:
Napisati C program koji na osnovu celobrojne matrice A (dobijene korišćenjem
random funkcije) dimenzija nxn, (n je paran broj i n<10), formira niz B na osnovu slike:
S1i
S12
S1
3
A za n = 6
S2 3
S 22
S 21
S1i – je zbir elemenata matrice A na gornjem i-tom ugaoniku, a
S2i – je zbir elemenata matrice A na donjem i-tom ugaoniku,
n
pri čemu i1.. .
2
Niz B se formira po formuli:
S1i S1i S 2i
bi
S 2i u suprotnom
Za računanje zbira S1i i S2i koristiti funkciju zbir.
Rešenje:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
85
#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();
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;
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;
}
86
/* Izracunavanje trazenog zbira. */
while(j!=m)
{
s=s+a[k][j]+a[j][k];
j+=q;
}
return s;
}
Primer 3:
Data je matrica A dimenzije mxn ( m N , n N , m 10, n 10 ). Napisati C
program koji bez korišćenja pomoćnih nizova ili matrica vrši sortiranje matrice desnom
spiralom u rastućem redosledu.
Rešenje
#include <stdio.h>
#include <conio.h>
#define MAX 9
int minimum(int a[][MAX],int m,int n,int k,int i,int j,int p,int str,int *q, int *w);
void main(void)
{
int a[MAX][MAX],m,n,min,pom,q,w;
int i,j,p,xu,yu,kon,k,xp=5,yp=5;
for(i=0;i<MAX;i++)
{
for(j=0;j<MAX;j++) a[i][j]=0;
}
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
87
xu=wherex();
yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&n);
}while(n<=0);
p=1;
kon=0;
k=0;
while(kon==0)
{
/*Svaki krug spirale pocinje sa glavne dijagonale.*/
i=j=k;
while(j<n-k&&kon==0)
{
/* Funkcija minimum odredi minimum od trenutnog elementa na spirali
do kraja spirale, po vrednosti vrati minimum, a po referenci odredi
pozicije prvog minimuma. */
min=minimum(a,m,n,k,i,j,p,1,&q,&w);
88
j--, i++;
while(i<m-k&&kon==0)
{
min=minimum(a,m,n,k,i,j,p,2,&q,&w);
a[q][w]=a[i][j];
a[i][j]=min;
if(p==m*n) kon=1;
p++, i++;
}
j--, i--;
while(j>=k&&kon==0)
{
min=minimum(a,m,n,k,i,j,p,3,&q,&w);
a[q][w]=a[i][j];
a[i][j]=min;
if(p==m*n) kon=1;
p++, j--;
}
j++, i--;
while(i>k&&kon==0)
{
min=minimum(a,m,n,k,i,j,p,4,&q,&w);
a[q][w]=a[i][j];
a[i][j]=min;
if(p==m*n) kon=1;
p++, i--;
}
i++, j++;
k++;
}
getch();
}
89
int minimum(int a[][MAX],int m,int n,int k,int i,int j,int p,int str,int *q, int *w)
{
int min,pom;
unsigned kon;
min=a[i][j];
*q=i,*w=j;
kon=0;
while(kon==0)
{
switch(str)
{
case 1: while(j<n-k&&kon==0)
{
if(a[i][j]<min) min=a[i][j],*q=i,*w=j;
if(p==m*n) kon=1;
p++;
j++;
}
j--, i++, str++;
break;
case 2: while(i<m-k&&kon==0)
{
if(a[i][j]<min) min=a[i][j],*q=i,*w=j;
if(p==m*n) kon=1;
p++, i++;
}
j--, i--, str++;
break;
case 3: while(j>=k&&kon==0)
{
if(a[i][j]<min) min=a[i][j],*q=i,*w=j;
if(p==m*n) kon=1;
p++, j--;
}
j++, i--, str++;
break;
case 4: while(i>k&&kon==0)
{
if(a[i][j]<min) min=a[i][j],*q=i,*w=j;
if(p==m*n) kon=1;
p++, i--;
}
i++, j++, str=1;
90
k++;
}
}
return min;
}
Primer 4:
Napisati C program koji omogućava 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, nerešenih, poraza, datih golova, primljenih golova i broja
osvojenih bodova na polusezoni. Potom se unose rezultati utakmica drugog dela sezone,
(vodeći pri tome računa ko je domaćin a ko gost) i ispisuje tabela na kraju sezone pri
čemu su u tabeli odgovarajućim bojama vrste označene ekipe koje:
Rešenje
#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;
91
/* Inicijalizacija matrice golova. */
for(i=0; i<MAX; i++)
for(j=0; j<MAX; j++) a[i][j]=0;
textmode(64);
textcolor(0); textbackground(15);
clrscr();
do{
clrscr();
printf("\n\tBroj klubova: ");
scanf("%d", &n);
}while(n<4 || n>MAX);
printf("\n\n\tUnesite rezultate 1. dela");
xu=wherex()-26, yu=wherey()+1;
sortiranje(n,tabela,a,1);
for(i=0;i<n+1;i++)
92
{
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("╝");
/* 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. */
gotoxy(45,yu-1);
printf("Unesite rezultate 2. dela");
xu=wherex()-25,yu=wherey()+1,yi-=2;
if(n<7) gotoxy(1,yi);
else gotoxy(1,yu+3+n*(n-1)/4);
/* Oznacavanje odredjenom bojom ekipe koja ide u kup sampiona, ekipa koje idu
u kup uefa i ekipa koje napustaju drustvo najboljih. */
93
for(i=0;i<n+1;i++)
{
/* Oznaka ekipe za kup sampiona. */
if(i==0)
{
textbackground(BLUE);
textcolor(15);
gotoxy(65,yt+i+2);
cprintf(" ");
}
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. */
94
int ispis(int n, int tabela[][REZ],int xi, int yi, int koji)
{
int i,j;
/* 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. */
if(br>n*(n-1)/4+1) gotoxy(xu+17,yu-1+br%(n*(n-1)/4+1));
else gotoxy(xu-1,yu+br);
95
deo. Tako se mora izvrsiti i prikaz ekipa (domacin : gost)
da se korisnik programa ne bi zbunio. */
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++;
}
}
}
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++)
96
{
pom=tabela[i][k];
tabela[i][k]=tabela[j][k];
tabela[j][k]=pom;
}
}
}
}
}
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]++;
tabela[i][DATI]+=a[i][j];
tabela[i][PRIM]+=a[j][i];
}
}
}
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];
97
tabela[i][k]=tabela[j][k];
tabela[j][k]=pom;
}
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;
}
}
}
}
}
98
3.4. ZADACI IZ VIŠEDIMENZIONALNIH
NIZOVA
Zadatak 1 (2)
Zadata je kvadratna matrica A dimenzije n ( n N , n 12) . Napisati C program koji
utvrđuje koliko elemenata matrice A ima pozitivnu vrednost.
Zadatak 2 (2)
Zadata je kvadratna matrica A dimenzije n ( n N , n 12) . Napisati C program koji
utvrđuje koliko elemenata matrice je veće od maksimalnog elementa na glavnoj
dijagonali.
Zadatak 3 (2)
99
Zadata je kvadratna matrica A dimenzije n ( n N , n 12) . 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 ( n N , n 12) . Napisati C program koji
vrši zamenu elemenata glane dijagonale sa elementima sporedne dijagonale.
Zadatak 5 (2)
Zadata je kvadratna matrica A dimenzije n ( n N , n 12) . Napisati C program koji
vrši zamenu elemenata prve i zadnje kolone.
Zadatak 6 (2)
Zadata je kvadratna matrica A dimenzije n ( n N , n 12) . 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 utvrđuje koliko elemenata matrice A dimenzije mxn ( m
N , n N , m 10, n 10 ) predstavlja ujedno najmanji element svoje vrste i kolone.
Zadatak 8 (2)
Zadata je matrica A dimenzije mxn ( m N , n N , m 10, n 10 ). Napisati C
program koji vrši sortiranje matrice A vrsta po vrsta.
Zadatak 9 (2)
Zadata je matrica X dimenzije mxn ( m N , n N , m 10, n 10 ). Napisati C
program koji na osnovu matrice X formira niz Z u koji ulaze redom minimalne vrednosti
kolona. Za određivanje minimalne vrednosti kolone koristiti funkciju minmkolone.
Zadatak 10 (2)
Napisati C program koji na osnovu matrice A dimenzije mxn ( m
N , n N , m 10, n 10 ) formira matricu B dimenzije (m-1)xn tako što se iz matrice A
u matricu B ne upisuje ona vrsta koja ima najveći zbir elemenata.
Zadatak 11 (2)
Napisati C program koji na osnovu unetog prirodnog broja n formira kvadratnu
matricu X dimenzije nxn ( n N , n 12) sledećeg izgleda:
1 2 3 n
0 1 2 n 1
A
0 0 0 0 0 0 1
Zadatak 12 (3)
100
Data je matrica A dimenzije mxn ( m N , n N , m 10, n 10 ). Napisati C
program koji bez korišćenja pomoćnih nizova ili matrica sažima matricu izbacivanjem
odgovarajuće i-te vrste i j-te kolone, pri čemu se i i j unose sa ulaza i
i [1..m], j [1..n] .
Zadatak 13 (3)
Napisati C program koji na osnovu unetog prirodnog broja n formira kvadratnu
matricu A dimenzije nxn ( n N , n 12) sledećeg izgleda:
1 n n 1 2
2 1 n 3
A 3 2 1 4
n n 1 n 2 1
Zadatak 14 (3)
Napisati C program koji na osnovu unetog prirodnog broja n formira kvadratnu
matricu A dimenzije nx2n ( n N , n 12) sledećeg izgleda:
1 2 3 n n 3 2 1
n 1 2 n 1 n 1 2 1 n
A
2 3 4 1 1 4 3 2
Matrica A se formira vrsta po vrsta korišćenjem funkcije formirajvrstu.
Zadatak 15 (3)
Napisati C program koji na osnovu matrice A dimenzije nxn ( n N , n 12) , pri
čemu se elementi matrice unose sa jednog polja i stalno se ima vizuelni prikaz formiranja
matrice (na samom početku 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 sledeći način:
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)
101
.
.
.
b(n) = a(n,n)
Zadatak 16 (3)
Napisati C program koji omogućava unos matrice A dimenzije mxn ( m
N , n N , m 10, n 10 ) i sortira njene kolone u rastućem ili opadajućem redosledu.
Kolona j se sortira u opadajućem 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 rastućem redosledu pri čemu j uzima vrednost sa intervala [1..n]. Za
sortiranje elemenata kolona koristiti funkciju sortkol, a za pronalaženje sredenje
vrednosti koristiti funkciju srednja. Na ekranu štampati preuređenu matricu A.
Zadatak 17 (3)
Napisati C program koji vrši sortiranje matrice A dimenzije mxn ( m
N , n N , m 10, n 10 ) vrsta po vrsta, na osnovu maksimalnog zbira po vrstama. Za
izračunavanje zbira elemenata vrste koristiti funkciju zbirvrste. Za sortiranje matrice A
vrsta po vrsta koristiti funkciju sortmatrice.
Napomena: Prilikom realizacije programa ne smeju se koristiti pomoćni nizovi ili
matrice.
Zadatak 18 (4)
Napisati C program koji na osnovu unetih prirodnih brojeva m i n koji sui manji od
sedam, korišćenjem generatora pseudoslučajnih jednocifrenih ili dvocifrenih prirodnih
brojeva formira matrice Amxn, a potom utvrđuje zonu određenu 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 sadržati minimalno četiri elementa matrice A. U slučaju da više 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 N , n N , m 10, n 10 ). U matrici veliki
broj elemenata ima vrednost nula. Napisati C program koji određuje i štampa najmanji
broj nula po vrstama odnosno kolonama. Za određivanje broja nula u pojedinoj vrsti ili
koloni koristiti funkciju brojnula.
Na primer:
Ako matrica A ima sledeći 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
102
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, korišćenjem generatora pseudoslučajnih jednocifrenih prirodnih brojeva
formira matrice Amxn i Bmxk, a potom vrši 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 određuje determinantu matrice A.
Determinanta matrice se određuje postupkom kojim se matrica transformiše da svi
elementi ispod glavne dijagonale imaju vrednost nula i tada proizvod elemenata na
glavnoj dijagonali predstavlja determinantu matrice.
Zadatak 22 (4)
Napisati C program koji za svakog studenta učitava broj indeksa i osvojene bodove
sa tri zadatka A, B i C, a zatim izračunava ukupan broj osvojenih bodova i na osnovu
toga pozivom funkcije ocena određuje zaključnu ocenu.
Obezbediti da se reziltati štampaju po opadajućoj vrednosti broja bodova u obliku:
1. 5653 20 30 30 80 8
2. 5555 25 25 22 72 7
.
103
.
.
Zadatak 23 (4)
Napisati C program koji korišćenjem generatora pseudoslučajnih jednocifrenih
prirodnih brojeva i unetog prirodnog broja n formira kvadratnu matricu dimenzije nxn,
n<10. Program utvrđuje koja dijagonala paralelna glavnoj dijagonali ima najviše
proizvoljno ponovljenoh elemenata (na primer ako se na i-toj dijagonali nalaze sledeći
elementi 5 3 1 1 5 5 6 1 i 5, traženi broj ponavljanja je 4 jer se među različitim
brojevima 5 3 1 i 6 broj 5 najviše puta ponovio i to 4 puta). Za određivanje traženog
broja jedne dijagonale koristiti funkciju odredi.
Broj dijagonala je n a kreće se od glavne dijagonale kao prve a naredne se dobijaju
redom iz gornjeg trougla matrice. Svaka dijagonala ima tačno po n elemenata (u slučaju
da ima n-3 elementa dopunjava se sa odgovarajućom dijagonalom iz donjeg trougla
matrice koja ima 3 elementa).
Zadatak 24 (4)
Data je matrica A dimenzije mxn ( m N , n N , m 10, n 10 ). Napisati C
program koji bez korišćenja pomoćnih nizova ili matrica određuje redni broj vrste koja
sadrži najviše različitih elemenata. Za određivanje broja različitih elemenata vrste
koristiti funkciju brojrazvrste.
Zadatak 25 (4)
Podaci o dizačima tegova jednog turnira smeštaju se u matricu DIZACI3xN pri
čemu je N broj dizača koji su učestvovali na turniru. U matrici A i-ta kolona sadrži
podatke za i-tog dizača tegova u istoj težinskoj kategoriji. Prvi podatak u koloni je težina
koju je takmičar podigao u dizanju sa trzajem, drugi je težina koju je takmičar podigao u
dizanju sa izvlačenjem, a treći je telesna težina takmičara.
U slučaju istih podataka, uzima se da je uspešniji takmičar manje telesne težine.
Napisati C program koji ispisuje redni broj dizača koji je šampion: u prvoj kategoriji,
drugoj kategoriji i u obe kategorije (zbir težina) u ukupnom plasmanu.
Zadatak 26 (5)
Napisati C program koji matricu A dimenzije mxn ( m N , n N , m 10, n 10 )
formira korišćenjem generatora pseudoslučajnih jednocifrenih ili dvocifrenih prirodnih
brojeva, a zatim po izboru korisnika vrši rotaciju matrice za 90 0, 1800 ili 2700.
korišćenjem funkcija rot90, rot180 ili rot270.
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 računa da li je n paran ili neparan broj što može uticati na
formiranje matrice.
Na primer:
Za n = 5 matrica A ima sledeći izgled:
104
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 igrača. Pozicije polja na tabli numerisani su
brojevima od 1 do 9 o što moraju znati i igrači. 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 završena nerešeno. Program realizovati
matricom A koja je dimenzije 60x50, koliko ima i polja za igru. Ako je vrednost člana 0
znači da niko od igrača do tada nije osdigrao potez na tom polju, ako je vrednost 1 na tom
polju je ranije već odigran potez od strane igrača "O", a ako je vrednost 2 na tom polju je
ranije već odigran potez od strane igrača "X". Igra se može završiti i ranije ako neko od
igrača odigra nulu kao potez sa numeričke tastature, i tada se na ekranu ispisuje koji je
igrač predao partiju.
Zadatak 29 (5)
Napisati C program koji omogućava formiranje matrica Amxn i Bkxp te po izboru
korisnika izračunava i prikazuje: zbir, razliku ili proizvod matrica A i B.
Funkcijom prikaziizbor treba prikazati sledeću 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: _ *
*********************************
Funkcija prikaziizbor omogućava da korisnik izabere jednu od ponuđenih opcija i
vraća redni broj izabrane opcije.
Funkcija unos matrica omogućava unos matrica A i B pri čemu se prvo unose
dimenzije matrice A uz ispisan opseg vrednosti promenljivih m i n, a potom se
omogućava 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 način se frmira i matrica B. Funkcija nakon unosa vraća
vrednost 1 ako je unos uspešno urađen.
105
Funkcija sabiranjematrica omogućava da se saberu matrice A i B ako je to
moguće. U slučaju da je sabiranje moguće funkcija vraća 1 a u suprotnom 0. Matrice se
mogu sabrati ako imaju iste dimenzije i ako su prvo unesene matrice. Na ekranu ispisati
odgovarajuću poruku zašto se matrice nisu mogle sabrati.
Funkcija oduzimanjematrica omogućava da se oduzmu matrice A i B ako je to
moguće. U slučaju da je oduzimanje moguće funkcija vraća 1 a u suprotnom 0. Matrice
se mogu oduzeti ako imaju iste dimenzije i ako su prvo unesene matrice. Na ekranu
ispisati odgovarajuću poruku zašto se matrice nisu mogle oduzeti.
Funkcija mnozenjematrica omogućava da se pomnože matrice A i B ako je to
moguće. U slučaju da je množenje moguće funkcija vraća 1 a u suprotnom 0. Matrice se
mogu pomnožiti ako je broj vrsta matrice A jednak broju kolona matrice B. Rezultujuća
matrica imaće broj vrsta jednak broju vrsta matrice A i broj kolona jednak broju kolona
matrice B. Matrice moraju prvo biti unesene. Na ekranu ispisati odgovarajuću poruku
zašto se matrice nisu mogle pomnožiti.
Zadatak 30 (5)
Napisati C program koji predstavlja igricu “pogodi“. Igra je namenjena za samo
jednog igrača. 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 kreće sve dok se ne pritisne SPACE. Nakon pritiska na
SPACE klizač prestaje da se kreće iz iz njega na dole spušta se loptica. Loptica može da
se kreće samo kroz tunele, na dole slobodnim padom, ako naiđe na kosa crta na desno da
se kreće na desno sve dok ne naiđe do kraja table ili na rupu na dole, ili ako naiđe na kosa
crta na levo da se kreće na levo sve dok ne naiđe 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 počinje da se kreće i ako se spusti na neki broj taj broj promeni boju tako da je
vidno da je pogođen. Ako kuglica udari u jedan od zidova kugla nije ništa uradila i klizač
ponovno počinje sa kretanjem. Tabla se može (ne uključujući liniju sa klizačem i liniju
sa brojevima) rorirati za jedno mesto cirkularno na gore ili za jedno mesto cirkularno na
dole (upravljanje se vrši sa strelicama na gore ili strelicama na dole). Rotiranje table
može se vršiti samo dok se klizač kreće (tj nema loptice da se kreće kroz tablu). Ako
igrač sa lopticom pogodi već pogođeno mesto (broj je označen svetlom bojom) broj
potamni tako da izgleda kao da ranije nije ni pogodio to polje. Na raspolaganju igrač ima
deset pokušaja da pređe tablu.
Problem se rešava sa statičnom matricom koja se mora dobro osmisliti tako da igra
ima smisla.
106
107
4. POGLAVLJE
STRINGOVI
108
4.1. STRINGOVI
Definicija stringa:
String je niz znakova koji se završava znakom '\0'. Prazan string sadrži samo
znak '\0'.
Deklaracija stringa:
char imestringa[MAX];
Inicijalizacija stringova:
Unos stringa:
Unos stringa se najčešće vrši bez indeksa, kao što je to
slučaj kod niza, a uz pomoć funkcija scanf ili gets.
109
Format %s označava konverziju u string. Funkcija fgets omogućava unos
stringa sve dok se ne pritisne ENTER i time dodaje znak '\0'. Ako funkcija naiđe na
grešku prilikom unosa vraća simboličku konstantu NULL.
Ispis stringa:
Ispis stringa se najčešće vrši bez korišćenja indeksa (za
razliku od niza) a uz pomoć funkcija printf ili puts.
Funkcija puts izvršava ispis znakova sve dok se ne dođe do znaka '\0' i prelazi
u novi red.
Primer 1:
Napisati C program koji omogućava unos stringa s i utvrđuje
koliko se puta znak c nalazi u stringu s. Znak c se unosi sa tastature.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h> /* U ovoj biblioteci se nalai funkcija fgets. */
#define MAX 30
void main(void)
{
char c, s[MAX];
unsigned i,br=0;
s[0]='\0'; /* Inicijalizacija stringa s. */
textmode(3);
textcolor(0);
textbackground(15);
clrscr();
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. */
}
110
printf("\n\nBroj pojave = %d.",br);
getch();
}
Primer 2:
Napisati C program koji vrši sažimanje stringa s, tako što se uzastopni višestruki niz
praznina zamenjuje sa samo jednom prazninom.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAX 30
void main(void)
{
char c, s[MAX];
unsigned i,j;
s[0]='\0';
textmode(3);
textcolor(0);
textbackground(15);
clrscr();
printf("String = ");
gets(s);
111
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++;
}
}
}
printf("\n\nNovi string = %s",s); /* Ispis novog stringa. */
getch();
}
112
4.2. STRINGOVI I FUNKCIJE
Kao i kod nizova string se ne može preneti kao argument funkcije, već se po
referenci prosleđuje adresa početka stringa. Za rad sa stringovima u funkcijama
osim adrese početka stringa ništa više nije potrebno, jer se string završava 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 biće ponovno ispisan.
Primer 1:
Napisati funkciju unos koja omogučava unos imena. Završetak unosa imena je
pritisak na taster ENTER. Ako korisnik unese neki karakter koji nije slovo, osim praznog
mesta, string će se izbrisati i moraće se izvršiti ponovni unos. Prvom slovo mora bitio
veliko, a ako nije funkcija prvo slovo konvertuje u veliko slovo.
Napisati C program koji demopnstrira primenu funkcije unos.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void)
{
/* Deklaracija stringa. */
char str[30]= "";
textmode(3);
textbackground(0);
textcolor(15);
clrscr();
printf("Unesite ime: ");
unos(str);
/* Definisanje funkcije. */
113
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;
if(c!='\r')
{
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 aritmetički izraz sa
zagradama, a zatim određuje njegova vrednost. Operandi u izrazu su celi brojevi, a
operacije mogu biti (+,-,* i /) pri čemu je / celobrojno deljenje. Pri određivanju vrednosti
izraza voditi računa 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
između dve zagrade sa najvećim prioritetom) i zagrada između kojih se izraz nalazio.
Rešenje
114
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
/* 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(15);
textcolor(0);
clrscr();
printf("Unesite izraz:\n");
gets(s);
brisipraznineitabulatore(s);
printf("\n = %s",s); /* Prikaz stringa s bez praznina i tabulatora. */
izraz1(s);
getch();
}
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++;
115
/* 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++;
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)
{
k=1;
while(s2[k]!='\0') s2[k-1]=s2[k],k++;
s2[k-1]='\0';
116
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')
{
if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/') br++;
i++;
}
if(br==1&&s[0]=='-') br--;
}while(br>0);
return s;
}
/* Prvo utvrdimo koliko dati izraz sadrzi operatora. Krece se od drugog znaka jer moze se
desiti da prvi znak bude predznak broja a on ne cini operator. */
i=1;
while(s[i]!='\0')
117
{
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. */
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);
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')
118
{
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'. */
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{
119
/* Deljenje sa nulom. */
printf("ERROR");
exit(1);
}
}
return rez;
}
/* 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;
/* 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++;
}
120
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++;
}
}
121
4.3. STRINGOVI I POKAZIVAČI
s[i] *(s + i)
Primer 1:
Napisati C program koji omogućava unos stringa i korišćenjem funkcije duzina
određuje dužinu stringa. Dužinu stringa pretstavlja broj znakova stringa bez znaka '\0'.
Prilikom realizacije funkcije nemojte koristiti lokalne promenljive (samo formalne
argumente) kao ni bilo koju bibliotečku funkciju.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAX 30
void main(void)
{
char s[MAX];
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
printf("\n\tString = ");
gets(s);
122
/* Funkcija izracunava duzinu stringa, a kako se ne smeju koristiti lokalne promenljive
prosledili smo jos jedan parametar koji pretstavlja brojac karaktera. */
/* 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 omogućava brisanje dela stringa pomoću funkcije brisi.
Funkcija brisi omogućava brisanje dela stringa s između indeksa k i p, uključujući i
karaktere koji se nalaze na tim indeksima Funkcija vraća 1 ako je uspešno obavila posao
ili 0 u suprotnom. Prilikom realizacije funkcije nemojte koristiti lokalne promenljive
(samo formalne argumente) kao ni bilo koju bibliotečku funkciju osim funkcije duzina iz
prošlog zadatka.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAX 30
void main(void)
{
char s[MAX];
int k, p;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
printf("\n\tString = ");
gets(s);
123
printf("\tk = ");
scanf("%d",&k);
printf("\tp = ");
scanf("%d",&p);
gotoxy(1,25);
getch();
}
/* 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;
while(*(s+p-k+1))
{
*s=*(s+p-k+1);
*s++;
}
*s='\0';
return 1;
}
Primer 3:
Napisati C program koji poredi dva stringa korišćenjem funkcije poredi. Funkcija
poredi poredi string s kao prvi argument sa stringom t koji je drugi argument funkcije i
vraća: 0 – ako su stringovi isti, pozitivna vrednost ako je s>t, ili negativnu vrednost ako
je s<t. String s je veći 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 ASCII tabele) karaktera iz stringa s
imao veću 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 bibliotečku funkciju.
Rešenje
124
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAX 30
void main(void)
{
char s[MAX], t[MAX];
int k;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
k=poredi(s,t);
if(k<0) printf("\n\n\tPrvi string je manji od drugog stringa!!");
else{
if(k==0) printf("\n\n\tStringovi su jednaki!!");
else printf("\n\n\tPrvi string je veci od drugog stringa!!");
}
gotoxy(1,25);
getch();
}
/* Dokle god su karakteri iz stringova jednaki i nismo dosli do kraja niti jednog
stringa ciklus se izvrsava. */
return *s - *t;
}
125
4.4. OSNOVNE FUNKCIJE ZA RAD SA ZNAKOVIMA I
STRINGOVIMA
Funkcija isalnum vraća vrednost različitu od nule ako je navedeni znak character
slovo ili cifra.
Funkcija isalpha vraća vrednost različitu od nule ako je navedeni znak slovo.
Funkcija isdigit vraća vrednost različitu od nule ako je navedeni znak character
cifra.
Funkcija isgraph vraća vrednost različitu od nule ako se navedeni znak character
može prikazati na ekranu (opseg kodova od 33 do 126) izuzimajući znak za razmak.
126
int islower(int caracter);
Funkcija islower vraća vrednost različitu od nule ako je navedeni znak character
malo slovo.
Funkcija isupper vraća vrednost različitu od nule ako je navedeni znak character
veliko slovo.
Funkcija isspace vraća vrednost različitu od nule ako je navedeni znak character
nevidljiv na ekranu (tabulator, vertikalni tabulator,...)
Funkcija isprint vraća vrednost različitu od nule ako se navedeni znak character
može prikazati na ekranu.
Funkcija toupper konvertuje malo slovo u veliko. Ako je navedeno slovo character
veliko funkcija ga ostavlja nepromenjenim.
Funkcija tolower konvertuje veliko slovo u malo. Ako je navedeno slovo character
malo funkcija ga ostavlja nepromenjenim.
127
Osnovne funkcije za rad sa stringovima
Funkcija strcpy kopira string t u string s znak po znak. Prethodni sadržaj stringa s se
gubi. Funkcija vraća pokazivač na string s.
Funkcija strcmp poredi dva stringa znak po znak. Ako je znak u prvom stringu s
veći od odgovarajućeg znaka u drugom stringu t, funkcija vraća negativnu vrednost. Ako
su stringovi indentični funkcija vraća 0.
Funkcija strncmp poredi prvih n bajtova dva niza znakova. Funkcija je identična
funkcija strcmp, stim što poredi samo prvih n karaktera.
Funkcija strchr traži prvo pojavljivanje navedenog ASCII znaka character u stringu
s, te ako uspešno obavi zadatak funkcija vraća pokazivač na prvo pojavljivanje
navedenog znaka ili vrednost NULL u suprotnom.
128
char *strrchr(char *s, int character);
Funkcija strchr vraća pokazivač na prvu pojavu određenog znaka character s desne
strane stringa s. Ako funkcija uspešno obavi zadatak biće vraćen pokazivač na prvu
poziciju unutar stringa, ili vrednost NULL u suprotnom.
Funkcija strstr vraća pokazivač na prvu pojavu podstringa t unutar stringa s. Ako
uspešno obavi zadatak funkcija vraća pokazivač na prvu pojavu podstringa, ili vrednost
NULL u suprotnom.
Funkcija strlen vraća dužinu stringa s u bajtovima, tj broj znakova stringa bez
znaka '\0'.
129
4.5. NIZ POKAZIVAČA NA STRINGOVE
Niz pokazivača na stringove pretstavlja niz koji sadrži adrese prvih članova
(početne adrese) stringova.
Na primer:
char *imena[3]={ "Petar","Misa","Slavko"};
P e t a r \0 M i s a \0 S l a v k o \0
imena
for(i=0;i<MAX;i++) niz[i]=NULL;
130
Mora se obezbediti da prvi pokazivač iz niza pokazivača pokazuje na neki prostor
u memoriji koji je dosta veliki (u stanju je da reši bilo koji slučaj).
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'. */
if(i!=0) niz[i]=niz[i-1]+strlen(niz[i-1])+1;
gets(s)
strcpy(niz[i],s);
}
131
Primer 1:
Napisati C program koji omogućava unos imena i prezimena n osoba n<31, a
potom vrši njihovo sortiranje po abecednom redosledu. Prilikom realizacija zadatka
koristiti niz pokazivača na stringove. Unos imena i prezimena vršiti odvojeno
korišćenjem funkcije unos. Funkcija unos prvo slovo imena ili prezimena pretvara u
veliko a sva ostala u mala slova. Unos imena ili prezimena završava se pritiskom na
SPACE, ENTER ili TAB. Ako se unese karakter koji nije slovo funkcija trazi ponovni
unos imena ili prezimena (jer je nastala greška).
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAX 30
#define VELIKI_PROSTOR 5000
void main(void)
{
/* Deklaracija promenljivih. */
char *niz[MAX], s[MAX], pom[MAX], c[VELIKI_PROSTOR], *pom1=c;
unsigned i, j, xu, yu;
int n;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
132
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);
unos(pom);
strcat(s,pom);
strcpy(niz[i],s);
printf("\n");
}
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;
}
}
}
printf("\nSortirana imena\n");
printf("Prezime i Ime:\n--------------\n");
for(i=0;i<n;i++) printf("%s\n",niz[i]);
getch();
}
133
xp=wherex(), yp=wherey();
do{
c=getch();
if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))
{
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 izvršen samo unos imena pomoću niza pokazivača imena (redom
Petar, Misa i Slavko) imaćemo sledeću sliku.
P e t a r \0 M i s a \0 S l a v k o \0
134
imena
pom1
Zona u memoriji gde su smšeteni stringovi jedan iza drugog
P e t a r \0 M i s a \0 S l a v k o \0
imena
Primer 2:
Napisati C program koji omogućava unos stringa u formatu:
String = "brv/brk/string_od_slova"
M o p _ i m
i z _
s l e
l i t i \0 c
i m _ d a _
135
Rešenje
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 80
textmode(3);
textbackground(15);
textcolor(0);
clrscr();
/* Izdvaja se deo stringa do znaka '/'. Taj string pretstavlja broj vrsta matrice, te se
funkcijom atoi dati string konvertuje u broj. */
c=strtok(s1,"/");
m=atoi(c);
c=strtok(NULL,"/");
n=atoi(c);
136
if(s[i]=='/') k=i;
i++;
}
/* 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';}
}
}
137
if(s[i]=='_') s[i]=' ';
i++;
}
s[k]='\0';
gotoxy(1,25);
getch();
}
138
4.6. MAKROI I FUNKCIJE SA PROMENLJIVIM
BROJEM ARGUMENATA
Makroi:
Definisanje makroa:
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
Prvi primer smo već ranije koristili za definisanje simboličke konstante. Nakon
indentifikatora MAX koji je napisan velikim slovom jer je indentifikator makroa
(poželjno je da je velikim slovom ispisan, iako prevodilac prihvata da je malo), sledi niz
simbola, a to je u ovom slučaju broj 30. Tokom celog programa gde god se pojavi
indentifikator MAX prevodilac će ga zamenjivati brojem 30. Niz simbola ne sme se
završiti sa znakom tačka zarez.
Drugi primer koristi blok jer se niz simbola ne sme završiti znakom tačka zarez.
Dugačak niz simbola, koji se ne može napisati u jednom redu znakom '/' na kraju reda
označava da je nastavak u sledećem redu. Makro može da se zamenjuje nekim delom
složene upravljačke strukture (da osim funkcija sadrži selekcije i cikluse).
Kod prvog i drugog primera makroi se pozivaju navođenjem imena makroa iza
koga ne mora pisati znak tačka zarez.
139
Treći primer koristi makro MAXBROJ koji slično funkcijama sadrži formalne
argumente a i b. Stvarni argument se prosleđuju formalnim argumentima izračuna se
izraz i vrednost se nalazi u indentifikatoru makroa. U ovom slučaju biće vraćena vrednost
argumenta a ili b.
Osnovna razlika između poziva makroa i poziva funkcije je u tome što se prilikom
poziva makroa tip argumenta makroa može biti proizvoljan. Makroi se zamenjuju još
pre prevođenja izvornog programa, dok funkcije postoje i za vreme izvršenja programa.
Za razliku od funkcija gde se prvo izračunala vrednost izraza, pa se vrednost prosledila
formalnom argumentu funkcije, kod poziva makroa to nije slučaj, već se ceo izraz
prosleđuje formalnom argumentu i kao takav učestvuje u nizu simbola.
Ako funklcije i makroi mogu da prime ulazne vrednosti putem parametara šta
kada koristiti?
140
se izvrši kod koga prevodilac proizvodi pojavljuje u programu samo jednom, a može se
pozivati proizvoljan broj puta bez ikakvog povećanja programa.
Na primer:
Prototip funkcije prikaz koja ima četiri obavezna formalna argumenta.
int prikaz(int x, int y, int br, char *text,...);
Standardno zaglavlje stdarg.h sadrži skup definisanih makroa koje definišu kako se
prolazi kroz listu neformalnih argumenata. Tip va_list se koristi za deklarisanje
promenljive ap (skraćeno od argument pointer) koja redom ukazuje na svaki neobavezni
argument funkcije.
va_list ap;
141
Makro va_start inicijalizuje pokazivačku promenljivu ap tako da pokazuje na prvi
neobavezni argument. Makro va_start se mora pozvati jedanput pre korišćenja
pokazivača ap.
va_start(ap, indentifikator_poslednjeg_obaveznog_argumenta);
Svaki poziv makroa va_arg vraća jedan argument i pomera pokazivač ap na
naredni argument.
va_arg(ap, tip);
va_end(ap);
Primer:
Napisati C program koji demonstrira koriscenje funkcije zbir sa promenljivim
brojem argumenata. Funkcija zbir izračunava zbir uzastopnih celih argumenata i nakon
toga zbir uzastopnih racionalnih argumenata.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <stdarg.h>
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(0);
textbackground(15);
clrscr();
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);
142
gotoxy(1,25);
getch();
}
va_start (ap,*s2);
for(i=1;i<=brc;i++) *s1+=va_arg(ap,int );
for(i=1;i<=brr;i++) *s2+=va_arg(ap,double );
va_end(ap);
}
143
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)
Aritmetički izraz unet sa tastature zapisan je u stringu s. Napisati C program koji
utvrđuje broj pojavljivanja aritmetičkih operatora (+,-,* i /) u izrazu.
Zadatak 3 (2)
Napisati funkciju koja iz stringa s briše svako pojavljivanje slova c. Funkcija vraća
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
vrši zamena uneti sa tastature.
Za realizaciju zamene koristiti funkciju zameni koja vraća broj izvršenih zamena.
Na ekranu prikazati novonastali string, kao i broj izvršenih zamena.
Na primer:
c=nd=m
String = Mislin da ni je zadatak iz stringa dosao kao kec na deset.
Zadatak 5 (3)
Napisati funkciju koja vraća pokazivač na prvo pojavljivanje određenog znaka c
s desne strane stringu s, ili NULL ako slova c nema u stringu s.
Zadatak 6 (2)
144
Napisati C program koji utvrđuje koliku u strigu s ima znakova interpunkcije: tačka,
zarez, tačka zarez, znak pitanja i znak uzvika. Za određivanje pojave određenog znaka
interpunkcije koristiti funkciju odredi. Na ekranu se prikazuje broj pojavljivanja onih
znakova interpunkcije kojih je bilo uopšte 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 višestruki niz praznina zamenjuje sa samo
jednom prazninom.
Zadatak 8 (3)
Napisati funkciju dodaj koja korišćenjem pokazivača (bez indeksa) vrši
nadovezivanje stringa t na kraj stringa s.
Zadatak 9 (2)
Napisati funkcijju void umetni(char *s, int k, char *t); koja umeće string t u string
s počev od pozicije k.
Zadatak 10 (5)
Napisati C program koji korišćenjem funkcije brisizagrade, iz stringa s uklanja
podstring koji se nalazi između zagrada uključujući i same zagrade. Podstring se uklanja
iako sadrži u sebi druge zagrade. Funkcija brisizagrade vraća broj izbrisanih
podstringova.
Zadatak 11 (3)
Napisati C program koji utvrđuje koliko reči ima u stringu s i transformiše string s
tako što najdužu i najkraću reč pretvara u reči sa velikim slovima. Ako ima više najdužih
ili najkraćih reči 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 briše višestruke praznine, a potom svaku
reč u stringu zamenjuje rečju 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:
String = Mislim da mi je zadatak iz stringa dosao kao kec na deset.
145
Novi String = milsiM ad im ej katadaz zi agnirts osaod oak cek an tesed.
Zadatak 13 (3)
Napisati C program koji utvrđuje broj reči u stringu s unesenog sa tastature i briše
višestruke praznine u stringu. Za utvrđivanje broja reči u stringu koristiti funkciju
brojreci, a za brisanje višestrukih praznina funkciju brisipraznine, koja vraća 0 ako nije
bilo višestrukih praznina u tekstu.
Na primer:
String = Mislim da mi je zadatak iz stringa dosao kao kec na deset.
Zadatak 15 (3)
Napisati funkcijju int strend(char *s, char *t); koja vraća 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 briše k
znakova počev od pozicije n. Ako od pozicije n do kraja stringa nema k znakova funkcija
vraća 0, a u suprotnom 1.
Zadatak 17 (4)
Napisati funkciju char *satoi(unsigned broj); koja celobrojni podatak broj pretvara
u string i vraća pokazivač na početak 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 vraća broj koji
pokazuje za koliko je string manje dužine od prvobitnog stringa i po referenci vraća
koliko string ima tabulatora a koliko praznina.
Zadatak 19 (4)
Napisati funkciju za šifrovanje i dešifrovanje stringa. Šifrovanje stringa se vrši tako
što se svako slovo reči iz stringa kružno pomeri za k mesta udesno.
Zadatak 20 (3)
Napisati C program koji po izboru korisnika transformiše reči koje se nalaze u
stringu s po sledećim pravilima:
146
1) Sve reči u stringu moraju početi 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.
Zadatak 21 (4)
Napisati C program koji demonstrira primenu funkcije tokeni koja vraća koji se
prvi token pojavio u stringu s, pri čemu su tokeni karakteri iz stringa t.
Zadatak 22 (4)
Napisati funkciju zbir koja vrši sabiranje brojeva koji se nalaze u stringu s. Broj
može uopšteno biti realan (sadrži decimalnu tačku) i da ispred (bez praznina između)
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 zaštićen. Prilikom startovanja programa od korisnika
programa se traži da unese šifru i prikazano mu je sa oznakama *, koliko šifra ima
karaktera. Nakon unesene šifre, ako šifra nije ispravna korisnik dobija odgovarajuću
poruku o tome, a zatim se obaveštava koji put po redu unosi šifru. Ima tri pokušaja da
pogodi koja je šifra. Ako ne pogodi iz tri pokušaja ispisaće se odgovarajuća poruka
praćena zvučnim signalom, a u slučaju da pogodi šifru odgovarajuća poruka praćena
drugim zvučnim signalom.
Zadatak 24 (4)
Napisati C program koji umeće string t (tj. reč) ispred najduže reči iz stringa s. Ako
postoji više najdužih reči, string t umetnuti ispred reči koja je bila najbliža početku
stringa s. Za određivanje 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
Novi String = Mislim da mi je ovaj zadatak iz stringa dosao kao kec na deset.
147
Zadatak 25 (5)
Napisati C program kojim se unosi korektno zapisan izraz u jednoj liniji, a zatim
određuje njegova vrednost. Operandi u izrazu su celi brojevi, a operatori mogu biti (+,-,*
i /) pri čemu je / celobrojno deljenje. Pri određivanju vrednosti izraza voditi računa o
prioritetu operacija, i u izrazu je dozvoljeno korišćenje zagrada.
Zadatak 26 (5)
Dopuni prethodni zadatak koji je u stanju da reši sledeće programske zahteve:
- Ako je izraz neispravno zapisan na izlazu prikazati reč ERROR.
- Ako se oslobađamo zagrada, a rezultat u zagradi je negativan broj, negativan
broj ostaje u zagradi i zagrada će nestati tek nakon sledeće operacije, ili ako je
to krajnji rezultat.
- Ako postoje zagrade koje su ispravno zapisane ali su višak potrebno ih je na
početku programa izbrisati.
Zadatak 27 (5)
Napisati C program koji je u stanju da dešifruje string s unesen sa tastature na
osnovu matrice. U stringu nema praznina, već je praznina zamenjena sa donjom crticom.
Dešifrovanje stringa se vrši pomoću 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 dešifrovanja stringa kreće 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 dešifrovanja od prethodnog (ako je prethodni broj
znakova bio veći od 1, a išlo 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
Zadatak 28 (5)
Napisati C program koji vrši šifrovanje i dešifrovanje stringa s. Šifrovanje stringa
vrši se tako što se svaka reč stringa zarotira cirkularno za k mesta, a potom se svaki niz
praznina imeđu reči zamenjuje sa brojem praznina u toj reči. Smatrati da u rečima nema
drugih simbola osim malih ili velikih slova abecede. U stringu se osim slova abecede
mogu pojaviti i znakovi interpunkcije (. , ; ! ?).
148
Za realizaciju šifrovanja koristiti funkciju sifruj, a za dešifrovanje funkciju
desifruj.
Zadatak 29 (5)
Napisati funkciju kompresija koja vrši kompresiju stringa po sledećem pravilu
datom u primeru.
aabaab -> 2(aab) -> 2(2(a)b)
Funkcija kompresija vraća broj tipa double koji (na osnovu početne i krajnje
dužine) vraća procenat izvršene kompresije.
Zadatak 30 (5)
Napisati funkciju dekompresija koja vraća nastali string iz prošlog zadatka u
prvobitan položaj.
149
150
5. POGLAVLJE
TEKSTUALNE DATOTEKE
151
5.1. DEFINICIJA DATOTEKE, PODELA DATOTEKA
Definicija:
Datoteka je osnovna logička jedinica u pogledu zapisa informacija na
jedinicama masovne memorije.
152
Konstanta NULL koja označava neuspešno izvršavanje 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 sadržaj se prebacuje na datoteku. Kad se bafer
isprazni njegov sadržaj se popunjava iz datoteke. Korišćenjem bafera
smanjuje se broj pristupa datoteci. Standardizovane funkcije su: fopen(),
fgetc(), fputc(), fprintf(), fscanf(), fgets(), fputs(), feof(), fclose(), ftell(),
fseek(), rewind(), fread() i fwrite().
FILE *dat;
153
5.2. OTVARANJE I ZATVARANJE DATOTEKE
Datoteka pre bilo kakve obrade mora biti otvorena. To se postiže funkcijom fopen().
Funkcija fopen otvara navedenu datoteku i vraća pokazivač na tu datoteku (tip FILE), a
ako dođe do greške funkcija vraća vrednost NULL. Prototip funkcije fopen je:
Na primer:
FILE *dat;
dat = fopen("primer.txt","r");
Nakon poziva funkcije fopen(); pokazivač dat kažemo da pokazuje na datoteku, ali
on u suštini ne pokazuje na stvarnu datoteku, već na strukturu FILE.
154
U ovom primeru deklaracijom pokazivača dat saopšteno je prevodiocu da je dat
pokazivač koji će sadržati u sebi adresu promenljive tipa FILE. Nakon poziva funkcije
fopen(), funkcija fopen() traži datoteku primer.txt na direktorijumu gde se nalazi exe fajl
našeg programa. Ako ga nađe formiraće strukturu tipa FILE u ZONI PODATAKA,
upisaće brojnu oznaku datoteke, početnu adresu prihvatne memorije i inicijalizovaće
pokazivač na prihvatnu memoriju. Nakon popunjavanja strukture pokazivaču dat biće
prosleđena adresa strukture u ZONI PODATAKA. Druge funkcije će kasnije koristiti
strukturu preko pokazivača dat, kako bi na osnovu početne adrese prihvatne memorije i
pokazivača na prihvatnu memoriju smeštale podatke na prihvatnu memoriju.
Zatvaranje jedne datoteke znači da se prekida veza, koja postoji između pokazivača
na datoteku i imena datoteke, tj pokazivača na strukturu dobija vrednost NULL. Prilikom
izvršavanja funkcije fclose, a pre prekidanja veze između pokazivača na datoteku i imena
datoteke, dolazi do ispisivanja sadržaja prihvatne memorije u datoteku. Funkcija vraća
vrednost 0 u slučaju uspešnog zatvaranja datoteke, ili EOF u slučaju otkrivanja grešaka.
Završetak izvršavanja programa dovodi do automatskog zatvaranja svih otvorenih
datoteka. Programi rade optimalnije kada ima otvoreno manje datoteka(od 10 do 20
datoteka). Zatvorenoj datoteci ne možemo pristupiti bez ponovnog otvaranja.
Primer:
Napisati deo koda koji omogućava definisanje pokazivača na datoteku, a potom
omogućiti otvaranje datoteke PRIMER.TXT za čitanje. Ako datoteka nije uspešno
otvorena prikazati odgovarajuću poruku.
Rešenje:
FILE *dat;
if((dat = fopen("primer.txt","r")==NULL)
{
printf("Datoteka primer.txt ne moze biti otvorena!!");
return;
}
fclose(dat);
155
5.3. ZNAKOVNO USMERENI ULAZ I IZLAZ
Funkcijama za prenos znakova vrši se čitanje ili pisanje pojedinačnih znakova ili
nizova znakova bez konverzije. Sada će biti prikazani prototipovi i opisi nekih od
funkcija:
Funkcija fgetc(); čita znak iz navedene datoteke, vraća znak i pomera se na sledeći
znak u datoteci. ako je uspešno obavila zadatak, funkcija će vratiti znak iz datoteke koji
je bio na redu za čitanje. Ako dođe do greške ili kraja datoteke, biće vraćena vrednost
EOF.
Funkcija fputc(); upisuje znak u datoteku. Ako funkcija uspešno obavi svoj zadatak,
biće vraćen znak koji je upisan u datoteku, inače, biće vraćena vrednost EOF.
Funkcija fgets(); čita niz znakova iz navedene datoteke. Funkcija može da pročita
maksimalno max_char - 1 znakova ili do pojave znaka za novi red '\n' (koga ne stavlja u
string promenljivu buffer) i iza pročitanih znakova doda znak '\0'.
Ako funkcija uspešno obavi svoj zadatak biće vraćen pokazivač na niz pročitanih
znakova (buffer). Ako dođe do greške ili kraja datoteke, biće vraćena vrednost NULL.
156
int ungetc(int character, FILE *dat);
Funkcija ungetc(); dodaje znak nazad u datoteku. Znak EOF se ne može dodati
nazad. Funkcija vraća znak koji je dodat nazad ili EOF u slučaju greške.
Funkcija feof(); testira indikator kraja datoteke i daje kao rezultat vrednost različitu
od nule, ukoliko je dostignut kraj datoteke, inače će biti vraćena vrednost nula.
Funkcija fflush(); briše sadržaj izlaznog bafera ili briše sadržaj ulaznog bafera. Ako
je funkcija uspešno obavila zadatak biće vraćena vrednost nula, inače, funkcija će vratiti
vrednost EOF.
Primer 1:
Napisati C program koji u tekstualnoj datoteci PRIMER.TXT utvrđuje koliko se
puta učitani znak sa tastature pojavljuje u datoteci.
Rešenje
#include <stdio.h>
#include <conio.h>
void main(void)
{
char c, e;
unsigned br=0;
FILE *dat;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
157
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 vrši zamena
uneti sa tastature.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void)
{
FILE *dat;
for(i=0;i<DUZINA_LINIJE;i++) s2[i]=NULL;
s2[0]=pom;
textmode(3);
textcolor(15);
textbackground(0);
158
clrscr();
if((dat=fopen("PRIMER.TXT","r"))==NULL)
{
printf("\n\n\tDatoteka PRIMER.TXT se ne moze otvoriti!!!");
return;
}
dat=fopen("PRIMER.TXT","w");
fclose(dat);
gotoxy(1,25);
getch();
}
i=0;
while(s[i]!='\0'&&s[i]!='\n')
{
if(s[i]==e) s[i]=d;
i++;
}
}
159
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:
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
Rešenje
#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;
if ((dat=fopen("DATUMI.TXT","r"))!=NULL)
{
do {
string[0]='\0';
160
/* Sve podatke iz datoteke smestamo u string. */
i=0;
do {
string[i++]=fgetc(dat);
}while (string[i-1]!='\n'&& string[i-1]!=EOF);
if (string[i-1]=='\n')
{
string[i]='\0';
strcpy(s,string);
p=strtok(s,"./-");
/* U promenljivoj c pamti se prvi separator. Oba separatora
moraju biti ista. */
i=strlen(p);
c=string[i];
dan=atoi(p);
p=strtok(NULL,"./-");
i+=strlen(p)+1;
mesec=atoi(p);
161
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);
}
}
}
}
p=NULL;
}while(string[i-1]!=EOF);
162
5.4. ARGUMENTI IZ KOMANDNE LINIJE
Funkcija main() kao prvi argument ima indentifikator tipa int (ne mora ime
indentifikatora biti argc), a kao drugi argument indentifikator tipa niza pokazivača 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:
Primer 1:
Napisati C program koji izračunava zbir brojeva zapisanih u tekstualnim
datotekama. Brojevi su realni i svaki broj nalazi se zapisan u novom redu tekstualne
datoteke. Omogućiti unos datoteka iz komandne linije. Utvrditi koja datoteka ima najveći
zbir. Ukoliko dođe do greške prilikom otvaranja datoteke, ispisati poruku koja datoteka
nije uspešno otvorena.
Rešenje
163
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
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);
}
gotoxy(1,25);
getch();
}
/* Funkcija zbir izracunava zbir brojeva iz jedne datoteke na koju pokazuje pokazivac dat.
Datoteka je vec ranije uspesno otvorena.*/
while(fgets(s,81,dat)!=NULL) sz+=atof(s);
return sz;
}
164
Primer 2:
Napisati C program koji utvrđuje koliko tekstualna datoteka sadrži reči koje
počinju i završavaju se znakom '#', kao i tabelarni prikaz pojava takvih reči u datoteci po
redovima. U datoteci nema reci koje počinju u jednom redu a završavaju se u drugom.
Naziv tekstualne datoteke sa putanjom unosi se sa tastature ili iz komandne linije.
Na primer:
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
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);
}else strcpy(izvor, naziv[1]);
165
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;
if(br!=0)
{
printf("\n\n\tREDNI BROJ REDA\t\t\tBROJ POJAVLJIVANJA\n");
printf("\t---------------------------------------------------\n");
for(i=0;i<k;i++)
{
if(niz[i]!=0) printf("\t\t%d\t\t\t\t%-3d\n",i+1,niz[i]);
}
}
gotoxy(1,25);
getch();
}
Primer 3:
Napisati C program koji vrši dešifrovanje rečenice zapisane u tekstualnoj dazoteci
čiji naziv sa putanjom se unosi sa tastature. U datoteci namerno postoji jedna reč koja
počinje i završava sa duplim slovom. Ako data tekstualna datoteka sadrži takvu reč i ako
se takva reč nalazi u datoteci SIFARNIK.TXT, znak je da je iz datoteke potrebno
dešifrovati rečenicu.
166
Datoteka SIFARNIK.TXT sadrži u svakom redu po jedan format oblika:
šifrovanareč broreči/brojrečenice* broreči/brojrečenice...@interpunkcijskiznak
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
FILE *dat;
niz[0]=ss;
for(i=1;i<150;i++) niz[i]=NULL;
textmode(3);
textbackground(15);
textcolor(0);
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;
}
167
/* 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
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);
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 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.*/
168
if((dat1=fopen("SIFARNIK.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka SIFARNIK.TXT se ne moze otvoriti!!");
getch();
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]);
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);
169
return strtok(NULL,"\0,\n");
}else sifrarec[0]='\0';
}
}
}
/* 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;
}
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]);
170
/* 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 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)
{
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;
171
kon=0;
while(s[i]!='\0'&&kon==0)
{
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;
}
}
}
return res;
}
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@.
Milostiv 5/2*4/1*12/6*11*3*20/3*11/1*25/6*32/4@?
172
PRIMER.TXT
173
5.5. FORMATIRANI ULAZ I IZLAZ
Funkcije koje predstavljaju formatirani ulaz i izlaz su: fprintf() i fscanf(). Ove dve
funkcije su slične 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 pokazivača na tip FILE i to su: stdin, stdout i stderr,
koji su definisani u datoteci stdio.h. Pokazivač stdin indentifikuje standardni ulaz
programa i pridružen 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
takođe pridružen terminalu sa kog je program aktiviran. Pokazivač stderr indentifikuje
standardnu datoteku za štampanje poruka o greškama, generisanih od strane sistema.
Pokazivač stderr je pridružen 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 pokazivača DOS operativni sistem podržava i pokazivače: stdprn
usmeren na standardni priključak za štampač, i stdaux koji ide na standardnu funkciju za
serijsku komunikaciju.
Primer:
Napisati C program koji utvrđuje broj reči u tekstualnoj datoteci čije ime sa
putanjom se unosi sa tastature.
Rešenje
#include <stdio.h>
#include <conio.h>
#define DUZINA 81
void main(void)
{
char *ime, *s;
unsigned n=0;
FILE *dat;
textmode(3);
textbackground(15);
textcolor(0);
clrscr();
174
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();
}
while(*s)
{
while(*s == ' ' || *s == '\n' || *s == '\t') s++;
if(*s)
{
br++;
while(*s != ' ' && *s != '\n' && *s != '\t' && *s != '\0') s++;
}
}
return br;
}
Izgled programa:
175
5.6. POZICIONIRANJE UNUTAR DATOTEKE
Funkcija fseek podešava poziciju datoteke za tok dat. Narednim čitanjem ili
pisanjem pristupa se podacima na početku te nove pozicije. Datoteka se tretira kao niz
bajtova, a funkcija fseek omogućava da se direktno pristupi do bilo kog bajta u datoteci.
Argument mode označava polaznu tačku, i može imati jednu od tri vrednosti zapisanih u
simboličkim konstantama:
Funkcija ftell trenutnu poziciju datoteka za tok dat izražen u bajtovima u odnosu na
početak datoteke, ili -1 u slučaju greške.
176
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 vrši zamena
uneti sa tastature. Na ekranu štampati izmenjeni sadržaj datoteke.
Rešenje
#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();
177
Vrsimo upis karaktera u datoteku pomocu funkcije fputc. */
fseek(dat,poz,SEEK_SET);
fputc(d,dat);
gotoxy(1,25);
getch();
}
Primer 2:
Napisati C program koji predstavlja poznatu igru "slagalica" iz televizijskog kviza
muzička slagalica. Korisnik unosi deset slova engleske abecede. Nakon svakog
pritisnutog tastera SPACE u odgovarajuće polje upisuje se po jedan znak. Korisnik ima
jedan minut na raspolaganju da unese svoju reč sa što više slova od ponuđenih. Program
utvrđuje da li je reč ispravno unesena na osnovu ponuđenih slova, a potom na osnovu
tekstuale datoteke RECI.TXT daje svoje rešenje koje ima najveći broj slova u sebi.
Rešenje
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<dos.h>
#include<time.h>
#include<ctype.h>
#define BR 18
#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);
178
void main(void)
{
int i=0,j=0;
char *rec="",*slova,c,*druga;
FILE *fajl;
randomize();
textmode(3);
textcolor(3);
textbackground(0);
clrscr();
fseek(fajl,0,SEEK_SET);
while(c!=EOF)
{
if((c=fgetc(fajl))=='\n')i++;
};
rand(rec,slova);
gotoxy(15,5);
crtaj();
179
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();
for(i=0;i<d;i++)
{
do{
r=random(BR);
}while(slova[r]!=' ');
slova[r]=rec[i];
}
180
/* 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]!=' ');
/* 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)
{
181
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;
182
/* 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{
_setcursortype(_NORMALCURSOR);
if(vr==VREME)
{
gotoxy(20,23);
printf(" ");
gotoxy(32,23);
printf("VREME JE ISTEKLO");
return 0;
}
gotoxy(15+i*2,14);
delay(20);
}while(!kbhit());
c=getch();
if(c==ESC) return 0;
183
druga[i++]=c;
druga[i]='\0';
gotoxy(13+i*2,14);
printf("%c",c);
}
184
5.7. ZADACI IZ TEKSTUALNIH DATOTEKA
Zadatak 1 (2)
Napisati C program koji izračunava 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 utvrđuje broj linija u tekstualnoj datoteci i štampa najdužu
liniju iz datoteke. Naziv datoteke bez putanje se unosi sa tastature.
Zadatak 3 (2)
Napisati C program koji utvrđuje koliko tekstualna datoteka sadrži reči. Naziv
tekstualne datoteke može se uneti preko komandne linije ili tastature.
Zadatak 4 (3)
Napisati C program koji određuje liniju koja sadrži najdužu reč. Ispisati na ekranu
redni broj linije i najdužu reč. Naziv tekstualne datoteke može se uneti preko komandne
linije ili tastature.
Zadatak 5 (3)
Napisati funkciju koja upoređuje dve tekstualne datoteke i vraća redni broj reda u
kojoj se po prvi put datoteke razlikuju, ili 0 ako su datoteke indentične. Naziv tekstualne
datoteke može se uneti preko komandne linije ili tastature.
Zadatak 6 (3)
Napisati C program koji pozivanjem funkcije brisi, višestruki 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:
PRIMER.TXT
Eeeh da miiiii jje laksiiii zzaddattak dao!!
Ovi pppprofesorrri uvekkk naas muce i mmaltreeetirraju.
Nnnnapokonn sam zavrssiooo.
PRIMER.TXT
Eh da mi je laksi zadatak dao!!
Ovi profesori uvek nas muce i maltretirraju.
Napokon sam zavrsio.
185
Zadatak 7 (2)
Napisati C program koji omogućava unos naziva tekstualne datoteke sa putanjom i
prebrojava koliko ima reči da a koliko ne u tekstualnoj datoteci. Za brojanje reči koristiti
funkciju brojireci.
Zadatak 8 (3)
Napisati C program koji utvrđuje koja linija u tekstualnoj datoteci poseduje najviše
reči. Ispisati datu liniju na ekranu i broj reči koliko ima data datoteka. Naziv tekstualne
datoteke može se uneti preko komandne linije ili tastature.
Zadatak 9 (2)
U tekstualnoj datoteci MATRICA.TXT nalazi se matrica. Prvi red datoteke sadrži
dva celobrojna podatka: broj vrsta i broj kolona koje ima matrica. Podaci su razdvojeni
blanko mestom (mestima) ili tabulatorom (tabulatorima).
Napisati C program koji izračunava zbir elemenata matrice, i vrši zatim sažimanje
matrice izbacivanjem svih onih kolona koji imaju zbir manji od zbira celokupne matrice.
Za izračunavanje zbira celokupne matrice koristiti funkciju zbir, a za izračunavanje zbira
elemenata jedne kolone funkciju zbirkolone.
Ispod već postojeće 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
5 3
-3 -2 -7
-3 5 -6
7 -3 10
5 -2 22
4 4 -5
186
Zadatak 10 (3)
Napisati C program koji uklanja komentare iz nekog C programa. Komentari u C
programu počinju sa /* a završavaju se sa */.
Zadatak 11 (4)
Napisati C program koji prikazuje sadržaj 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
sledeće strane koristiti taster SPACE.
Zadatak 12 (4)
Zadata je tekstualna datoteka ULAZ.TXT, pri čemu svaki red ove datoteke ima
samo jednu potpunu rečenicu koja se završava tačkom. Znači da posle tačke nema više
karaktera u rečenici. Između reči u rečenici može postojati više praznih mesta. Rečenica
može imati najviše 80 karaktera. Koristeći funkciju najveci iz svakog reda datoteke
utvrđuje se reč koja je najduža, a potom se svi karakteri (mala slova) reči pretvaraju u
velika slova. Uz pomoć funkcije upis, ove reči se upisuju u izlaznu datoteku
IZLAZ.TXT. Funkcijom ispis se sadržaj datoteke IZLAZ.TXT štampa na ekranu.
Program realizovati u programskom jeziku C.
Zadatak 13 (4)
Napisati C program koji utvrđuje koja rečenica u tekstualnoj datoteci poseduje
najviše reči. Ispisati koliko ima rečenica u datoteci kao i rečenicu koja ima najviše reči i
broj reči koliko ima data rečenica.
Rečenica se završava tačkom, upitnikom ili uzvičnikom.
Zadatak 14 (4)
Napisati C program koji pronalazi sva pojavljivanja date reči (sekvenca od
maksimalno 30 karaktera) u datoj tekstualnoj datoteci. Na izlazu štampati redne brojeve
rečenica iz datoteke u kojima se reč pojavljuje Ignorisati višestruko pojavljivanje reči u
jenoj rečenici.
Zadatak 15 (3)
Napisati C program koji spaja dve sortirane datoteke u treću sortiranu datoteku koja
sadrži samo različite elemente ulaznih datoteka. Program omogućava rad sa više 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 reči (ime i
prezime) razdvojeni blanko mestom. Obe reči počinju velikim slovom. Ako se pojave
greške da neka od reči počinje malim slovom program automatski ispravlja tu grešku u
izlaznoj datoteci.
187
Zadatak 16 (4)
Napisati C program koji vrši šifrovanje datoteke tako što se svaka reč u datoteci
zapisuje u invernom poretku. Ako je neka reč počinjala velikim slovom i rotirana reč
počinjaće 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(FILE *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 vrši zamenu svake pojave reči s sa
reči t. Program realizovati funkcijom int zamenirec(FILE *filepionter, chat *s, char *t);
koja vraća 0 ako reči s nema u datoteci, a 1 u suprotnom.
Zadatak 18 (5)
Napisati C program koji u datoj tekstualnoj datoteci, pronalazi i briše rečenice koje
se višestruko ponavljaju. Rečenice počinju velikim slovom ili brojem, a završavaju se
tačkom, uzvičnikom, upitnikom ili oznakom EOF. Omogućiti unos naziva iz komandne
linije.
Zadatak 19 (5)
Napisati C program koji prikazuje spisak referenci u datoj tekstualnoj datoteci.
Svaka referenca u tekstu je označena sa svojim brojem u uglastim zagradama. Na izlazu
štampati reference sa brojevima, svaka referenca u novom redu.
Zadatak 20 (4)
Napisati C program koji utvrđuje koliko datoteka, čije ime sa ekstenzijom se unosi
iz komandne linije, sadrži pasusa. Pasus koji sadrži najveći broj reči formatizovati tako
da sve reči budu pretvorene reči sa velikim slovima.
Zadatak 21 (5)
Učenici su napisali velike C programe na praktičnoj nastavi. Profesor je zadao
pravilo da se u programu ne sme koristiti naredba bezuslovnog skoka goto. Kako
profesora mrzi da kontroliše ceo kod, potrebno je napisati C program koji utvrđuje da li
proizvoljni C ili CPP program čije ime sa ekstenzijom se unose sa tastature sadrži
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 tačno jedna rečenica. Ako rečenica ima više od 80 karaktera
nastavlja se upis u novom redu.
188
Zadatak 23 (5)
Napisati C program koji utvrđuje koliko ima zbirova u datoteci. Svaki zbir počinje
u novom redu datoteke i završava se znakom jednakosti. Zbir se može prostirati u više
redova. Brojevi mogu biti celobrojni ili racionalni. U izrazima nema zagrada, ali se mora
poštovati prioritet operatora. Ako se zbir nastavlja u sledećem redu poslednji znak mora
biti znak operacije. Formirati novu datoteku REŠENJE.TXT koja će sadržati isto što i
ulazna datoteka, stim što se posle jednakosti mora nalaziti i rezultat, čime se završava taj
red. Naziv ulazne datoteke uneti sa tastature ili iz komandne linije.
Zadatak 24 (4)
U tekstualnoj datoteci čiji naziv se učitava sa tastature nalazi se inicijalizacija
trodimenzionalne matrice. Potrebno je modifikovati datoteku tako da u njoj ostaju samo
elementi trodimenzionalne matrice odvojeni međusobno 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}
}
}
ULAZ.TXT
1234
5678
9 10 11 12
4345
5678
9 4 11 22
189
Zadatak 25 (5)
Data je tekstualna datoteka pod imenom TEKST.TXT. Napisati C program koji
štampa sadržaj datoteke na ekran, ali tako da kompletan tekst bude poravnat i po desnoj i
po levoj margini na sledeći način.:
Poravnavanje na levo vršiti najobičnijim štampanjem od prve kolone ekrana;
Poravnavanje na desno vršiti tako da desna margina bude u onoj koloni u
kojoj se završava najduži redoriginalnog teksta; i
Ostale redove (koji su kraći od originalno najdužeg), “Produžavati“ tako što
će se između reči ubacivati približno ravnomerno prazna mesta, onoliko
njih koliko je potrebno da red dostigne dužinu najdužeg.
Zadatak 26 (5)
Na osnovu C programa koji je obrađen u zadatku 30 oblasti višedimenzionalni
nizovi, igrica POGODI, doraditi program tako da poseduje tri nivoa.
Prvi nivo je već obrađen u predhodnoj verziji.
Drugi nivo omogućava da se mora redom pogađati brojevi od 1 do 6. Ako se pogodi
pogrešno polje ne menja se boja (ostaje tamna).
Treći nivo omogućava da se polja moraju tako pogađati da na kraju dobijemo
sortiran niz brojeva. Nakon svakog pogotka na neki broj on se zarorira sa svojim
sledbenikom, dok u slučaju 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 pređenu tablu dobija
po 5 bodova pomnoženo sa brojem nivoa koji je poslednji pređen u igri.
Zadatak 27 (5)
U tekstualnoj datoteci nalazi se neki tekst sastavljen od reči i tačaka koje
označavaju krajeve rečenica. Između reči se nalazi jedna ili više praznina.
Napisati C program koji vrši formatiranje teksta po sledećim pravilima:
Između reči može da bude tačno jedna praznina;
Ispred prve reči teksta nema praznina;
Ispred tačke nema praznine;
Iza tačke postoji tačno jedna praznina i prva reč iza tačke počinje uvek
velikim slovom; i
dužina reda u datoteci ne sme biti veća od 80 karaktera.
Zadatak 28 (5)
Potrebno je napraviti tekst procesor koji je u stanju da:
1) unosi tekst;
2) umeće nove redove teksta;
3) kretanje kroz tekst pomoću strelica;
4) sa breakspace briše znak iz teksta uz pomeranje teksta toga reda u levo za
jedno mesto; i
5) uz pomoć tastera delete briše jedan red teksta gde se trenutno kursor nalazi.
190
Zadatak 29 (5)
Date su tekstualne datoteke REZULTATI.TXT i GOLOVI.TXT sa sledećim
izgledom:
REZULTATI.TXT
GOLOVI.TXT
Zadatak 30 (5)
Napisati C program koji pretstavlja poznatu igricu TETRIS. Omogućiti formiranje
četiri nivoa igrice. Postoji više oblika u tetrisu. Stalno se prikazuje koji je sledeći oblik.
Sledeći oblik se dobija na slučajan način. Sa strelicom levo pomera se oblik na levo, sa
strelicom desno pomera se oblik na desno, sa strelicom na gore vrši se rotiranje oblika, a
sa strelicom na dole vrši se brzo spuštanje na dole. Kraj igrice je ako se pritisne taster
ESC. Ako se skupi određeni broj bodova prelazi se u sledeći nivo. U slučaju da se ne
uspe u tom nivou vraća se na prethodni nivo.
U tekstualnoj datoteci čuvati pet najboljih rezultata. Rezultat je opisan sa
skljupljenim brojem poena i imenom igrača.
191
192
6. POGLAVLJE
193
6.1. DEFINICIJA STRUKTURE DEKLARACIJA STRUKTURE
PRISTUP ČLANOVIMA STRUKTURE ITIPOVI
KOJE DEFINIŠE KORISNIK
Definicija strukture:
Struktura predstavlja izvedeni tip podatka koji sadrži promenljive istog ili
različitog tipa. Koristi se u slučajevima kada su podaci u međusobnoj vezi, jer se
mogu grupisati pod istim imenom.
struct ime_strukture {
niz_deklaracija
};
Primer 1:
Napisati C program koji omogućava formiranje strukture radnik sa poljima:
Rešenje
194
U zadatku je logično koristiti strukturu, jer kad kažemo radnik ne može se opisati
kao jedan osnovni podatak, jer se sastoji od više podataka koji ga opisuju: Prezime i ime
je string, datum rođenja je string, godina radnoga staža je celobrojan podatak, koeficijent
je racionalan podatak. Ne može se opisati ni nizom jer kod niza svi podaci moraju biti
istog tipa Radnik se ne može 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 različitog tipa.
Ti podacin predstavljaju polja ili članove strukture, a u nekim literaturama se sreće 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();
195
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. */
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;
}
gotoxy(1,25);
getch();
}
196
Izvedeni tipovi podataka često imaju dugačka imena, što zahteva mnogo pisanja i
nepreglednost koda. Da bi se ovaj problem rešio koristi se rezervisana reč typedef.
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include<ctype.h>
#define MAX 31
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();
197
printf("\tGodine radnoga staza = ");
xu=wherex(), yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%d",&a.staz);
}while(a.staz<0);
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;
}
Primer 2:
Napisati C program koji utvrđuje i na ekranu iscrtava (korišćenjem teorije
bioritma), skale fizičkog, intelektualnog i emocionalnog stanja tog dana. Dan se utvrđuje
korišćenjem strukture struct date za očitavanje sistemskog datuma. Bioritam se utvrđuje
na osnovu datumac rođenja po sledećoj formuli:
2
y sin( ( d mod x)) gde je mod operator ostataka celobrojnog deljenja
x
U formuli je d broj dana od rođenja, a x može imati tri vrednosti x 23,28,33
23 - fizičko stanje,
28 - emocionalno stanje, i
33 - umno stanje
198
Rešenje
#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(0);
textbackground(15);
clrscr();
printf(" \n");
for(i=0;i<26;i++) printf(" \n");
gotoxy(1,1);
/* Unosi se datum rodjenja u obliku stringa s. Postupak unosa se ponavlja ako je datum
neispravno unesen.*/
199
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++;
/*Dodaje se jos jedan dan ako je obuhvacen februar mesec a godina prestupna. */
if(mes>=2&&(god%4==0||god%400==0)) sdan++;
/*Dodaje se jos jedan dan ako je obuhvacen februar mesec a godina prestupna. */
if(sadmes>2&&(sadgod%4==0||sadgod%400==0)) sdan++;
200
gotoxy(4,22); printf("\n\tIma %d dana.",sdan);
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(15); gotoxy(16,11);
printf("| | |");
textbackground(2);
gotoxy(4,12);printf("Emocionalni:");
for(i=0;i<j;i++)cprintf(" ");
j=(1+fiz)*30;
textbackground(15); gotoxy(16,13);
printf("| | |");
textbackground(4);
gotoxy(8,14);printf("Fizicki:");
for(i=0;i<j;i++)cprintf(" ");
textbackground(15);
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;
201
/* Izmedju dana, meseca i godine rodjenja mora se nalaziti separator (tacka, zarez ili
prazno mesto). Funkcijom strto izdvajaju se delovi stringa. */
/* 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;
202
6.2. INICIJALIZACIJA STRUKTURE
NIZ STRUKTURA
Ako se u ovom primeru hoće koristiti više radnika tada koristimo niz struktura.
Niz struktura se definiše na isti način kao bilo koji niz Svaki član niza je tipa strukture, a
u ovom primeru je to Tradnik.
203
Tradnik x[50], a; /* Ovde je a jedna strukturna promenljiva, a x predstavlja niz
struktura. */
unsigned i;
Inicijalizacija niza struktura vrši se kao inicijalizacija bilo kog niza. Prvo inicijalizujemo
strukturnu promenljivu a.
a potom niz struktura pomoću ciklusa tako što svaki element niza dobija vrednost a, koja
je predhodno inicijalizovana.
for(i=0;i<50;i++) x[i]=a;
Prvo se pše indeks niza, a potom operator tačka da se pristupa članu strukture.
Primer 1:
Napisati C program koji omogućava unos n učenika n<31 sa podacima: ime do 15
karaktera, prezime do 15 karaktera i broj izostanaka. Prikazati spisak pet ucenika sa
najvećim brojem izostanaka sortiranih u opadajućem redosledu po broju izostanaka. Ako
dva ili više učenika imaju isti broj izostanaka drugi kriterijum je po abecednom
redosledu.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#define MAX 30
/* Prototipovi funkcija. */
void brisi(unsigned xu, unsigned yu);
void unesistring(char s[], unsigned k);
204
void main(void)
{
Tucenik niz[MAX], a = {"","",0}, pom;
unsigned i, j, k, xn, yn, xu, yu;
int n;
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
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;
205
}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;
}
}
}
}
}
}
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. */
gotoxy(xu,yu);
for(i=1;i<=25-yu;i++)
{
for(j=1;j<=80-xu;j++) printf(" ");
}
}
206
/* 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 učitava tekstualnu datoteku UCENIK.TXT koja u prvom
redu sadrži centrirano ispisan naziv odeljenja, sledi prazan red, pa spisak učenika sa
podacima, pri čemu se u jednom redu nalaze podaci o jednom učeniku.
Ako je učenik nedovoljan u polju prosečna ocena pisaće broj nedovoljnih ocena, a
ako je neocenjen broj neocenjenih predmeta. U računanje prosečne ocene odeljenja ne
računaju se oni učenici koji su nedovoljni ili neocenjeni.
Rešenje
#include <conio.h>
#include <stdio.h>
#include <string.h>
#define MAX 32
207
/*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);
208
pom=strtok(NULL," ");
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");
if(pit2==1)
{
strcpy(niz[i-1].uspeh,"NEDOVOLJAN");
niz[i-1].sr=l;
}
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;
209
/* 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();
}
210
6.3. STRUKTURE I FUNKCIJE
Primer 1:
Definiši nov tip podatka Tucenik, sa poljima prezime (od maksimalno 30
karaktera) i brizostanaka. Potom deklariši promenljive a i b tipa Tucenik, kao i
pokazivač pok koji može da pokazuje na promenljive tipa Tucenik.
Rešenje:
Tucenik a, b, *pok=NULL;
pok=&a;
strcpy((*pok).ime_prezime,"");
pok->brizostanaka=0;
211
Strukture i funkcije:
Prosleđivanje člana strukture kao argumenta funkcije.
Prosleđivanje strukture kao argumenta funkcije, i
Prosleđivanje pokazivača na strukturu kao argumenta funkcije.
Primer 2:
Napisati C program koji primenom struktura omogućava unos dva datuma rođenja,
osobe A i osobe B. Struktura datuma je opisana sa godinom, mesecem i danom rođenja.
Program utvrđuje 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.
Rešenje
#include <stdio.h>
#include <conio.h>
/* Prototipovi funkcija. */
Tdatum unos(char *s);
char razlika(Tdatum a, Tdatum b, int *raz);
unsigned zbir(Tdatum *x);
void main(void)
{
/* Deklaracija dve strukturne promenljive. Prva se odnosi na osobu A, a
druga na osobu B. */
Tdatum a,b;
int raz=0,star=0;
212
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
a=unos("A"); /* Funkciji unos pomocu 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 omogucava 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,k;
int pom;
printf("\tMesec: ");
xu=wherex(),yu=wherey();
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
213
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 .*/
switch(x.mesec)
{
case 1: case 3: case 5: case 7: case 8: case 12: case 10:
if(pom<=0 || pom>31) k=0;
else k=1;
break;
case 2: if(x.mesec % 4 == 0 || x.mesec % 400 == 0)
if(pom<=0 || pom>29) k=0;
else k=1;
else if(pom<=0 || pom>28) k=0;
else k=1;
break;
case 4: case 6: case 9: case 11: if(pom<=0 || pom>30) k=0;
else k=1;
}
}while(k==0);
x.dan=pom; /* Polju strukture pristupa se operatorom tacka. */
/* 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;
s1=zbir(&a);
/* Izracunavamo ukupan broj dana osobe 'B' od racunanja kalendara pa do rodjenja osobe
'B'. */
s2=zbir(&b);
214
if(s1<s2)
{
*raz=s2-s1;
return 'A';
}
if(s2<s1)
{
*raz=s1-s2;
return 'B';
}
return '0';
}
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;
}
}
return k;
}
Primer 3:
215
Napisati C program koji korišćenjem funkcije unos omogućava unos napona i struje
na jednom potrošaču u kompleksnom obliku. Prototip funkcije unos je:
Karakter c može imati vrednosti 'U' ili 'I'. Ako ima vrednost 'U' unosiće se napon u
kompleksnom obliku, a ako ima vrednost 'I' unosiće se struja u kompleksnom obliku.
Funkcija vraća strukturu tipa Tkomp koja se sastoji od realnog i imaginarnog dela
kompleksnog broja.
Korišćenjem funkcije potrosac utvrđuje se prenosom po referenci impendasa
potrošača i prividna snaga u kompleksnom obliku tipa Tkomp.
Funkcija vraća:
1 - ako je potrošač induktivnog karaktera;
-1 – ako je potrošač kapacitivnog karaktera; ili
0 – ako potrošač nije induktivnog ni kapacitivnog karaktera.
Rešenje
#include <stdio.h>
#include <conio.h>
/* 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(15);
textcolor(0);
clrscr();
216
/* 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');
switch(k)
{
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!!");
}
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) = ");
217
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);
}
(*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);
(*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. */
218
6.4. RAD SA BINARNIM DATOTEKAMA
Na primer:
FILE *dat;
dat=fopen("PRIMER.DAT","rb");
Prilikom rada sa binarnim datotekama koriste se dve funkcije: fread (za učitavanje
podataka) i fwrite (za upis podataka) u binarnu datoteku.
Primer 1:
Zadata je binarna datoteka SMENE.DAT. Datoteka se sastoji od binarnih reči, koje
predstavljajju podatke o jednodnevnom učinku smene..
Napisati C program koji na osnovu binarne datoteke o jednodnevnom učinku smene
daje po izboru korisnika: tabelarni prikaz učinka odgovarajuće smene i tabelarni
219
uporednidni prikaz učinka 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 smešteni u 24 bitnu reč oblika:
Binarna datoteka se sastoji od više podataka (za svaku smenu i merno mesto jedan
podatak, tj binarna reč), pri čemu je svaki podatak smešten u 24-bitnu reč.
Rešenje
#include <stdio.h>
#include <conio.h>
/* Prototipovi funkcija. */
void UcinakSmene(TMatrica JednUcinak);
void UporednaLista(TMatrica JednUcinak);
char OsnMeni();
char UcitajPodatke(TMatrica JednUcinak);
void Inicijalizacija(TMatrica JednUcinak);
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
/* Inicijalizacija matrice. */
Inicijalizacija(JednUcinak);
220
/* Prikazuje se uporedni prikaz smena. */
case '2': UporednaLista(JednUcinak);
break;
/* Izlazak iz programa. */
case '3': kraj=1;
}
} while (!kraj);
}
}
for (i=0;i<4;i++)
{
for (j=0;j<5;j++) JednUcinak[i][j]=0;
}
}
unsigned i,j,BrKomada;
FILE *dat;
unsigned long temp;
}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
pretstavlja broj proizvoda koje je i-ta smena napravila na j-tom mernom
mestu. */
221
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) --> ");
return(odg);
}
do{
/* Korisnik unosi broj smene za koju hoce da vidi tabelarni prikaz. */
clrscr();
222
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));
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');
}
clrscr();
printf("Br. mer. I smena II smena III smena IV smena Ukupno za");
printf("\nmesta mer. mesto\n");
printf("--------------------------------------------------------------------");
223
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 teško formirati u editoru teksta, već je to potrebno rešiti
programski. Iz tog razloga napisaćemo mali program koji omogućava formiranje binarne
datoteke SMENE.DAT koja će vam poslužiti za testiranje.
Primer 2:
Napisati C program koji omogućava formiranje datoteke SMENE.DAT koja će
nam poslužiti za testiranje prethodnog zadatka.
Rešenje
# include <stdio.h>
# include <conio.h>
#define MAX 20
224
void main (void)
{
FILE *dat;
long broj;
char pom;
for (i=0;i<MAX;i++)
{
printf("Unesite %d. broj ",i+1);
if(i<9) printf(" ");
for(j=0;j<24;j++)
{
do{
pom=getch();
}while(pom!='0'&&pom!='1');
printf("%c",pom);
x[j]=pom-48;
}
p=1,broj=0;
for (k=0;k<24;k++)
{
broj=broj+x[23-k]*p;
p=p*2;
}
printf("\n");
}
fclose(dat);
}
225
6.5. FORMIRANJE HEDERA ZA RAD SA MIŠEM
Kreiraćemo heder sa imenom MIS.H kojeg ćemo koristiti kad god nam je u
programu potrebno koristiti miša. Nije potrebno znati kako funkcije rade ako hoćete
koristiti miša. Potrebno je samo znati šta radi koja funkcija i poznavati dobro strukturu
miša, tj tip podatka Tmiss koja je definisana u hederu MIS.H.
MIS.H
/* Interapt 33H omogucava kacenje drajvera misa. Interapti se pisu u heksadecimalnom obliku*/
/* 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);
TMiss.instaliran = reset();
TMiss.x = TMiss.y = TMiss.starax = TMiss.staray = -1;
TMiss.vidljiv = 0;
kursor_uklj();
}
226
/* Funkcija da_levo utvrdjuje da li je pritisnut levi taster misa. */
int da_levod(void)
{
union REGS r;
if(!TMiss.instaliran) return 1;
r.x.ax = 3;
int86(MOUSE_INTR,&r,&r);
if(!TMiss.instaliran) return 0;
r.x.ax = 3;
int86(MOUSE_INTR,&r,&r);
/* 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);
/* Koordinate misa se uvek zadaju kao da se radi o grafičkom režimu. Iz tih razloga vrši se
deljenje koordinata sa 8 kako bi se izvršilo pretvaranje u tekstualni režim. */
227
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;
}
if(TMiss.vidljiv) return;
/* Mis se prikazuje tako što se u akumulatoru upiše vrednost 1 i pozove interapt 33h. */
r.x.ax = 1;
int86(MOUSE_INTR,&r,&r);
if(!TMiss.vidljiv) return;
TMiss.vidljiv = 0;
}
return r.x.ax ? 1 : 0;
}
228
Primer:
Napisati C program koji omogućava demonstraciju rukovanja sa mišem u
programima pod DOS-om. Nakon pritiskanja levog tastera miša na tekućoj 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.
Rešenje
#include <stdio.h>
#include <conio.h>
#include "mis.h"
void main(void)
{
textmode(3);
textcolor(15);
textbackground(0);
clrscr();
/* Iskljucujemo kursor. */
_setcursortype(_NOCURSOR);
/* Stalno utvrdjujemo poziciju kursora misa i da li je pritisnut levi ili desni taster misa. */
while(citaj())
{
kursor_isklj();
gotoxy(TMiss.x,TMiss.y);
textbackground(0);
cprintf("1");
TMiss.levod=0;
kursor_uklj();
}
229
/* 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;
}
}
230
6.6. ZADACI IZ STRUKTURA, NIZOVA STRUKTURA I BINARNIH
DATOTEKA
Zadatak 1 (2)
Napisati C program koji omogućava unos dva ugla i izračunava njihov zbir.
Svaki ugao je okarakterisan sa poljima:
1) stepen (00-3600),
2) minut (0'-59'), i
3) sekund (0"-59")
Zadatak 2 (2)
Napisati C program koji korišćenjem funkcije dekupol prevodi tačku 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 omogućava unos napona i struje pomoću stringova u
trigonometrijskom obliku: u (t ) U max cos( wt ) i i (i ) Im ax cos( wt ) .
Program treba da predstavi struju i napon u algebarskom obliku, a potom da izračuna
impedansu potrošača.
Zadatak 4 (2)
Napisati C program koji izračunava obim poligona koji se zadaje sa nizom svojih
tačaka. Svaka tačka je opisana sa x i y koordinatom.
Zadatak 5 (2)
Napisati C program koji formira i na ekranu štampa tabelarni prikaz sledećeg
oblika:
Zadatak 6 (3)
U Dekartovom koordinatnom sistemu zadat je skup od n, n<100 kružnica. Svaka
kružnica opisana je sa poljima: x-koordinata centra, y-koordinata centra i poluprečnikom.
Napisati C program koji pronalazi i na ekranu štampa one kružnice koje u sebi sadrže
najviše drugih kružnica.
231
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
tačke konveksnog poligona. Ako se tačke u datoteci nalaze zapisane po redu koji
odgovara matematičkom smeru obilaska kroz poligon, napisati C program koji
izračunava pozivom funkcije teziste koordinate težišta poligona.
Težište poligona računa se po formulama:
1 n 1 n
xt xi i yt yi
n i 1 n i 1
Zadatak 8 (3)
Napisati C program koji omogućava unos razlomka u obliku strukture pod imenom
racionalni koja se sastoji od dva polja: brojilac i imenilac. Koristeći funkciju skrati
omogućiti da se razlomak dovede u oblik koji se ne može skratiti, i kao takav se štampa
na ekranu.
Zadatak 9 (3)
Napisati C program koji učitava niz struktura o uspehu učenika na prijemnom
ispitu, a zatim klasifikuje kandidate u tri kategorije A, B i C. Svaka struktura koja se
učitava sa ulaza sadrži dva polja: ime i poeni, a u obradi treba dodeliti i treće polje rang.
Kandidat je u rangu: A ako ima više od 80% od ukupnog broja bodova koji se može
osvojiti na ispiti, B ako ima više od 35%, ili C u suprotnom. Niz struktura se učitava iz
binarne datoteke čije ime se unosi sa tastature.
Zadatak 10 (3)
Napisati C program koji omogućava unos dva razlomka i pozivom odgovarajućih
funkcija izračuna i prikaže na ekranu njihov zbir, razliku, proizvod i količnik. Razlomak
je u obliku strukture pod imenom racionalni koja se sastoji od dva polja: brojilac i
imenilac.
Zadatak 11 (3)
Napisati C program koji omogućava učitavanje 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 opadajućem redosledu po broju bodova, a ukoliko više
kandidata ima isti broj bodova, drugi kriterijum je sortiranje u rastućem abecednom
redosledu. Obrađene podatke iz niza struktura upisati u novu tekstualnu datoteku.
Zadatak 12 (3)
Napisati C program koji učitava tekastualnu datoteku i formira niz struktura sa
poljima: reč i broj pojave te reči u datoteci, sortira niz struktura u opadajućem redosledu
po broju pojavljivanja reči u datoteci, a u slučaju da više reči ima isti broj pojavljivanja,
po abecedi. Na kraju štampati na ekranu tabelarni prikaz pojave reči u tekstualnoj
datoteci.
232
Zadatak 13 (3)
Formirati tekstualnu datoteku UCENICI.TXT pa u tu datoteku uneti podatke za n
učenika n<50, i to (prezime, ime, datum rođenja oblika dd.mm.gg, uspeh opisno izražen,
putnik Da ili Ne, i izostanci). U svakom redu nalaze se podaci o samo jednom učeniku.
Očitati datoteku i podatke smestiti u niz struktura. Strukturu sortirati po abecednom
redosledu i štampati je na ekranu.
Zadatak 14 (3)
Napisati C program za praćenje glasanja na muzičkom festivalu. Svaka pesma
dobija ocenu žirika (od 0 do 10) i ocenu publike (od 0 do 10). Program treba da omogući:
unos naziva pesme, naziv izvođača, broj osvojenih bodova, kao i izlistavanje rezultata po
opadajućem 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
tačke konveksnog poligona. Ako se tačke u datoteci nalaze zapisane po redu koji
odgovara matematičkom smeru obilaska kroz poligon, napisati C program koji
izračunava pozivom funkcije povrsina površinu poligona.
Površina trougla zadata sa koordinatama temena tačaka A(xa,ya), B(xb,yb) i
C(xc,yc) računa se po formulu:
1
P xa ( yb yc ) xb ( yc ya) xc ( ya yb)
2
Zadatak 16 (4)
Napisati C program koji formira niz struktura na osnovu tekstualne datoteke
IGRACI.TXT o takmičarima svetskog prvenstva u fudbalu tako da svaka struktura
takmičara sadrži sledeća polja: Prezime, Ime, Broj na dresu, Godine života, Ime
reprezentacije, Broj učešća na svetskim prvenstvima, Broj zlatnih, Broj srebrnih i Broj
bronzanih medalja.
Sortirati reprezentacije prema uspešnosti na svetskim prvenstvima i ispitati koja
reprezentacija ima najveću cenu na tržištu.
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 staža... treći red
plata radnika... četvrti red
ime radnika2... peti red, itd.
233
Zadatak 18 (4)
Napisati C program za mesečnu evidenciju saobraćaja vozila preko mostova. Podaci
se nalaze u datoteci organizovanoj po 32-bitnim rečima jednog brojanja:
Zadatak 19 (4)
Napisati C program koji omogućava evidenciju stanja bankovnih računa korisnika
u jednoj banci. Jedan račun se opisuje brojem računa, imenom i prezimenom vlasnika
računa, matičnim brojem vlasnika računa, stanjem računa. Program treba da omogući
pregled stanja računa za zadatog korisnika, izlistavanje svih računa koji su u minusu,
otvaranje novog računa za novog korisnika, kao i funkciju za prenos zadate svote sa
jednog na drugi račun u okviru banke. Jedan korisnik može imati samo jedan otvoreni
račun 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 rastućem redosledu šifre čiji elementi sadrže sledeća polja: st_sifra,
st_kolicina, st_cena i st_vrednost.
234
Zadatak 21 (5)
Napisati C program za elektronsko vođenje školske biblioteke. Svaki član
biblioteke je okarakterisan sa:
1) Prezi
me i ime,
2) Člans
ki broj,
3) Adres
a stanovanja,
4) Razre
d,
5) Telefo
n, i
6) Broj
uzetih knjiga.
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 određivanje inverzne matrice je sledeći: Prvo se formira jedinična
matrica AINZ. Matrica je jedinična ako su svi elementi na glavnoj dijagonaliu jednaki
jedan. Sada se od matrice A formira jedinična matrica. Kod matrice se mogu izvršavati
sledeće transformacije: sabiranje jedne vrsta (kolone) sa drugom vrstom (kolonom),
množenje vrste (kolone) brojem različitim od nule ili množenjem jedne vrste (kolone)
brojem i dodavanjem drugoj vrsti (koloni). Sav postupak koji se radi sa vrstama
(kolonama) matrice A tako da ona postane jedinična raditi i sa vrstama (kolonama)
matrice AINZ. Kada nakon ovih postupaka matrica A postane jedinična tada će matrica
AINZ postati inverzna matrica matrice A.
235
Program omogućava š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 matričnom
obliku omogućava rešavanje sistema linearnih jednačina.
x1 c1
a11
a
a12 a13 . . . a1n x c
. . . a 2 n 2 2
X C
a 22 a 23
A 21
.
. . . . .
. .
a n1 a2n a3n . . . a nn
xn c n
Rešenje matrične jednačine je dato u obliku: X A 1 C gde je A-1 inverzna
matrica matrice A. Slično kao i u predhodnom zadatku potrebno je obezbediti da rešenja
budu u obliku razlomaka koji se ne mogu skratiti. Sistem jednačina nalazi se zapisan u
tekstualnoj datoteci čiji naziv sa putanjom se unosi sa tastature.
Zadatak 24 (5)
Napisati C program za vođenje takmičenja iz osnova elektrotehnike. Svaki
takmičar je opisan sa imenom i prezimenom, naziv škole, ime grada i broj osvojenih
poena. Na osnovu unetih podataka formira se lista takmičara. Na osnovu liste rezultata
formirati dve datoteke. U datoteku POBEDNICI.TXT upisati takmičare koji su se
plasirali na daljnje takmičenje (20% učesnika). U datoteku PLASMAN.TXT upisati
plasman škola učesnica na takmičenju po rezultatu (ukuopan broj bodova koje su
takmičari te škole ostvarili).
Omogućiti da se formirane datoteke mogu štampati na štampaču (77 linija 12
inčna dužina papira). Stranice moraju imati zaglavlje i numeraciju.
236
Zadatak 25 (5)
Napisati C program koji na osnovu učitane datoteke sa C programom i na ekranu
prikazuje sledeći tabelarni prikaz pojave naredbi selekcije if, if-else ili naredbi ciklusa
for, while ili do-while po redovima u datoteci, u obliku:
Zadatak 27 (5)
U tekstualnoj datoteci SOKOBAN.TXT nalaze se zapisane table koje je potrebno
preći od popularne video igrice SOKOBAN. Table su razdvojene sa jednim praznim
redom. Vrednosti polja table može imati jednu od sledećih vrednosti: 0 – hodnik kroz koji
se gura crvena kockica i gde se kursor može kretati, 1 – zid, 2 – cevena kockica koju
treba pregurati na neko od postavljenih mesta obeleženih sa crnom kockicom, 3 – crna
kockica ili mesto gde treba dogurati crvenu kockicu i 4 – kursor u obliku smeska kojim se
kroz hodnike krećete sa strelicama i možete 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 zvučni signal prelazi se u
sledeći nivo. Kursor može gurati samo jednu kockicu u jednom smeru, a ako poguša
odjednom gurati njih više ili se pokuša gurati kockica a da je iza zid čuje se zvučni signal.
U slučaju da se pogrešilo tako da se ne može preći nivo sa SPACE se vraća na početak
tog nivoa. Ako se stisne ESC završava se igrica a od korisnika se traži ime kako bi se
podaci sačuvali u datoteci i time omogućilo da se prilikom ponovnog startovanja igrice
ne kreće od prve table već od one koju poslednji put nije pređena.
Zadatak 28 (5)
Napisati C program koji predstavlja poznatu igricu MINE stim da će se u ovom
slučaju igrica igrati sa tastaturom. Na samom početku programa pojavljuje se naslov sa
velikm slovima MINE koje su dobijene crtanjem kockica po kockica, a ispod toga meni
237
čija je prvobitna opcija označena crvenom bojom. Kroz meni se možete kretati sa
strelicama na gore i na dole. Sa leve strane nalazi se obaveštenje da se sa velikim slovom
L može dobiti lista 10 najboljih rezultata za dati nivo sa poljima ime igrača i vreme za
koje je igricu rešio, a ispod slovo S sa kojim se uključuje ili isključuje 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 označava broj
mina koje se na tabli nalaze.
Kada se izabere određeni nivo pritisne se ENTER formira se tabla za igru pri čemu
se a desne strane može videti vreme koje protiče dok traje igra. U gornjem levom uglu
nalazi se podatak koliko je zastavica ostalo. U gornjem desnom uglu nalazi se slovo S i
pored odgovarajuća poruka koja obaveštava šta će se desiti sa zvukom ako se unese
veliko slovo S.
Na sredini table nalazi se kursor sa kojim se strilicama može 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 nemože otvoriti. Kada se postavi
zastavica broj zastavica u gornjem levom uglu se automatski smanjuje za jedan.
U slučaju da se tabla reši sve zastavice će blinkovati i nakon pritisnutog tastera
ENTER ako je ostvareno vreme među prvih 10 pojaviće se lista najboljih sa imenom
Anonimus koje se može sa BACKSPACE izbrisati ili sa ENTER potvrditi.
U slučaju da se otvorilo polje gde postoji mina otvaraju se sva polja i mine koje su
obeležene sa crvenom zvezduicom će blinkovati. Ako se otvori polje gde nije mina
pojaviće se broj koji opisuje koliko mina to polje graniči, a ako je taj broj nula, broj se ne
prikazuje već se prikazuju svi najbliži brojevi koji nisu nule a nalaze se oko tog polja.
Nakon završetka igranja na odgovarajućoj tabli vračamo 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 slučajan način.
Zadatak 29 (5)
Napisati C program koji pretstavlja popularnu igricu ASOCIJACIJE iz muzičke
slagalice. Igrica je namenjena za dva igrača. U tekstualnoj datoteci u svakom redu nalazi
se po jedna reč. Reč ne sme da bude duža od 15 karaktera. Prva reč odnosi se na polje A1,
druga reč na polje A2, treća reč na polje A3, četvrta reč na polje A4, peta reč je rečenje
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 rešenje kolone B, itd. Ima četiri kolone A, B, C i D. Poslednja reč
je rešenje asocijacije. U datoteci postoji više asocijacija. Asocijacije su razdvojene
praznim redom. Na slučajan način 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 obaveštavate da igra sledeći
igrač. Igrica se igra sa mišem. Postoji polje KRAJ koje kada kliknete završavate igricu, i
iscrtava se rešenje asocijacije. Kada kliknete na polje za odgovor na kolonu ili konačno
rešenje, pojavljuju se zvezdice, ali broj zvezdica je uvek isti i ne zavisi od rešenja tog
polja. Ako igrač pogodi rešenje kolone cela kolona se iscrtava u njegovoj boji i za rešenje
238
dobija pet poena. Može otvarati sledeće polje ili kliknuti na DALJE čime omogućava da
polje otvara sledeći igrač. Igrač ne može da otvara polje za rešenje ako nije otvorio neko
ne otvoreno polje. Polje može otvarati iz bilo koje kolone.
Pogodak na konačno rešenje nosi 10 poena, pri čemu ako neka od kolona nisu
pogođena dobijaju se i poojeni (za svaku ne pogođenu kolonu po 5 poena) za te kolone.
Zadatak 30 (5)
Napisati C program koji pretstavlja igricu UKRŠTENICA. Prilikom startovanje
igrice unosi se ime tekstualnog fajla gde je zapisan format jedne ukrštenice. Na osnovu
tog formata iscrtava se prazna ukrštenica. Igrica se igra mišem ili tastaturom. Na osnovu
položaja kursora na donjim poljima (horizontalno, vertikalno) ispisuje se pitanje koje
odgovara odgovoru u toj vrsti ili koloni. Prilikom klika miša na neko polje na donjim
poljima se ispisuje horizontalno i vertikalno pitanje. Koje je horizontalno ili vertikalno
pitanje može se dobiti klikom na “polje sa pitanjem“. Kroz ukrštenicu može se kretati
strelicama. Unose se slova koja sde iscrtavaju žutom bojom.
Igrica se završava kada se klikne desim tasterom miša. Tada se dobijaju odgovori
na postavljena pitanja, pri čemu su slova crvene boje ako su na tim mestima bili pogrešni
odgovori, plave boje ako su bili tačni odgovori, ili žute boje ako korisnik na tim poljima
nije dao nikakav odgovor.
Na sledećoj strani dat je format tekstualne datoteke u kojoj je smeštena ukrštenica
sa pitanjima. Komentarima su data objašnjenja pravila po kojima je datoteka formirana.
Te komentare ne smete pisati u vašoj datoteci kada je budete formirali.
Format datoteke je predstavljen na sledećoj strani:
239
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 */
240
-@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/
241
7. POGLAVLJE
242
7.1. DINAMIČKA DODELA MEMORIJE
Definicija:
Deo memorije koji se dodeljuje u toku izvršavanja programa naziva se
dinamička zona memorije ili hip memorija.
Funkcija malloc alocira size bajtova u dinamičkoj zoni memorije. Ako uspešno
obavi zadatak funkcija vraća generički pokazivač na alocirani prostor u memoriji.
Ako dođe do greške biće vraćena vrednost NULL.
Funkcija free oslobađa prethodno alociranu memoriju na čiju početnu adresu sadrži
pokazivač buffer. Pokazivač buffer dobio je adresu pozivom funkcije malloc, calloc ili
realloc.
Primer 1:
Napisati deo koda koji omogućava deklaraciju pokazivača na tip podataka Tucenik,
a potom formira objekat na koga taj pokazivač pokazuje. U slučaju da se objekat nije
mogao formirati prikazati poruku da nije bilo dovoljno memorije.
Rešenje:
243
if(pokazivac = (Tucenik *) malloc(sizeof(Tucenik)) == NULL)
{
printf("Nije dobro alocirana memorija!! "),
return;
}
free(pokazivac);
Primer 2:
Napisati C program koji omogućava formiranje strukture radnik sa poljima:
Rešenje
#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;
/* 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 */
244
textmode(3);
textcolor(0);
textbackground(15);
clrscr();
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. */
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();
245
do{
gotoxy(xu,yu);
printf(" ");
gotoxy(xu,yu);
scanf("%lf",&a);
}while(a<=0);
pokazivac->koeficijent=a;
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;
}
}
246
/* Funkcija ispis_dohotka ispisuje dohodak koji je radnik ostvario i oslobadja prostor u
dinamickoj zoni memorije jer se objekat vise nece koristiti. */
247
7.2. JEDNOSTRUKO SPREGNUTA LISTA
Pojam i definicija, dodavanje elementa u listu
Na primer:
int a = 0, *pok = NULL;
pok=&a;
Zona podataka:
Pok a
CBD3 0
CBD3
pok=(Tcvor *)malloc(sizeof(Tcvor));
248
Na primer:
Zona podataka
Dinamička zona
objekat
249
Prikaz logičke i fizičke predstave јеdnostruko spregnute liste
250
void inicijalizacijaliste(Tcvor **glava)
{
*glava = NULL;
}
Prvi slučaj:
251
Drugi slučaj:
REZIME
252
• Kod nizova је isti logički i fizički poredak elemenata. Elementu sе pristupa
pomoću indeksa. Znači lak i brz pristup, što čini prednosti niza struktura u оdnosu
nа јеdnostruko spregnutu listu.
• Kod niza je potrebno аlocirati statički fiksan memorijski prostor којi sе
dimenzioniše prema maksimalno оčekivanom broju elemenata, što doprinosi
slabijem iskorišćenju memorijskog prostora. Takođe kod niza je neefikasno brisanje
i umetanje elemenata nа proizvoljnom mestu, јеr оni zahtevaju pomeranje
elemenata niza, dok se kod liste izvrši samo promena vrednosti pokazivača kojima
su čvorovi liste povezani.
novi = formcvor();
if(*glava==NULL) *glava=novi;
else{
tek=*glava
while(tek->sledeci!=NULL) tek=tek->sledeci;
tek -> sledeci=novi;
}
}
Razlikuju se dva slučaja. Prvi kada nema elemenata u listi i drugi kada ima
elemenata u listi. U prviom slučaju radi se isto kao i kod vezivanja na početak liste, samo
se povezuje pokazivač glava da pokazuje na novi element.
Prvi slučaj:
253
U drugom slučaju koriste se još jedan pomoćni pokazivač tek. Njegov zadatak je
da se prođe kroz listu tako da pokazivač tek na kraju po izlasku iz ciklusa pokazuje na
poslednji element u listi. Sada se uz pomoć pokazivača tek element lako vezuje na kraj
liste.
Drugi slučaj:
254
7.3.2. Traženje elementa u jednostruko spregnutoj listi
Traženje elementa u listi podrazumeva utvrđivanje da li neki elemenat liste ima
isti informacioni sadržaj kao i ključ (složeni podatak sa kojim se poredi).
Traženje elementa vrši se pomoću funkcije koja vraća adresu elementa u listi koji
ima isti informacionmi sadržaj kao i ključ, ili NULL ako nema takvog elementa u listi.
U listi samo jedan elemenat prilikom traženja poseduje takvo svojstvo. Funkciji
se po vrednosti prosleđuju pokazivač glava i ključ. Prosleđivanje po vrednosti se vrši iz
razloga što se vrednosti pokazivača glava neće promeniti, a ni ključ koji je tipa Tslog kao
i informacioni sadsržaj čvora liste.
Traženje se vrši pomoću pomoćnog pokazivača koji se postavlja na početku 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 pronađe takav element pomoćni pokazivač tek
posedovaće adresu tog elementa liste, a u slučaju da se ne pronađe imaće 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 traženja elementa u listi razlikuju se dva slučaja, Prvi da postoji element
liste koji ima isti informacioni sadržaj kao i ključ, i drugi da takvog elementa nema u listi.
Ključ može da bude podatak složenog tipa. U ovom primeru radi lakšeg praćenja ključ i
informacioni sadržaj su podaci osnovnog tipa int.
Prvi slučaj:
KLJUČ:15
255
Drugi slučaj:
KLJUČ:30
256
7.3.3. Brisanje liste i oslobađanje zauzete memorije
Prilikom rada sa dinamičkim strukturama podataka na kraju programa mora se
osloboditi zauzeta memorija u dinamičkoj zoni podataka (hip-a). To se u ovom slučaju
radi pomoću funkcije kojoj se prosleđuje pokazivač glava po referenci (jer će mu se
vrednost prilikom brisanja menjati).
Pri realizaciji koristi se pomoćni pokazivač tek, a brisanje se vrši sa početka liste
(onaj čijiu adresu sadrži pokazivač glava). Kada pokazivač glava bude imao vrednost
NULL znači da je lista obrisana iz memorije.
while(*glava!=NULL)
{
tek=*glava;
*glava=tek->sledeci;
free(tek);
}
}
Iteracija 1
257
Interacija 2
Iteracija 3
258
Primer:
Zadata je tekstualna datoteka BANKA.TXT koja sadrži podatke o štedišama jedne
banke. U svakom redu datoteke nalaze se podaci o jednom štediši banke u formatu:
259
65 godine života. Godišnja kamata u ovom trenutku za dobijanje stambenog kredita je
4.75% i zapišite je u simboličkoj 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 Mesečna rata.
Svaki red datoteke NEODOBRENI.TXT je u formatu:
Šifra i Redni broj opcije (broj jedan) zbog koga kredit nije odobren) u slučaju da
podnosilac kredita nije štediša banke, ili Šifra, Prezime, Ime i Redni brojevi opcija zbog
kojih kredit nije odobren (međusobno odvojeni zarezima).
Rešenje
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
/* 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;
260
Tcvor *glava;
char s[100];
if((dat=fopen("BANKA.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka BANKA.TXT se ne moze otvoriti!!");
return;
}
inicijalizacija(&glava);
uradi(glava);
printf("\n\n\tPosao je uspesno obavljen!!");
novi=(Tcvor *)malloc(sizeof(Tcvor));
novi->sled=NULL;
261
void dodajnapocetak(Tcvor **glava,Tcvor *novi)
{
if(*glava==NULL) *glava=novi;
else novi->sled=*glava, *glava=novi;
}
if((ul=fopen("KREDITI.TXT","r"))==NULL)
{
printf("\n\n\t\tDatoteka KREDITI.TXT se ne moze otvoriti!!");
return;
}
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);
/* 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 ");
}
262
}
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);
}
while(*glava!=NULL)
{
tek=*glava;
*glava=(*glava)->sled;
tek->sled=NULL;
free(tek);
}
}
7.4. JEDNOSTRUKO SPREGNUTA LISTA
Brisanje elementa iz jednostruko spregnute liste
Formiranje sortirane jednostruko spregnute liste
tek= trazi(*glava,kljuc);
if(tek==NULL) return 0;
263
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;
}
Prvi slučaj:
Prvi slučaj je kada je element koji se briše prvi elemenat liste. Prilikom brisanja
elementa mora se prvo utvrditi da li elementa ima u listi, što se radi pomoću funkcije
traži koja je obrađena na prošlom času. Ako funkcija vrati vrednost NULL znak je da
elementa nema u listi, a u suprotnom pomoćni pokazivač tek dobija adresu pronađenog
elementa koga treba izbrisati iz liste. U prvom slušaju pokazivači tek i pret pokazuju gde
i pokazivač glava.
264
Drugi slučaj:
Drugi slučaj obuhvata varijante kada je element koji se briše nije prvi element
liste. Prilikom brisanja elementa mora se prvo utvrditi da li elementa ima u listi, što se
radi pomoću funkcije trazi koja je obrađena na prošlom času. Ako funkcija vrati vrednost
NULL znak je da elementa nema u listi, a u suprotnom pomoćni pokazivač tek dobija
adresu pronađenog elementa koga treba izbrisati iz liste. Kada smo našli elementa koga
treba izbrisati i njegovu adresu sadrži pokazivač tek, kako je lista jednostruko spregnuta
ne postoji pokazivač kojim bismo lako došli do elementa koji je logički predhodnik od
elementa koji se briše, moramo koristiti još jedan pomoćni pokazivač pok. Prolazimo
while ciklusom kroz listu sve dok pok ne dobije adresu predhodnika od elementa koji se
briše. Izvrši se prelančavanje liste i sa funkcijom free oslobodi memorija.
265
Pokazivači iza i ispred koriste se u slučaju 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 ligički
sledeći u odnosu na onog koji se uvezuje, a pokazivač iza pokazuje na čvor koji je logički
prehodnik u odnosu na čvor koji se uvezuje. U slučaju da je potrebno uvezati čvor na kraj
liste, pokazivač ispred imaće vrednost NULL (jer nema logičkog sldbenika), a pokazivač
iza pokazivaće na poslednji element liste. Kada pokazivači iza i ispred sadrže potrebne
adrese, tada je lako izvršiti vezivanje novog elementa.
ispred=*glava;
while(ispred!=NULL&&novi->info.pod>ispred->info.pod)
{
iza=ispred;
ispred=ispred->sledeci;
}
novi->sledeci=ispred;
if(*glava==ispred) *glava=novi;
else iza->sledeci=novi;
}
U ovom primeru smatralo se da informacioni sadržaj čvora liste sadrži podatak pod
koji će učestvovati u ispunjavanju uslova kriterijuma sortiranja. Može više podataka
učestvovati u kriterijumima sortiranja, ali tada je potrebno modifikovati datu funkciju u
while uslovu. Iteratifni postupak formiranja jednostruko spregnute liste može se opisati
kroz četiri slučaja.
Prvi slučaj:
U prvom slučaju lista je prazna, te se novi čvor dodaje na početak liste.
Drugi slučaj:
U drugom slučaju postoji lista, a element koji se dodaje u listi treba da se uveže na
početak liste. U ovom slučaju while ciklus se nije izvršio ni jednom te pokazivač iza
266
pokazuje na prvi cvor liste, gde i pokazivač glava, a kako liste ima to im je vrednost
različita od NULL.
Treći slučaj:
U ovom slučaju čvor treba uvezati na kraj liste. To se zaključilo na osnovu vrednosti
pokazivača iza i ispred nakon završetka while ciklusa. Pokazivač iza pokazivaće na rep
liste, a pokazivač ispred imaće vrednost NUUL.
267
Četvrti slučaj:
U ovom slučaju nakon završetka while ciklusa pokazivači iza i ispred su različiti od
NULL, a to je znak da je novi element potrebno uvezati negde na sredinu liste (nije
početak, a nije ni kraj liste). Pokazivač ispred pokazivaće na čvor koji je logički
sledbenik u odnosu na element koji se uvezuje u listu, a pokazivač iza pokazivaće na čvor
koji je logički prethodnik u odnosu na element koji se uvezuje u listu.
268
Rekurzivni postupak znači 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 uveže u listu a na njega pokazuje pokazivač novi.
Prvi slučaj:
U prvom slučaju lista je prazna, te se novi element uvezuje na stvarni početak liste.
Izvrseno je prosledjivanje pokazivača glava po referenci na stek, te se prvi element liste
vezuje na početak liste
Drugi slučaj:
U drugom slučaju element se ne uvezuje na stvarni početak liste. Kako se poziva
rekurzivna funkcija, to će kada se zadovolje uslovi iskakanja iz rekurzije, pokazivač
glava iz poslednjeg aktivacionog zapisa pokazivati na logičkog sledbenika u odnosu na
element koga treba uvezati u listu. Znači da će se izvršiti uvezivanje na početak liste u
odnosu na pokazivač glava iz poslednjeg aktivacionog zapisa.
269
270
Nakon uvezivanja završava se poslednje pozvana rekurzivna funkcija, a kako
ispod nje nema naredbi završiće se prethodno pozvana rekurzivna funkcija, itd. Znači
brisaće se jedan po jedan aktivacioni zapisa sa steka.
271
Primer:
U tekstualnoj datoteci POLINOM.TXT nalaze se polinomi. Svaki red datoteke
sadrži jedan polinom. Polinom je opisan sa nizom uređenih parova
(a k , x k ), k [1..n] k N n N . Nacrtati najjednostavniji i ujedno najefikasniji
strukturni dijagram (uz objašnjenje zašto baš on) i na osnovu njega napisati C program
koji na osnovu datoteke izračunava rezzultujući polinom, kao zbir svih polinoma koje
sadrži datoteka. Na kraj datoteke dodati liniju kojom se podvlači crta, a ispod crte
štampati i rezultujući polinom.
Rešenje
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
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!");
272
}
/* 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);
printf("\n\n\t\tPosao je obavljen!!");
getch();
}
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';
prvi=atoi(prvis);
j=0,i++;
while(s[i]!=')') drugis[j]=s[i],i++,j++;
drugis[j]='\0';
drugi=atoi(drugis);
273
{
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;
/* 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 = ");
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,",");
}
}
274
Test primer:
(2,5),(2,1),(3,0)
(1,4),(9,0)
(2,5),(2,1),(3,0)
(1,4),(9,0)
---------------------------------------
SAB = (2,5),(1,4),(2,1),(12,0)
7.5. STEK
Realizacija stek-a pomoću niza
Realizacija stek-a pomoću jednostruko spregnute liste
275
vrh
Primer 1:
Napisati C program koji vrši ažuriranje tekstualne datoteke REDOVI.TXT
primenom steka (ealizovanog pomoću niza). U svakom redu datoteke nalaze se podaci o
jednom učeniku. Nije potrebno obrađivati te podatke već treba datoteku ažurirati u
inverznom poretku po redovima.
Na primer:
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
/* Prototipovi funkcija. */
unsigned push(FILE *dat, Tredovi niz[], int *n);
unsigned pop(FILE *dat, Tredovi niz[], int *n);
void main(void)
{
276
/* 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();
/* Datoteka se ponovno otvara sada za pisanje i time se predhodni sadrzaj datoteke brise.
*/
dat=fopen("REDOVI.TXT","w");
fclose(dat);
printf("\n\nU datoteku REDOVI.TXT upisani su redovi u obrnutom redosledu!!");
gotoxy(1,25);
getch();
}
if(fgets(s,80,dat)!=NULL)
277
{
/* 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");
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;
return 1;
}
Primer 2:
Napisati C program koji vrši ažuriranje tekstualne datoteke REDOVI.TXT
primenom steka (realizovanog pomoću jednostruko spregnute liste). U svakom redu
datoteke nalaze se podaci o jednom učeniku. Nije potrebno obrađivati te podatke već
treba datoteku ažurirati u inverznom poretku po redovima.
Na primer:
Rešenje
#include <stdio.h>
278
#include <conio.h>
#include <string.h>
#include <stdlib.h>
/* Prototipovi funkcija. */
unsigned push(FILE *dat, Tcvor **vrh);
unsigned pop(FILE *dat, Tcvor **vrh);
void main(void)
{
/* Deklaracija promenljivih. */
FILE *dat;
Tcvor *vrh=NULL, *glava=NULL;
textmode(3);
textbackground(0);
textcolor(15);
clrscr();
/* Datoteka se ponovno otvara sada za pisanje i time se predhodni sadrzaj datoteke brise.
*/
dat=fopen("REDOVI.TXT","w");
fclose(dat);
printf("\n\nU datoteku REDOVI.TXT upisani su redovi u obrnutom redosledu!!");
279
getch();
}
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;
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;
if(*vrh==NULL) return 0;
return 1;
}
280
Primer 3:
Zadata je tekstualna datoteka PRIMER.TXT. Korišćenjem dinamičke strukture podataka
STEK formirati izlaznu datoteku IZLAZ.TXT gde će biti zapisana datoteka PRIMER.TXT u
invernom poretku po pasusima. Između pasusa postoji prazan red.
Rešenje:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
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;
}
/* 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);
281
}
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;
}
novi=(Tcvor *)malloc(sizeof(Tcvor));
strcpy(novi->rec,s); novi->sled=NULL;
if((*vrh)==NULL) *vrh=novi;
else{
novi->sled=*vrh;
*vrh=novi;
}
}
return pok;
}
Primer:
U tekstualnoj datoteci LAVIRINT.TXT nalazi se mapa lavirinta. U prvom redu su
dimenzije matrice lavirinta, a u sledećim redovima je matrica lavirinta. Elemente lavirinta
čine brojevi od 0-3, čija su značenja:
282
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 više izlaza koji
se nalaze takođe na krajevima matrice (prva vrsta, zadnja vrsta, prva kolona, zadnja
kolona). Potrebno je prikazati sve moguće puteve izlaska iz lavirinta. Sa pritiskom na bilo
koji taster prikazuje se sledeći put izlaska (sledeće rešenje).
Zadatak rešiti rekurzivnom tehnikom.
Rešenje
#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)
{
/* 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);
283
clrscr();
textcolor(4);
_setcursortype(_NOCURSOR);
gotoxy(36,2);
cprintf("LAVIRINT");
/* 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;
}
/* Odredjuju se startne pozicije gornjeg ugla lavirinta tako da lavirint bude uvek na
sredini ekrana. */
*startx=41-3*(*kol)/2;
*starty=12-(*vr)/2;
284
if(m[i][j]==2) *poci=i, *pocj=j;
}
}
fclose(dat);
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);
cprintf(" $ "); /* Sa karakterom $ oznacice se covek u lavirintu.
*/
}
if(m[i][j]==3)
{
textbackground(0);
textcolor(2);
cprintf("IZL");
}
}
}
285
/* 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{
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);
}
/* 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);
286
textcolor(4);
cprintf("$");
}
}
}
while(!kbhit()); /* Dok ne pritisnes taster gledaj resenje. */
287
Za razliku od jednostruko spregnute liste omogućeno je lakše dodavanje elementa
na kraj liste. Prilikom dodavanja elementa na kraj jednostruko spregnute liste moralo se
sa pomoćnim pokazivačem doći 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 tačno jedna reč. Jedna reč može se pojavljivati u više redova datoteke. Formirati
dinamičku 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.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
void main(void)
{
288
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;
}
/* 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;
dat=fopen("IZL.TXT","w");
tek=glava;
while(tek!=NULL)
{
289
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 račun u formatu:
U datoteci se može nalaziti više uplata i isplata sa istom šifrom. Na osnovu ulazne
datoteke formirati dinamičku strukturu podataka RED.
Nakon formiranja reda (ne može više članova reda imati istu šifru), izvršiti njegovo
sortiranje u rastućem redosledu, ali bez korišćenja dodatnih čvorova i objekata.
Na osnovu dinamičke strukture, formirati izlaznu datoteku IZRAC.TXT u kojoj će
biti prikazani podaci sortirani u rastućem redosledu po kriterijumu stanje na računu.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
void main(void)
290
{
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;
}
printf("\n\n\t\tPosao je obavljen!!");
getch();
}
if(tek==NULL)
291
{
/* 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;
if(!strcmp(ui,"U")) tek->info.iznos+=pom.iznos;
else tek->info.iznos-=pom.iznos;
}
}
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;
}
/* Sada se taj cvor uvezuje u novi red, gde je pokazivac na prvi cvor glava1, a
pokazivac na rep rep1. */
292
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;
}
tek=*glava;
while(tek!=NULL)
{
293
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
294
Često je potrebno od jednog čvora liste doći do njegovog logičkog predhodnika.
Kod jednostruko spregnute liste bilo bi potrebno preći sve članove liste od prvog čvora
do predhodnika. Zbog toga je korisno da svaki čvor, pored pokazivača na sledeći čvor,
poseduje i pokazivač na predhodni čvor liste. Kada čvor liste poseduje dva pokazivača,
jedan na predhodni, a drugi na sledeći čvor liste, kažemo 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 spoljašnja pokazivača,
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
pokazivače. Prilikom umetanja novog čvora u listu, osim pokazivača koji pokazuje na
objekat koji se umeće u listu i jednog koji pokazuje na čvor liste ispred (ili iza) koga
treba umetnuti novi čvor, nisu potrebni dodatni pokazivači. Prilikom brisanja potrebno je
imati samo pokazivač na čvor koji treba da se izbrise iz liste.
.
poc kraj
Primer 1:
Zadata je kestualna datoteka BROJEVI.TXT koa u svakom redu sadrži po jedan
racionalan broj. Na osnovu sadržaja datoteke formirati dvostruko spregnutu listu.
Čvor liste je definisan na sledeći način:
Rešenje
#include <stdio.h>
295
#include <conio.h>
#include <stdlib.h>
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));
novi->brpojava=1;
novi->br=atoi(s);
if(tek==poc)
296
{
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();
}
Primer 2:
297
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 služi za čuvanje podataka o polaganju svih
vandrednih učenika za bilo koje ispite u nekom proizvoljnom vremenskom periodu.
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje
zašto baš on) i na osnovu njega napisati C program koji za izabranog studenta na osnovu
evidencionog broja štampa na ekranu tabelarni prikaz položenih ispita. U svakom redu po
jedan ispit: Redni broj ispita, Šifra i naziv ispita, Datum polaganja ispita i ocena.
Program ne vrši kontrolu podataka iz binarnih datoteka, jer se smatra da su podaci
ispravni.
Rešenje
#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. */
298
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. */
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);
/* Unosi se evidencionalni broj ucenika. */
evbroj=unos_ceo();
299
if(evbroj==-1) return;
textbackground(15);
glava=NULL;
ucenik=fopen("UCENIK.DAT","r+b");
300
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);
301
fclose(ispit);
c=getch();
}while(c!=ESC);
}
x=0;
do{
c=getch();
if(c==ESC) return -1;
/* 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);
}
302
{
while(tek!=NULL&&(tek->info.evbroj)!=evbroj) tek=tek->sledeci;
if(tek==NULL)
{
return NULL;
}else{
return tek;
}
}
Primer 3:
Tekstualna datoteka LETOVI.TXT sadrži spisak svih avionskih linija jedne avio
kompanije. Svaka linija teksta sadrži sledeća polja: broj leta, ime grada iz kojeg avion
poleće, ime grada do koga avion leti i cenu leta, pri čemu su pojedina polja razdvojena sa
znakom #:
broj leta # poletni grad # odredišni grad # cena leta
Može postojati više letova čiji poletni grad je isti. Takođe može postojati više letova
sa istim odredišnim gradom.
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje
zašto baš on) i na osnovu njega napisati C program koji omogućava:
303
Za zadate gradove A i B odrediti niz letova kojima se stiže iz grada A do
grada B sa minimalnim brojem sletanja, kao i ukupnu cenu ovakvog leta.
U analizu dolazi maksimalno tri sletanja.
Rešenje
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
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)
{
printf("\n\tDatoteka se ne moze otvoriti!!!");
return;
}else{
304
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;
strcpy(glava->grad,iz);
glava->sledeci=NULL;
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));
pok=pret->sledeci;
strcpy(pok->grad,iz);
pok->sledeci=NULL;
305
/* 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(BLUE);
textbackground(WHITE);
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(" ");
/*Unos opcije*/
do{
gotoxy(x+1,y);
306
a=getche()-48;
}while(a<=0&&a>5);
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;
case 3: printf("\n\n\tPoletanje: ");
scanf("%s",&iz);
printf("\tSletanje: ");
307
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);
308
/*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);
while(p3!=NULL)
{
p3=p3->dalje;
309
/* 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;
}
310
Tcvor *pol;
pol=glava;
while(pol!=NULL&&strcmp(pol->grad,kljuc)) pol=pol->dalje;
return pol;
}
311
Zadatak 1 (2)
Zadata je tekstualna datoteka TEKST.TXT. Nacrtati najjednostavniji i ujedno
najefikasniji strukturni dijagram (uz objašnjenje zašto baš on) i na osnovu njega napisati
C program koji modifikuje datoteku TEKST.TXT tako što se polazna datoteka
transformiše u datoteku čiji su redovi ispisani u obrnutom poretku.
Zadatak 2 (2)
U tekstualnoj datoteci SPISAK.TXT nalazi se spisak građana gde je u jednoj liniji
teksta prezime, ime i težina. Podaci su razdvojeni sa praznim mestima i/ili tabulatorima.
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje
zašto baš on) i na osnovu njega napisati C program koji brzo daje odgovor na upit težina
za zadatog građanina.
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 uređenih parova (a k , x ), k [1..n] k N n N . Nacrtati
k
najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje zašto baš on) i
na osnovu njega napisati C program koji na osnovu datoteke izračunava i u trećem 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 tačno
jedno ime i prezime međusobno razdvojeni blanko mestima i/ili tabulatorima. Nacrtati
najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje zašto baš on) i
na osnovu njega napisati C program koji na ekranu i u datoteci IZVESTAJ.TXT štampa
izveštaj sledećeg izgleda:
Zadatak 5 (2)
Zadata je tekstualna datoteka BROJEVI.TXT koja u svakom redu sadrži uopšteno
jedan realan podatak Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram
(uz objašnjenje zašto baš on) i na osnovu njega napisati C program koji iz datoteke briše
one brojeve koji su negativni i imaju vrednost veću od srednje vrednosti brojeva iz
datoteke. Za izračunavanje srednje vrednosti koristiti funkciju srednjavrednost čiji je
prototip: double srednjavrednost(Tcvor **glava); gde je glava pokazivač na prvi
elemenat liste.
Zadatak 6 (2)
312
Zadata je tekstualna datoteka BROJEVI.TXT koja u svakom redu sadrži uopšteno
jedan realan podatak Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram
(uz objašnjenje zašto baš on) i na osnovu njega napisati C program koji preuređuje
datoteku tako da se prvo ispisuju negativni brojevi sortirani u opadajućem redosledu, a
potom pozitivni brojevi sortirani u rastućem redosledu. U svakom redu nalazi se samo
jedan broj.
Zadatak 7 (2)
Zadata je tekstualna datoteka SPISAK.TXT koja sadrži spisak imena i prezimena.
U svakom redu datoteke nalazi se tačno jedno ime i prezime međusobno 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 objašnjenje zašto baš on) i na osnovu njega
napisati C program koji efikasno rešava dati problem.
Zadatak 8 (3)
Binarna datoteka KRUGOVI.DAT je formata: x (double), y (double) i r (double).
Sa x i y označen je centar kruga a r je poluprečnik kruga. Nacrtati najjednostavniji i
ujedno najefikasniji strukturni dijagram (uz objašnjenje zašto baš on) i na osnovu njega
napisati C program koji iz datoteke izbacuje sve one krugove koji se nalaze unutar
krugova sa najvećim poluprečnicima.
Zadatak 9 (3)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje
zašto baš on) i na osnovu njega napisati C program za vođenje evidencije robe neke
tehničke prodavnice. Roba je okarakterisana: nazivom (do 30 karaktera), šifrom (do 15
karaktera), količinom u magacinu i cenom po komadu.
Zadatak 10 (3)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje
zašto baš on) i na osnovu njega napisati C program za praćenje glasanja na muzičkom
festivalu. Svaka pesma dobija ocenu žirija od 0 do 10 i ocenu publike od 0 do 10.
Program treba da omogući unos naziva pesme, naziv izvođača, broj osvojenih bodova,
kao i izlistavanje rezultata po opadajućem redosledu broja bodova.
Zadatak 11 (3)
313
Zadata je tekstualna datoteka TEKST.TXT. Nacrtati najjednostavniji i ujedno
najefikasniji strukturni dijagram (uz objašnjenje zašto baš on) i na osnovu njega napisati
C program koji modifikuje datoteku TEKST.TXT tako što se polazna datoteka
transformiše u datoteku čije su rečenice ispisane u obrnutom poretku.
Zadatak 12 (3)
Data je binarna datoteka čije ime se unosi sa tastature u formatu: oznaka (string od
6 karaktera), količina (float) i datum (string oblika dd.mm.gggg). Oznaka predstavlja
uređaj koji proizvodi neki proizvod. Količina predstavlja proizvedenu količinu na tom
uređaju u toku dana koji je označen sa datum. Nacrtati najjednostavniji i ujedno
najefikasniji strukturni dijagram (uz objašnjenje zašto baš on) i napisati C program koji
sekvencijalno učitava 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 najveću količinu. U svakom redu datoteke nalaze se podaci
oblika (oznaka, količina 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.
Zadatak 14 (3)
U tekstualnoj datoteci TELEFONI.TXT u svakom redu nalazi se zapisan po tačno
jedan broj telefona (između brojeva mogu postojati praznine, tabulatori i crtice). Korisnik
je dobio ogroman telefonski račun te od pošte zatraži da za dati mesec dobije izveštaj
telefonskih poziva. Pošta molbu ne prihvati (vlasnik telefona nije u zemlji), ali mu
drugarica iz pošte 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 objašnjenje
zašto 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
najveći broj impulsa datog meseca.
314
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) međusobno 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 objašnjenje zašto baš
on) i na osnovu njega napisati C program koji sekvencijalno učitava tekstualne datoteke,
formira odgovarajuću strikturu i na osnovu nje izlazne matrice IZLAZxx.TXT koje
pretstavljaju rezultujuće matrice zapisane u formatu ulaznih matrica. Svaka datoteka
IZLAZxx.TXT sadržaće 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 objašnjenje
zašto baš on) i na osnovu njega napisati C program koji automatizuje finalno takmičenje
u streljaštvu n kome učestvuje 10 finalnih strelaca, najboljih po plasmanu iz
predtakmičenja. Svaki strelac ima 10 hitaca koji se ocenjuju u opsegu od 0.0 do 11.0
bodova. Svaki strelac je okarakterisan sledećim atributima: takmičarski broj, ime i
prezime, broj bodova iz predtakmičenja i bodovima finalnih hitaca. Program treba da
omogući sledeće funkcije:
Zadatak 17 (4)
Data je tekstualna datoteka čiji naziv se unosi sa tastature. Nacrtati najjednostavniji
i ujedno najefikasniji strukturni dijagram (uz objašnjenje zašto baš on) i na osnovu njega
napisati C program koji na osnovu unesene reči utvrđuje koliko se ta reč pojavljuje u
datoteci i u kojim sve redovima se nalazi i koliko puta.
Zadatak 18 (4)
Datoteka DELOVI.DAT sadrži 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 objašnjenje zašto baš on) i
na osnovu njega napisati C program koji za zadati automobil izlistava sve njegove
raspoložive 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 postojećeg dela iz strukture.
315
Zadatak 19 (4)
U tekstualnoj datoteci čiji naziv se unosi sa tastature nalaze se podaci: prezime, ime,
prosečna ocena, broj opravdanih izostanaka i broj neopravdanih izostanaka. Podaci su
razdvojeni sa po jednim praznim mestom. Nacrtati najjednostavniji i ujedno najefikasniji
strukturni dijagram (uz objašnjenje zašto baš on) i na osnovu njega napisati C program
koji daje prikaz podataka po sledečim kriterijumima:
Rastući poredak po prosečnoj oceni, a drugi kriterijum sortiranja je
alfanumerički poredak po prezimenu i imenu učenika; i
Opadajući poredak po broju neopravdanih izostanaka, drugi kriterijum je
veći broj izostanaka, a treći kriterijum je alfanumerički kriterijum po
prezimenu i imenu učenika.
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 međusobno
razdvojena sa jednim praznim mestom: šifra poreza (dve cifre), stopa saveznog poreza
(tri cela i dva decimalna mesta) i republička stopa poreza (tri cela i dva decimalna mesta).
U datoteci ROBA.TXT u svakom redu nalazi se tri podatka međusobno razdvojena
sa jednim praznim mestom: šifra robe (12 cifara), cena robe (pet celih i dva decimalna
mesta) i šifra poreza kojem podleže ta roba (dve cifre).
U datoteci PRODAJA.TXT u svakom redu nalazi se tri podatka međusobno
razdvojena sa jednim praznim mestom: šifra robe koja je prodata (12 cifara), datum kada
je roba prodata u formatu dd.mm.gggg i količina te robe prodate tog datuma (tri cela i dva
decimalna mesta)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje
zašto baš on) i na osnovu njega napisati C program koji izračunava proseke obaveza za
zadati period i štampa izveštaj sledećeg izgleda:
Zadatak 21 (4)
Data je tekstualna datoteka BANKA.TXT koja u svakom redu sadži tri podatka
međusobno razvojena sa po jednim praznim mestom: račun (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 sledeći način:
Ako smo pročitali podatke jednog objekta čiji atribut račun nije u listi,
uvežite ga na kraj.
316
Ako smo pročitali podatke jednog objekta čiji atribut račun se nalazi u listi,
uvezati ga iza poslednjeg čvora sa tim računom.
Koristeći se sadržajem liste, odštanpati sledeći izveštaj:
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 može nalaziti više podataka sa istom
šifrom) i ekst (string od 20 karaktera).
Napisati C program koji sekvencijalno čita datoeku i formira jednostruko spregnutu
listu sortiranu u rastućem redosledu šifre, tako da su svi duplikati jedne šifre vezani u
listu čiji je početak u sortiranoj listi. Ta lista duplikata treba da je formirana po principu
umetanja na poslednje mesto u listi.
Na kraju odštampati izveštaj sledećeg izgleda:
Zadatak 23 (5)
Date su binarne datoteke GRADJANI.DAT i RACUNI.DAT. Datoteka
GRADJANI.DAT je formata: prezime i ime građanina (do 40 karaktera), JMBG (13
karaktera) i dažbine koje građanin treba da plati. Datoteka RACUNI.DAT sadrži podatke
o žiro i tekućim računima građana i to: JMBG, broj računa i stanje na računu. Jedan
građanin može da ima više žiro ili tekućih računa, a može uopšte da nema računa.
Program treba da formira sledeću strukturu:
317
Lista građana dodavanjem na početak;
Lista računa za svakog građanina u listi građana;
Iz tako dobijene strukture izvršiti izbacivanje građana koji imaju više novca na
računima, nego što je iznos njihovih dažbina; i
Smeštanje ostataka liste u tekstualnu datoteku DUZNICI.TXT, pri čemu svaki red
datoteke sadrži podatke: ime, prezime, JMBG i iznos duga. Podaci su razdvojeni sa
jednim praznim mestom.
Zadatak 24 (5)
U Sremskim Karlovcima svake godine održavaju se dani vina. Ove godine rešeno je
da se putem SMS poruka izvrši takmičenje. Poruke se upisuju u datoteku
PORUKE.TXT. Svaki red datoteke sadrži jednu poruku u formatu:
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.
Zadatak 25 (5)
Mali Perica je počeo da skija. Perica je egzibicionista i ne skija po stazama, već
skija kako stigne. Zbog toga, služba spasavanja je rešila da napravi program koji će
simulirati kretanje Perice od početne pozicije do cilja. Program prikazuje sva moguća
rešenja. Mapa terena se nalazi u datoteci MAPA.TXT. Prvi red datoteke čine dva broja
(broj vrsta i broj kolona mape) međusobno 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
međusobno razdvojeni praznim mestima koji označavaju startno mesto od koje Perica
počinje da skija.
318
Perica se spušta samo u pravcu jedne koordinate (ne dijagonalno), i to isključivo sa
mesta koje ima veću visinu na mesto niže visine. Potencijalni cilj su ona mesta koja na
mapi imaju najmanju visinu.
Zadatak 26 (5)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje
zašto baš on) i na osnovu njega napisati C program za elektronsko vođenje školske
biblioteke. Svaki član biblioteke je okarakterisan sa:
7) Prezi
me i ime,
8) Člans
ki broj,
9) Adres
a stanovanja,
10) Razre
d,
11) Telefo
n, i
12) Broj
uzetih knjiga.
Zadatak 27 (5)
Nacrtati najjednostavniji i ujedno najefikasniji strukturni dijagram (uz objašnjenje
zašto baš on) i na osnovu njega napisati C program koji prihvata podatke o posetiocima
nekog preduzeća gde je svaki posetioc okarakterisan sa: prezimenom i imenom (do 30
karaktera), JMBG (13 karaktera) i vremenom ulaska i napuštanja preduzeća.
319
1. Unos podataka o posetiocu pri ulasku i izlasku iz preduzeća;
2. Prikaz svih podataka o posetama za datog zaposlenog, tabela sa kolonama:
ULAZAK, IZLAZAK, PREZIME I IME;
3. Prikaz svih poseta koji još nisu izašli iz preduzeća, tabela sa kolonama:
ULAZAK, PREZIME I IME, POSETA ZA;
4. Prikazati na ekranu ime i prezime najvećeg zabušanta. Najveći zabušant je
onaj radnik koji je najveći interval vremena proveo u razgovoru sa svojim
posetiocima. U slučaju da je njih više imalo isti maksimalni vremenski
interval trajanja posete, najveći zabušant postaje onaj radnik koga je u toku
dana posetilo najviše 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 sadrže podatke o proizvođačima automobila i kupcima jedne auto
kuće. Datoteke sadrže sledeće podatke:
PROIZVODI.TXT
Naziv proizvođača automobila (od maksimalno 40 karaktera);
Mesto (od maksimalno 20 karaktera).
AUTOMOBILI.TXT
Tip automobila (od maksimalno 30 karaktera);
Naziv proizvođača (od maksimalno 40 karaktera);
Cena (od maksimalno 10 karaktera); i
Količina na lageru (od maksimalno 5 karaktera)
KUPCI.TXT
Ime kupca (od maksimalno 30 karaktera);
Tip automobila (od maksimalno 30 karaktera); i
Već uplaćeni iznos (od maksimalno 10 karaktera).
2) Spisak svih kupaca. Za svakog kupca navesti spisak svih automobila koje
kupuje, ukupno uplaćen iznos kao i ukupan iznos koji duguje auto kući.
320
Zadatak 29 (5)
U tekstualnoj datoteci BEGUNAC.TXT nalazi se mapa zamka. Na ulazu u zamak
nalazi se begunac. Postoji više puteva u zamku kojim je begunac mogao pobeći policiji,
kao i više izlaza iz zamka. U samom zamku na jednom mestu policija je postavila zasedu.
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 odgovarajuće težine.
Između formata zapisa pitanja nalazi se prazan red. Format zapisa pitanja prostire se
u ŽŽ reda. Prvi red sadrži broj koji predstavlja težinu pitanja i samo pitanje, razdvojeni
znakom #. U naredna četiri reda nalaze se ponuđeni 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 tačno na postavljeno pitanje. Svaka naredna opcija nosi više novca i
ima veću težinu 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 poneđena četiri odgovora (ispred odgovora je slovo A..D). Igrac može
pritiskom na odgovarajuće slovo dati odgovor ili zatražiti pomoć. Ako da odgovor na
pitanje pritiskom na odgovarajuće slovo, računar mu saopštava da li je odgovor tačan te
ako jeste može odgovarati na sledeće pitanje veće težine i saopštava mu se koliko ima
trenutno novca. Ako je odgovorio pogrešno kraj je igre. Igraču su na raspolaganju i tri
pomoći: pomoć računara1 (brišu se dva od četiri ponuđena odgovora), pomoć računara2
(briše se jedno od četiri ponuđena odgovora) i pomoć prijatelja (na osnovu četiri učitana
broja koja su predstavljala procente, prikazuju se procentualna zastupljenost odgovora A,
321
B, C i D od strane puublike). Pomoći su numerisane sa brojevima 1, 2 i 3. Igrač u toku
igre može ako hoće iskoristiti ponuđene pomoći, ali svaku pomoć samio jednom u toku
cele igre.
Igra se može u toku trajanja programa igrati više puta, ali se ne smeju ponavljati
pitanja od predhodnih odigranih partija.
322