Professional Documents
Culture Documents
Zbirka Vjezbi Iz Programskog Jezika C PDF
Zbirka Vjezbi Iz Programskog Jezika C PDF
ZBIRKA ZADATAKA
IZ
PROGRAMSKOG JEZIKA C
V 1.0 05/08/2015
_________________________________________________________
ETF Beograd
ETF Podgorica
ETF Sarajevo
FER Zagreb
FSB Split
FTN Kosovska Mitrovica
MAT FAK Beograd
PMF Niš
PMF Srbsko Sarajevo
FTN Čačak
UN Singidunum Beograd
VTŠ Čačak
VTŠ Niš
_____________________________________________________________
Sakupio i obradio:
jjanko2015@gmail.com
SADRŽAJ
_________________________________________________________________
C reference card ANSI
Službeni podsetnik FER Zagreb
1.ETF Beograd
2.ETF Podgorica
3.ETF Sarajevo
4.FER Zagreb
5.FSB Split
6.FTN Kosovska Mitrovica
7.MAT FAK Beograd
8.PMF Niš
9.PMF Srbsko Sarajevo
10.FTN Čačak
11.UN Singidunum Beograd
12.VTŠ Čačak
13.VTŠ Niš
_________________________________________________________________
Napomena:
4 5 6
Programiranje i programsko inženjerstvo – službeni podsjetnik verzija 2013.b
Viši prioritet
0 znamenka nula 48 referenciranje .
A veliko slovo A 65 postfiks ++ --
a malo slovo a 97 ! ~ ++ -- sizeof & *
prefiks ++ -- D → L
unarni + -
Prikaz realnih brojeva
(cast) D → L
IEEE 754 jednostruka IEEE 754 dvostruka
preciznost preciznost * / % L → D
K = BE + 127 K = BE + 1023 binarni + - L → D
denormalizirani broj: K = 0 denormalizirani broj: K = 0 << >> L → D
± ∞ ili NaN: K = 255 ± ∞ili NaN: K = 2047 < <= > >= L → D
Niži prioritet
najveći pozitivan broj najveći pozitivan broj == != L → D
3.4 × 1038 1.8 × 10308 & L → D
najmanji pozitivan broj najmanji pozitivan broj ^ L → D
1.4 × 10-45 4.9 × 10-324
| L → D
ρ 2-24 6 × 10-8 ρ 2-53 1.1 × 10-16 && L → D
|| L → D
math.h ? : D → L
double fabs (double x); x = *= /= %= += -=
double sin (double x); D → L
&= ^= |= <<= >>=
double cos (double x); , L → D
double tan (double x);
string.h
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t maxlen);
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t maxlen);
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t maxlen);
char *strchr(const char *s, int c);
Programiranje i programsko inženjerstvo – službeni podsjetnik verzija 2013.b
char *strrchr(const char *s, int c);
char *strstr(const char *string, const char *substring);
char *strpbrk(const char *string, const char *setofcharacters);
ctype.h
int toupper(int ch);
int tolower(int ch);
int isdigit(int c); provjerava je li znak znamenka (0-9)
int isalpha(int c); provjerava je li znak slovo (A-Z ili a-z)
int isalnum(int c); provjerava je li znak slovo (A-Z ili a-z) ili znamenka (0-9)
int isprint(int c); provjerava može li se znak ispisati (0x20-0x7E)
int iscntrl(int c); provjerava je li znak kontrolni (0x7F ili 0x00-0x1F)
int isspace(int c); provjerava je li znak praznina
int islower(int c); provjerava je li znak malo slovo (a-z)
int isupper(int c); provjerava je li znak veliko slovo (A-Z)
stdio.h
int getchar(void); vraća učitani znak ili EOF
int putchar(int ch); vraća ispisani znak ili EOF (kod pogreške)
int scanf(const char *format, arg1, arg2, ...,arg n);
vraća broj učitanih argumenata (0…n) ili EOF (kraj datoteke)
int printf(const char *format, arg1, arg2, ...,arg n); vraća broj ispisanih znakova
mode: "w","a","r","w+","a+","r+" Napomena: U Windows op. sustavu za binarne datoteke treba na kraj dodati b
int fclose(FILE *fp); vraća 0 ako je operacija uspjela ili EOF u slučaju pogreške
int fgetc(FILE *stream); vraća pročitani znak ili EOF (pogreška ili kraj datoteke)
int fscanf (FILE *stream, const char *format, arg1, arg2, ..., arg n);
vraća broj učitanih argumenata ili EOF(pogreška ili kraj datoteke)
char *fgets(char *s, int n, FILE *stream);
vraća NULL u slučaju pogreške ili kraja datoteke
int fputc(int c, FILE *stream);
vraća ispisani znak ili EOF u slučaju pogreške
int fprintf (FILE *stream, const char *format, arg1, arg2, ..., arg n);
vraća broj ispisanih znakova ili EOF u slučaju pogreške
int fputs(char *s, FILE *stream);
vraća nenegativni broj ili EOF u slučaju pogreške
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
vraća broj učitanih objekata. (0..n)
size_t fwrite(void *ptr, size_t size, size_t n, FILE *stream);
vraća broj ispisanih objekata. U slučaju pogreške taj je broj < n.
int fseek(FILE *stream, long offset, int whence);
vraća 0 ako je pozicioniranje uspjelo ili broj različit od 0 u slučaju pogreške
whence: SEEK_SET – pozicioniranje u odnosu na početak datoteke
SEEK_CUR - pozicioniranje u odnosu na trenutnu poziciju u datoteci
SEEK_END - pozicioniranje u odnosu na kraj datoteke
long ftell(FILE *stream); vraća trenutnu poziciju u datoteci ili -1 u slučaju pogreške
ELEKTROTEHNIČKI FAKULTET
UNIVERZITETA U BEOGRADU
PROGRAMIRANJE 2
MATERIJAL ZA VEŽBE NA TABLI I PRIPREMU ISPITA
verzija: 26.06.2008.
http://rti.etf.rs/ir1p2
SADRŽAJ
Predstavljanje realnih brojeva 3
Standard za aritmetiku realnih brojeva 3
Zaokruživanje 5
Zadatak Z12 6
Zadatak IZ3 6
Zadatak IZ4 7
Zadatak IZ5 8
Zadatak IZ34A (integralni ispit, 09.10.1998. godine) 9
Zadatak Z14 9
Programski jezik C 10
Zadatak C5 10
Zadatak C10 11
Operatori: prioritet i redosled primene 12
Zadatak C15 13
Zadatak C20 14
Zadatak C25 15
Zadatak C30 16
Zadatak C35 17
Zadatak C40 17
Zadatak C45 18
Zadatak C47 19
Zadatak C48 19
Zadatak C50 20
Zadatak C55 21
Zadatak C57 22
Zadatak C60 22
Zadatak C65 23
Zadatak C70 24
Zadatak C75 25
Zadatak C80b 26
Zadatak C90 27
Zadatak C95 28
Zadatak C100 29
Zadatak C104 30
Zadatak C110 32
Zadatak C115 33
Zadatak C120 34
Zadatak C122 37
Zadatak C125 41
Zadatak CI-2007-Jan-2 42
Zadatak CI-2006-Okt-1 43
Zadatak CI-2007-Okt-2 44
Zadatak CI-2006-Sep-2 45
Zadatak CI-2006-Jan-1 46
Zadatak CI-2006-Jan-2 48
Zadatak CI-2006-Sep-1 49
Zadatak C2008-A1 50
Zadatak C2008-S11 50
Zadatak C2008-S12 51
Zadatak C2008-S21 51
Zadatak C2008-S22 52
Standard specificira:
1. Osnovni i prošireni format realnih brojeva
2. Operacije +, –, *, /, ostatka (rem), kvadratnog korena( ) i komparaciju realnih brojeva
3. Konverzije: celi brojevi ⇔ realni brojevi
4. Konverzije: realni brojevi ⇔ realni brojevi (različiti formati brojeva)
5. Konverzije: osnovni format realnih brojeva ⇔ decimalni niz znakova
6. Rukovanje kodovima grešaka
Osnovna osobina standarda: niz bitova, generisan kao rezultat aritmetičke operacije, može nositi
dvojaku informaciju:
1. ispravno obavljena operacija ⇒ niz bitova je rezultat operacije
2. detektovana je neka greška ⇒ niz bitova je binarno kodirani signal greške
(tzv. NaN = Not a Number)
Postoje dva tipa NaN–a:
1. signalni NaN (signal NaN) – signalizira neispravnu operaciju kad god se pojavi u ulozi
operanda
2. tihi (mirni) NaN (quiet NaN) – za skoro sve aritmetičke operacije ne signalizira neispravnost
U skladu sa IEEE standardom, realni brojevi se u memorijske reči smeštaju na sledeći način:
R = (–1)s⋅2E⋅M
U zavisnosti vrednosti bita polja eksponent, postoje četiri različita načina tumačenja sadržaja
memorijske reči u kojoj je smešten realan broj.
1. Kada biti polja eksponent nisu sve 0 ili sve 1 (e≠0000...0 i e≠1111...1), vrednost
eksponenta E se nalazi u opsegu [Emin, Emax] i tada memorijska reč sadrži uobičajen realni
broj sa normalizovanom mantisom. Vrednost mantise M se računa dodavanjem skrivenog
bita vrednosti 1 i decimalnog zareza ispred niza bita polja mantisa: M=1.mmmmm...m.
Skriveni bit se podrazumeva pa zbog toga nije potrebno posebno ga skladištiti u memorijskoj
reči.
2. Kada su biti polja eksponent sve 0 (e=0000...0), ali biti polja mantisa nisu sve 0
(m≠0000...0), tada memorijska reč sadrži realan broj sa nenormalizovanom mantisom.
Vrednost eksponenta E se u ovom specijalnom slučaju računa kao E=e-v+1. Vrednost
mantise M se računa dodavanjem skrivenog bita vrednosti 0 i decimalnog zareza ispred niza
bita polja mantisa: M=0.mmmm...m. Kao i u prethodnom slučaju, ovaj skriveni bit se
podrazumeva. Smisao realnih brojeva sa nenormalizovanom mantisom je proširenje opsega za
realne brojeve veoma male apsolutne vrednosti.
3. Kada su biti polja eksponent i mantisa sve 0 (e=0000...0, m=0000...0), tada memorijska
reč sadrži realan broj čija je vrednost 0. Treba primetiti da zbog znaka (bit s), standard
dozvoljava postojanje pozitivne i negativne nule (+0 i -0) ali između njih ne pravi razliku (tj.
imaju istu vrednost).
4. Kada su biti polja eksponent sve 1 (e=1111...1), vrednost eksponenta E je veća od Emax i
razlikuju se dva slučaja:
a. vrednosti bita polja mantisa su sve 0 (m=0000...0) : realni broj ima vrednost ±∞ (u
zavisnosti od vrednosti bita s)
b. vrednosti bita polja mantisa nisu sve 0 (m≠0000...0) : radi se o NaN-u, koji označava
matematički nedefinisanu vrednost
Pozitivni realni brojevi, manji od najmanjeg realnog broja (minREALl) koji je moguće predstaviti sa
zadatim brojem bita se zaokružuju na vrednost 0 (tzv. potkoračenje, eng. underflow), dok se
pozitivni realni brojevi veći od najvećeg realnog broja (maxREAL) zaokružuju na vrednost +∞ (tzv.
prekoračenje, eng. overflow). Slično važi za negativne realne brojeve.
0
-∞ [ ] | [ ] +∞
-maxREAL -minREAL minREAL maxREAL
IEEE Standard uvodi 4 formata realnih brojeva (format se odnosi na broj bitova pojedinih polja):
(1) jednostruki (2) jednostruki prošireni (3) dvostruki (4) dvostruki prošireni
1 k=8 p = 23
s e e e e e e e e mmmmmmmmmmmmmmmmmmmmmmm
31 30 23 22 0
Opseg brojeva:
1. Najmanji nenormalizovani: e=0 ⇒ R = (–1)s⋅2-126⋅(0.00000…………1)
2. Najveći nenormalizovani: e=0 ⇒ R = (–1)s⋅2-126⋅(0.11111…………1)
3. Najmanji normalizovani: e=1 ⇒ R = (–1)s⋅2-126⋅(1.00000…………0)
4. Najveći realan broj: e=254 ⇒ R = (–1)s⋅2127⋅(1.11111…………1)
Zaokruživanje
Zbog ograničenog broja bita polja mantisa, najčešće nije moguće prezicno smeštanje realnog broja u
memorijsku reč, već se pristupa zaokruživanju. Podrazumeva se da je posmatrani broj, pre smeštanja
u memorijsku reč, beskonačno precizan, pa se zaokruživanje vrši sa ciljem da se uklopi u odredišni
format. Skoro sve operacije nad realnim brojevima daju najpre “beskonačno precizan” rezultat koji se
potom zaokružuje prema odredišnom formatu.
1. Osnovni način zaokruživanja: prema najbližoj vrednosti.
2. Ako su dve zaokružene vrednosti podjednako udaljene od “beskonačno precizne” vrednosti –
bira se ona vrednost kod koje je bit najmanjeg značaja 0.
3. Ako je apsolutna vrednost “beskonačno precizne” vrednosti:
|R| ≥ 2Emax⋅(2–2–p), vrši se zaokruživanje na (–1)s⋅(∞)
p i Emax se određuju iz odredišnog formata.
U praksi, ovo znači sledeće (desno od vertikalne crte se nalaze biti koji se odbacuju):
1 2 3 4
binarna x.xx | 0zzz...zzz x.xx | 1yyy...yyy x.x0 | 100...00 x.x1 | 100...00
predstava broja (makar jedan y je 1)
vrednost na koju x.xx x.xx + 0.01 x.x0 x.x1 + 0.01
se zaokružuje
Ako se pažljivije pogleda, ovakav način zaokruživanja odgovara uobičajenom načinu zaokruživanja
realnih brojeva.
Gubitak tačnosti ima za posledicu da kod računarskog sabiranja realnih brojeva ne važi uvek zakon
asocijativnosti.
Zadatak Z12
Za smeštanje realnih brojeva koriste se 8 bitova od kojih 3 bita predstavljaju eksponent u kodu sa
viškom. Mantisa se smešta sa skrivenim bitom. Za brojeve veće od nule odrediti najmanju i najveću
vrednost koja se može predstaviti na gornji način.
Zadatak IZ3
Napomena: ovaj zadatak ilustruje razliku između savremenog IEEE standarda za reprezentaciju
realnih brojeva i standarda VAX koji mu je prethodio.
Format predstave realnih brojeva je seeeemmmmm – s je bit za znak broja, eeee su bitovi za
eksponent broja (kôd sa viškom), a mmmmm su bitovi normalizovane mantise (sa skrivenim bitom).
U računaru A – predstava realnih brojeva je sa viškom 8, a u računaru B – sa viškom 7. U računaru A
– mantisa je 0.5≤MA<1, a u računaru B – mantisa je 1≤MB<2. Izgled jednog broja u računaru B, u
skladu sa opisanim formatom, je 3DF16. Kako je predstavljen realan broj iste vrednosti u računaru A?
A) 3DF16
B) 3FF16
C) 3FE16
Rešenje
Prvi način: Moguće je reći, da je predstava realnih brojeva u računaru B u skladu sa duhom IEEE
standarda, imajući u vidu da je višak 7 = 24-1 -1, a mantisa je oblika MB = 1.mmmmm.
Zbog toga, broj 3DF16 = 1|1110|111112 predstavlja maxREAL, kad je računar B u pitanju.
Kako je maxREALIEEE = 2⋅maxREALVAX, može se zaključiti da ovaj broj nije moguće predstaviti u
računaru A, jer je maxREALVAX dva puta manji od posmatranog broja.
Drugi način:
B: 3DF16 = 1|1110|111112 EB = eeeeB – 7 = 7 MB = 1.mmmmmB = 1.111112
MA = 0.1mA mA = 111112
Odgovor: N
Zadatak IZ4
Format predstave realnih brojeva pomoću reči širine 10 bita je: bit najveće težine za znak broja,
četiri bita za eksponent u kôdu sa viškom 7, i pet bitova najmanje težine za normalizovanu mantisu
sa skrivenim bitom (1≤M<2). Rezultat sabiranja brojeva čiji je izgled A=16068 i B=05158 je:
A) 16338
B) 15668
C) 17668
Rešenje
A: 1|1100|00110 B: 0|1010|01101
SA=1 ⇒ A <0 SB=0 ⇒ B >0
EA=12–7=5 EB=10–7=3
MA=1.00110 MB=1.01101
MA = 1.00110
–MB’ = 0.01011
––––––––––––––––––
MA+B = 0.11011 ovde se mora izvršiti normalizacija.
MA+B = 1.10110⋅2–1
Odgovor: B
Zadatak IZ5
U nekom računaru, celi brojevi su predstavljeni u drugom komplementu pomoću reči širine 10 bita,
a za predstavljanje realnih brojeva je takođe predviđeno 10 bita, i to tako da bit najveće težine
određuje znak broja, sledeća 4 bita su za eksponent broja u kôdu sa viškom 7, a preostalih 5 za
normalizovanu mantisu sa skrivenim bitom (1≤M<2). Ako je izgled realnog broja na lokaciji X: 39716,
a izgled celog broja na lokaciji J: 31016, koji će biti izgled lokacije realne promenljive Y nakon izvršene
operacije Y=X+J? Računanje obavljati upotrebljavajući realne brojeve.
A) 3FA16
B) 3E516
C) 3BA16
Rešenje
X: 1|1100|10111 J: 1100010000
–J = 0011110000 = 1.111⋅27
SX = 1, X<0 SJ = 1, J<0
MX = 1.10111 MJ = 1.11100
EX = 12 – 7 = 5 EJ = 7
EJ > EX
X = – MX⋅2-2⋅27
MX’ = 0.01101|11 ≈ 0.01110
MJ= 1.11100
+MX’= 0.01110
–––––––––––––
MY =10.01010 = 1.00101 ⋅ 21
Y: 1|1111|00101 = 3E516
Odgovor: B
Sada je potrebno svesti ova dva broja na isti eksponent i pri tome izvršiti zaokruživanja, ako se za
tim ukaže potreba:
J = (-1)∙0.110111∙28 = (-1)∙0.0110111∙28 ≈ (-1)∙0.011100∙28.
Pošto su brojevi različitog znaka, oduzimamo mantisu manjeg od mantise većeg broja:
MI: 0.101111
-MJ: - 0.011100
MI-MJ: 0.100110
Traženi broj izgleda ovako: 0.100110∙28, što je jednako pozitivnom celom broju 00100110002 = 9816
= 15210.
Odavde se može zaključiti da je apsolutna razlika ova dva zbira jednaka 4.
Napomena: Kada se vrši konverzija iz celobrojnog u realni broj, vrši se zaokruživanje na po
vrednosti najbliži realni broj koji se može predstaviti u memoriji datog računara. Konverzija u
obrnutom smeru podrazumeva ili zaokruživanje početnog realnog broja na po vrednosti najbliži celi
broj ili prosto odsecanje razlomljenog dela realnog broja. Ako nije posebno naglašeno, podrazumeva
se prvi pristup.
Odgovor: A
Zadatak Z14
Brojevi sa pokretnom tačkom u računaru imaju binarni oblik seeeeeemmmmmmmmm, gde je s
bit za znak broja, m su bitovi normalizovane mantise sa skrivenim bitom (0.5≤M<1), e su bitovi
eksponenta u kodu sa viškom 25. Naći zbir brojeva x i y čiji su oblici u računaru zadati u brojnom
sistemu sa osnovom q. Rezultate proveriti pretvaranjem zadatih vrednosti i rezultata u decimalni
brojni sistem.
PROGRAMSKI JEZIK C
Zadatak C5
Sledeći program za određivanje rešenja linearne jednačine Ax+B=0, za A<>0, napisan na
programskom jeziku C, sadrži više grešaka. Ispraviti sve greške!
main main predstavlja funkciju – treba da stoji main()
Float _x,a,b C je CaseSensitive jezik (razlikuje mala i velika slova)
deklaracija treba da stoji unutar programskog bloka
{
scanf('%f %f',a,b); niz znakova u jeziku C se ogranicava parom znakova "
scanf zahteva adresu, a ne vrednost; Prevodilac za jezik C ne
prijavljuje ovo kao gresku.
_x=-b/a;
printf('%f',_X) _X nije dobro, jer smo deklarisali _x
}
Rešenje:
Ispravljeni program izgleda ovako:
#include <stdio.h> /* na početku svakog programa dolaze direktive */
main()
{
float _x,a,b; /* _x ne smeta (Promenljiva moze sadrzati znak _ ) */
scanf("%f %f",&a,&b);
_x=-b/a;
printf("%f",_x); /* svaka naredba jeziku C završava se znakom tacka-zarez; */
}
Komentar:
Neispravno napisan program je testiran i kompajliran u programskom paketu Visual Studio.net.
Poruke kompajlera su sledeće:
Compiling...
c5.c
c5.c(5) : error C2061: syntax error : identifier 'Float'
c5.c(5) : error C2059: syntax error : ';'
c5.c(7) : error C2143: syntax error : missing ';' before '{'
c5.c(7) : error C2449: found '{' at file scope (missing function header?)
c5.c(8) : error C2015: too many characters in constant
c5.c(14) : error C2059: syntax error : '}'
Na početku svakog programa koji nešto učitava ili ispisuje mora postojati direktiva include sa
parametrom <stdio.h>. Ovo predstavlja uputstvo prevodiocu da iz datoteke stdio.h treba da
pročita osobine bibliotečkih funkcija za ulaz i izlaz podataka.
Zadatak C10
Sastaviti program na programskom jeziku C za ispisivanje tablice ASCII kodova za sve štampajuće
znake.
Rešenje
ASCII kod sa brojem 32 je blanko simbol ili razmak. Prva 32 ASCII koda (od 0 do 31) i svi ASCII
kodovi veći ili jednaki 127 predstavljaju specijalne simbole koji se koriste u različite svrhe i najčešće
nemaju neko jasno slovno značenje. Koristili su se za iscrtavanje DOS prozora, i na taj način simulirali
grafiku u tekstualnom režimu rada. Konkretno, prozori razvojnog okruženja Turbo C su napravljeni na
ovaj način! ASCII kodovi između 32 i 126 su štampajući znaci, i ima ih ukupno 95.
Znaci se prikazuju po kolonama. U jednoj koloni se prikazuje po 19 znakova, a u jednom redu se
prikazuje po 5 znakova (5x19=95). Prikazaćemo sve ASCII kodove od 32 do 126.
Program za prikazivanje tablice ASCII kodova može se realizovati na više načina.
I način
#include <stdio.h>
main()
{
char c;
int i;
printf ("\t\tTablica ASCII kodova \n \n");
for(c = ' '; c < ' ' + 19; c++)
{
for(i = 0; i < 95; i += 19)
printf("%3d%c ", c+i, c+i);
putchar('\n');
}
}
Komentar:
U drugom rešenju se koristi skok sa proizvoljnim odredištem: goto. Korišćenje naredbe goto treba
izbegavati (bilo koji algoritam koji sadrži goto može se ostvariti na neki drugi način, što i pokazuje prvo
rešenje). Glavni razlog za izbegavanje naredbe goto je taj što ta naredba ima veliki stepen slobode u izboru
odredišta skoka tako da omogućava sastavljanje nestrukturiranih, vrlo nepreglednih programa, koji jako često
sadrže mnogo grešaka uzrokovanih upravo lošom strukturom.
Primeri
Relacijski operatori Operatori za dodelu vrednosti
Izraz Objašnjenje (rezultat) Izraz Objašnjenje
5 > 7 0 y = a * x + b
10 <= 20 1 d *= e + f d = (d*(e+f))
8 == 13 > 5 8==(13>5) -> 8==1 -> 0 d = d * e + f d = ((d*e)+f)
14 > 5 < 3 (14>5)<3 -> 1<3 -> 1 a=b=c=d+5 c=d+5,b=c,a=b
a < b < 5 (a<b)<5 -> (0/1)<5 -> 1 a = b++ + c=d<<3,u=b,b=b+1,a=u+(3*c)
a+5 >= c-1.0/e (a+5)>=(c-(1.0/e)) 3*(c=d<<3)
a = b++ + 3*c greška !
= d<<3
Odgovor:
1. x=(x+(y=(y-m))
2. n=(n % (y+m))
3. m-(j-1); m=m+1; j=j-1
4. x=j * j++ ; ovo zavisi od toga kojim se redom racuna, sa leva na desno ili obrnuto
Odgovor: implementaciono zavisno
5. ((j+1)==m)!=(y*2); j=j+1
Zadatak C20
Sastaviti program na programskom jeziku C koji učitava srednje temperature po mesecima za 12
meseci i na osnovu njih izračuna i ispiše srednju temperaturu za celu godinu.
Rešenje:
#include <stdio.h>
#define BROJ_MESECI 12
main()
{
enum meseci {JAN=1,FEB,NAR,APR,MAJ,JUN,JUL,AVG,SEP,OKT,NOV,DEC};
enum meseci mesec=JAN;
/*
Moguce je umesto gornje dve linije napisati samo jednu:
enum meseci {JAN=1,FEB,NAR,APR,MAJ,JUN,JUL,AVG,SEP,OKT,NOV,DEC} mesec=JAN;
*/
float temperature[BROJ_MESECI];
float srednja_temp=0;
while (1)
{
printf("Temperatura za mesec %2d: ",mesec);
scanf("%f",&temperature[mesec - 1]); /* niz u C-u uvek ide od 0 */
srednja_temp+=temperature[mesec - 1];
if (mesec==DEC) break;
mesec++;
}
srednja_temp/=BROJ_MESECI;
printf("Srednja temperatura je %.2f\n",srednja_temp);
}
/*
Jasno je da nam niz nije potreban za racunanje srednje vrednosti
dovoljno je da mesecnu temperaturu ucitavamo u neku pomocnu (float)
promenljivu i da nju dodajemo na srednja_temp
*/
Komentar
Prikaz nekih vrednosti adresa i niza temperature:
&temperature,p: 22FC(SS):0FCC
&temperature[0],p: 22FC(SS):0FCC - adresa clana 0
&temperature[1],p: 22FC(SS):0FD0 - adresa clana 1
temperature: { 3.0,8.0,12.0,15.0,20.0,26.0,29.0,30.0,26.0,20.0,13.0,7.0 }
- prikaz celog niza
temperature[0]: 3.0 - vrednost clana sa indeksom 0
Ovakav prikaz se može dobiti pomoću Watch prozora razvojnog okruženja Turbo C. Najpre se navodi izraz čija
se vrednost posmatra, a onda način kako ona treba da bude ispisana. Uz pomoć ovog dodatka, može se isti
izraz posmatrati na više načina.
izraz,d – kao broj
izraz,c – kao karakter
izraz,p – kao pokazivač (adresa)
Zadatak C25
Sastaviti program na programskom jeziku C za određivanje broja velikih slova, malih slova i cifara
u tekstu koji se iz proizvoljnog broja redova učitava preko glavne ulazne jedinice. Tekst se završava
znakom za kraj datoteke.
Rešenje
#include <stdio.h>
#include <ctype.h> /* treba za funkcije vezane za ispitivanje slova */
main()
{
int znak, vel_sl=0, mal_sl=0,cifra=0;
while ((znak=getchar())!=EOF)
{
vel_sl += isupper(znak) != 0; /* ctype.h */
mal_sl += islower(znak) != 0; /* ctype.h */
cifra += isdigit(znak) != 0; /* ctype.h */
}
printf("Velikih slova ima %d\n",vel_sl);
printf("Malih slova ima %d\n",mal_sl);
printf("Cifara ima %d\n",cifra);
}
Komentar
U zaglavlju ctype.h se nalaze prototipovi funkcija za ispitivanje znakova. U ovom programu su upotrebljene
sledeće funkcije:
- isupper(znak): ispituje da li je zadovoljen uslov (znak>='A') && (znak<='Z')
- islower(znak) : ispituje da li je zadovoljen uslov (znak>='a') && (znak<='a')
- isdigit(znak) : ispituje da li je zadovoljen uslov (znak>='0')&&(znak<='9')
Sve is_ funkcije vraćaju 0 za logičku neistinu, a različito od 0 (ne obavezno 1) za logičku istinu
Zadatak C30
Sastaviti program na programskom jeziku C koji učitava decimalan pozitivan celi broj u obliku niza
znakova i ispisuje njegovu vrednost u binarnom obliku. Pretpostaviti da se za interno predstavljanje
celih brojeva koristi 16 bitova.
Rešenje
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main()
{
char dec[10];
short int bin, i;
Komentar
16-bitni binarni broj može da ima najveću vrednost 65535, ukoliko se tretira kao unsigned, odnosno 32767,
ukoliko se tretira kao signed. To konkretno znači da je za ovaj 16-bitni prikaz dovoljno koristiti niz brojeva
char dec[6] (5 za cifre i 1 za terminator). Sa druge strane, ako se u ovom zadatku unese neki broj veći od
65535/32767 rezultat neće biti ispravan (biće prikazano samo najnižih 16-bitova zadatog broja ako je short int
na datom računaru duži od 16 bita).
Funkcija atoi se može koristiti i za konverziju negativnih vrednosti.
Treba imati na umu i sledeću činjenicu: ako se unese više od 10 znakova nepredvidiv je ishod izvršavanja
ovog programa, jer niz 'dec' ima dodeljeno svega 10 znakova (bajtova) u memoriji i ništa preko toga! Ostatak
memorije pripada drugim podacima ili drugom programskom kodu, tako da se upisivanjem van granica niza
može izazvati nepredvidivo ponašanje.
Zadatak C35
Koja od datih konstrukcija na programskom jeziku C predstavlja ekvivalent iskaza na programskom
jeziku Pascal: if (a>b) then begin a:=1; b:=1 end
A) if (a>b) { a=1; b=1; }
B) if (a>b) a=1, b=1;
C) if (a>b) a=1; b=1;
Komentar
Odgovor će biti A ili V (A i B), zavisno od toga kako se definiše ekvivalentnost dva iskaza.
A) Ovo je upravo prepisana selekcija sa Pascala na C.
B) Ukoliko je ispunjen uslov biće izvršena jedna instrukcija u then grani, pri čemu se ona sastoji od
2 izraza. Efekat izvršavanja ova dva izraza je u ovom slučaju identičan slučaju pod A).
C) b=1 se izvršava u svakom slučaju, što ne važi za originalni segment.
Zadatak C40
Šta ispisuju sledeći programi?
a) b)
#include <stdio.h> #include <stdio.h>
main() main()
{ {
int x; int x=0,i;
for (x=0;x<100;x++) for (i=0;i<5;i++)
{ switch (i)
/* ako x nije deljivo sa dva {
vrati se na pocetak tela ciklusa */ case 1: x+=1;
if (x%2) /* ukoliko je i=1 izvrsava se deo
continue; iza case 1: i case 2: */
/* do ovde dolazi samo ako je case 2: x+=2; break;
x deljivo sa 2 (x mod 2 = 0) */ /* Ako je i=2 izvrsava se samo deo
printf("%d\n",x); iza case 2: (zbog break;) */
} case 4: x+=3;
} /* Ako je i=4 izvrsava se samo deo
A) Sve cele brojeve od 0 .. 99 iza case 4: */
}
B) Sve parne brojeve od 0 .. 99 printf("d=%d\n",x);
C) Sve neparne brojeve od 0 .. 99 }
A) 5
Odgovor
B) 6
B C) 9
Odgovor
N
Komentar
Najpre je x=0;
Za i=0, x se ne menja (x=0);
Za i=1, x+=1; x+=2; => x=3;
Za i=2, x+=2; => x=5;
Za i=3, x se ne menja;
Za i=4, x+=3; => x=8;
Zadatak C45
Sastaviti program na programskim jeziku C koji formira slučajan celobrojni niz sastavljen od
jednocifrenih brojeva i izvrši uređivanje niza po neopadajućem redosledu vrednosti brojeva.
Rešenje:
Za sortiranje brojeva postoji niz algoritama. Više detalja o ovoj oblasti se može pronaći u knjizi
“Strukture podataka” profesora Tomaševića. Ovde je predstavljen najjednostavniji algoritam pod
nazivom Selection sort, odnosno sortiranje metodom izbora. Ideja je sledeća: u i-tom prolazu se
odabere i-ti (u ovom slučaju) najmanji broj, pa se smesti na i-to mesto.
#include <stdio.h>
#include <stdlib.h>
#define DIM 50
main()
{
int n,a[DIM],i,j,b;
for (;;)
{
printf("\n\n Duzina niza (max %d): ",DIM); scanf("%d", &n);
if ((n <= 0) || (n > DIM)) break;
/* break prekida for ciklus. Ovo je ciklus sa izlazom u sredini */
printf("\nPocetni niz: \n\n");
for (i=0;i<n;i++)
printf("%d%c", a[i] = rand()/((double)RAND_MAX+1.0)*10,
(i % 30 == 29 || i == n-1) ? ('\n') : (' '));
/* Generisace se slucajni brojevi u intevalu od 0 .. 10.
rand() generise slucajan broj od 0 .. RAND_MAX
(RAND_MAX je u slucaju TurboC-a 32767 ) */
/* sledi sortiranje */
for (i = 0; i < n-1; i++)
for (j = i+1; j < n; j++)
if (a[i] > a[j]) b = a[i],a[i] = a[j],a[j] = b; /* zamena 2 promenljive */
printf("\nSortirani niz:\n\n");
for (i = 0; i < n; i++)
printf("%d%c", a[i], (i % 30 == 29 || i == n-1) ? ('\n') : (' '));
Zadatak C47
Koji od programskih segmenata na programskom jeziku C daju isti izlaz kao dati programski
segment na programskom jeziku Pascal?
j:= -2;
for i:= -2 to j*j do
begin write(j:3); j:=j+1 end;
A) for (i=j=-1;i<=j*j;i++,j++) printf(" %3d ",j);
B) i=-2; while (printf(" %3d ",i),i++ -4);
C) i=j=-2; while (i++ == 4 ? 0 : 4) printf(" %3d ",j++);
Obrazloženje:
U programskom jeziku Pascal se interval for ciklusa određuje neposredno po ulasku u ciklus i ne
menja se u toku izvršavanja ciklusa, dok se u programskom jeziku C uslov kod for ciklusa računa pre
svakog ponavljanja.
Ovaj programski segment na programskom jeziku Pascal ispisuje -2,-1,0,1,2,3,4.
Programski segment (A) na programskom jeziku C je logički neispravan, jer i nikada neće prestići
vrednost j*j. Dodirna tačka im je za i==0,j==0 i i==1,j==1, ali posle toga zbog obostranog
inkrementiranja i će biti uvek manje od j*j. U realnosti, u nekom trenutku će doći do prekoračenja
opsega celih brojeva, i j*j će postati manje od i, za vrednost j takvu da vrednost izraza j*j
prekoračuje maksimalni celi broj.
Programski segment (B) na programskom jeziku C je logički ispravan i ispisuje iste vrednosti kao i
dati programski segment na programskom jeziku Pascal. Zadnji ispisani broj je 4, tada se ne postiže
uslov za ulaz u petlju (i-4 == 0, što predstavlja logičku neistinu), a kao bočni efekat i=5.
Programski segment (C) na programskom jeziku C je logički ispravan. Međutim, on ne ispisuje iste
vrednosti kao i programski segment na programskom jeziku Pascal. Ispisuje jedan broj manje (tj. sve
od -2 do 3). Iz ciklusa se izlazi kada je i==4. Broj koji se ispisao pre toga je bio 3, a bočni efekat je
bio j=4.
Zadatak C48
Data su tri segmenta programa na programskom jeziku C:
I
for (i=x=y=0; ; ++i)
{x++; if (i==n) break; y++; }
printf(“%ld %ld”,x,y);
II
x=0, y=0;
for (i=0; i<=n; i++)
{x=x+1; if (i<n) continue; y=y+1;}
printf(“%ld %ld”,x,y);
III
x=i=0;
while (i<=n)
{ i++; ++x; y=x>n;}
printf(“%ld %ld”,x,y);
Ako su sve promenljive celi brojevi koja dva segmenta daju isti izlaz za n>0?
A) I i II B) II i III C) I i III
Obrazloženje:
I uvek ispisuje x=n+1, y=n,a II i III uvek ispisuju x=n+1, y=1 (n ne utiče na vrednost y).
Zadatak C50
Napisati na programskom jeziku C program koji analizira tekst koji se unosi sa standardnog ulaza,
prepoznaje realne brojeve po formatu cc...c.ddd...d i ispisuje ih po formatu c.ddE+ee, a sve
ostale učitane znake ispisuje bez izmene.
Rešenje
#include <stdio.h>
#include <ctype.h>
#define DECIMALNA_TACKA '.'
#define ZNAK_ZA_KRAJ '!'
main()
{
int c, j, broj_cifara;
double vrednost, decimala;
do
{
/* sve dok se ne pojavi neka cifra, ispisuju se karakteri sa ulaza */
while (! ( isdigit(c = getchar()) || (c==ZNAK_ZA_KRAJ) ) )
putchar(c);
if (c == ZNAK_ZA_KRAJ)
break; /* Ukoliko je nadjen znak ! onda se prekida glavna petlja */
vrednost = 0.;
broj_cifara = 0;
/* sve dok se ne naidje na tacku, dodaje se vrednosti pritisnuta cifra na kraj */
while ( isdigit(c) )
vrednost = vrednost * 10 + (c-'0'), c = getchar();
if (c == DECIMALNA_TACKA)
/* sve dok se unose cifre, dodaju se na kraj decimalnog dela */
{
c=getchar();
while ( isdigit(c) )
{
broj_cifara++;
decimala = c - '0';
for (j=0; j < broj_cifara; j++)
decimala/=10;
vrednost += decimala;
c = getchar();
}
}
ungetc(c,stdin);
printf("%1.2E",vrednost);
} while (c != ZNAK_ZA_KRAJ); /* '!' je trenutno znak za kraj */
}
Obrazloženje
Iz programa se izlazi ukoliko se bilo gde u liniji upiše znak '!'
Od unete cifre, broj koji ona predstavlja dobija se kada se od njenog ASCII koda oduzme ASCII
kod znaka '0'.
Pitanje
Šta će se dobiti na izlazu za sledeći red?
123.123.123
Odgovor:
1.23E+02.1.23E+02
Zadatak C55
Šta ispisuje sledeći program?
a)
/*C55a*/
#include <stdio.h>
main()
{
int a[]={1,0}, *p;
p=a;
printf("%d, ", *p++);
printf("%d\n", *p);
}
A) 1, 2 B) 1, 0 C) 0, 0
Komentar
Odgovor je B. Prioritet * i ++ je isti, ali je asocijativnost ove grupe operatora sdesna ulevo.
b)
/*C55b, J.Protic*/ printf("\n");
#include <stdio.h> for (p=&a[0], i=0; p+i<a+4; p++, i++)
main() printf("%d", *(p+i));
{ printf("\n");
int a[]={0, 1, 2, 3, 4}; for (p=a+4, i=0; i<=4; i++)
int i, *p; printf("%d", p[-i]);
for (p=a, i=0; p<=&a[4]; p++) printf("\n");
printf("%d", *p); }
Rešenje
01234
02
43210
c)
/*C55c, L.Kraus, primer, modifikacija J.Protic, I.Tartalja, dopuna A.Bosnjakovic*/
#include <stdio.h>
#include <stdlib.h>
main()
{
int **a, n, i, j;
printf("N="); scanf("%d", &n);
a = calloc(n, sizeof(int*)); /*alocira memoriju za n pokazivaca na vrste*/
for (i=0; i<n; i++)
{
*(a+i)= calloc(n, sizeof(int));
/*alocira memoriju za n elemenata vrste koji su tipa int*/
for (j=0; j<n; j++) *(*(a+i)+j) = rand()/((double)RAND_MAX + 1) * 10;
/* C55c.c(44) : warning C4244: '=' : conversion from 'double ' to 'int ', possible loss
of data */
}
for (i=0; i<n; printf("\n"), i++)
for (j=0; j<n; j++)
printf("%d", *(*(a+i)+j));
for (i=n-1; i>=0; i--) printf("%d", *(*(a+i)+n-1-i));
putchar('\n');
}
A) sadržaj matrice vrstu po vrstu, a potom sporednu dijagonalu, sleva-udesno
B) sadržaj matrice vrstu po vrstu, a potom glavnu dijagonalu, sdesna-ulevo
C) sadržaj matrice vrstu po vrstu, a potom sporednu dijagonalu, sdesna-ulevo
Odgovor:
A
Materijal za vežbe na tabli i pripremu ispita Strana 21 od 52
Elektrotehnički fakultet Univerziteta u Beogradu Programski jezik C
Zadatak C57
Da bi se učitani znakovni niz (string) precizno ispisao «unatrag» (samo znaci koji su unošeni sa
standardnog ulaza), koja naredba se može staviti umesto ***?
scanf(%s%, string1); a = string1; *** while (a>string1) putchar(*(--a));
A) while (*a) a++;
B) for (; *a; a++);
C) while (*a++);
Odgovor
V (A i B)
Komentar
Umesto *** mora da stoji naredba koja će postaviti pointer a tako da pokazuje na NULL (‘\0’)
karakter pointera string1, jer se u narednoj while petlji pointer a najpre dekrementira pa se tek
tada ispisuje odgovarajući znak. Odgovor C nije dobar jer postavlja (zbog bočnog efekta) pointer a
na znak iza ‘\0’ karaktera.
Zadatak C60
Napisati program na programskom jeziku C koji učitava jedan znakovni niz (string) S1 i jedan ceo
broj M, a zatim formira novi znakovni niz S2 samo od onih znakova na čijim su pozicijama
odgovarajući bitovi broja M jednaki 1. Smatrati da se ceo broj predstavlja u 16-bitnoj lokaciji, a da
znakovni niz može imati najviše 16 znakova. Na kraju, program ispisuje novi znakovni niz S2.
Rešenje
/* C60.c, 9.4.1994., II parcijalni ispit */
#include <stdio.h>
main()
{
short int M, maska;
char S1[17], *s1, S2[17], *s2;
Komentar
U ovom programu promenjiva maska služi da ispitamo gde se nalaze jedinice u broju M koji zadaje korisnik.
Broj bitova broja M (16) odgovara broju znakova stringa S1. Na osnovu pozicije tih jedinica određuju se
znakovi koji će biti u stringu S2. Svaki od stringova S1 i S2 zauzima ukupno 17 bajtova u memoriji – 16 za
same znakove i 1 za završni nulti znak.
Uslov (maska && *s1) je neophodan da bi se dobio ispravan niz s2.
Zadatak C65
Koji od sledećih izraza je ekvivalentan izrazu ar[1][2], ako je data sledeća deklaracija:
int ar[][3]={{0,1,2}, {3,4,5}}
A) *(int*) ( ((char*)ar + (1*3*4)) + (2*4) )
B) *(ar[1]+2)
C) *((*ar+1)+2)
Odgovor
B
Obrazloženje
Zadatak C70
Napisati program na programskom jeziku C koji učitava dva znakovna niza, izvrši nadovezivanje
drugog na prvi, okrene “naopako“ dobijeni niz i ispiše ga na standardnom izlaznom uređaju.
Rešenje
#include <stdio.h>
#include <string.h>
main()
{
int n;
char c, *d, *p, *prvi, *drugi;
printf(“Maksimalna duzina: “);
scanf(“%d\n”, &n);
p = calloc(2*n+1, sizeof(char)) ;
d = calloc(n+1, sizeof(char));
if ((NULL == d) || (NULL == p))
printf(“Nije moguca alokacija!\n”);
else
{
prvi = p; drugi = d;
while ((*p = getchar()) != ‘\n’) p++;
*p = ‘\0’;
while ((*d = getchar()) != ‘\n’) d++;
*d = ‘\0’;
p = prvi; d = drugi;
/* konkatenacija */
while (*p) p++;
while (*p++=*d++);
/* okretanje */
p = prvi;
for (d=p+(strlen(p)-1); p < d; p++, d--)
c=*p, *p=*d, *d=c;
printf(“%s\n”, prvi);
free(p); free(d);
}
Komentar
Za string p se alocira dvostruko više memorije zbog nadovezivanja nizova. OBAVEZNO treba proveriti da li je
uspela alokacija memorije.
Nakon alokacije memorije, vrši se učitavanje stringova, znak po znak, korišćenjem bibliotečke funkcije
getchar(). Zatim se vrši konkatenacija, tako što se drugi string nadoveže na prvi.
Okretanje dobijenog niza u datom rešenju radi se tako što prvi član menja mesto sa poslednjim, drugi sa
pretposlednjim, itd.
S obzirom na to da postoji dinamička alokacija memorije, svu alociranu memoriju OBAVEZNO treba osloboditi
kada ona više nije potrebna (u ovom slučaju pre završetka programa).
Zadatak C75
Napisati program na programskom jeziku C koji ponavlja sledeću sekvencu operacija:
1. učitava informaciju o tipu podataka sa kojim će raditi (ceo broj ili znak);
2. učitava dužinu niza podataka;
3. učitava niz podataka zadatog tipa i dužine u dinamički alociranu memoriju;
4. ispisuje u heksadecimalnom obliku sadržaj učitanih podataka, bajt po bajt.
Rešenje
#include <stdio.h>
#include <stdlib.h>
main()
{
void *blok_p, *bajt_p;
int lnt, n;
char o, *format_p;
while(1)
{
o = 0;
while (o != 'c' && o != 'Z' && o != 'k')
{
printf("Tip brojeva: (c)eli/(z)naci, ili (k)raj?");
scanf("%c", &o);
switch(o)
{
case 'c' :
lnt = sizeof(int);
format_p = "%d";
break ;
case 'z' :
lnt = sizeof(char) ;
format_p = "%c" ;
break ;
case 'k' :
break ;
default: printf("Neispravan unos! Ponovite.\n");
}
}
if (o == 'k') break ;
printf("Broj podataka?");
scanf("%d", &n);
blok_p = malloc(lnt*n) ;
printf("Podaci:\n");
for (bajt_p=blok_p; bajt_p<(char*)blok_p+n*lnt; (char*)bajt_p+=lnt)
/*konverzija tipa, pretvaramo generički pokazivac u pokazivač na char */
{ printf("?"); scanf(format_p, bajt_p); }
printf("Bajtovi:\n");
for (bajt_p = blok_p; bajt_p<(char*)blok_p+n*lnt; ((char*)bajt_p)++)
printf("%x", *(char *)bajt_p);
printf("\n");
free(blok_p);
}
}
Komentar
Bajt_p i blok_p su generički pokazivači; pošto kod njih nije određen tip pokazivanih podataka, takav
pokazivač ne može se koristiti za pristup podacima, već samo za čuvanje informacije o adresi nekog podatka.
Pre pristupa nekom podatku, neophodno je generički pokazivač, upotrebom operatora za konverziju tipa,
pretvoriti u pokazivač na željeni tip podataka. Posledice su nepredvidive ako pokazivani podatak nije tipa koji
je naznačen u operatoru za konverziju tipa.
Zadatak C80b
Sastaviti program na jeziku C za učitavanje imena gradova uz njihovo uređivanje po abecednom
redosledu i ispisivanje rezultata. U svakom redu se učitava po jedno ime sve dok se ne učita prazan
red.
/* program za sortiranje imena gradova */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main()
{
char *adrese[MAX_GRAD], *adresa;
int znak, br_grad = 0, duz, i;
do
{
adresa = calloc(MAX_DUZ, sizeof(char));
for (duz = 0; duz < MAX_DUZ - 1; duz++)
if ((znak = getchar()) != '\n')
*(adresa + duz) = znak;
else
break;
*(adresa + duz) = '\0';
if (!duz)
{
free(adresa); break;
}
adresa = realloc(adresa, duz + 1);
for (i = br_grad - 1; i >= 0; i--)
if (strcmp(adrese[i], adresa) > 0)
adrese[i + 1] = adrese[i];
else
break;
adrese[i+1] = adresa;
} while (br_grad++ < MAX_GRAD);
Komentar:
Ova tema je detaljno obrađena u knjizi profesora Krausa. Savetuje se studentima da detaljno prouče primere
iz knjige.
Zadatak C90
Napisati program koji ispisuje redom binarne vrednosti brojeva koji su zadati putem komandne
linije. Glavnu obradu izdvojiti u potprogram, a potprogram smestiti u posebnu datoteku.
raspak.h
/* limits.h - implementation dependent values
limits.h sadrzi vrednosti koje se ticu maksimalnih i minimalnih velicina podataka,
kao i broja bitova koriscenih za neke tipove podataka, a koje su zavisne od konkretnog
ostvarenja programskog jezika C */
#include <limits.h>
raspak.c
#include "raspak.h"
void raspak( unsigned k, int bit[] )
{
int i = NUM_BITS( unsigned );
while ( i ) bit [ --i ] = k & 1, k >>= 1;
}
c90.c
/*
Napisati program koji ispisuje binarne vrednosti brojeva koji
su zadati na komandnoj liniji. Glavnu obradu izdvojiti u potprogram
*/
#include <stdio.h>
#include <stdlib.h>
#include "raspak.h"
Komentar
raspak.h – definiciona datoteka u kojoj su deklarisani svi potrebni tipovi podataka, simboličke konstante,
definicije makroa, kao i prototipovi korišćenih funkcija.
raspak.c – sadrži funkciju za rad sa binarnim brojevima (to je ono što se traži u zadatku).
c90.c – ovde je smešten je glavni program, koji koristi definicije iz raspak.h i poziva funkciju čija je
implementacija u raspak.c
Zadatak C95
Navesti tip identifikatora x u sledećim definicijama:
Zadatak C100
Napisati funkciju na programskom jeziku C koja realizuje algoritam QuickSort. Funkcija treba da
sortira niz podataka proizvoljnog tipa. Kriterijum sortiranja definisan je funkcijskim parametrom.
Rešenje
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
void swap( void **p1, void **p2 )
{
void *temp = *p1;
*p1 = *p2;
*p2 = temp;
}
/* rekurzivna varijanta */
void quicksort(void *v[], int left, int right, int (*comp)(const void *, const void * ))
{
int i, last;
if( left >= right ) return;
last = left;
for ( i = left + 1; i <= right; i++ )
if ( ( *comp )( v[ i ], v[ left ] ) < 0)
swap( &v[ ++last ],&v[ i ] );
swap( &v[ left ], &v[ last ] );
quicksort( v, left, last - 1, comp );
quicksort( v, last + 1, right, comp );
}
#define MAX_STR 20
#define MAX_DIM 10
void main()
{
char *niz[ MAX_DIM ];
int i,n;
for ( i = 0; i< MAX_DIM; i++ )
{
niz[ i] = calloc( MAX_STR, 1 );
if ( ( niz[ i ] == NULL )
|| ( fgets( niz[ i ], MAX_STR, stdin ) == NULL )
|| ( *( niz[ i ] ) == '\n' )
) break;
}
n = i - 1;
quicksort( niz, 0, n, strcmp );
for ( i = 0; i <= n; i++ ) fputs( niz[ i ], stdout );
}
Komentar
Funkcija swap ima dva argumenta; ovom funkcijom se postiže da **p1 pokazuje tamo gde je pokazivao
**p2 i obrnuto. Funkcija quicksort se zasniva na algoritmu particijskog sortiranja, realizovana je
rekurzivno, i treba da uredi neuređen niz.
Deklaracijom int (*comp)(const void*, const void*) definiše se pokazivač na funkcije čija je
povratna vrednost tipa int i koje imaju dva argumenta tipa const void*. Tamo gde se u programskom
kodu nalazi (*comp)(v[i], v[left]) imamo indirektno adresiranje koje se primenjuje na promenljivu
comp, što je praktično poziv funkcije koja se u memoriji nalazi na adresi na koju pokazuje pokazivač comp. Da
bi ovo bilo ispravno, funkcija na koju comp pokazuje se mora slagati po tipu/tipovima argumenata navedenim
pored (*comp).
Zadatak C104
Napisati program u programskom jeziku C za rad sa kompleksnim brojevima. Preko argumenata
programa zadaju se dva kompleksna broja i to tako da se prvo navodi realan deo prvog broja, zatim
imaginarni deo prvog broja, zatim realni i imaginarni deo drugog kompleksnog broja, respektivno.
Ako korisnik ne unese tačan broj argumenata potrebno je prekinuti izvršavanje programa. Takođe
treba napisati potprogram koji proverava da li znakovni niz sadrži broj i pomoću tog potprograma
treba ispitati da li su svi navedeni argumenti zaista brojevi. Ako bar jedan argument nije broj,
potrebno je prekinuti izvršavanje programa. Program treba da sadrži i potprogram za sabiranje dva
kompleksna broja koji vraća kompleksni broj kao rezultat kao i potprogram za konjugovanje
kompleksnog broja koji nema povratnu vrednost. Glavni program treba da na standardnom izlazu
ispiše sve argumente programa, zbir kompleksnih brojeva i konjugovane vrednosti oba kompleksna
broja. Ispis treba vršiti pozivom odgovarajućeg potprograma koji takođe treba napisati. Kompleksne
brojeve predstaviti strukturom.
Rešenje
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
while(*pstr)
{
if (!isdigit(*pstr) && *pstr!='.')
return FALSE;
if (*pstr == '.')
{
if (bTacka)
return FALSE;
bTacka = TRUE;
}
pstr++;
}
return TRUE;
}
if (argc != 5)
{
printf("Unesite tacno cetiri argumenata pri startu programa!\n");
return -1;
}
z1.Re = atof(argv[1]);
z1.Im = atof(argv[2]);
z2.Re = atof(argv[3]);
z2.Im = atof(argv[4]);
return 0;
}
Komentar
Zadavanje argumenta putem komandne linije znači da glavni program ima dva argumenta. Argumenti
komandne linije su stringovi, te ih moramo konvertovati pre korišćenja. Ti argumenti omogućavaju prenošenje
parametara glavnom programu koji se zadaju u sastavu komande operativnog sistema za izvršavanje
programa.
Zadatak C110
Date su sledeće deklaracije:
typedef int CeoBroj;
typedef int *PokazivacNaCeoBroj;
typedef int NizCelihBrojeva[100];
CeoBroj *pokazA;
PokazivacNaCeoBroj pokazB;
NizCelihBrojeva niz;
struct {
int x,y;
} zapisA;
struct {
int x,y;
} zapisB, zapisC;
Koje od sledećih naredbi dodele su semantički ispravne?
pokazA = pokazB; /* OK */
pokazA = niz; /* OK */
niz = pokazA; /* GREŠKA */
zapisB = zapisC; /* OK */
zapisA = zapisB; /* GREŠKA */
Obrazloženje
Prvi primer je ispravan zato što je moguća dodela između dve promenljive koje su istog tipa –
pokazA i pokazB su pokazivači na int. Drugi primer je ispravan jer pokazA sada pokazuje tamo
gde pokazuje niz. Tip imena niza je tip nepromenljivog pokazivača na nulti član, zato je treći primer
pogrešan, jer se ne može nepromenljivom pokazivaču dodeliti nova vrednost.
U programskom jeziku C se koristi strukturna ekvivalencija tipova (typedef imena se pri tome
zamenjuju odgovarajućim tipom) osim u slučaju struktura i unija. Za strukture i unije koristi se
ekvivalencija po imenu. Svaka neimenovana struktura je poseban tip, čak i u slučaju da su sva polja
neke dve strukture međusobno identična.
Zadatak C115
Sastaviti program na programskom jeziku C za spajanje sadržaja nekoliko sekvencijalnih tekst
datoteka u jednu izlaznu datoteku. Imena datoteka se zadaju kao parametri u komandnoj liniji. Ime
izlazne datoteke je prvi parametar. Ukoliko je prvi parametar "-", izlazna datoteka je stdout.
Rešenje
#include <stdio.h>
#include <string.h>
main (int argc, char *argv[])
{
void prepis (FILE *, FILE*);
FILE *ulaz, *izlaz;
char *prog = argv[0];
izlaz = stdout;
if (argc > 1)
{
argc--;
if (strcmp(*++argv, "-") != 0)
if ((izlaz = fopen(*argv, "w")) == NULL)
{
fprintf(stderr,"%s:greska u otvaranju datoteke %s\n",prog,*argv);
exit(1);
}
}
while(--argc > 0)
if ((ulaz = fopen(*++argv, "r")) != NULL)
prepis(ulaz, izlaz), fclose(ulaz);
else
{
fprintf(stderr,"%s: ne postoji datoteka %s\n", progr, *argv);
exit(2);
}
fclose(izlaz);
exit (0);
}
Komentar
Elementi char *argv[] (niz pod imenom argv čiji su elementi pokazivači na char, gde operativni sistem
smešta stringove iz komandne linije) se mogu tretirati u kodu sa *argv zbog promocije – niz se ne može
inkrementirati kao što se to radi u datom primeru, ali ako se kao parametar funkcije navede neki niz, C to
automatski tretira kao pokazivač na tip podataka kome pripadaju elementi niza, a za pokazivače je
inkrementiranje dozvoljeno.
Zadatak C120
U binarnoj datoteci se nalaze zapisi o automobilima i vozačima. Svaki zapis sadrži podatak o tipu
entiteta, samom entitetu i celobrojnu vrednost sledećeg zapisa u logički organizovanoj listi. Prvi zapis
u datoteci je i prvi zapis liste, a poslednji zapis liste je zapis u čijem polju ukazatelja na sledeći zapis
stoji 0. Svaki zapis u datoteci ima polje koje sadrži broj logički sledećeg zapisa u datoteci.
Napisati:
1. potprogram koji čita navedenu datoteku i formira listu zapisa u dinamički dodeljenoj memoriji,
pri čemu zapise povezuje u suprotnom smeru od smera u datoteci;
2. potprogram koji ispisuje na standardnom izlazu listu iz tačke a) i
3. glavni program koji poziva gornje potprograme
cz120.h
#include <stdio.h>
cz120.c
#include <stdio.h>
#include "cz120.h"
if (argc > 2)
kreiraj_datoteku(argv[1]);
if (av_bin = fopen(argv[1],"rb"))
{
formiraj_listu(av_bin,&lista);
pisi_listu(lista);
}
}
pisi_av.c
#include <stdio.h>
#include "cz120.h"
pisilist.c
#include "cz120.h"
void pisi_listu(struct element_lis *lista)
{
while(lista)
{
switch (lista->z.a.t)
{
case AUTO: pisi_auto(lista); break;
case VOZAC: pisi_vozac(lista); break;
default: printf("Neispravan element liste!\n");
}
lista = lista->s;
}
}
kr_dat.c
#include "cz120.h"
void kreiraj_datoteku(char* filename)
{
struct element_dat bafer;
int izbor = 1;
FILE *file = fopen(filename, "wb");
while(izbor)
{
printf("Auto[1] ili vozac[2] ili kraj unosa[bilo sta]? \n");
scanf("%d", &izbor);
switch(izbor)
{
case AUTO:
printf("Unesite redom sledece podatke: boja, model, registarski broj, KLJUC: \n");
scanf("%s%s%s%d", bafer.z.a.boja, bafer.z.a.model, bafer.z.a.reg_br, &bafer.b);
bafer.z.a.t = AUTO; break;
case VOZAC:
printf("Unesite redom sledece podatke: ime, prezime, pol, broj dozvole: \n");
scanf("%s%s%s%s%d", bafer.z.v.ime, bafer.z.v.prezime, bafer.z.v.pol,
bafer.z.v.br_dozvole, &bafer.b);
bafer.z.v.t = VOZAC; break;
default: izbor = 0;
}
if (izbor)
fwrite(&bafer, sizeof(struct element_dat), 1, file);
}
fclose(file);}
Zadatak C122
Potrebno je realizovati u programskom jeziku C skup funkcija za rad sa listom čije je ponašanje
isto kao ponašanje podatka tipa liste iz pseudojezika. Funkcije za rad sa listom treba da se zovu isto
kao u pseudojeziku (find_bolp, insert, move_forward...) i treba da budu realizovane u zasebnoj
implementacionoj .c datoteci. Takođe je potrebno napraviti odgovarajuću definicionu .h (header)
datoteku u kojoj će biti deklarisani svi potrebni tipovi podataka i prototipovi korišćenih funkcija.
Podaci se u listi skladište preko generičkog pokazivača (void *), a potrebno je obezbediti brisanje
podataka sadržanih u listi kroz call-back mehanizam. Napraviti inicializacionu funkciju koja inicijalizuje
listu i koja postavlja odgovarajuću funkciju koja se poziva kroz call-back mehanizam pri uništavanju
liste. Pointer na ovu funkciju se prosleđuje kao argument funkcije za inicijalizaciju liste. U listu je iz
tekstualne datoteke potrebno pročitati podatke o studentima. Podaci su u fajl složeni tako da je u
jednom redu ime i prezime studenta, u drugom broj indeksa u formatu Broj/GodinaUpisa i u trećem
prosek studenta. Nakon čitanja iz datoteke, upisati sve podatke o studentima iz liste u novu binarnu
datoteku i to tako da se upisuju samo podaci o studentima sa prosekom većim od 8.5.
pj_lista.h
#define TRUE 1
#define FALSE 0
struct SList
{
TListStatus lsStatus; /* status - trenutni polzaj u listi */
struct SListElement *pHead; /* pokazivac na glavu liste */
struct SListElement *pCurrent; /* pokazivac na tekuci element */
void (*destructor)(void *); /* pokazivac na funkciju koja ima argument tipa void* */
};
pj_lista.c
#include <stdlib.h>
#include "pj_lista.h"
if (pList->lsStatus == lsBOLP)
{
pList->pCurrent = pList->pHead;
if (pList->pCurrent == NULL)
pList->lsStatus = lsEOLP;
else
pList->lsStatus = lsCURRENT;
}
else
{
pList->pCurrent = pList->pCurrent->pNext;
if (pList->pCurrent == NULL)
pList->lsStatus = lsEOLP;
}
return TRUE;
}
/* pList - pokazivac na tip Tlist, pData - podatak koji ce biti ubacen u listu. */
int insert(TList *pList, void *pData)
{
TListElement *pNewElem;
if (pList->lsStatus == lsEOLP)
return FALSE;
if (pNewElem == NULL)
return FALSE;
pNewElem->pData = pData;
pNewElem->pNext = NULL;
if (pList->lsStatus == lsBOLP)
{
pNewElem->pNext = pList->pHead;
pList->pHead = pNewElem;
pList->pCurrent = pNewElem;
pList->lsStatus = lsCURRENT;
}
else
{
pNewElem->pNext = pList->pCurrent->pNext;
pList->pCurrent->pNext = pNewElem;
pList->pCurrent = pNewElem;
}
return TRUE;
}
return NULL;
}
void destroy_list(TList *pList)
{
TListElement *pElem, *pHelpElem;
for (pElem = pList->pHead; pElem != NULL; )
{
pHelpElem = pElem->pNext;
if (pList->destructor)
(*pList->destructor)(pElem->pData); /* na ovom mestu pointer na funkciju */
/* se dereferencira i zatim se poziva ta funkcija */
/* sa argumentom pElem->pData */
free(pElem);
pElem = pHelpElem;
}
}
cz122.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pj_lista.h"
void main()
{
FILE *f1, *f2;
TList list;
TStudent *pStudent;
char *pKrajLinije;
f2 = fopen("studenti.bin", "wb");
if (f2 == NULL)
{
printf("Datoteka za upis nece da se otovori!\n");
fclose(f1);
return;
}
while (!feof(f1))
{
pStudent = (TStudent *)calloc(sizeof(TStudent), 1);
fgets(pStudent->strIme, 255, f1);
/*
Funkcija fgets cita string sve do kraja linije, ali ukljucuje i kraj linije u string!
Zato cemo koristiti strchr funkciju koja vraca adresu prvog karaktera koji se zadaje kao
drugi argument funkcije u okviru stringa koji se zadaje kao prvi argument funkcije.
Ako karakter nije pronadjen strchr vraca NULL. Kada pronadjemo karakter za kraj linije,
prosto cemo ga izbaciti postavljajuci ga na '\0' sto oznacava kraj stringa.
*/
if ((pKrajLinije = strchr(pStudent->strIme, '\n')) != NULL)
*pKrajLinije = '\0';
fclose(f1);
find_bolp(&list);
while (TRUE)
{
move_forward(&list);
if (eolp(&list))
break;
pStudent = (TStudent*)get(&list);
printf("Ime i prezime: %s\n", pStudent->strIme);
printf("Broj indeksa: %d/%02d\n", pStudent->nBroj, pStudent->nGodUpisa);
printf("Prosek: %4.2f\n", pStudent->fProsek);
if (pStudent->fProsek > 8.5)
{
if (fwrite(pStudent, sizeof(TStudent), 1, f2) == 1)
printf("Kandidat uspesno upisan u novi fajl...\n\n");
else
{
printf("Greska pri upisu! Program prekinut.\n");
break;
}
}
else
printf("Kandidat nije zadovoljio uslove za upis u novi fajl!\n\n");
}
fclose(f2);
destroy_list(&list);
printf("** KRAJ **\n");
}
Zadatak C125
Pod pretpostavkom da su zapisi u datoteci uređeni u leksikografski uređeno stablo, šta ispisuje
dati program za zadatu datoteku (prvi argument komandne linije) i zadati ključ (drugi argument)?
#include <stdio.h>
#include <string.h>
struct tree_elem
{
char key[7];
unsigned long left, right;
};
void create(char* filename)
{
struct tree_elem buffer;
FILE *file = fopen(filename, "wb");
while (!ferror(file))
{
printf("\nKEY LEFT RIGHT: ");
scanf("%6s %lu %lu", buffer.key, &buffer.left, &buffer.right);
if (strcmp(buffer.key, "END") == 0) break;
fwrite(&buffer, sizeof(struct tree_elem), 1, file);
}
fclose(file);
}
void traverse( FILE *file, char key[], unsigned long node)
{
struct tree_elem buffer;
static int ukupno_aktivacija = 0;
int ova_akt;
printf("Pocetak aktivacije %d\n", ova_akt = ++ukupno_aktivacija);
if ( node == 0 )
{ printf("Kraj aktivacije %d\n", ova_akt); return; }
fseek( file, ( node - 1 ) * sizeof( struct tree_elem ), SEEK_SET);
fread( &buffer, sizeof(struct tree_elem ), 1, file );
if ( ferror( file ) ) return;
traverse( file, key, buffer.left );
if ( strcmp( key, buffer.key ) >= 0)
{
printf( "%s\n", buffer.key );
traverse( file, key, buffer.right );
}
printf("Kraj aktivacije %d\n", ova_akt);
}
void main( int argc, char *argv[] )
{
FILE *file; /* ovako odredjujemo da li kreiramo datoteku ili */
if (argc > 3) create(argv[1]); /* koristimo vec napravljenu nekom ranijom prilikom */
if ( ( file = fopen( argv[1], "rb" ) ) == NULL )
fprintf( stderr, "Greska pri otvaranju datoteke %s\n", argv[1] );
else
traverse( file, argv[2], 1 );
}
A) ključeve svih zapisa u datoteci u leksikografskom poretku
B) ključeve svih zapisa manjih do jednakih zadatom, u leksikografskom poretku
C) ključeve svih zapisa manjih do jednakih zadatom, u obrnutom leksikografskom poretku
Odgovor
B
Komentar
Promenljive ukupno_aktivacija i ova_akt služe za pojašnjavanje rednog broja aktivacije posmatrane
rekurzivne funkcije traverse, i nemaju uticaja na suštinu zadatka.
Komentar
U funkciji zbir() su prikazana dva različita pristupa dobijanja vrednosti broja zapisanog u heksadecimalnom
brojnom sistemu. Najpre se vrši konverzija broja a, tako što se u ciklusu analizira znak po znak, sve dok se ne
dođe do kraja znakovnog niza. Primetiti da nigde nije pretpostavljena dužina nizova a i b, pa je ovo rešenje
univerzalno (u onoj meri u kojoj opseg predstavljanja celih brojeva dozvoljava). Za praktične primene, ovom
rešenju nedostaje provera da li znakovni nizovi a i b zaista predstavljaju cele brojeve u heksadecimalnom
zapisu. To se, međutim, nije tražilo - pa nije ni prikazano u rešenju. Nakon ciklusa za konverziju broja a, vrši
se konverzija broja b pozivom funkcije sscanf(). Ova funkcija se ponaša slično scanf() odnosno fscanf(), s
tim što je izvor koji treba čitati u datom formatu zadat znakovnim nizom koji se zadaje kao prvi argument. U
ovom slučaju radi se o nizu b. Naziv sscanf() zapravo potiče string scanf. U ostalim aspektima, može se
smatrati da se ova funkcija ponaša kao scanf().
Zadatak CI-2006-Okt-1
Napisati program na programskom jeziku C koji izračunava broj osvojenih bodova na šampionatu
trka Formule 1. Podaci o vozačima i timovima se nalaze u tekst datoteci vozaci.txt prema sledećem
formatu: u svakom redu datoteke redom su zapisani prezime i ime vozača i naziv tima za koji vozač
vozi (svako polje po 30 karaktera najviše). Poznato je da ima tačno 28 vozača koji učestvuju u
trkama i da se na šampionatu vozi 20 trka. Podaci o rezultatima trka smešteni su tekst datoteci
trke.txt tako da se u svakom redu datoteke nalaze redni brojevi pozicija jednog vozača po završetku
svake trke (20 pozicija, za svaku trku po jedna). U slučaju da vozač ne prođe cilj (odustane od trke),
broj pozicije za tu trku je 0. Podaci u prvom redu datoteke trke.txt odgovaraju vozaču iz prvog reda
datoteke vozaci.txt, itd. Bodovi za vozače za jednu trku se računaju na sledeći način: prvih 8 vozača
dobija 10, 8, 6, 5, 4, 3, 2 i 1 bod respektivno, ostali 0 bodova. Program treba da izračuna i na
standardnom izlazu ispiše osvojene bodove tako da u jednom redu stoje prezime i ime vozača,
osvojen broj bodova i naziv tima.
#include <stdio.h>
main() {
FILE *vozaci, *trke; Nemojte NIKAD
char prezime[31], ime[31], tim[31];
int v,p,pozicija,poena; programski kod
vozaci = fopen("vozaci.txt", "r"); učiti napamet.
trke = fopen("trke.txt", "r");
if( ! vozaci || ! trke ) {
if( ! vozaci ) printf("Neuspelo otvaranje datoteke vozaci.txt\n");
else fclose(vozaci);
if( ! trke ) printf("Neuspelo otvaranje datoteke vozaci.txt\n");
else fclose(trke);
exit(0);
}
for(v=0; v<28; v++) {
fscanf(vozaci, "%s %s %s", prezime, ime, tim);
poena = 0;
for(p=0; p < 20; p++) {
fscanf(trke, "%d", &pozicija);
switch(pozicija) {
case 1: poena += 10; break;
case 2: poena += 8; break;
case 3: poena += 6; break;
case 4: poena += 5; break;
case 5: poena += 4; break;
case 6: poena += 3; break;
case 7: poena += 2; break;
case 8: poena += 1; break;
}
}
printf("%s %s %d %s\n", prezime, ime, poena, tim);
}
Svako ponavljanje bez
fclose(vozaci);
fclose(trke);
} razumevanja programskog koda
je štetno i na ispitu će biti
kažnjavano oduzimanjem poena.
Komentar
Provera da li su datoteke uspešno otvorene nije najjezgrovitije zapisana, ali je verovatno najpribližnija načinu
na koji se razmišlja prilikom donošenja odluke. Najpre je izvršeno otvaranje obe datoteke. Ako bilo koja od
njih nije uspešno otvorena, potrebno je prekinuti program, a prethodno prethodno ispisati koja zapravo nije
uspešno otvorena (moguće – obe). Za onu koja je uspešno otvorena se ne vrši ispisivanje već njeno
zatvaranje. Iako obaveštenje o nastalim greškama pri radu nije traženo u postavci, ovde je to prikazano iz
edukativnih razloga.
Zadatak CI-2007-Okt-2
Napraviti program na programskom jeziku C koji obrađuje datoteku koja sadrži izvorni program na
programskom jeziku C. Potrebno je datoteku prepisati u novu datoteku, tako da se izostave svi
komentari i očuva uređenost teksta po redovima. Primer:
Ulazna datoteka Odgovarajuća izlazna datoteka
#include <stdio.h> #include <stdio.h>
/* ispis proizvoda i kolicnika dva broja main()
*/ {
main() int a, b;
{ scanf("%d%d", &a, &b);
int a, b; printf("%d", a*b);
scanf("%d%d", &a, &b); printf("%d", a/b);
printf("%d", a*b); /* ispis a*b */ }
/* ispis a/b */ printf("%d", a/b);
}
Imena ulazne i izlazne datoteke se zadaju kao prvi i drugi parametar komandne linije i imaju
najviše 30 znakova. U slučaju da dođe do greške pri otvaranju neke od datoteka, ispisati poruku o
greški i prekinuti izvršavanje programa.
#include <stdio.h>
int main(int argc, char *argv[]) {
char znak;
enum StanjeObrade { VAN_K, POC_K, UNUTAR_K, KRAJ_K } stanje = VAN_K;
FILE *ul, *izl;
if (NULL == (ul = fopen(argv[1], "r"))) {
fprintf(stderr, "Doslo je do greske pri otvaranju %s\n", argv[1]);
return 1;
}
if (NULL == (izl = fopen(argv[2], "w"))) {
fclose(ul);
fprintf(stderr, "Doslo je do greske pri otvaranju %s\n", argv[2]);
return 2;
}
Nemojte NIKAD
while ((znak = fgetc(ul)) != EOF) {
switch(stanje) {
programski kod
case VAN_K:
if ('/' == znak) stanje = POC_K;
učiti napamet.
else fputc (znak, izl);
break;
case POC_K:
if ('*' == znak) stanje = UNUTAR_K;
else stanje = VAN_K, fputc('/', izl), fputc(znak, izl);
break;
case UNUTAR_K:
if ('*' == znak) stanje = KRAJ_K;
break;
case KRAJ_K:
if ('/' == znak) stanje = VAN_K;
else stanje = UNUTAR_K;
break;
}
}
Svako ponavljanje bez
fclose(ul);
fclose(izl);
razumevanja programskog koda
}
return 0; je štetno i na ispitu će biti
kažnjavano oduzimanjem poena.
Komentar
Zadatak se bavi nešto složenijom obradom ulazne datoteke u odnosu na jednostavno prepisivanje podataka. U
programu se uvodi pojam "stanja" na osnovu kojeg se odlučuje kako treba tretirati ulazni tekst. Na primer,
ako se trenutna obrada vrši unutar komentara, ništa se ne prepisuje u izlaznu datoteku i obrnuto. S obzirom
na to da se početak i kraj komentara označava pomoću dva karaktera (/ i *), uvodi se četiri stanja: van
komentara, početak komentara, unutar komentara i kraj komentara. U stanju van komentara,
svi znaci se prepisuju, osim kada se pojavi znak /. Tada je potrebno pročitati naredni znak i utvrditi da li je on
* (počinje komentar) ili nije (treba / poslati u izlaznu datoteku). Dakle, kada u stanju van komentara naiđe
znak /, potrebno je preći u novo stanje, u kojem se očekuje dolazak znaka *. Slično se vrši izlazak iz
komentara.
stderr je izlazni uređaj koji se automatski stvara i koji služi kao "kanal" za ispis grešaka. Njegovo korišćenje
nije zahtevano u postavci zadatka – njegova uloga u ovom rešenju je edukativna.
Zadatak CI-2006-Sep-2
Napisati program koji jednu tekst datoteku prepisuje u drugu tekst datoteku, uz očuvanje
uređenosti teksta po linijama. Linije u kojima postoji neparan broj znakova razmaka se prepisuju tako
da sva slova budu mala, a ostale tako da sva slova budu velika. Linije ne mogu biti duže od 80
znakova. Imena tekst datoteka se zadaju putem standardnog ulaza; ne mogu biti duža od 30
znakova. U slučaju da ne uspe otvaranje neke od datoteka, ispisati poruku korisniku u kojoj se
navodi sa kojom datotekom je došlo do problema i prekinuti izvršenje programa.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
main() {
char ime_ul_dat[30+1], ime_izl_dat[30+1], linija[80+1+1];
FILE *ul_dat, *izl_dat;
Nemojte NIKAD
int duz_lin, i, br_raz; programski kod
scanf("%s", ime_ul_dat); učiti napamet.
scanf("%s", ime_izl_dat);
ul_dat = fopen(ime_ul_dat, "r");
if (NULL == ul_dat) {
fprintf(stderr, "Doslo je do greske pri radu sa %s\n", ime_ul_dat);
exit(EXIT_FAILURE);
}
izl_dat = fopen(ime_izl_dat, "w");
if (NULL == izl_dat) {
fclose(ul_dat);
fprintf(stderr, "Doslo je do greske pri radu sa %s\n", ime_izl_dat);
exit(EXIT_FAILURE);
}
while (fgets(linija, 82, ul_dat) != NULL) {
duz_lin = strlen(linija);
br_raz = 0;
for (i = 0; i < duz_lin; i++)
br_raz += isspace(linija[i]) != 0;
for (i = 0; i < duz_lin; i++)
if (br_raz % 2)
linija[i] = tolower(linija[i]);
else
linija[i] = toupper(linija[i]);
fputs(linija, izl_dat);
}
fclose(ul_dat);
Svako ponavljanje bez
fclose(izl_dat); razumevanja programskog koda
je štetno i na ispitu će biti
}
Zadatak CI-2006-Jan-1
U cilju proglašenja najboljeg igrača(MVP) na odbojkaškom turniru, organizacioni odbor turnira je
doneo sledeću odluku o načinu bodovanja učinka igrača: poen iz servisa vredi 1 poen, poen iz smeča
vredi 0.5 poena, a blokada 0.2 poena. Podaci o učinku svih igrača za vreme celog turnira nalaze se u
tekstualnoj datoteci odbojka.txt. U jednom redu datoteke nalaze se podaci za jednog igrača. Za
svakog igrača se pamti njegovo ime i prezime (niz od tačno 30 karaktera), visina (ceo broj), težina
(ceo broj), broj ostvarenih poena iz servisa na turniru (ceo broj), broj poena iz smeča (ceo broj) i
broj blokada (ceo broj). Napisati program na programskom jeziku C koji iz datoteke odbojka.txt
čita podatke o igračima i pronalazi prvog igrača sa najvećim brojem ostvarenih poena i na
standardnom izlazu ispisuje ime tog igrača i broj ostvarenih poena.
Rešenje sa fgets
#include<stdio.h>
#include<string.h>
main() {
Nemojte NIKAD
double poen_serv = 1.0, poen_smec = 0.5, poen_blok = 0.2;
double max_poeni = 0.0, poeni;
programski kod
char ime_i_prez[31], max_ime_i_prez[31];
unsigned visina, tezina, br_serv, br_smec, br_blok;
FILE *ul_dat = fopen("odbojka.txt", "r");
učiti napamet.
if( ul_dat == NULL )
exit(0);
Komentar
Ovaj zadatak je rešen na dva veoma slična načina. U rešenju prikazanom na ovoj strani koristi se funkcija
fgets() da pročita ime i prezime igrača kao jednu celinu (tj. kao jedan red teksta) i smesti ih u znakovni niz
ime_i_prez.
Drugo rešenje, prikazano na sledećoj strani, koristi funkciju fscanf() za čitanje imena i prezimena kao dva
nezavisna znakovna niza, zbog čega je naknadno potrebno izvršiti njihovo spajanje u jedan znakovni niz:
najpre se pročita ime i smesti u znakovni niz ime_i_prez. Nakon toga se u poseban niz prezime smešta
pročitano prezime. Zatim se na ranije pročitano ime dodaje jedan znak razmaka a posle toga i pročitano
prezime. Dodavanje jednog znakovnog niza na kraj drugog se vrši funkcijom strcat().
Treba primetiti sledeće. Očekivano da oba rešenja daju isti rezultat u smislu čitanja imena i prezimena. Ipak,
ne mora biti tako: ako ulazna datoteka sadrži više od jednog razmaka između imena i prezimena, ti razmaci će
ostati nakon čitanja kada se koristi funkcija fgets(). To se neće desiti kada se za čitanje imena i prezimena
koristi funkcija fscanf() jer ona automatski ignoriše sve razmake koji razdvajaju dva niza znakova.
fclose(ul_dat);
Zadatak CI-2006-Jan-2
Napisati potprogram double bin2dbl(char * num) na programskom jeziku C koji na osnovu
znakovnog niza (stringa) num koji predstavlja binarnu reprezentaciju realnog broja izračunava i kao
rezultat vraća brojnu vrednost tipa double, koja će se ispisati u decimalnom brojnom sistemu. String
num ima najviše 10 binarnih cifara uključujući i decimalnu tačku koja može a ne mora postojati.
Napisati glavni program na programskom jeziku C koji sa standardnog ulaza učitava string num,
poziva potprograma bin2dbl i na standardnom izlazu ispisuje dobijeni rezultat. (npr. za unos
“1011.101” program treba da ispiše rezultat 11.625).
#include <stdio.h>
#include <string.h>
double bin2dbl(char *num) {
unsigned num_length = strlen(num), i = 0;
double celi_deo = 0, razl_deo = 0;
/* ako prvi znak nije decimalna tacka, računa se celi deo broja */
if (num[i] != '.') {
celi_deo = num[0] - '0';
/* dok se ne stigne do kraja broja ili do decimalne tacke */
while (++i < num_length && num[i] != '.')
celi_deo = celi_deo * 2 + (num[i] - '0');
}
Nemojte NIKAD
/* ako postoji razlomljeni deo, kreće se od kraja */
if (i < num_length) programski kod
učiti napamet.
/* dok se ne stigne do decimalne tacke */
while (i < --num_length)
razl_deo = (razl_deo + num[num_length] - '0')/2;
main() {
char ul_num[11];
printf("Unesite binarni broj koji treba prevesti u decimalni brojni sistem: ");
scanf("%s", ul_num);
printf("%7.3lf\n", bin2dbl(ul_num));
} Svako ponavljanje bez
razumevanja programskog koda
je štetno i na ispitu će biti
kažnjavano oduzimanjem poena.
Komentar
Tražena funkcija izračunava vrednost realnog broja zapisanog u binarnom brojnom sistemu i od dobijene
vrednosti pravi podatak tipa double. Obrada se vrši na sledeći način: ako niz ne počinje znakom '.', onda je u
pitanju celobrojni deo tog realnog broja. Pravi se ciklus koji se ponavlja sve dok se ne obrade svi znakovi u
nizu (slučaj kada je zadat ceo broj) ili dok se ne naiđe na decimalnu tačku (realni broj sa razlomljenim delom).
Do nastavka funkcije se dakle stiže u tri situacije: niz je počeo decimalnom tačkom ili obrada niza je završena
ili tokom obrade celobrojnog dela se stiglo do decimalne tačke. S obzirom na to da se u slučaju prve i treće
situacije postupa isto (određuje se razlomljeni deo), najpre se eliminiše druga situacija (završena obrada)
proverom da li je i manje od num_length. Ako je taj uslov ispunjen, u novom ciklusu se određuje vrednost
razlomljenog dela, s tim što obrada ide od kraja niza, zbog prirode problema (krajnje desna pozicija je pozicija
cifre najmanje težine).
Ova funkcija nije prilagođena praktičnoj upotrebi, jer bi to zahtevalo da se pre određivanja vrednosti broja
izvrši provera da li se dati znakovni niz zaista sastoji od cifara 0 i 1 i najviše jednog decimalnog zareza.
Preporučuje se pisanje funkcije koja to utvrđuje za samostalnu vežbu.
Zadatak CI-2006-Sep-1
Na programskom jeziku C napisati potprograme i glavni program koji vrše obradu niza realnih
brojeva. Unos podataka, obrada, ispis rezultata i oslobađanje memorije se vrši u potprogramima.
Potprogram za unos sa standardnog ulaza učitava broj elemenata niza realnih brojeva tipa float,
alocira potrebnu dinamičku memoriju sa smeštanje tog niza i učitava elemente niza. Ovaj potprogram
treba da proveri uspešnost poziva funkcije za dodelu dinamičke memorije i u slučaju neuspeha
prekida izvršavanje programa. Potprogram za obradu, ispis i oslobađanje memorije štampa sve
brojeve iz unetog niza koji su u opsegu +/- 10% od vrednosti aritmetičke sredine niza. Nakon ispisa,
potprogram oslobađa dinamički alociranu memoriju. Napisati glavni program koji redom poziva
opisane potprograme. Potprogrami sa glavnim programom smeju razmenjivati podatke samo preko
liste argumenata i povratne vrednosti.
#include <stdio.h>
#include <stdlib.h>
#define FAILURE 0
#define SUCCESS 1
int Unos(float **niz_Adr, int *br_el_Adr) {
float *niz;
int i, br_el;
printf("Unesite broj elemenata: "); Nemojte NIKAD
scanf("%d", &br_el);
niz = calloc(br_el, sizeof(float));
programski kod
if (NULL == niz) return FAILURE;
for (i = 0; i < br_el; i++)
učiti napamet.
scanf("%f", &niz[i]);
*niz_Adr = niz;
*br_el_Adr = br_el;
return SUCCESS;
}
void ObradaIspisDealociranje(float *niz, int br_el) {
float arit_sred = 0.0;
int i;
for(i = 0; i < br_el; i++) arit_sred += niz[i];
if (0 != br_el) arit_sred /= br_el;
printf("%f\n", arit_sred);
for(i = 0; i < br_el; i++)
if (niz[i] >= 0.9 * arit_sred && niz[i] <= 1.1 * arit_sred)
printf("%f\t", niz[i]);
printf("\n");
free(niz);
}
main() {
Svako ponavljanje bez
float *niz = 0; razumevanja programskog koda
int br_el;
if (Unos(&niz, &br_el)) je štetno i na ispitu će biti
else
ObradaIspisDealociranje(niz, br_el);
kažnjavano oduzimanjem poena.
printf("Greska pri unosu\n");
niz = 0;
}
Komentar
U postavci se eksplicitno traži da glavni program komunicira sa potprogramima putem argumenata i povratnih
vrednosti. Takav pristup u pisanju programa se preporučuje čak i ako se posebno ne naglasi. Takođe, nije
navedeno - ali bi trebalo podrazumevati, međusobna komunikacija potprograma treba da se odvija na isti
način.
Funkcija za unos i alokaciju memorije vraća vrednost celobrojnu vrednost - FAILURE odnosno SUCCES u
zavisnosti od uspeha. S obzirom na to da ta funkcija alocira memoriju za niz koji treba učitati – dakle menja
vrednost pokazivača, u potprogram se prenosi adresa pokazivača na dati niz brojeva. U suprotnom nikakva
izmena ne bi bila vidljiva van potprograma. Kod dealokacije memorije, ne prosleđuje se adresa pokazivača jer
se ne očekuje da se promena vrednosti tog pokazivača vidi sa mesta poziva (u ovom slučaju iz glavnog
programa). Ipak, u toj situaciji programer treba da vodi računa da nakon poziva funkcije za dealokaciju
memorije postavi vrednost to pokazivača na 0. U ovom zadatku to nije neophodno jer se taj pokazivač više ne
koristi (kraj programa), ali je dobra praksa.
for(e.c.a=0;e.c.a<br;e.c.a++)
for(e.d.a=0;e.d.a<5;e.d.a++)
for(e.c.a=0;e.c.a<5;e.c.a++)
for(e.c.b=0;e.c.b<5;e.c.b++) s++;
printf("%d", s);
}
A) 30 (B) 28 C) 628
Komentar
S obzirom na to da je kod elemenata unije memorijski prostor deljen, polja a i b strukture c dele iste lokacije
sa poljima a i b strukture d. Drugim rečima, svaka promena nad poljima a i b strukture c istovremeno
predstavlja i promenu nad poljima a i b strukture d i obrnuto.
Na početku promenljiva s dobija vrednost 3 a br 5. Dakle, spoljni ciklus (e.c.a) se na prvi pogled ponavlja 5
puta. Medjutim, vec naredni unutrašnji ciklus (e.d.a) se vrši nad istim podatkom, tako da kada on bude
završen, e.d.a će imati vrednost 5, a to automatski važi i za e.c.a. Sledeći for ciklus se odvija ponovo nad
e.c.a. Na osnovu prethodnog zaključka, kada on bude završen, automatski će biti ispunjen uslov za prekid
prva dva ciklusa. Prema tome, "koristan efekat" u programu imaju naredna dva ugneždena ciklusa. Ukupan
broj izvršavanja operacije s++ je zbog toga 25. Kako je početna vrednost s bila 3, konačna vrednost u
trenutku ispisivanja će biti 28.
Zadatak C2008-S11
Napisati program na programskom jeziku C koji sa standardnog ulaza čita znak po znak do kraja
linije. Znakovi se čitaju jedan po jedan. U početku se dinamički alocira niz od 10 elemenata. Nadalje,
svaki put kada u nizu treba više mesta, niz se proširi za još 10 znakova.
#include<stdlib.h>
#include<stdio.h>
void main(){
char *p=NULL, c;
int i = 0;
while( (c=getchar()) != '\n') {
if (i%10 == 0) p = realloc( p, (i+10) * sizeof(char) );
p[i++] = c;
}
if (i%10 == 0) p = realloc( p, (i+1) * sizeof(char) );
p[i++] = '\0';
printf("%s\n",p);
free(p); Svako ponavljanje bez
} razumevanja programskog koda
je štetno i na ispitu će biti
kažnjavano oduzimanjem poena.
Zadatak C2008-S12
Napisati segment programa na programskom jeziku C koji menja dimenziju kvadratne matrice sa
staroN na N. Ako se matrica smanji, tada elementi koji ostanu u novoj matrici treba da budu
neizmenjeni u odnosu na staru matricu. Ako se matrica poveća, elementi koji su postojali u staroj
matrici treba da ostanu neizmenjeni.
if (N < staroN) {
for (j = 1; j < N; j++)
for (i = 0; i < N; i++) m[j*N+i] = m[j*staroN+i];
}
if (N != staroN) m = realloc(m,N*N*sizeof(unsigned int));
if (N > staroN){
for (j = staroN-1; j > 0; j--)
for (i = staroN-1; i >= 0; i--)
m[j*N+i] = m[j*staroN+i];
}
Zadatak C2008-S21
Napisati program na programskom jeziku C koji sa standardnog ulaza čita znak po znak do kraja
linije. Znakovi se čitaju jedan po jedan. U početku se dinamički alocira niz od 10 elemenata. Nadalje,
svaki put kada u nizu više nema mesta, niz se proširi za još 10 znakova. U slučaju da realokacija
bude neuspešna, završiti čitanje i ispisati ono što može da stane u već alocirani prostor.
Rešenje
#include<stdlib.h>
#include<stdio.h>
Nemojte NIKAD
void main(){ programski kod
char *staro_p=NULL, *novo_p, c;
int i = 0; učiti napamet.
while( (c=getchar()) != '\n') {
if (i%10 == 0) {
novo_p = realloc( staro_p, (i+10) * sizeof(char) );
if (novo_p == NULL) {
printf("Neuspesno realociranje\n");
break;
}
else staro_p = novo_p;
};
staro_p[i++] = c;
}
if (i%10 == 0) {
novo_p = realloc( staro_p, (i+1) * sizeof(char) );
if (novo_p == NULL) {
printf("Neuspesno realociranje\n");
i--;
}
else staro_p = novo_p;
};
staro_p[i] = '\0';
printf("%s\n",staro_p);
Svako ponavljanje bez
free(staro_p); razumevanja programskog koda
} je štetno i na ispitu će biti
kažnjavano oduzimanjem poena.
Zadatak C2008-S22
Napisati program na programskom jeziku C koji učita broj vrsta i broj kolona i potom učita matricu
tih dimenzija. Program potom učita broj kolone koju treba izbaciti i izbacuje tu kolonu iz matrice.
Zatim čita redni broj vrste na koji umeće vrstu koju će učitati sa standardnog ulaza.
Rešenje
#include<stdlib.h>
#include<stdio.h>
void main(){
unsigned int **m, **novo_m;
int M, N, i, j, k;
scanf("%d %d", &M, &N);
m = malloc(M * sizeof(unsigned int*));
for (j = 0; j < M; j++){
m[j] = malloc( N * sizeof(unsigned int) );
for (i = 0; i < N; i++)scanf("%u", &m[j][i] );
}
Komentar
Zbog čitljivosti programa, u ovom rešenju su izostavljene provere da li je alokacija (realokacija) uspešno
izvršena. Pri pisanju bilo kakvog programa ove provere NE SMEJU biti izostavljene. Izostavljanjem tih provera,
ponašanje programa u slučaju nedostatka prostora nije predvidivo i može dovesti do katastrofalnih posledica.
aaa _1_
a12 Windows
12a vece-manje
_12a north&south
3. Koju će vrijednost imati realna promjenljiva B poslije datog niza naredbi? Na koji način se u tu
promjenljivu može upisati tačan rezultat date operacije?
int A;
float B;
A=5;
B=5*A/7; /* B = 3 */
4. Koju će vrijednost uzeti promenljive s1 i s2 nakon izvršenja svake od datih naredbi? Koju će vrijednost
uzeti promenljiva s2 ako se u poslednjem izrazu izostavi spoljašnji par zagrada u drugom sabirku?
1. Napisati program koji za uneti prirodni broj računa zbir njegovih cifara.
#include<stdio.h>
main()
{
int s=0,broj;
printf("Unesi prirodan broj\n");
scanf("%i",&broj);
while (broj!=0){
s+=broj%10;
broj/=10;
}
printf("Suma cifara prirodnog broja je: %d\n",s);
}
2. (Sa I kolokvijuma) Napisati program u programskom jeziku C koji učitava prirodan broj N i koji ispituje
da li je taj broj savršen broj. Prirodan broj je savršen ukoliko je jednak sumi svih svojih djelilaca koji su
manji od njega. Na izlazu štampati odgovarajuću poruku. Primjer: Broj 28 je djeljiv sa 1,2,4,7,14 i 28,
pa je zbir djelilaca manjih od njega 1+2+4+7+14=28, a to znači da je broj 28 savršen.
#include<stdio.h>
main()
{
int N,i,suma=0;
printf("Uneti broj N: ");
scanf("%d",&N);
for(i=1; i<N; i++){
if(N%i==0){
suma+=i;
}
}
if(suma==N)
printf("Broj %d jeste savrsen broj\n",N);
else
printf("Broj %d nije savrsen broj\n",N);
}
#include<stdio.h>
main()
{
int N=1;
float suma=0,op;
op=1.0/(N*N);
while(op>1e-4){
suma=suma+op;
N=N+1;
op=1.0/(N*N);
}
printf("Suma je %f",suma);
}
4. Napisati program koji računa najveći zajednički delilac (NZD) brojeva a i b pomoću Euklidovog
algortima:
1. Ako je a=b, tada je NZD=a i to je kraj algoritma.
2. Od većeg broja oduzmemo manji i vraćamo se na prvi korak.
#include<stdio.h>
void main()
{
int a, b;
puts("Unesi cijele brojeve");
scanf("%d %d",&a,&b);
while(a!=b) {
if (a>b)
a-=b;
else
b-=a;
}
printf("NZD je: %d\n",a);
}
Treći čas računskih vežbi iz Programiranja I
1. Napisati program koji formira podniz datog niza koji se sastoji od onih elemenata koji su veći od datog
cijelog broja.
#define MAX 20
#include <stdio.h>
main()
{
int N,C,k=0,i,a[MAX],b[MAX];
printf("Unesi broj clanova niza:");
scanf("%d",&N);
printf("Unesi cijeli broj:"); scanf("%d",&C);
printf("Unesi clanove niza:");
for(i=0;i<N;i++){
scanf("%d",a+i);
if(a[i]>C)
b[k++]=a[i];
}
if(k>0){
printf("Elementi niza koji su veci od datog cijelog broja
su:\n");
for(i=0;i<k;i++) printf("%d ",b[i]);
}
}
2. Napisati program koji definiše niz cijelih brojeva X i koji vrši sumiranje elemenata tog niza korišćenjem
pomoćne pokazivačke promjenljive. Prilagoditi program tako da eventualna izmjena broja elemenata
niza u njegovoj inicijalizaciji ne zahtijeva intervenciju na programu.
#include<stdio.h>
main(){
int X[]={-3,4,2,7,11,-9};
int *p, i, suma=0;
for(i=0; i < sizeof(X)/sizeof(X[0]); i++) {
p=&(X[i]); suma+=*(p+i); ili suma+=*p++, pri čemu
suma+=*p; pre petlje mora p=&(X[0]); ili p=X.
}
printf("Dobijena suma je: %d\n",suma);
}
3. Napisati program koji učitava matricu cijelih brojeva A, dimenzija NxM, i koji tu matricu štampati
prateći strelice prikazane na slici. Npr., za matricu:
1 2 3 4
11 12 13 14
A
21 22 23 24
31 32 33 34
redosljed štampanja treba da bude: 1,11,21,31,32,22,12,2,3,13,23,33,34,24,14,4.
#include <stdio.h>
main(){
int i,j,n,m, a[20][20];
printf("Unesi dimenzije matrice a: ");
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&a[i][j]);
for(j=0;j<m;j++)
if(j%2==0)
for(i=0;i<n;i++)
printf("%d ",a[i][j]);
else
for(i=n-1;i>=0;i--)
printf("%d ",a[i][j]);
}
Četvrti čas računskih vježbi iz Programiranja I
1. Učitati string koji sadrži manje od 20 karaktera sa tastature i sva mala slova u tom stringu
konvertovati u velika, a ostale karaktere ne menjati.
#include<stdio.h>
#include<string.h>
main()
{ char niz[20];
int i;
puts("Unesi neku rec");
scanf("%s",niz);
for (i=0;i<strlen(niz);i++){
if (niz[i]>='a' && niz[i]<='z')
niz[i]-='a'-'A';
}
printf("Novi string je: %s",niz);
}
2. Napisati program koji učitava string, koji predstavlja rečenicu, i koji koristeći funkciju
proverava da li je rečenica ispravno zadata. Ispravno zadata rečenica zadovoljava sljedeće:
a) Rečenica mora početi velikim slovom i završiti se tačkom.
b) Riječi su proizvoljni podstringovi koji mogu sadržati samo mala slova.
c) Riječi mogu biti razdvojeni jednim razmakom (SPACE), zarezom ili tačka-zarezom.
U glavnom programu učitati string, pozvati funkciju i na izlazu ispisati obavještenje da li je
rečenica ispravno zadata.
#include <stdio.h>
#include <string.h>
main(){
int p;
char s[20];
printf("\nUnesi string ");
gets(s);
p=recenica(s);
if(p==1)
printf("Nije");
else
printf("Jeste");
}
int recenica(char *s){
duz=strlen(s);
if(ind==0)
{
for(i=1;i<duz-1;i++){
return ind;
3. Napisati program koji sadrži funkciju koja određuje i štampa srednju vrednost niza realnih
brojeva. Broj članova, kao i članovi niza se zadaju po startovanju programa.
#include<stdio.h>
main()
{
int n,i;
float a[20];
puts("Uneti broj clanova niza");
scanf("%d",&n);
puts("Uneti elemente niza");
for(i=0;i<n;i++)
scanf("%f",a+i);
printf("Srednja vrednost ovog niza je: %f\n",sred_niz(n,a));
}
#include<stdio.h>
main(){
int N,k=0;
long i=1;
printf("Uneti N ");
scanf("%d",&N);
while(k<N){
if(savrsen(i)==1){
k=k+1;
printf("%d\n",i);
}
i=i+1;
}
}
1. Napisati program koji na zadatom sortiranom nizu primjenjuje binarno pretraživanje uz pomoć
odgovarajuće rekurzivne funkcije.
#include <stdio.h>
#include <conio.h>
main(){
int A[30], N, i, poz;
printf("Uneti duzinu niza");
scanf("%d",&N);
printf("Uneti elemente niza");
for(i=0;i<N;i++)
scanf("%d",A+i);
printf("Uneti element koji se trazi: ");
scanf("%d",&K);
poz = binarno(A,0,N-1,N/2);
if (poz == -1)
printf("Nema takvog elementa");
else
printf("Element se nalazi na poziciji %d!",poz);
getch();
}
#include <stdio.h>
#include <conio.h>
main(){
int A[30], N, i;
printf("Uneti duzinu niza");
scanf("%d",&N);
printf("Uneti elemente niza");
for(i=0;i<N;i++)
scanf("%d",A+i);
merge_sort(A,0,N-1,N/2);
printf("Sortirani niz je: ");
for(i=0;i<N;i++)
printf("%d ",A[i]);
getch();
}
1. Sastaviti program koji od elemenata dinamičkog niza formira druga dva dinamička niza, niz
nenegativnih i niz negativnih brojeva. Prikazati elemente tako dobijenih nizova.
#include<stdio.h>
#include<stdlib.h>
main()
{
int *a,*b,*c,i,j=0,k=0,duz,duz1=0;
puts("Uneti duzinu niza");
scanf("%d",&duz);
a=(int *)malloc(duz*sizeof(int));
if(a==NULL){
puts("Nema memorije"); exit(1);
}
puts("Elementi niza");
for(i=0;i<duz;i++){
scanf("%d",a+i);
if(a[i]>=0)
duz1++;
}
b=(int *)malloc(duz1*sizeof(int));
c=(int *)malloc((duz-duz1)*sizeof(int));
if((b==NULL)||(c==NULL)){
puts("Nema memorije"); exit(1);
}
for(i=0;i<duz;i++)
if(a[i]>=0)
b[j++]=a[i];
else
c[k++]=a[i];
free(a);
puts("Pozitivni brojevi su:");
for(i=0;i<duz1;i++)
printf("%d ",b[i]);
puts("Negativni brojevi su:");
for(i=0;i<duz-duz1;i++)
printf("%d ",c[i]);
free(b);
free(c);
}
2. Napisati program kojim se unose dva cijela broja a i b (a<b, ne treba provjeravati). Program treba da
generiše niz svih slučajno raspoređenih brojeva iz intervala [a,b], pri čemu se elementi niza ne smiju
ponavljati. Niz dinamički alocirati.
#include <stdio.h>
#include <stdlib.h>
void generisi(int *, int, int);
int main()
{
int *X, a,b,i;
// ovom naredbog podešavamo generator slučajnih brojeva
srand (time(NULL));
printf("Unesite a i b:");
scanf("%d%d",&a,&b);
X=(int *)malloc((b-a+1)*sizeof(int));
if (X==NULL)
{
printf("Nema memorije!");
exit(1);
}
generisi(X,a,b);
printf("Generisani niz slucajnih brojeva je: ");
for (i=0;i<b-a+1;i++)
printf("%d ",X[i]);
free(X);
}
// I varijanta
void generisi(int *X, int a, int b)
{
int i, k=0, broj,ind;
while (k<b-a+1)
{
broj=a+rand()%(b-a+1);
ind=1;
for (i=0;i<k;i++)
if (X[i]==broj)
{
ind=0;
break;
}
if (ind)
X[k++]=broj;
}
}
// II varijanta
void generisi(int *X, int a, int b)
{
int i, t, poz;
for (i=0;i<b-a+1;i++)
X[i]=a+i;
for (i=0;i<b-a+1;i++)
{
poz=rand()%(b-a+1);
t=X[i];
X[i]=X[poz];
X[poz]=t;
}
}
Sedmi čas računskih vježbi iz Programiranja I
1. Svaki red fajla c:\broj.txt sadrži po jedan cijeli broj. Sastaviti program koji štampa najmanji i najveći cijeli broj u
tom fajlu.
#include<stdio.h>
main()
{
FILE *fp;
int najmanji, najveci, broj;
fp=fopen("c:\\broj.txt","r");
if(fp==NULL){
printf("Greska pri otvaranju fajla");
exit(1);
}
fscanf(fp,"%d",&broj);
najmanji=broj;
najveci=broj;
while(fscanf(fp,"%d",&broj)!=EOF){
if(broj<najmanji)
najmanji=broj;
if(broj>najveci)
najveci=broj;}
fclose(fp);
printf("Najmanji je broj %d, a najveci %d\n", najmanji, najveci);
}
2. Svaki red fajla Brojevi.txt sadrži po jedan prirodan broj. Napisati program koji formira fajl 2_9.txt prepisujući
samo one brojeve iz fajla Brojevi.txt koji nemaju drugih cifara osim 2 i 9. Primjeri takvih brojeva su 2, 9, 22, 29,
229 itd. Nakon datih obrada zatvoriti predmetne fajlove. Vodite računa da li su fajlovi korektno otvoreni.
#include<stdio.h>
void main()
{
int broj, pom, cif, ind;
FILE *a, *b;
if((a=fopen("c:\\Brojevi.txt","r"))==NULL) {
puts("Greska pri otvaranju fajla"); exit(1); }
if((b=fopen("c:\\2_9.txt","w"))==NULL) {
puts("Greska pri otvaranju fajla"); exit(1); }
while(fscanf(a,"%d",&broj)!=EOF) {
ind=1; pom=broj;
while(pom!=0){
cif=pom%10;
if(cif!=2 && cif!=9)
ind=0;
pom/=10;
}
if(ind && broj!=0)
fprintf(b,"%d\n",broj);
}
fclose(a); fclose(b);
}
Osmi čas računskih vježbi iz Programiranja I
1. Elementi liste su celi brojevi. Sastaviti program koji vrši sumiranje brojeva upisanih u čvorovima liste
korišćenjem rekurzivne funkcije.
#include<alloc.h>
struct str {
int a;
struct str *sled; };
main()
{
struct str *elem, *pom, *glava;
int i, n;
puts("Uneti broj elemenata liste");
scanf("%d",&n);
puts("Elementi liste");
for(i=0;i<n;i++){
elem=(struct str *) malloc(sizeof(struct str));
scanf("%d",&(elem->a));
elem->sled=NULL;
if(i==0){
pom=elem;
glava=elem;
}
else {
pom->sled=elem;
pom=elem;
}
}
printf("Zbir je %d ",sabiranje(glava));
}
2. Elementi liste su sortirani celi brojevi. Sastaviti program koji učitava ceo broj i smešta ga u sortiranu listu tako da
se ne naruši sortiranost. Umetanje tog broja izvršiti pomoću funkcije, a ne u okviru glavnog programa.
#include<stdio.h>
#include<alloc.h>
struct str {
int a;
struct str *sled;
};
main()
{
struct str *elem, *pom, *glava;
int i, n, broj;
puts("Uneti broj elemenata liste");
scanf("%d",&n);
puts("Elementi liste");
for(i=0;i<n;i++){
elem=(struct str *) malloc(sizeof(struct str));
scanf("%d",&(elem->a));
elem->sled=NULL;
if(i==0){
pom=elem;
glava=elem;
}
else {
pom->sled=elem;
pom=elem;
}
}
printf("Uneti neki broj ");
scanf("%d",&broj);
pom=umetanje(glava,broj);
for(i=0;i<=n;i++){
printf("%d ",pom->a);
pom=pom->sled;
}
}
1. Elementi liste su parovi; prvi u paru je cio broj k, a drugi je realan broj a, što znači da taj element liste
definiše član polinoma axk. Dakle, cijela lista zadaje jedan polinom p(x). Napisati program koji formira
datu listu, zatim učitava realan broj x, argument polinoma, a nakon toga računa vrijednost polinoma p(x)
korišćenjem rekurzivne funkcije. Štampati dobijenu vrijednost.
struct lista {
int k;
float a;
struct lista *next;
};
2. Elementi liste su riječi. Napisati funkciju koja određuje da li su te riječi leksikografski uređene u rastući
poredak.
struct lista {
char rijec[20];
struct lista *next;
};
3. Elementi liste su cijeli brojevi. Napisati program kojim se od početne liste formiraju dvije nove liste, lista
sa parnim i lista sa neparnim elementima. Štampati dobijene liste.
#include <stdio.h>
#include <stdlib.h>
struct str
{
int a;
struct str *sled;
};
int main()
{
int n,i;
struct str *el, *pre, *glava, *lista, *glPar=NULL, *glNep=NULL, *prePar=NULL,
*preNep=NULL;
puts("Unijeti broj elemenata liste:");
scanf("%d",&n);
if(i==0) glava=el;
else pre->sled=el;
pre=el;
}
lista=glava;
while(lista!=NULL){
if((lista->a)%2 == 0){
if(glPar==NULL) glPar=lista;
else prePar->sled=lista;
prePar=lista;
}
else{
if(glNep==NULL) glNep=lista;
else preNep->sled=lista;
preNep=lista;
}
lista=lista->sled;
}
if(prePar) prePar->sled=NULL;
if(preNep) preNep->sled=NULL;
}
4. Na osnovu unešene matrice susjedstva grafa sa 5 čvorova provjeriti da li je taj graf usmjeren ili
neusmjeren.
#include <stdio.h>
void main()
{
int ms[5][5];
int i, j, ind=1;
puts("Uneti matricu susedstva grafa ");
for(i=0;i<5;i++)
for(j=0;j<5;j++)
scanf("%d",&ms[i][j]);
for(i=0;i<5;i++)
if(ms[i][i]==1)
ind=0;
if(ind)
for(i=0;i<5;i++) {
for(j=0;j<5;j++) /* for(j=i+1;j<5;j++) */
if(ms[i][j]!=ms[j][i])
ind=0;
if(ind==0)
break;
}
if(ind)
printf("\nNeusmjeren!\n");
else
printf("\nUsmjeren!\n");
}
Deseti čas računskih vježbi iz Programiranja I
struct drvo {
int a;
struct drvo *left;
struct drvo *right;
};
3. Svakom vrhu pridružena je jedna riječ dužine manje od 12 karaktera. Sastaviti potprogram koji određuje
koliko puta se pojavljuje data riječ.
struct drvo {
char rijec[12];
struct drvo *left;
struct drvo *right;
};
struct drvo {
int n;
struct drvo *left;
struct drvo *right;
};
5. Dato je binarno drvo u čijim su čvorovima upisani cijeli brojevi. Odrediti redosljed štampanja tih brojeva
ukoliko koristimo:
a) Inorder obilazak (lijevo poddrvo, korijen, desno poddrvo);
b) Preorder obilazak (korijen, lijevo poddrvo, desno poddrvo);
c) Postorder obilazak (lijevo poddrvo, desno poddrvo, korijen).
a) 11, 4, 9, 7, 6, 2, 5, 3, 1
b) 2, 7, 4, 11, 9, 6, 5, 3, 1
c) 11, 9, 4, 6, 7, 1, 3, 5, 2
LoVe dOts... ForEver... Autor: Murtic Nirmel
ETF - 2005/2006 www.etf.ba
- t =(x , y , z ) ,
1 1 1 1
- t =(x , y , z ).
2 2 2 2
Kao izlaz program daje udaljenost izmedju tih tacki.
RJEŠENJE:
RJEŠENJE:
# include <stdio.h>
int main () {
// Definisanje potrebnih varijabli
float VT,MT,CV,CM,UKUPNO,RACUN,UDIOM,UDIOV;
// Unos male tarife, velike tarife, cijene male tarife i cijene velike tarife
printf("\n Unesi potrosnju po velikoj tarifi (KWh): ");
scanf("%f", &VT);
printf("\n Unesi potrosnju po maloj tarifi (KWh): ");
scanf("%f", &MT);
printf("\n Cijena za veliku tarifu po jednom Kwh: ");
scanf("%f", &CV);
printf("\n Cijena za malu tarifu po jednom Kwh: ");
scanf("%f", &CM);
// Racunanje ukupne potrosnje
UKUPNO=VT+MT;
// Racunanje cijene ukupne potrosnje (cijena po maloj tarifi + cijena po
// velikoj tarifi)
RACUN=VT*CV+MT*CM;
// Izracunava udio velike i male tarife u ukupnoj potrosnji (procenat)
UDIOM=(MT/UKUPNO)*100;
UDIOV=(VT/UKUPNO)*100;
// Ispis rezultata
printf ("\n Ukupna potrosnja elektricne energije je: %.f KWh", UKUPNO);
printf ("\n Ukupna cijena elektricne energije je: %.f KM", RACUN);
printf ("\n Udio velike tarife u potrosnji je: %.f procenata", UDIOV);
printf ("\n Udio male tarife u potrosnji je: %.f procenata", UDIOM);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main() {
// Definisanje varijabli
float A,B,C,D,MAX,MIN;
// Unos skupova
printf("\n Unesi prvi skup X[A,B] A>B: ");
scanf("%f,%f", &A,&B);
printf("\n Unesi drugi skup Y[C,D] C>D: ");
scanf("%f,%f", &C,&D);
RJEŠENJE:
# include <stdio.h>
int main () {
// Definisanje varijabli
float a,b,c,x,izvod;
// Unos koeficijenata a,b,c
printf ("Unesi koef. (a,b,c) funkcije f(x)=ax2+bx+c (-10<(a,b,c)<10):");
scanf("%f,%f,%f", &a,&b,&c);
// Unos vrijednosti x
printf ("Unesi vrijednost x");
scanf("%f", &x);
// Ispit uslova
if (a>-10&&a<10&&b>-10&&b<10&&c>-10&&c<10){
// Izracunavanje izvoda po odredjenoj matematickoj formuli
izvod=2*a*x+b;
// Ispis izvoda
printf("Prva derivacija u tacki x=%.f je %.f", x, izvod);
// Ispis odgovarajuce poruke ukoliko uslov nije zadovoljen
} else printf ("Koeficijenti nisu iz odgovarajuceg intervala!");
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main() {
// Definisanje varijabli
int x[3], i, j, p;
// Unos brojeva
printf("\n Unesi tri broja u rasponu od 50 do 200 (U formatu: a, b, c): ");
scanf("%d, %d, %d", &x[0], &x[1], &x[2]);
// Provjera jesu li brojevi iz odgovarajuceg intervala
if (x[0]>50&&x[1]>50&&x[2]>50&&x[0]<200&&x[1]<200&&x[2]<200) {
/* Sortiranje brojeva
Potrebne su nam dvije for petlje koje ce „listati“ brojeve koji se nalaze u
nekom nizu. Ovaj tip sortiranja se uglavnom svodi na provjeru da li je prvi
broj manji od drugog ili treceg, i ako jeste, onda mijenja mjesto sa tim
brojem. Medjutim nakon ovoga nije zavrseno sortiranje. Ako npr. Unesemo
brojeve 3, 2, 1, nakon prvog prolaska imamo 2, 3, 1 nakon drugog 2, 1, 3 ali
jos uvijek nije zavrseno sortiranje, i zbog toga i postoji prva for petlja
koja ce to ponoviti jos jednom i dobivamo 1, 2, 3 i niz je sortiran, i sada ga
samo jos treba ispisati na ekran. */
for (i=0;i<2;i++)
for (j=0;j<2;j++)
if (x[j]>x[i]) {
p=x[i];
x[i]=x[j];
x[j]=p;
}
// Ispis sortiranih brojeva
printf("\n Sortirani brojevi: %d, %d, %d ", x[0], x[1], x[2]);
// Ako brojevi nisu iz intervala, ispis odgovarajuce poruke
} else { printf("\n Svi brojevi nisu iz intervala 50 do 200!!!");
}
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
int main()
{
// Definisanje varijabli
int n, i;
// Unos nekog prirodnog broja
printf("Unesite broj: ");
scanf("%d", &n);
/* For petlja postavlja brojac „i“ na vrijednost unesenog broja, i provjerava
se da li je taj broj djeljiv sa 5, 7 ili 11, i ako jeste printa ga na ekran i
umanjuje brojac za jedan, ako broj nije djeljiv sa ovim brojevima, onda se
samo brojac umanji na kraju for petlje bez printanja broja na ekranu. Isti se
postupak ponavlja i za broj manji za jedan, kao i broj manji za dva... sve
tako do broja 1 (mogli smo staviti i 4 jer brojevi ispod 5 svakako nisu
djeljivi sa ovim brojevima! */
for(i=n;i>0;i--)
{
if ((i % 5 == 0)||(i % 7 == 0)||(i % 11 == 0)) printf("\n Broj: %d", i);
}
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
int main()
{
// Definisanje varijabli
float i=1,n,suma=0;
// Unos prirodnog broja
printf ("\n Unesi broj n:");
scanf("%f", &n);
/* Racunanje sume
While petlja vrti podprogam u okviru while petlje sve dok je brojac „i“ koji
je na pocetku 1, manji od unesenog broja n. Ako je uneseni broj 1 ne ulazi se
u petlju i na izlazu se ispisuje Suma je:1. Ako je broj veci od 1 onda se
racuna suma prema matematickoj formuli. Grupisali smo formulu datu u zadatku
tako da trazimo sume po dva broja (odnosno razlike), i zatim te razlike
brojeva sabiramo, ali moramo paziti jer moramo brojac „i“ uvecati za 2 jer smo
u formuli ukljucili odmah 2 broja.
Ovaj nacin ima i dobru i losu stranu. Dobra strana je jer nemoramo uvoditi
nikakvu pomocnu varijablu i citav kod za racunanje sume se sastoji od dva
izraza, a losa strana je kad unesemo neparne brojeve sto necemo dobiti tacnu
sumu i tako kad unesemo broj 3 program ce izracunati 1-1/2+1/3=0.5 sto nije
tacno, a to smo dobili jer program nemoze grupisati clanove po 2 jer ih imamo
tri i zadnji ostaje sam i ne racuna se. Ali ovaj mali nedostatak mozemo
zanemariti jer se u ovakvim zadacima obicno unose veliki brojevi da se sve
svodi na preciznost nalazenja broja 0.69 pa nam je svejedno da li je zadnji
clan uracunat ili ne, ali eto ako zelimo ipak 100% precizno uraditi, zadatak
moze se uraditi i bez grupisanja sa mijenjanjem predznaka sume, ali to uradite
sami :) */
while ((i<n)&&(n>1)) {
suma=suma+(1/i-1/(i+1));
i=i+2;
}
// Ispis sume
if (n>1) printf ("\n Suma je: %f", suma); else if (n=1) printf ("Suma je: 1");
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main() {
/* Deklarisanje varijabli
Definisanje dvodimenzionalne matrice 12 sa 9 (12 mjeseci, a broj 9 je ustvari
broj slova od kojih se sastoje mjeseci, najvise ima semptembar (9 slova). */
int m,g,d,i;
char mj[12][9]={{"Januar"},{"Februar"},{"Mart"},{"April"},
{"Maj"},{"Juni"},{"Juli"},{"August"},{"Septembar"},
{"Oktobar"},{"Novembar"},{"Decembar"}};
// U programu se uvodi i naredba „goto“ koja „skace“ sa linije na liniju
// programa.
pocetak:
// Unos mjeseca i godine
printf ("\n Unesi mjesec i godinu (m,g):"); scanf ("%d,%d", &m,&g);
// Ako se unese 1,3,5,7,8,10 ili 12 mjesec onda ima d=31 dan
if ((m==1)||(m==3)||(m==5)||(m==7)||(m==8)||(m==10)||(m==12)) d=31; else
// Ako se ipak unese 4,6,9 ili 11 mjesec onda ima d=30 dana
if ((m==4)||(m==6)||(m==9)||(m==11)) d=30; else
/* Ili ako se ipak unese mjesec 2 onda se provjerava jos i prijestupna godina
(svaka godina djeljiva sa 4), i u zavisnosti da li je prijestupna ili ne d=29
odnosno d=29 dana. Ako broj nije od 1 do 12 vraca se na pocetak programa*/
if ((m==2)) if ((g%4==0)) d=29; else d=28; else goto pocetak;
// Ispis mjeseca koji se nalazi zapisan u mj[] (m-1 jer nam je januar pod
brojem 0)
printf("%s , %d. g., broj dana: %d", mj[m-1], g, d);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main (){
// Deklarisanje varijabli
float A[10][10], MIN;
int i,j;
/* Unos matrice (koristimo 2 for petlje pri unosu (i su redovi a j su kolone).
Brojevi se unose po redovima.
*/
printf("\n Unesi matricu A[10][10]: \n");
for (i=0;i<10;i++)
for (j=0;j<10;j++)
{
printf(" [%d,%d]:", i+1, j+1);
scanf("%f", &A[i][j]);
}
/* Trazenje najmanjeg elementa na dijagonali!
Postupak je sljedeci. Elementi na dijagonali su tipa [i,j] gdje su i,j
jednaki. Tako dijagonalni elementi matrice 3x3 su [1,1], [2,2], [3,3]. Posto
nam trebaju samo elementi kada su (i,j) jednaki koristimo jednu for petlju. Na
pocetku stavimo da je najmanji element prvi element na poziciji [1,1], u C-u
je pozicija (0,0) ustvari pozicija (1,1) u realnom svijetu. I ulazimo u for
petlju. Ispituju se redom brojevi kod kojih su brojaci „i“ i „j“ jednaki. Ako
je neki od brojeva koji se ispitaju manji od MIN onda se taj broj pridruzi
varijabli MIN. */
MIN=A[0][0];
for (i=1,j=1;i<10;i++,j++) if (A[i][j]<MIN) MIN=A[i][j];
// Ispis najmanjeg broja na dijagonali
printf("\nNajmanji element na glavnoj dijagonali je: %.f", MIN);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main (){
// Deklarisanje varijabli
int N;
double F;
// Deklarisanje prototipa funkcije
double faktor (int n);
//Unos prirodnog broja
printf("\nUnesi prirodan broj N: ");
scanf("%d", &N);
/* Pozivanje funkcije faktor() i pridruzivanje vrijednosti koju funkcija
izracuna varijabli F */
F=faktor(N);
// Ispis faktorijele
printf("Faktorijela od %d je: %g", N, F);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
main (){
// Definisanje varijabli
int n, i, niz[100], max;
// Unos broja elemenata
printf("\nUnesi broj elemenata: ");
scanf("%d", &n);
// Unos niza od N elemenata (pomocu for petlje)
for (i=0;i<n;i++)
{
printf ("\nUnesi elemenat broj %d: ", i+1);
scanf("%d", &niz[i]);
}
// Postavljanje vrijednosti max na vrijednost prvog clana niza
max=niz[0];
/* For petlja vrti brojeve od 2 broja (prvi je ukljucen u liniju iznad) i
provjerava se da li je i-ti broj veci od max i ako jeste varijabli max se
pridruzuje vrijednost tog elementa*/
for (i=1;i<n;i++)
if (max<niz[i]) max=niz[i];
// Ispis najveceg elementa niza
printf("Najveci element niza je: %d", max);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
main (){
// Definisanje varijabli
float A[5], B[5], C[5];
int i;
/* Unos elemenata prvog polja (pomocu for petlje, i+1 zbog realnosti, da nam
ne ispisuje se na ekranu "Unesi element 0") */
for (i=0;i<5;i++){
printf("\nUnesi %d element prvog polja: ",i+1);
scanf("%f", &A[i]);
}
// Unos elemenata drugog polja
for (i=0;i<5;i++){
printf("\nUnesi %d element drugog polja: ",i+1);
scanf("%f", &B[i]);
}
// Racunanje clanova matrice C po formuli C=2*A+B (pomocu jedne for petlje).
for (i=0;i<5;i++) C[i]=2*A[i]+B[i];
// Ispis elemenata polja A
printf("\nElementi prvog polja A: ");
for (i=0;i<5;i++) printf("%.f ", A[i]);
// Ispis elemenata polja B
printf("\nElementi drugog polja B: ");
for (i=0;i<5;i++) printf("%.f ", B[i]);
// Ispis elemenata polja C
printf("\nElementi treceg polja C: ");
for (i=0;i<5;i++) printf("%.f ", C[i]);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
main (){
// Definisanje varijabli
int n, i, niz[100], min;
// Unos broja elemenata
printf("\nUnesi broj elemenata: ");
scanf("%d", &n);
// Unos niza od N elemenata (pomocu for petlje)
for (i=0;i<n;i++){
printf ("\nUnesi elemenat broj %d: ", i+1);
scanf("%d", &niz[i]);
}
// Postavljanje vrijednosti min na vrijednost prvog clana niza
min=niz[0];
/* For petlja vrti brojeve od drugog broja (prvi je ukljucen u liniju iznad) i
provjerava se da li je i-ti broj manji od min i ako jeste varijabli min se
pridruzuje vrijednost tog elementa. */
for (i=1;i<n;i++)
if (min>niz[i]) min=niz[i];
/* For petlja vrti sve brojeve i za svaki broj se vrsi provjera da li je manji
od dvostruke vrijednosti nadjenog najmanjeg broja, i ako je taj broj zaista
manji od 2*min ispisuje se na ekran, a ako nije ide se na iduci broj. */
for (i=0;i<n;i++)
if (niz[i]<min*2) printf("\n %d", niz[i]);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
main (){
// Definisanje prototipa funkcije
int izbaci2389(int x);
// Definisanje varijabli
int N, X;
// unos prirodnog broja
printf("\nUnesi prirodan broj: ");
scanf("%d", &N);
// Poziv funkcije i pridruzivanje rezultata varijabli X
X=izbaci2389(N);
// Ispis prepravljenog broja
printf("\nPrepravljeni broj: %d", X);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
main (){
// Definisanje prototipa funkcije
void racun(float vt, float mt);
// Definisanje varijabli
float vt, mt;
// Unos potrosnje po velikoj i maloj tarifi
printf("Unesi potrosnju za veliku tarifu: ");
scanf("%f", &vt);
printf("Unesi potrosnju za malu tarifu: ");
scanf("%f", &mt);
// Poziv void funkcije (funkcija ne vraca rezultat), sa argumentima vt i mt
racun(vt, mt);
// Kraj programa
getch();
return 0;
}
// Funkcija koja kreira racun za utrosak energije na osnovu argumenata vt i mt
void racun(float vt, float mt)
{
float cijena;
// Racunanje ukupne cijene na osnovu argumenata vt i mt i zadatih cijena
cijena=vt*0.10+mt*0.05;
// Ispis rezultata
printf("\n--------------RACUN ZA UTROSENU EL. ENERGIJU-------------------- ");
printf("\nPotrosnja VT: %f KWh", vt);
printf("\nPotrosnja MT: %f KWh", mt);
printf("\n**************************************************************** ");
printf("\nUkupno: %f KM", cijena);
printf("\n**************************************************************** ");
}
16. Napisati funkciju koja kao argument uzima tri cijela broja
a, p i c. Funkcija vraca cijeli broj koji se dobije tako da se u
broju a iza p-te cifre s desne strane umetne cifra c.
Ako je p veci od ukupnog broja cifri izlaz iz funkcije treba biti
jednak ulazu. Ako se broj c sastoji od više cifri onda se umece
samo zadnja cifra iz tog broja.
Prototip funkcije je: int umetni(int a, int p, int c)
Nakon toga, napišite program koji ucitava neki pozitivan cijeli
broj a, poziciju umetanja cifre p i broj koji definira cifru koja
se umece c, te poziva funkciju umetni() i ispisuje na standardnom
izlazu rezultirajuci broj.
RJEŠENJE:
# include <stdio.h>
main (){
// Definisanje prototipa funkcije
int umetni(int a, int p, int c);
// Definisanje varijabli
int a, p, c, rez;
// Unos brojeva a,p,c
printf("Unesi brojeve a, p, c: ");
scanf("%d,%d,%d", &a,&p,&c);
// Poziv funkcije umetni() i pridruzivanje rezultata varijabli rez
rez=umetni(a,p,c);
// Ispis rezultata
printf("Rezultat: %d", rez);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
int main() {
// Definisanje varijabli
int n,i;
// Kraj programa
getch();
return 0;
}
a x + a x = b
11 1 12 2 1
a x + a x = b
21 1 22 2 2
(nepoznate su x i x )
1 2
RJEŠENJE:
#include <stdio.h>
int main() {
// Definisanje varijabli
float a11,a21,a12,a22,x1,x2,b1,b2;
/* Unos podataka (U dijelu %fx1%fx2=%f izmedju %fx1 i %fx2 nema plusa, u
suprotnom bi morali pri unosu operacije - (minus) upisivati +-) */
printf("\n Unesite 1 linearnu jednacinu a11x1+a12x2=b1 (x1, x2 nepoznate): ");
scanf("%fx1%fx2=%f", &a11, &a12, &b1);
printf("\n Unesite 2 linearnu jednacinu a21x1+a22x2=b2 (x1, x2 nepoznate): ");
scanf("%fx1%fx2=%f", &a21, &a22, &b2);
/* Izracunavanje x2 metodom supstitucije */
x2=(b2 * a11 - a21 * b1) / (a22 * a11-a21 * a12);
/* Izracunavanje x1 metodom uvrstavanja x2 u prvu jednacinu */
x1=(b1 - a12 * x2) / a11;
/* Provjerava se da li je sistem odredjen */
/* Ukoliko je sistem odredjen ispisuju se rjesenja, u suprotnom se ispisuje
poruka: RJEŠENJE ne postoji */
if ((a11*a22)==(a12*a21)) printf("\nRJEŠENJE ne postoji!!!");
else printf("\nRezultat je: x1=%.2f i x2=%.2f", x1, x2);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
int main() {
// Definisanje varijabli
int i,j,p,niz[4];
/* Unos brojeva niza (4 broja), pomocu for petlje koja ide od 1 do 4. */
printf("\n Unesite 4 cijela broja!");
for(i=1;i<=4;i++){
printf("\n %d broj: ", i);
scanf("%d",&niz[i]);
}
/* Proces sortiranja
Koristena je metoda bubblesort (spomenuta u jednom od zadataka ranije), to je
metoda „preljevanja“, provjerava se da li je j-ti clan manji od j+1-vog i ako
jeste mijenjaju se mjesta.
Npr. Unesemo 1,2,3,4. Nakon prvog prolaska imamo 2,1,3,4. Nakon drugog
prolaska 2,3,1,4. Nakon treceg prolaska imamo 2,3,4,1. I onda prva for petlja
proces ponavlja jos jednom. Pa imamo 3,2,4,1 zatim i 3,4,2,1 pa onda ostaje
isto jer je 2 vec vece od 1. Ali niz nije sortiran! Prva for petlja jos jednom
pokrece postupak i imamo 4,3,2,1. Proci ce se onako bezveze jos 2 puta kroz
petlju „j“ i zatim se izlazi iz petlje, i ispisuju se rezultati*/
for(i=1;i<=3;i++)
for(j=1;j<=3;j++)
if (niz[j+1]>niz[j]) {
p=niz[j];
niz[j]=niz[j+1];
niz[j+1]=p;
}
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main () {
// Definisanje varijabli
int i,br, ispit;
// Unos jednog prirodnog broja
printf ("\n Unesi prirodan broj: ");
scanf ("%d", &br);
// Provjera da li je broj prirodan, i ako nije ispisuje
// se poruka da broj nije prirodan
if (br<=0) printf("\n Broj nije prirodan"); else
// Provjera da li je uneseni broj, broj 1, i ako jeste,
// ispisuje se odgovarajuca poruka
if (br==1) printf("\n Broj 1 nije ni prost ni slozen"); else
/* Ako je unesen prirodan broj veci od 1, provjerava se da li je broj prost
ili slozen, varijabla "ispit" kao rezultat. Djelimo broj „br“ sa svakim brojem
manjim od polovine unesenog broja. Na pocetku je „ispit=0“ sto nam govori da
je broj neparan. Ulazi se u petlju i pocinje dijeljenje sa brojevima 2,3,4...
Ako se broj „br“ uspije podijeliti sa nekim od brojeva varijabla ispit ce
automatski poprimiti vrijednost 1. U zavisnosti da li je broj „br“ uspio se
podijeliti sa nekim brojem bez ostatka, zavisiti ce i cinjenica da li je broj
prost ili slozen. */
{
ispit=0; i=2;
while (i<br/2) {
if ((br % i == 0)) ispit=1;
i++;
}
// Ispis odgovarajuce poruke na izlazu (PROST ILI SLOZEN)
if (ispit) printf("\n Broj je slozen"); else printf("\n Broj je prost");}
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main () {
// Definisanje varijabli
int i;
float n,f;
// Ispis rezultata
printf("\n Faktorijela od broja %.0f je: %0.f", n, f);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main () {
// Definisanje varijabli
int i,broj,suma;
// Unosenje prirodnog broja sa tastature u rasponu od [2,100]
printf("\n ULAZ: Broj \"N\" u rasponu od [2,100]: ");
scanf("%d", &broj);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main () {
// Definisanje varijabli
float eps,pi,n;
// Ispis broja PI
printf ("PI je: %f", pi);
RJEŠENJE:
#include <stdio.h>
main(){
float A[10][10], B[10][10], C[10][10];
int RA, RB, KA, KB, i, j, k;
// Unos dimenzija prve i druge matrice
printf("\nUnos dim. matrica A[RA,KA], B[RB,KB], u obliku \"RA,KA,RB,KB\": ");
scanf("%d,%d,%d,%d", &RA, &KA, &RB, &KB);
for (i=0;i<RA;i++)
for (j=0;j<KB;j++) {
C[i][j]=0;
for (k=0;k<KA;k++) C[i][j]=C[i][j]+A[i][k]*B[k][j]; }
// Ispis matrice A
printf("\nMatrica A[%d,%d]: \n", RA, KA);
for (i=0;i<RA;i++){
printf("\n");
for (j=0;j<KA;j++) printf("%4.f ", A[i][j]); }
// Ispis matrice B
printf("\nMatrica B[%d,%d]: \n", RB, KB);
for (i=0;i<RB;i++){
printf("\n");
for (j=0;j<KB;j++) printf("%4.f ", B[i][j]); }
// Ispis matrice C
printf("\nMatrica C[%d,%d]: \n", RA, KB);
for (i=0;i<RA;i++){
printf("\n");
for (j=0;j<KB;j++) printf("%4.f ", C[i][j]); }
// Ispis poruka ukoliko podaci nisu regularni
} else printf("\n Matrice se nemogu pomnoziti!");
} else printf("\n Matrice nisu u odgovarajucem intervalu!");
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main(){
// Definisanje varijabli
float MATRIX[5][5], SUMA[5], sumaR, sumaK;
int i,j, Kolona, Red;
/* Racunanje suma po redovima. Sabiramo sve brojeve prvog reda, znaci „i“ se
ne mijenja, a „j“ se uvecava za 1 sve do 5. I kada se sabere tih 5 brojeva, to
je suma prvog reda i zapisuje se u SUMA[0], zatim se isto ponavlja za ostale
redove, tako sto se samo „i“ uvecava za 1 i prelazi time na iduci red. */
for (i=0;i<5;i++)
for (j=0;j<5;j++)
SUMA[i]=SUMA[i]+MATRIX[i][j];
// Ispis rjesenja
printf("\nU %d koloni je najmanja suma koja iznosi %.f", Kolona, sumaK);
printf("\nU %d redu je najveca suma koja iznosi %.f", Red, sumaR);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
// Funkcije „duzina“, „izbroji“ i „samogl“
// Funkcija duzina prima pokazivac na prvo slovo nekog stringa, a zatim u
while petlji provjerava se koliko znakova ima rijec, kada se dodje do nultog
znaka, izlazi se iz petlje, rezultet je varijabla „d“ koja se vraca iz
funkcije.
int duzina(char *string)
{
int d=0;
while (*string++!='\0') d++;
return d;
}
/* Slicno prvoj funkciji, samo funkcija pored pokazivaca na prvi znak stringa
prima i znak koji se broji. I umjesto da broji se broj clanova, umjesto d++
ide uslov (ako je slovo na koje pokazuje pokazivac nase slovo), „b“ se uveca
za 1. Kada „dodje“ while petlja do nultog znaka, izlazi se iz petlje a
varijabla „b“ se vraca kao rezultat.
NAPOMENA: U gornjoj funkciji stoji u uslovu *string++ sto prebaca pokazivac na
iduci clan nakon sto while petlja napravi jedan „krug“, dok u drugoj funkciji
stoji u uslovu samo *string ali je poslije if petlje uvecan pokazivac za „1“,
sto nam daje opet isti efekat. */
int izbroji(char *string, char c)
{
int b=0;
while (*string!='\0')
{
if (*string==c) b++;
string++;
}
return b;
}
int main()
{
// Definisanje varijabli
char a[80],c;
// Unos rijeci bez razmaka i jednog slova koje ce se prebrojavati
printf("\nUnesite jednu rijec do 20 znakova (bez razmaka):");
scanf("%s",a);
printf("\nKoji znak treba prebrojati:");
scanf("\n%c",&c);
// Ispis rjesenja
printf("\nUnesena rijec sadrzi %d znakova!",duzina(a));
printf("\nBroj znakova %c je: %d",c,izbroji(a,c));
printf("\nBroj samoglasnika je: %d", samogl(a));
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
main ()
{
// Definisanje varijabli
float temp[10], *p;
int i;
// Definisanje prototipa funkcija
float maxtemp(float *p);
float prtemp(float *p);
// Unos 10 temperatura u niz temp[];
for (i=0;i<10;i++)
{
printf("\nUnesi temperaturu br.%d: ",i+1);
scanf("%f", &temp[i]);
}
// Postavljanje pokazivaca p na prvi clan niza temp[];
p=temp;
// Isipis rezultata uz poziv funkcija
printf("\nMaksimalna temperatura je: %.1f", maxtemp(p));
printf("\nProsjecna temperatura je: %.1f", prtemp(p));
// Kraj programa
getch();
return 0;
}
/* Funkcija maxtemp() prima pokazivac na realan niz i pomocu for petlje (vidi
11. zadatak) pronalazi se najveci broj (temperatura i vraca se iz funkcije */
float maxtemp(float *p)
{
float max=*p;
int i;
for (i=0;i<10;i++) { if (max<*p) max=*p; p++; }
return max;
}
/* Funkcija prtemp() prima pokazivac na realan niz i pomocu for petlje se
saberu svi clanovi niza i na kraju (poslije for petlje) se podijeli sve sa 10
(broj temperatura), tj. vraca se vrijednost (pr/10) kao rezultat */
RJEŠENJE:
# include <stdio.h>
main ()
{
// Definisanje varijabli
float temp[10], *p;
int i, n;
// Definisanje prototipa funkcija
float maxtemp(int n, float *p);
float prtemp(int n, float *p);
// Unos broja n
printf("\nUnesi broj temperatura: ");
scanf("%d", &n);
// Unos n temperatura u niz temp[];
for (i=0;i<n;i++)
{
printf("\nUnesi temperaturu br.%d: ",i+1);
scanf("%f", &temp[i]);
}
// Postavljanje pokazivaca p na prvi clan niza temp[];
p=temp;
// Isipis rezultata uz poziv funkcija
printf("\nMaksimalna temperatura je: %.1f", maxtemp(n, p));
printf("\nProsjecna temperatura je: %.1f", prtemp(n, p));
// Kraj programa
getch();
return 0; }
/* Funkcija prima pokazivac na realan niz, i broj n i pomocu for petlje (vidi
11. zadatak) pronalazi se najveci broj (temperatura i vraca se iz funkcije */
float maxtemp(int n, float *p) {
float max=*p;
int i;
for (i=0;i<n;i++) { if (max<*p) max=*p; p++; }
return max; }
/* Funkcija prima pokazivac na realan niz i broj „n“ i pomocu for petlje se
saberu svi clanovi niza i na kraju (poslije for petlje) se podijeli sve sa
brojem „n“ (broj temperatura), tj. vraca se vrijednost (pr/n) kao rezultat */
float prtemp(int n, float *p){
float pr=0;
int i;
for (i=0;i<n;i++) { pr=pr+*p; p++; }
return (pr/n); }
RJEŠENJE:
#include <stdio.h>
// Funkcija adresa()
char *adresa(char *ime, char *prezime)
{
// Definisanje varijabli potrebnih za rad u funkciji
char *p, POMOC[]="@etf.unsa.ba", *POM;
/* Pointer „p“ pokazuje na pocetak prezimena, a „POM“ pokazuje na pomocni niz
“POMOC“ u kojem se nalazi string „@etf.unsa.ba.“ */
p=prezime; POM=POMOC;
// Glavni program
int main(){
// Definisanje varijabli
char *ime, *prezime, *c;
char U1[100], U2[100];
// Unos podataka ime i prezime
printf("\nUnesi ime:");
scanf("%s", &U1);
printf("\nUnesi prezime:");
scanf("%s", &U2);
// Postavljanje pokazivaca „c“ na pocetak prezimena
c=U2;
// Postavljanje pokazivaca ime i prezime na stringove U1 i U2
ime=U1;
prezime=U2;
// Poziv funkcije „adresa()“ i slanje pokazivaca „ime“ i „prezime“ u funkciju
prezime=adresa(ime, prezime);
// Ispis Email adrese
printf("\nGenerirana korisnikova Email adresa: %s", c);
// Kraj programa
getch();
return 0;
}
struct datum
{
int dan;
int mjesec;
int godina;
};
drodj.dan=24;
drodj.mjesec=5;
drodj.godina=1978;
RJEŠENJE:
# include <stdio.h>
// Ispis rjesenja
printf("\nDatum rodjenja: %d.%d.%d", drodj.dan, drodj.mjesec, drodj.godina);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
main() {
// Definisanje varijabli
FILE *datoteka;
char dat[60], znak;
int znakovi, br=0, rez=0;
// Unos putanje do datoteke
printf("Unesi putanju do datoteke: ");
scanf("%s", &dat);
// Ispituje se da li datoteka postoji, ako postoji, ide se dalje u program u
// suprotnom se ispisuje error poruka i izlazi iz programa
if ( (datoteka = fopen (dat, "r")) == NULL) {
printf("Greska kod otvaranja datoteke %s !\n", dat);
getch();
exit(1); }
// Unos broja znakova
printf("Unesi broj znakova: ");
scanf("%d", &znakovi);
/* While petlja vrti se i uzima se znak po znak iz datoteke sve dok ne dodje
se do kraja datoteke i kada stignemo na kraj izlazi se iz programa. Ukoliko je
uneseni karakter razlicit od znakova ? ! . \n , \t i blanko znaka onda se
varijabla br uveca za jedan, u suprotnom se provjeri da li je broj br jednak
broju znakova koji smo unjeli, i ako jeste varijabla rez se uveca za jedan, i
onda se br postavi na 0. Kada stignemo do kraja datoteke izlazi se iz
petlje.*/
while((znak=fgetc(datoteka))!=EOF){
if ((znak=='?')||(znak=='!')||(znak==' ')
||(znak=='.')||(znak=='\n')||(znak==',')||(znak=='\t')) {
if (br==znakovi) rez++; br=0;} else br++;
}
/* Ukoliko zadnja rijec se sastoji od trazenog broja znakova, ona nece biti
uracunata jer smo izasli iz petlje, pa je potrebno dodati ovaj uslov iza
petlje da bi smo imali 100% tacan program*/
if (br==znakovi) rez++;
//Zatvaranje datoteke
fclose(datoteka);
// Izlaz iz programa
printf("Datoteka %s sadrzi %d rijeci sa %d znakova.", dat, rez, znakovi);
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
#include <stdlib.h>
main(){
/* Definisanje varijabli:
Neo - pokazivac na fajl koji se cita
Trinity - pokazivac na fajl u koji se pise
// Zatvaranje datoteka...
fclose(Neo);
fclose(Trinity);
// Kraj programa...
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
// Funkcija okreni
void okreni(char *p){
// Definisanje pomocnih varijabli
char pom;
int i=0, j=0, br=0;
// Brojanje slova rijeci, pointer „odlazi“ na kraj rijeci.
while (*p!='\0') {br++; p++;}
/* Pointer je „otisao“ na kraj rijeci, a nama treba u nastavku da je na
pocetku, pa cemo ga vratiti na pocetak tako sto ga pomaknemo za isti broj
mjesta nazad, za koji smo ga while petljom pomjerili naprijed! */
p=p-br;
// Glavni dio programa, ALGORITAM.
/* Recimo da smo unjeli rijec LOVE. Rijec koju trebamo dobiti kao rezultat je
EVOL. Znaci potrebno je zamjeniti zadnje slovo sa prvim, i drugo sa
predzadnjim. Brojac „i“ nam predstavlja znak do kojeg smo dosli sprijeda, a
brojac „j“ straga. Na pocetku ce biti i=0, j=3 (jer je br=3, nemojte se
zbuniti sto je 3 a ne 4, tu su ipak cetiri clana 0,1,2,3). Znaci nakon sto se
for petlja jednom izvrsi „i“ se uveca za 1 i postaje 1, a j se umanji za 1 i
postane 2. Znaci u prvom slucaju pomocu pomocne varijable „pom“ mijenjamo
znakove na 0 i 3 poziciji, drugi put ce se zamjeniti znakovi na 1 i 2
poziciji. I dobili smo trazenu rijec. Mozda zbunjuje uslov i<br/2; ali je
neophodan, broj permutacija je jednak polovini duzine rijeci, nacrtajte sebi
neki primjer i zakljucite to :). Ukoliko se uzme rijec sa neparnim brojem
slova onda se srednji clan ne pomjera nigdje, ostaje, sto je i logicno. Dok se
clanovi oko njega izmjenjaju simetricno. Funkcija nevraca nikakvu vrijednost,
ali promjene ostaju zapamcene zbog pristupa vrijednostima preko pointera! */
for (i=0,j=br-1;i<br/2;i++,j--){
pom=*(p+i);
*(p+i)=*(p+j);
*(p+j)=pom;
}
}
// Glavni program
main(){
// Definisanje varijabli i pointera
char NIZ[100];
char *t;
// Unos neke rijeci i zapisivanje iste u NIZ
printf("Unesi neku rijec: ");
scanf("%s", &NIZ);
RJEŠENJE:
#include <stdio.h>
// Funkcija ubaci5();
int ubaci5(int n,int a,int b) {
// Definisanje varijabli
int c=0,t=1,o,i;
/* Brojac „i“ krece od 1(prvi znak straga) i ide dok broj „n“ koji smo primili
u funkciju ne postane 0. Svaki put kada for petlja se izvrsava ponovo, uzima
se ostatak dijeljenja sa 10, odnosno uzima se zadnja cifra broja „n“, i
pridruzuje varijabli „o“. Zatim se broj „n“ podijeli sa 10, cime mu se odbije
zadnja cifra. Suma „c“ se uvecava za „t*o“ gdje t se mijenja kao
1,10,100,1000. Kada i bude jednako „a“ ili „b“ onda se umjesto „t*o“ doda
„t*5“ i time se na „a-to/b-to“ mjesto doda broj 5 umjesto broja koji je bio na
toj poziciji. Naredba „continue;“ ce vratiti na pocetak for petlje kako se
nebi izvrsile i linije ispod, jer bi time dobili ubacivanje brojeva, a ne
zamjenu!!! Savjet: Probajte napisati recimo petocifren broj, i skontajte malo
na papiru prvo kako biste te zamjene uradili, skontajte ulogu varijabli „o“ i
„t“!!! */
for (i=1;n>0;i++){
o=n%10;
n=n/10;
if (i==a) {c=c+t*5; t=t*10; continue;}
if (i==b) {c=c+t*5; t=t*10; continue;}
c=c+t*o;
t=t*10;}
return c;}
main(){
// Definisanje varijabli a,b,n
int n, a, b;
// Unos brojeva a,b,n
printf("Unesi prirodan bron n:"); scanf("%d", &n);
printf("Unesi brojeve a,b:"); scanf("%d,%d", &a, &b);
/* Poziv funkcije, slanje n,a,b u funkciju, a rezultat se
pridruzuje varijabli n, koja se printa u iducoj liniji. */
n=ubaci5(n,a,b);
printf("%d", n);
// Kraj programa.
getch();
return 0; }
RJEŠENJE:
#include <stdio.h>
main(){
// Definisanje varijabli
FILE *Neo, *Trinity;
char grad[15];
float JAN, FEB, MAR, PRO;
/* Provjera da li postoji datoteka gradovi.txt i ako ne postoji ispis greske,
u suprotnom se nastavlja program */
if ((Neo=fopen("C:\\gradovi.txt","r"))==NULL)
{
printf("Greska pri otvaranju datoteke");
return 0;
}
// Otvaranje datoteke prosjeci.txt
Trinity=fopen("C:\\prosjeci.txt","w");
/* Citanje podataka iz datoteke gradovi.txt izracunavanje prosjecne
temperature PRO i printanje u datoteku prosjeci.txt */
RJEŠENJE:
RJEŠENJE:
RJEŠENJE:
RJEŠENJE:
# include <stdio.h>
// Ispis datoteke na standardni izlaz zadrzavajuci strukturu po redovima...
void ispis(FILE *datoteka){
char znak;
printf("\nSadrzaj datoteke je: \n\n");
while(fscanf(datoteka,"%c", &znak)!=EOF){
printf("%c", znak);
}
}
main() {
// Definisanje pokazivaca na datoteku
FILE *datoteka;
// Otvaranje datoteke za citanje
datoteka=fopen("c:\\pismo.txt","r");
// Poziv funkcije za ispis datoteke na ekran...
ispis(datoteka);
fclose(datoteka);
// Otvaranje datoteke za citanje
datoteka=fopen("c:\\pismo.txt","r");
// Poziv funkcije za prepis datoteke u novu mijenjajuci mala i velika slova.
ispisunovu(datoteka);
fclose(datoteka);
// Otvaranje datoteke za citanje
datoteka=fopen("c:\\pismo.txt","r");
/* Poziv funkcije za ispis datoteke u obrnutom redosljedu na izlaz (prva
postaje zadnja, druga postaje pretposljednja rijec...) */
ispisobrnuto(datoteka);
fclose(datoteka);
// Otvaranje datoteke za citanje
datoteka=fopen("c:\\pismo.txt","r");
/* Poziv funkcije za ispitivanje da li je neka rijec palindrom (isto znacenje
kada se cita i u obrnutom smjeru) */
palindrom(datoteka);
fclose(datoteka);
// Kraj programa...
getch();
return 0;
}
RJEŠENJE:
#include <stdio.h>
// Definisanje varijabli
int i,b=0,dva=0,tri=0,cetiri=0,vise=0, brojslova=0, prosjek=0;
/* Ukoliko znak do kojeg smo dosli nije „?“ „!“ „.“ „\n“ , „\t“ ili „blanko“
brojac „b“ se uvecava za 1, brojac „b“ nam pokazuje koliko slova je u rijeci
izbrojano. */
if ((tekst[i]=='?')||(tekst[i]=='!')||(tekst[i]==' ')
||(tekst[i]=='.')||(tekst[i]=='\n')||(tekst[i]==',')||(tekst[i]=='\t')) {
// Glavni program
main(){
// Definisanje varijabli
int br=0, i=0, p=0, dva, tri, cetiri, vise, prosjek;
char tekst[1000];
/* Unos teksta (koristio sam while petlju koja upisuje znak po znak, a ne %s
koja upisuje cijeli string odjednom, a zasto? pa jednostavno jos uvijek neznam
drugi nacin da izbjegnem situaciju kad upisete prvi razmak, a program to
shvati kao kraj stringa i racuna samo da je string prva rijec, a ostalo kao da
niste unjeli. Ovako se ucita sve sto unesete sa tastature, sto nam i treba. U
zadatku nije naznaceno sta ce biti prekid unosa, pa sam ja stavio tacku :) )*/
printf("Unesi tekst[i], (Tacka za kraj unosa!):");
while (tekst[i-1]!='.') { scanf("%c", &tekst[i]); i++; br++;}
/* Poziv funkcije u koju saljemo tekst koji smo unijeli kao i brojac „br“ koji
je prebrojao broj unesenih karaktera, mogli smo i bez njega, al eto ja nekako
vise volim for petlje od while petlji :) */
STAM_REZ(tekst, br);
RJEŠENJE:
#include <stdio.h>
main() {
// Definicija varijabli
int i,a,b,min,nzd=1;
// Unos dva prirodna broja
printf("Unesi dva broja: ");
scanf("%d,%d", &a, &b);
// Pridruzuje se varijabli min manji od unesena 2 broja
if (a<=b) min=a; else min=b;
// I se stavlja da je jednako min, i umanjuje se sve do 1... prvi broj
// sa kojem uspiju podijeliti se oba broja je i NZD... izlazi se iz petlje kad
// se oba broja uspiju bodijeliti...
for (i=min;i>0;i--){
if (((a%i)==0)&&((b%i)==0)) {nzd=i; break;}
}
// Ispis NZD-a
printf("\nNajveci zajednicki sadrzilac je: %d" , nzd);
// Kraj programa
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
main(){
// Definisanje varijabli
int n,i,j,niz[100],pom;
// Unos broja clanova niza
printf("\n Unesite broj clanova: "); scanf("%d", &n);
/* Unos niza */
for (i=0;i<n;i++){
printf("\n Unesi clan %d :", i+1);
scanf("%d", &niz[i]); }
/* Znaci imamo neki niz, recimo od 5 clanova: [1,3,4,2,5] i trebamo ga
sortirati od veceg ka manjem broju... na kraju treba izgledati [5,4,3,2,1].
Pri koristenju ove metode, koristimo dvije for petlje, od kojih je jedna (po
„i“ brojacu, tu samo onako radi reda) :) dok druga petlja obavlja vecinu
posla. Mozete primjetiti da u uslovu stoji „i<(n-1)“ kao i „j<(n-1)“. Ako
pogledamo jedan niz od 5 clanova i ako bi mijenjali brojeve tako da mijanjamo,
prvi i drugi clan, zatim drugi i treci, pa 3 i 4, pa 4 i 5. Znaci imamo 4
izmjene iako imamo 5 clanova, i zbog toga u uslovu ide „n-1“ umjesto „n“!
Znaci program radi tako da se vanjska for petlja izvrsi „n-1“ puta a
unutrasnja se izvrsi „(n-1)*(n-1)“ puta... u nasem slucaju od 5 clanova, znaci
16 puta. Mozda je ova metoda spora dosta jer se okrece 16 puta, sto bi se
moglo smanjiti, ali zbog jednostavnosti izgleda, prvo sam uzeo ovu metodu.
Dalje imamo uslov u unutrasnjoj petlji „niz[j]<niz[j+1]“ koji bi u prijevodu
znacio, ako je j-ti clan manji od iduceg (j+1) onda im mijenja mjesta...
Graficki desavanja pri sortiranju naseg niza izgledaju ovako (uspravno
citajte).
1 - 3 3 3 3 4 4 4 4 4 4 4 4 5 5 5 5
3 - 1 4 4 4 3 3 3 3 3 5 5 5 4 4 4 4
4 - 4 1 2 2 2 2 5 5 5 3 3 3 3 3 3 3
2 - 2 2 1 5 5 5 2 2 2 2 2 2 2 2 2 2
5 - 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1
I na kraju smo dobili soritran niz... znaci 16 puta se vrtila unutrasnja
petlja po 4 puta je kretala od prvog do cetvrtog clana i vrsila izmjene po
uslovu u if petlji, i na kraju rezultat mora biti sortiran niz! Da smo htjeli
obrnuto da sortiramo od najmanjeg ka najvecem samo bi se promjenio znak < u
uslovu u if petlji u znak > ... :) */
for (i=0;i<(n-1);i++)
for (j=0;j<(n-1);j++)
if (niz[j]<niz[j+1]) {
pom=niz[j+1];
niz[j+1]=niz[j];
niz[j]=pom;
}
// Ispis niza i kraj programa...
printf("\n Ispis niza: ");
for (i=0;i<n;i++) printf("[%d]", niz[i]);
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
main(){
// Definisanje varijabli
int n,i,j,niz[100],pom;
// Unos broja clanova niza
printf("\n Unesite broj clanova: "); scanf("%d", &n);
/* Unos niza */
for (i=0;i<n;i++){
printf("\n Unesi clan %d :", i+1);
scanf("%d", &niz[i]); }
1 - 3 4 4 5 5 5 5 5 5 5
3 - 1 1 1 1 3 3 4 4 4 4
4 - 4 3 3 3 1 1 1 2 3 3
2 - 2 2 2 2 2 2 2 1 1 2
5 - 5 5 5 4 4 4 3 3 2 1
for (i=0;i<(n-1);i++)
for (j=i+1;j<n;j++)
if (niz[j]>niz[i])
{
pom=niz[i];
niz[i]=niz[j];
niz[j]=pom;
}
getch();
return 0;
}
RJEŠENJE:
# include <stdio.h>
// Definisanje strukture
struct struktura {
char ime[100];
char prezime[100];
int bodovi;
};
main(){
// Definisanje varijabli
int n,i,j;
struct struktura spisak[100];
struct struktura pom;
// Unos broja clanova niza
printf("\n Unesite broj imena: "); scanf("%d", &n);
/* Unos imena, prezimena, bodova i direktan upis u strukturu*/
for (i=0;i<n;i++){
printf("\n Unesi %d ime:", i+1);
scanf("%s", &spisak[i].ime);
printf(" i prezime:");
scanf("%s", &spisak[i].prezime);
printf(" i bodove:");
scanf("%d", &spisak[i].bodovi);
}
/* Proces sortiranja */
for(i=0;i<(n-1);i++)
for(j=0;j<(n-1);j++)
if (spisak[j].bodovi<spisak[j+1].bodovi)
{
pom=spisak[j];
spisak[j]=spisak[j+1];
spisak[j+1]=pom;
}
// Ispis niza i kraj programa...
for (i=0;i<n;i++) printf("\n%d. [%s %s]: %d", i+1, spisak[i].prezime,
spisak[i].ime, spisak[i].bodovi);
getch();
return 0;
}
Preuzeti instalaciju razvojne okoline MS Visual Studio .NET 2008 Professional sa stranica
http://msdnaa.fer.hr/ i instalirati ga na vlastito računalo. Dozvoljene su i verzije 2005 i 2010.
Start → Programs → Microsoft Visual Studio 2008 → Microsoft Visual Studio 2008
Prilikom pokretanja sučelja obično se pojavi tzv. Start Page na koje se vidi lista nekoliko
zadnje kreiranih projekata, što se inače koristi za brzi pristup prethodno kreiranim projektima.
Slika 1.
Odabirom opcije New Project pojavit će se dijalog kao na slici 2. U ovom dijalogu
odaberite:
tip projekta: Visual C++ → Win32 Console Application
ime projekta: u polje Name umjesto <Enter name> upišite željeno ime
1
Programiranje i programsko inženjerstvo, FER
Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Slika 2
Slika 3
2
Programiranje i programsko inženjerstvo, FER
Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Slika 4
U ovom je trenutku stvoren projekt koji još uvijek ne sadrži niti jednu datoteku s
programskim kodom.
4. Pisanje programa
3
Programiranje i programsko inženjerstvo, FER
Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Slika 5
Nakon toga potrebno je odabrati da želite dodati C++ datoteku (slika 6) i dati joj ime
koje mora završavati s ekstenzijom .c (u ovom primjeru tu ćemo datoteku nazvati
vjezba.c). Pritisnite gumb Open i datoteka će se stvoriti i postati dijelom projekta.
Slika 6
U novodobiveni prostor za pisanje programa koji je dobiven dodavanjem datoteke
vjezba.c potrebno je upisati program. Za vježbu upišite program sa slajda 21 prvog
predavanja (02-UvodProgramiranje).
4
Programiranje i programsko inženjerstvo, FER
Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Slika 7
5. Prevođenje programa
Potrebno je izvesti izgradnju izvršne datoteke odabirom opcije izbornika Build → Build
ImeVašegProjekta (na slici 7 to je opcija Build Vjezba1)
Slika 8
U slučaju da vaš program nema grešaka pojavit će se poruka kao na slici 8. U slučaju da se
Output prozor ne vidi, pokrenite opciju izbornika View → Output.
5
Programiranje i programsko inženjerstvo, FER
Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Ako je program imao grešaka na ovom prozoru će se pojaviti lista grešaka gdje se dvoklikom
miša na pojedinu od njih možete pozicionirati na redak u kojem se ta pogreška nalazi.
Slika 9
6. Pokretanje programa
Ako je program bio bez grešaka možete ga pokrenuti odabirom opcije Start Without
Debugging iz izbornika Debug (slika 9).
Slika 10
Želite li testirati neki drugi program, a da pri tome sačuvate već napisani program,
možete koristiti jednu od ovih metoda:
zatvorite projekt korištenjem opcije File → Close Solution, te
cjelokupni opisani postupak ponoviti s nekim drugim imenom
u već postojeće rješenje koje sadrži jedan projekt dodati još jedan tako da
u Solution Exploreru desnom tipkom miša kliknete na Solution
ImeRješenja (u ovom primjeru Solution 'Vjezba1') i odaberete
opciju Add → New Project. Postupak dodavanja novog projekta je
sličan već opisanom postupku.
Ako imate više otvorenih projekata, odabir koji projekt (program) želite pokrenuti obavlja se
tako da se na željeni projekt klikne desnom tipkom miša i odaberete Set as
StartUpProject (slika 10).
6
Programiranje i programsko inženjerstvo, FER
Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Slika 11
7
Programiranje i programsko inženjerstvo
Sveučilište u Zagrebu - Fakultet elektrotehnike i računarstva -Zavod za primijenjeno računarstvo
Pokrenuti MinGW Installer alat te putem njega instalirati osnovne komponente paketa MinGW. U
lijevom polju potrebno je odabrati Basic Setup i zatim u desnom polju označiti stavku mingw32-base.
Nakon toga u izborniku odaberite Installation -> Apply Changes te u novootvorenom prozoru kliknite
na gumb Apply.
Nakon provedene instalacije potrebno je podesiti sistemsku varijablu PATH dodavanjem putanje do
direktorija bin paketa MinGW. Ako ste MinGW instalirali s inicijalnim (default) postavkama,
direktorij bin paketa MinGW će biti C:\MinGW\bin.
1
Control Panel -> System and Security -> System
Potrebno je kliknuti na link koji se nalazi s lijeve strane -> Advanced system settings
U novootvorenom prozoru odabrati karticu (tab) Advanced te zatim kliknuti na gumb Environment
Variables… kako je prikazano na slici:
2
Nakon toga potrebno je u listi System variables odabrati varijablu Path i kliknuti na gumb Edit
;C:\MinGW\bin\
3
Obratite pažnju na znak ; na početku teksta koji se dodaje u varijablu Path.
Napomena:
Ako ste MinGW instalirali u drugom direktoriju (umjesto u C:\MinGW) tada u tekstu kojim se
dopunjava varijabla Path, zamijeniti C:\MinGW s putanjom do tog direktorija.
Navedeni tekst dodajte na kraj postojećeg sadržaja varijable Path, vodeći računa o tome da
postojeći sadržaj varijable ne obrišete!
Studenti koji imaju problema sa instalacijom najnovije inačice MinGW kolekcije na svoje Windows
računalo mogu pokušati ovu alternativnu metodu:
4
2. Pisanje i pokretanje programa
Nakon što ste instalirali paket MinGW, u direktoriju C:\PPI (ili neki drugi direktorij po vašem
izboru) stvorite znakovnu datoteku (npr. koristeći uređivač teksta Notepad) „ppi.c“. U znakovnu
datoteku upišite sljedeći kod:
#include<stdio.h>
int main(void){
printf("Programiranje i programsko inzenjerstvo");
return 0;
}
1. Pokrenite command prompt (npr. Start menu -> Run pa upišite „cmd“) i pozicionirajte se u
direktorij C:\PPI.
2. Pokrenite prevodilac GCC naredbom
cc -ansi -pedantic-errors -Wall -o ppi.exe ppi.c
Prvo se navodi naziv programa koji obavlja prevođenje – „cc“. Nakon toga navode se
parametri:
-ansi – parametar kojim osiguravamo prevođenje sukladno ANSI standardu
-pedantic-errors – parametar kojime zahtijevamo detaljno ispisivanje grešaka u
programu
-Wall – parametar kojime zahtijevamo detaljan ispis upozorenja
Zatim slijedi parametar „–o“ kojim se određuje kako će se zvati izvršna datoteka, u našem
slučaju to je „ppi.exe“. Na kraju je naveden naziv datoteke s izvornim kodom, „ppi.c“.
Nakon prevođenja programa ppi.c, pokrenite izvršnu datoteku „ppi.exe“. Na zaslonu će se ispisati
tekst „Programiranje i programsko inzenjerstvo“.
5
Napomena:
Ako vam prilikom pokretanja prevodioca GCC sustav javi sljedeću grešku
'cc' is not recognized as an internal or external command, operable program or batch file.
znači da sistemska varijabla Path nije ispravno podešena. Ako niste u mogućnosti podesiti varijablu
Path, možete napraviti sljedeće:s
1. Pozicionirajte se u direktorij bin unutar direktorija u kojeg ste instalirali MinGW. Ako ste
ostavili inicijalne postavke tada se to direktorij nalazi u C:\MinGW\bin
2. Sada možete pokrenuti GCC prevodilac, ali za naziv datoteke s izvornim kodom morate unijeti
cijelu putanju do te datoteke. Isto vrijedi i za naziv izvršne datoteke
Ako se datoteka s izvornim kodom nalazi u C:\PPI\ppi.c te ako u istom direktoriju (C:\PPI)
želimo stvoriti i datoteku s izvršnim kodom, GCC prevodilac treba pokrenuti :
Kao naziv datoteke s izvornim kodom naveden je C:\PPI\ppi.c, a kao naziv izlazne datoteke
navedena je datoteka C:\PPI\ppi.exe.
Program se pokreće navođenjem apsolutnog ili relativnog puta do datoteke s izvršnim kodom, u
našem primjeru:
C:\PPI\ppi.exe
6
Programiranje i programsko inženjerstvo
Sveučilište u Zagrebu - Fakultet elektrotehnike i računarstva -Zavod za primijenjeno računarstvo
c) Start u okvir za pretraživanje (Search) upisati cmd, nakon čega se otvara prozor
prikazan pod b)
d) istovremeni pritisak tipki Windows i R (Win+R), nakon čega se otvara prozor prikazan pod b)
Nakon toga otvara se prozor s znakovnim sučeljem:
1
2 Izvođenje programa i naredbi
Pokretanje naredbe ili programa obavlja se upisivanjem njegovog imena, argumenata (npr. naziv
datoteke) i opcija (parametri koji modificiraju djelovanje naredbe, a navode se iza znaka /), te
pritiskom na tipku Enter. Ne razlikuju se velika i mala slova u nazivima datoteka, naredbi i opcija.
Dakle, sasvim je svejedno je li upisano npr. HELP ili help.
Naredba se upisuje iza prompta, koji se pojavljuje kada je sučelje spremno od korisnika prihvatiti
naredbu. Prompt obično završava znakom >.
U nastavku su navedeni primjeri korištenja pojedinih naredbi u njihovom osnovnom obliku. Popis
uobičajenih naredbi moguće je dobiti upisivanjem naredbe help. Za prikaz dodatnih informacija o
pojedinoj naredbi, potrebno je upisati help naziv_naredbe.
Program koji se izvodi može biti prekinut istovremenim pritiskom na tipke Ctrl i C (Ctrl+C).
Izvođenje programa može biti privremeno zaustavljeno pritiskom na tipku Pause ili kombinacijom tipki
Ctrl+S. Nastavak izvođenja na ovaj način zaustavljenog programa obavlja se pritiskom na bilo koju
tipku, na primjer Enter.
Naredbom exit završava se rad s znakovnim sučeljem i zatvara pripadni prozor.
Primjer:
help help (dobivanje uputa o radu programa help)
help tree (dobivanje uputa o radu programa tree; uz kratki opis naredbe dan je i opis
dozvoljenih opcija: /F i /A, pa je moguće, na primjer, zadati naredbu: tree /f)
2
Datotečni sustav računala je dio operacijskog sustava koji služi za organiziranje, upravljanje i pristup
datotekama. Upravljanje datotekama jedna je od osnovnih zadaća operacijskog sustava. Operacijski
sustav, između ostalog, vodi evidenciju o fizičkom smještaju datoteka na mediju za pohranu te nudi
sučelje za otvaranje postojećih, stvaranje novih datoteka, čitanje iz datoteke, pisanje u datoteku,
premještanje, preimenovanje te brisanje datoteka i direktorija.
Svaki disk sadrži jedan izvorni ili osnovni direktorij (root) koji je označen znakom \. Kako broj izvornih
direktorija ovisi o broju diskova, da bi se znalo o kojem se izvornom direktoriju radi, ispred znaka \
navodi se i oznaka diska, npr. C:\, D:\, itd. U nekim operacijskim sustavima (npr. Unix), postoji samo
jedan izvorni direktorij te se ne navodi oznaka diska.
Na slici je, u grafičkom sučelju operacijskog sustava Windows (pomoću programa Windows Explorer),
prikazana stablasta struktura direktorija na disku C te, na desnoj strani, sadržaj (direktoriji i datoteke)
direktorija \cygwin\lib:
3
Prikaz stablaste strukture direktorija u
znakovnom sučelju omogućava naredba tree.
Ako je naredba zadana bez opcija, ispisuju se
samo nazivi direktorija. Navođenjem opcije /f,
biti će prikazane i datoteke (slika desno).
Operacijski sustav prati trenutnu poziciju
korisnika unutar datotečnog sustava za vrijeme
dok koristi znakovno korisničko sučelje. Ta se
trenutna pozicija naziva radni (working, current)
disk i radni direktorij. Informacija o radnom disku i
radnom direktoriju sastavni je dio prompta. Na
slici desno prompt predstavlja tekst
C:\cygwin\lib>, što znači da je radni disk C, a
radni direktorij je direktorij lib, koji je
poddirektorij direktorija cygwin smještenog u
izvornom direktoriju.
Relativni put ovisi o radnom direktoriju. Prilikom navođenja relativnog puta do datoteke moguće je
koristiti i posebne oznake:
. označava radni direktorij
.. označava direktorij nadređen radnom direktoriju
Na primjer, ako je radni direktorij C:\users\hrvoje (apsolutni put do tog direktorija), oznaka .
predstavlja oznaku za direktorij C:\users\hrvoje, oznaka .. predstavlja oznaku za direktorij C:\users, a
..\.. je oznaka za izvorni direktorij C:\. Relativni put do datoteke čije je ime popis.txt, a nalazi se u
direktoriju C:\users\ana je ..\ana\zivotopis.txt.
Većina naredbi kao argument prihvaća naziv jedne ili više datoteka, odnosno direktorija. Ako se kod
navođenja naziva izostavi ime direktorija ili diska, podrazumijeva se da se radi o trenutno radnom
direktoriju i disku.
Kod nekih naredbi nije potrebno pisati puno ime datoteka ili direktorija, već je moguće koristiti i
posebne znakove (tzv. metaznakove, wildcard):
* zamjenjuje neodređeni niz, bilo koju kombinaciju znakova
? zamjenjuje samo jedan, bilo koji znak.
Na primjer, niz ?.txt određuje sve datoteke koje imaju ime duljine jednog znaka i nastavak txt.
4
Primjer:
tree \ (prikaz stablaste strukture direktorija radnog diska, počevši od izvornog direktorija,
bez prikaza datoteka)
5
mkdir c:\tmp (stvaranje direktorija tmp u izvornom direktoriju na disku C)
mkdir tmp (stvaranje direktorija tmp u radnom direktoriju)
6
3.9 Brisanje direktorija (rmdir)
Naredbom rmdir briše se navedeni direktorij. Ako nisu navedene dodatne opcije, direktorij je
moguće obrisati samo ako je prazan, tj. ako u njemu nema niti jedne datoteke ili direktorija.
Korištenjem opcije /s moguće je obrisati i direktorij koja nije prazan.
Primjer:
rmdir C:\tmp (brisanje praznog direktorija tmp u izvornom direktoriju)
rmdir /s vjezba (brisanje direktorija vjezba koji se nalazi u radnom direktoriju,
direktorij će biti obrisan i ako nije prazan)
4 Preusmjeravanje (redirekcija)
Prilikom izvođenja naredbi u znakovnom sučelju podrazumijeva se da se ulazni podaci prihvaćaju s
tipkovnice, a izlazni ispisuju na zaslonu. Tipkovnica predstavlja standardni ulaz, a zaslon standardni
izlaz. Međutim, ponekad je potrebno izlazne podatke preusmjeriti u datoteku, ili pak ulazne podatke,
umjesto s tipkovnice, preuzeti iz datoteke. To se postiže korištenjem znakova za preusmjeravanje:
> preusmjerava izlaz u datoteku; ako datoteka već postoji, briše se njen dotadašnji sadržaj
< preuzima ulazne podatke iz datoteke
>> preusmjerava izlaz u datoteku; ako datoteka već postoji, podaci se dodaju na kraj datoteke
7
5 Editori teksta
Editori teksta su programi namijenjeni pisanju teksta u kojem nema posebnih znakova za
formatiranje (tzv. kontrolnih kôdova). Za razliku od editora, programi za uređivanje teksta, osim slova
i uobičajenih znakova, ubacuju posebne znakove koji služe za formatiranje konačnog teksta
(određivanje rubova, određivanje tipa i veličine slova i sl.). Za pisanje programa koriste se isključivo
editori.
Na vježbama se koristi editor Notepad. Editor je moguće pokrenuti na dva načina:
navođenjem samo naredbe notepad,
navođenjem naredbe notepad iza koje slijedi ime datoteke koju je potrebno editirati (notepad
ime_datoteke).
Ako je editor pokrenut na prvi način, potrebno je naknadno navesti ime datoteke u koju se želi
spremiti upisani tekst. Međutim, kako je txt ponuđeni nastavak za naziv datoteke, često se dogodi
da datoteka dobije dodatni nastavak txt, a treba paziti i na direktorij u koji će biti smještena. Na
primjer, ako je datoteku potrebno nazvati ppi.c, moguće je da zapravo bude nazvana ppi.c.txt.
Zato je preporuka pokretati editor uz navođenje naziva datoteke (uz mogućnost navođenja
apsolutnog ili relativnog puta):
notepad ppi.c (editorom se otvara datoteka ppi.c koja je smještena u radnom
direktoriju)
notepad d:\vjezbe\p.c (editorom se otvara datoteka p.c koja je smještena u direktoriju
\vjezbe na disku D)
8
Zadaci za vježbu
1) Obaviti sljedeće:
1. Izvorni direktorij na disku C proglasiti radnim direktorijem (u nastavku vježbe radni disk i
direktorij promijeniti samo kada je to traženo u zadatku).
2. Na disku C u izvornom direktoriju kreirati direktorij vjezba.
3. Unutar direktorija vjezba, ne mijenjajući radni direktorij, kreirati direktorije osobno i ppi.
4. Uz korištenje relativnog puta proglasiti direktorij C:\vjezba\osobno radnim direktorijem,
te unutar njega kreirati direktorije txt i slike.
5. Uz korištenje apsolutnog puta proglasiti direktorij slike radnim direktorijem, a zatim u taj
direktorij kopirati nekoliko slika (možete ih prethodno potražiti korištenjem npr. programa
Windows Explorer). Prilikom kopiranja slika navesti apsolutni put do direktorija u kojem se
nalaze slike, a relativni put do direktorija u koji je potrebno kopirati slike.
6. Jednom naredbom proglasiti direktorij C:\vjezba\osobno\txt radnim direktorijem, uz
korištenje relativnog puta.
7. Provjeriti postoji li u radnom direktoriju datoteka nema.me.
8. Editorom Notepad u datoteku zivot.txt upisati neki tekst.
9. Kopirati datoteku zivot.txt u datoteke pom.txt i pom1.txt u radnom direktoriju.
10. Ispisati stablastu strukturu direktorija (bez datoteka) na disku C počevši od izvornog
direktorija. Privremeno zaustaviti te nakon toga nastaviti ispisivanje te strukture na zaslon.
11. Ispisati stablastu strukturu direktorija, uključujući datoteke, počevši od direktorija vjezba uz
korištenje relativnog puta. Usporediti dobivenu strukturu sa strukturom prikazanom u
grafičkom sučelju, koristeći program Windows Explorer.
12. Pozvati program help bez argumenata, a izlaz programa preusmjeriti u datoteku
help.txt.
13. Ispisati sadržaj radnog direktorija.
14. Prebaciti datoteku help.txt u nadređeni direktorij.
15. Ispisom sadržaja radnog, a zatim i nadređenog direktorija, provjeriti je li kopiranje uspješno
obavljeno.
16. Bez promjene radnog direktorija, na zaslon ispisati sadržaj datoteke help.txt.
17. U radnom direktoriju obrisati sve datoteke čije ime započinje slovom p.
18. Proglasiti izvorni direktorij radnim direktorijem navođenjem relativnog puta.
19. Obrisati direktorij C:\vjezba\osobno\txt (navesti apsolutni put do direktorija).
20. Obrisati sve datoteke u direktoriju C:\vjezba\osobno\slike (navesti relativni put do
direktorija).
21. Obrisati direktorij osobno.
2) Napisati program koji će pročitati dva cijela broja i ispisati veći broj. Izvorni kod pohraniti u
datoteci proba.c u direktoriju ppi kreiranom u 1. zadatku. Za editiranje koristiti editor Notepad
(naziv datoteke navesti prilikom pokretanja editora). Prevesti program pomoću prevodioca GCC,
a izvršnu datoteku nazvati proba.exe. Izvesti program tako da se:
1) brojevi čitaju s tipkovnice, a rezultat ispisuje na zaslon monitora
2) brojevi čitaju s tipkovnice, a rezultat ispisuje u datoteku izlaz.txt
3) brojevi čitaju iz datoteke ulaz.txt koja je prethodno pripremljena pomoću editora, a
rezultat ispisuje na kraj datoteke izlaz.txt, bez uništavanja njenog prethodnog sadržaja
9
Rješenja
1)
1. cd c:\
2. mkdir vjezba
3. mkdir vjezba\osobno
mkdir vjezba\ppi
4. cd vjezba\osobno
mkdir txt
mkdir slike
5. cd c:\vjezba\osobno\slike
npr: copy c:\users\hrvoje\slike\*2013*.jpg .
6. cd ..\txt
7. dir nema.me
8. notepad zivot.txt
9. copy zivot.txt pom.txt
copy zivot.txt pom1.txt
10. tree \
privremeno zaustavljanje izvođenja: Pause (ili Ctrl+S)
nastavak izvođenja: bilo koja tipka
11. tree /f ..\..
12. help > help.txt
13. dir
14. move help.txt ..
15. dir .
dir ..
16. type ..\help.txt
17. del p*
18. cd ..\..\..
19. rmdir /s C:\vjezba\osobno\txt
20. del C:\vjezba\osobno\slike
21. rmdir /s C:\vjezba\osobno
2) cd c:\vjezba\ppi
notepad proba.c
U znakovnu datoteku proba.c upisati sljedeći kod:
#include <stdio.h>
int main(void) {
int x,y;
printf("Upisite dva cijela broja: ");
scanf("%d %d", &x, &y);
if (x>y) {
printf("%d\n", x);
} else {
printf("%d\n", y);
}
return 0;
}
10
cc -ansi -pedantic-errors -Wall -o proba.exe proba.c
1) proba.exe
2) proba.exe > izlaz.txt
type izlaz.txt
3) notepad ulaz.txt
U znakovnu datoteku proba.c upisati dva cijela broja, npr:
10 5
11
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 25
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
1. vježbe uz predavanja
Uputa: kojim brojem n treba podijeliti broj m da bi se kao ostatak dijeljenja dobila zadnja
(krajnje desna) znamenka broja m? Postoji li u programskom jeziku C aritmetička
operacija kojom se izračunava ostatak cjelobrojnog djeljenja?
2. S tipkovnice učitati polumjer kruga (realni broj). Ako je učitani broj pozitivan, izračunati
opseg i površinu kruga, te na zaslon ispisati:
zadani polumjer je: xxxxxx.xxxx
opseg kruga je: xxxxxx.xxxx
povrsina kruga je: xxxxxx.xxxx
inače (ako učitani broj nije pozitivan) na zaslon treba ispisati:
broj xxxxxx.xxxx nije ispravan polumjer kruga
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 25
Rješenja
1.
#include <stdio.h>
int main (void) {
int broj, zadnjaZnamenka;
printf("Upisite jedan pozitivan cijeli broj: ");
scanf("%d", &broj);
if (broj > 0) {
zadnjaZnamenka = broj % 10;
} else {
printf("Broj %5d nije pozitivan broj\n", broj);
}
return 0;
}
2.
#include <stdio.h>
int main (void) {
float polumjer, opseg, povrsina;
scanf("%f", &polumjer);
if (polumjer > 0) {
opseg = 2 * polumjer * 3.14159;
povrsina = polumjer * polumjer * 3.14159;
printf("zadani polumjer je: %11.4f\n", polumjer);
printf("opseg kruga je: %11.4f\n", opseg);
printf("povrsina kruga je: %11.4f\n", povrsina);
} else {
printf("broj %11.4f nije ispravan polumjer kruga\n", polumjer);
}
return 0;
}
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 25
3.
#include <stdio.h>
int main (void) {
int broj, ostatak;
scanf("%d", &broj);
printf("ucitan je broj: %5d\n", broj);
if (broj < 0) {
printf("broj je negativan\n");
}
ostatak = broj % 2;
if (ostatak == 0) {
printf("broj je paran\n");
} else {
printf("broj je neparan\n");
}
return 0;
}
ili
#include <stdio.h>
int main (void) {
int broj;
scanf("%d", &broj);
printf("ucitan je broj: %5d\n", broj);
if (broj < 0) {
printf("broj je negativan\n");
}
if (broj % 2 == 0) {
printf("broj je paran\n");
} else {
printf("broj je neparan\n");
}
return 0;
}
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 47
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
2. vježbe uz predavanja
1. Pročitajte i zaključite što bi sljedeći program (kada bi bio ispravan) trebao raditi.
#include <stdio.h>;
int mein (void) {
integer xa; ya; xb; yb; xc; yc;
printf("Upisite koordinate vrha trokuta A >");
scan("%d %d", &xa, &ya);
printf("Upisite koordinate vrha trokuta B >");
scan("%d %d", &xb, &yb);
printf("Upisite koordinate vrha trokuta C >");
scan("%d %d", &xc, &yc);
xTezista = xa + xb + xc / 3;
yTezista = ya + yb + yc / 3;
printf("Teziste trokuta A(%d, %d), B(%d, %d), C(%d, %d) jest T(%d, %d)"
, xa, ya, xb, yb, xc, yc, xTezista, yTezista);
return 0
}
Zatim pomoću copy-paste upišite program u datoteku na svom računalu i pokušajte ga
prevesti. Prvo ispravite isključivo sintaktičke pogreške. Nakon toga ispravite pogreške
povezivanja. Kada se program uspješno prevede, testirajte program s različitim ulaznim
podacima:
- za vrhove trokuta s koordinatama (0, 0), (3, 3) i (6, 0)
- za vrhove trokuta s koordinatama (0, 0), (1, 1) i (2, 0)
- za vrhove trokuta s koordinatama (0, 0), (1.5, 1.5) i (3, 0)
Ispravite sve logičke pogreške.
Uputa: pri rješavanju ovog zadatka korisno je poslužiti se C prevodiocem, koji će otkriti
one sintaktičke pogreške i pogreške povezivanja koje sami možda ne uspijete uočiti.
2. Napisati C program kojim će se s tipkovnice učitati pozitivni cijeli broj koji ima 5
znamenaka. Nije potrebno provjeravati je li korisnik upisao ispravan broj. Program treba
na zaslon ispisati prvu i posljednju znamenku učitanog broja.
3. Napisati C program kojim će se s tipkovnice učitati pozitivni cijeli broj koji ima 5
znamenaka. Nije potrebno provjeravati je li korisnik upisao ispravan broj. Program treba
na zaslon ispisati drugu i četvrtu znamenku.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 47
Rješenja
1. Sintaktičke pogreške:
− točka-zarez se ne smije stavljati iza pretprocesorskih naredbi
− definicija varijabli xa, ya, xb, yb, itd. je neispravna. Varijable koje se odjednom
definiraju međusobno se odjeljuju zarezom, a ne točkom-zarezom. Tip integer ne
postoji.
− varijable xTezista i yTezista nisu definirane
− nedostaje točka-zarez iza naredbe return.
Pogreške povezivanja:
− u stdio.h ne postoji funkcija scan (postoji scanf)
− program mora sadržavati funkciju main (a ne mein)
Logičke pogreške:
− koordinate težišta se neispravno izračunavaju. X koordinate triju vrhova treba prvo
zbrojiti, a tek tada podijeliti s 3 (trenutno se na kvocijent z/3 dodaje vrijednost za x i y.
Isto vrijedi i za y koordinate.
− nakon dodavanja zagrada program će ispravno raditi za koordinate vrhova (0, 0), (3,
3) i (6, 0), ali ne i za koordinate (0, 0), (1, 1) i (2, 0). Razlog je u cjelobrojnom
dijeljenju i tipu rezultata: 0+1+0 cjelobrojno podijeljeno s 3 daje 0, a ne 0.33333.
Potrebno je promijeniti tip svih varijabli: koordinate vrhova trokuta i težišta trebaju biti
realni, a ne cijeli brojevi.
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 47
2.
#include <stdio.h>
int main (void) {
int broj;
printf("Upisite 5-znamenkasti pozitivni cijeli broj: ");
scanf("%d", &broj);
printf("Prva znamenka: %d\n", broj/10000);
printf("Posljednja znamenka: %d\n", broj%10);
return 0;
}
3.
#include <stdio.h>
int main (void) {
int broj;
printf("Upisite 5-znamenkasti pozitivni cijeli broj: ");
scanf("%d", &broj);
printf("Druga znamenka: %d\n", broj%10000/1000);
printf("Cetvrta znamenka: %d\n", broj%100/10);
return 0;
}
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 84
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
3. vježbe uz predavanja
1. Pročitajte i zaključite što bi sljedeći program (kada bi bio ispravan) trebao raditi.
Napišite tekst programskog zadatka koji bi odgovarao programu. Nacrtajte dijagram toka.
Zatim pomoću copy-paste upišite program u datoteku na svom računalu i pokušajte ga
prevesti. Ispravite sve vrste pogrešaka i testirajte s različitim ulaznim podacima.
#definiraj PI 3,1415926
float main (void) {
int a;
float b;
printf("Upisite duljinu velike poluosi a>");
scanf("%f", &a);
printf("Upisite duljinu male poluosi b>");
scanf("%f", &b);
if (a > 0) {
if (b > 0) {
povrsina = A x B x pi;
printf("Povrsina elipse s poluosima a=%f i b=%f je %f", povrsina);
scanf("%f", &b);
} else {
printf("Duljina male poluosi mora biti veca od nule.\nKraj. ");
}
} else {
printf("Duljina velike poluosi mora biti veca od nule.\nKraj. ");
}
return O;
}
Ako korisnik upiše bilo koji drugi cijeli broj, tada ispisati poruku
Upisite temperaturu izrazenu u stupnjevima Celsius >
te s tipkovnice učitati jedan realni broj koji predstavlja temperaturu izraženu u stupnjevima
Celsius, izračunati ekvivalentnu temperaturu izraženu u stupnjevima Fahrenheit te ispisati
temperaturu izraženu u obje jedinice
xxxx.xxx st. C = xxxx.xxx st. F
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 84
3. Nacrtati dijagram toka i napisati C program za zbrajanje ili množenje realnih brojeva. Na
početku program treba ispisati poruku
Program za zbrajanje ili mnozenje.
Upisite dva realna broja >
i učitati cijeli broj kojim se određuje vrsta operacije. Ako je korisnik upisao broj 1, tada treba
izračunati i ispisati zbroj operanada, a ako je upisao broj 2, tada izračunati i ispisati
umnožak operanada. Ako za odabir vrste operacije korisnik nije upisan niti broj 1 niti broj 2,
tada treba ispisati poruku
Neispravan odabir operacije.
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 84
Rješenja
1. Programski zadatak: napisati program kojim će se učitati duljine velike i male poluosi elipse.
Nakon učitavanja duljina obje osi, ispitati ispravnost unesenih podataka. Ako je velika poluos
neispravno zadana, ispisati poruku "Duljina velike poluosi mora biti veca od nule.", u sljedećem
retku na zaslonu ispisati "Kraj", te završiti s izvršavanjem programa. Ako je mala poluos
neispravno zadana, ispisati poruku "Duljina male poluosi mora biti veca od nule.", u sljedećem
retku na zaslonu ispisati "Kraj", te završiti s izvršavanjem programa.
Ako su duljine obje osi ispravno zadane, izračunati površinu elipse i ispisati poruku " Povrsina
elipse s poluosima a=x.xxxxxx i b=x.xxxxxx je x.xxxxxx.
Dijagram toka:
učitaj a, b
Da
a>0
Ne
Da
ispiši "neispravna
b>0
velika os, kraj"
Ne
ispiši "neispravna izračunaj i ispiši
mala os, kraj" površinu elipse
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 84
2.
#include <stdio.h>
int main (void) {
float cels, fahr;
int izbor;
printf("Program za konverziju Fahrenheit - Celsius i obrnuto.\n");
printf("Za F u C upisite 1, a za C u F bilo koji drugi cijeli broj >");
scanf("%d", &izbor);
if (izbor == 1) {
printf("Upisite temperaturu izrazenu u stupnjevima Fahrenheit >");
scanf("%f", &fahr);
cels = (fahr - 32.) * 5. / 9.;
printf("%8.3f st. F = %8.3f st. C\n", fahr, cels);
} else {
printf("Upisite temperaturu izrazenu u stupnjevima Celsius >");
scanf("%f", &cels);
fahr = cels * 9. / 5. + 32.;
printf("%8.3f st. C = %8.3f st. F\n", cels, fahr);
}
return 0;
}
Ne
op = 1
Da
Ne
ispiši zbroj op = 2
Da
ispiši "neispravna
ispiši umnožak
operacija"
#include <stdio.h>
int main (void) {
float x, y;
int operacija;
printf("Program za zbrajanje ili mnozenje.\nUpisite dva realna broja >");
scanf("%f %f", &x, &y);
printf("Upisite vrstu operacije (1-zbrajanje, 2-mnozenje) >");
scanf("%d", &operacija);
if (operacija == 1)
printf("Zbroj je %f\n", x + y);
else
if (operacija == 2)
printf("Umnozak je %f\n", x * y);
else
printf("Neispravan odabir operacije.\n");
return 0;
}
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
4. vježbe uz predavanja
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
14. Dekadski broj -9 pohraniti u registar od 5 bitova (tehnikom dvojnog komplementa). Rezultat
prikazati kao
a. binarni broj
b. heksadekadski broj
c. oktalni broj
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
Rješenja
1. 29 : 2 = 14 ostatak 1
14 : 2 = 7 ostatak 0
7 : 2 = 3 ostatak 1
3 : 2 = 1 ostatak 1
1 : 2 = 0 ostatak 1
2. Prva znamenka jest jedinica, ali u zadatku piše da nije korištena tehnika dvojnog
komplementa. To znači da se radi o pozitivnom broju:
1⋅27 + 0⋅26 + 0⋅25 + 1⋅24 + 1⋅23 + 0⋅22 + 1⋅21 + 1⋅20 = 155
3. U zadatku piše da se za prikaz broja koristi tehnika dvojnog komplementa, ali prvi bit u
registru nije jedinica. To znači da je u registru prikazan pozitivan broj. Vrijednost određujemo
na isti način kao da se tehnika dvojnog komplementa uopće ne koristi:
1⋅24 + 1⋅23 + 0⋅22 + 1⋅21 + 1⋅20 = 27
4. Za prikaz broja se koristi tehnika dvojnog komplementa, a prvi bit u registru jest jedinica.
To znači da je u registru prikazan neki negativan broj x. Izračunavanjem dvojnog
komplementa dobit će se broj koji je jednak po apsolutnoj vrijednosti, ali suprotnog
predznaka (dakle, pozitivan broj):
10011011 -> x
01100100 -> jedinični komplement
+ 1 dodaje se jedan kako bi se dobio dvojni komplement
= 01100101 -> -x
Dobiveni broj -x je pozitivan broj (prvi bit mu nije jedinica), stoga se lako može odrediti o
kojem se dekadskom broju radi:
1⋅26 + 1⋅25 + 0⋅24 + 0⋅23 + 1⋅22 + 0⋅21 + 1⋅20 = 10110
Ako je -x=10110, onda je x=-10110.
Konačno rješenje jest: u registru je pohranjen dekadski broj -101
5. Negativni cijeli brojevi prikazuju se tehnikom dvojnog komplementa. Nije moguće direktno
odrediti binarni prikaz broja -14, stoga se prvo određuje binarni prikaz pozitivnog broja 14
(uzastopnim dijeljenjem s 2). Voditi računa o tome da registar ima 5 bitova!
+1410 = 011102
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
Binarni broj iste apsolutne vrijednosti, ali suprotnog predznaka dobije se izračunavanjem
dvojnog komplementa
01110
10001 -> jedinični komplement
+ 1 dodaje se jedan kako bi se dobio dvojni komplement
= 10010 -> dvojni komplement
Konačno rješenje: -14 prikazan u tehnici dvojnog komplementa u registru od 5 bitova jest
10010
6. Slično kao u prethodnom zadatku. Treba voditi računa da se sada radi o 10-bitnom registru!
+1410 = 00000011102
Negativna vrijednost dobije se izračunavanjem dvojnog komplementa
0000001110
1111110001 -> jedinični komplement
+ 1 dodaje se jedan kako bi se dobio dvojni komplement
= 1111110010 -> dvojni komplement
Konačno rješenje: -14 prikazan u tehnici dvojnog komplementa u registru od 10 bitova jest
1111110010
7. a) Ako se ne koristi tehnika dvojnog komplementa, raspon brojeva koji se može prikazati u
registru od n bitova jest [0, 2n-1]. Najveći broj koji se može prikazati u 12-bitnom registru
jest 212-1 = 4095. Najmanji broj koji se može prikazati jest 0.
b) Ako se koristi tehnika dvojnog komplementa, raspon brojeva koji se može prikazati u
registru od n bitova jest [-2n-1, 2n-1-1]. Najveći broj koji se može prikazati u 12-bitnom
registru jest 211-1 = 2047. Najmanji broj koji se može prikazati jest -2048.
8. a) Ako se ne koristi tehnika dvojnog komplementa, raspon brojeva koji se može prikazati u
registru od 5 bitova jest [0, 31], a u registru od 6 bitova [0, 63]. Potreban je registar od 6
bitova.
b) Ako se koristi tehnika dvojnog komplementa, raspon brojeva koji se može prikazati u
registru od 6 bitova jest [-32, 31], a u registru od 7 bitova [-64, 63]. Potreban je registar
od 7 bitova.
9. a) 00100 -> 4
+ 00111 -> 7
= 01011 -> 11
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
b) 01100 -> 12
+ 11011 -> -5
= 00111 -> 7
c) 00111 -> 7
+ 01011 -> 11
= 10010 -> -14
U ovom slučaju rezultat nije kakav bi se očekivao jer se u registru od 5 bitova, u tehnici
dvojnog komplementa, broj 18 ne može prikazati.
d) 01100 -> 12
+ 10000 -> -16
= 11100 -> -4
Rješenje: 156
Provjera: 1⋅82 + 5⋅81 + 6⋅80
b) 11010 = 11011102
Binarne znamenke grupirati po tri. PAZITI da se grupiranje obavi "s desna na lijevo":
1 101 1102 = 1568
11. a) 94 : 16 = 5 ostatak 14
5 : 16 = 0 ostatak 5
Rješenje: 5E
Provjera: 5⋅161 + 14⋅160
b) 9410 = 10111102
Binarne znamenke grupirati po četiri. PAZITI da se grupiranje obavi "s desna na lijevo":
101 11102 = 5E16
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
Heksadekadski broj se lako pretvara u oktalni: heksadekadski broj treba napisati kao
binarni broj, zatim binarne znamenke grupirati u grupe po tri. PAZITI da se grupiranje obavi
"s desna na lijevo":
F 2 C16 = 1111 0010 11002 = 111 100 101 1002 = 74548
4 E16 = 0100 11102 = 01 001 1102 = 1168
13. Oktalni broj se lako pretvara u heksadekadski: oktalni broj treba napisati kao binarni broj,
zatim binarne znamenke grupirati u grupe po četiri. PAZITI da se grupiranje obavi "s desna
na lijevo":
7 6 4 3 18 = 111 110 100 011 0012 = 111 1101 0001 10012 = 7D1916
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 67
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
5. vježbe uz predavanja
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 67
11. Napisati sadržaje registara u kojima je, prema IEEE 754 standardu za prikaz brojeva u
jednostrukoj preciznosti, pohranjen sadržaj varijabli x i y nakon obavljanja sljedećih naredbi:
float x, y;
x = 0.f;
y = -3.75f / x;
12. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u
jednostrukoj preciznosti, pohranjen sadržaj varijable x nakon obavljanja sljedećih naredbi:
float x;
x = 0.f;
x = x / x;
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 67
Rješenja
1. Pri rješavanju ovakvih zadataka treba se sjetiti koji se najveći/najmanji brojevi mogu prikazati
u varijablama određenih tipova podataka.
2. Prvi bit za predznak se postavlja na P=1. Time je pitanje predznaka riješeno (upamtiti: u
IEEE 754 formatu se ne koristi ništa što podsjeća na tehniku dvojnog komplementa!)
Sada treba odrediti karakteristiku i mantisu. Prvo pretvoriti broj u binarni oblik:
17.7812510 = 10001.110012
Normalizirati:
10001.110012 = 1.000111001 ⋅ 24
BE = 410 ⇒ K = 4 + 127 = 13110 = 100000112
M = 1.000111001
U 32-bitni registar prepisati P, K, te M (ali BEZ SKRIVENOG BITA!):
1 10000011 00011100100000000000000
Grupirati po tri znamenke s desna na lijevo
11 000 001 100 011 100 100 000 000 000 0002 = 301434400008
Grupirati po četiri znamenke s desna na lijevo
1100 0001 1000 1110 0100 0000 0000 00002 = C18E400016
3. Varijable tipa float pohranjuju se prema IEEE 754 formatu jednostruke preciznosti
C2 B0 00 0016 = 1100 0010 1011 0000 0000 0000 0000 00002
Odrediti predznak: P = 1, stoga je broj negativan.
Odrediti binarni eksponent:
K = 100001012 = 13310 ⇒ BE = 133 - 127 = 6
M = 1.011000000000000000000002
Rezultat se dobije množenjem mantise s 2BE
1.011000000000000000000002 ⋅ 26 = 1011000.02 = 88.010
Ne zaboraviti negativni predznak (jer P=1)
Konačni rezultat: -88.0
4. 128.12510
5. -12.62510
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 67
6. K = 255, u mantisi su svi bitovi postavljeni na nulu. Radi se o prikazu beskonačnosti. Budući
da je predznak P=1, konačno rješenje jest: -∞.
7. K = 255, a u mantisi postoji jedan ili više bitova koji su postavljeni na jedinicu. U registru je
prikazana vrijednost NaN (Not a Number).
10. 80 00 00 0116 = 1000 0000 0000 0000 0000 0000 0000 0001
12. Rezultat operacije je NaN. Rješenje jest (jedno od mogućih, jer na predavanjima nismo
specificirali koje vrijednosti trebaju imati bitovi u mantisi kad se prikazuje NaN): 7F C0 00
0016
13. Ispravnost vlastitog rješenja provjeriti izvođenjem programskog odsječka na računalu.
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 102
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
6. vježbe uz predavanja
1. Odredite najveću moguću relativnu i najveću moguću apsolutnu pogrešku koja se može
očekivati pri pohrani broja 2⋅1022 u IEEE 754 formatu jednostruke preciznosti.
4. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u
dvostrukoj preciznosti pohranjen broj -0.2510. Sadržaj registra napisati u heksadekadskom
obliku.
5. U registru od 64 bita upisan je broj C0 3D 80 00 00 00 00 0016. Napisati koji je broj
predstavljen u tom registru, ako registar služi za pohranu varijable double x. Rezultat
napisati u dekadskom brojevnom sustavu.
6. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u
dvostrukoj preciznosti pohranjen broj -∞. Sadržaj registra napisati u heksadekadskom
obliku.
7. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u
dvostrukoj preciznosti pohranjena vrijednost NaN. Sadržaj registra napisati u
heksadekadskom obliku.
8. Odredite najveću moguću relativnu i najveću moguću apsolutnu pogrešku koja se može
očekivati pri pohrani broja 2⋅1022 u IEEE 754 formatu dvostruke preciznosti.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 102
Rješenja
1. Najveća moguće relativna pogreška ovisi isključivo o broju bitova mantise m. Vodite računa
o tome da parametar m uključuje i skriveni bit. Kod prikaza prema IEEE 754 standardu
jednostruke preciznosti m = 24.
Najveća moguća relativna pogreška iznosi 2-24 ≈ 6 ⋅ 10-8
Najveća moguća apsolutna pogreška ovisi o parametru m i konkretnom broju x koji se
prikazuje:
Najveća moguća apsolutna pogreška iznosi x ⋅ 2-24 ≈ 2 ⋅ 1022 ⋅ 6 ⋅ 10-8 = 1.2 ⋅
1015
4. BFD0000000000000
5. -29.5
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 102
6. FFF0000000000000
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 132
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
7. vježbe uz predavanja
1. Napisati C program koji će s tipkovnice učitati cijeli broj x, a zatim na zaslon ispisati tekst
Istina je ako je učitani broj u intervalu [1, 9] ili je u intervalu [80, 90].
2. Napisati C program koji će s tipkovnice učitati cijeli broj m, a zatim na zaslon ispisati tekst
Istina je ako je učitani broj neparan pozitivan broj.
3. Napisati C program koji će na zaslon ispisati tekst Istina je ako uvjet iz 1. zadatka
nije zadovoljen (napisati jedno rješenje uz korištenje operatora negacije i jedno rješenje
bez korištenja operatora negacije).
4. Napisati C program koji će na zaslon ispisati tekst Istina je ako uvjet iz 2. zadatka
nije zadovoljen (napisati jedno rješenje uz korištenje operatora negacije i jedno rješenje
bez korištenja operatora negacije).
5. Napisati C program koji će s tipkovnice učitati dva znaka u varijable c1 i c2 tipa char.
Ako su oba učitana znaka velika slova abecede (A-Z) i pri tome su oba znaka
samoglasnici, ispisati tekst Ucitani znakovi su "veliki" samoglasnici
(primijetite da unutar teksta treba dva puta ispisati i dvostruke navodnike).
6. Ispisati tekst Barem jedan od znakova nije veliki samoglasnik ako uvjet iz
5. zadatka nije zadovoljen (napisati jedno rješenje uz korištenja operatora negacije i
jedno rješenje bez korištenja operatora negacije).
7. Napisati C program koji će s tipkovnice učitati znak. Ako je učitani znak malo slovo
abecede ili znamenka, ispisati tekst Istina je.
8. Napisati C program koji će s tipkovnice učitati dva znaka. Ako oba učitana znaka
predstavljaju heksadekadske znamenke, ispisati poruku Upisan je ispravan
dvoznamenkasti heksadekadski broj.
9. Što je rezultat evaluacije svakog od sljedećih izraza (treba odrediti tip podatka i
vrijednost):
12 / 2*3
15 / 2*3
15. / 2*3
15.f / 2*3
15.f / 2*3.
15 / 2*3.
12 / (2*3)
2 * 2+3
2 * 5%2
2 * (5%2)
(float)15/2/3
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 132
(float)(15/2/3)
(float)(15/2)/3
(float)((15/2)/3)
3.5f * (double)4 + 3 * 5/(double)2
10. Što će biti sadržaj svake od definiranih varijabli nakon obavljanja sljedećeg
programskog odsječka (za varijable tipa char treba navesti njihovu numeričku
vrijednost):
char c1, c2;
float f1, f2;
double f3, f4;
c1 = 132.f - (double)2;
f1 = -2147483648.0;
f2 = -2147483645.0;
f3 = -2147483645.0;
f4 = -2147483645.0f;
c2 = 126;
int i;
i = !0 <= 101 % 100;
printf ("%d\n", i);
i = !1 && !200 || !0 && !100;
printf ("%d\n", i);
i = (!1 && !0 || 100) + 'a' - 'A';
printf ("%d\n", i);
i = 'a' - 'A' + 18;
printf ("%c %d\n", i, i);
i = 10;
printf ("%d\n", i==15);
printf ("%d\n", i);
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 132
Rješenja
1. #include <stdio.h>
int main (void) {
int x;
scanf("%d", &x);
if (x >= 1 && x <= 9 || x >= 80 && x <= 90) {
printf("Istina je");
}
return 0;
}
2. #include <stdio.h>
int main (void) {
int m;
scanf("%d", &m);
if (m > 0 && m % 2 != 0) {
printf("Istina je");
}
return 0;
}
ili
if ((x < 1 || x > 9) && (x < 80 || x > 90)) {
ili
if (m <= 0 || m % 2 == 0) {
5. #include <stdio.h>
int main (void) {
char c1, c2;
scanf("%c%c", &c1, &c2);
if ((c1 == 'A' ||
c1 == 'E' ||
c1 == 'I' ||
c1 == 'O' ||
c1 == 'U')
&&
(c2 == 'A' ||
c2 == 'E' ||
c2 == 'I' ||
c2 == 'O' ||
c2 == 'U')) {
printf("Ucitani znakovi su \"veliki\" samoglasnici");
}
return 0;
}
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 132
6. if (!((c1 == 'A' ||
c1 == 'E' ||
c1 == 'I' ||
c1 == 'O' ||
c1 == 'U')
&&
(c2 == 'A' ||
c2 == 'E' ||
c2 == 'I' ||
c2 == 'O' ||
c2 == 'U'))) {
ili
if ( c1 != 'A' &&
c1 != 'E' &&
c1 != 'I' &&
c1 != 'O' &&
c1 != 'U'
||
c2 != 'A' &&
c2 != 'E' &&
c2 != 'I' &&
c2 != 'O' &&
c2 != 'U') {
7. #include <stdio.h>
int main (void) {
char c;
scanf("%c", &c);
if (c >= 'a' && c <= 'z' || c >= '0' && c <= '9') {
printf("Istina je");
}
return 0;
}
8. #include <stdio.h>
int main (void) {
char c1, c2;
scanf("%c%c", &c1, &c2);
if ((c1 >= 'a' && c1 <= 'f' ||
c1 >= 'A' && c1 <= 'F' ||
c1 >= '0' && c1 <= '9')
&&
(c2 >= 'a' && c2 <= 'f' ||
c2 >= 'A' && c2 <= 'F' ||
c2 >= '0' && c2 <= '9')) {
printf("Upisan je ispravan dvoznamenkasti heksadekadski broj");
}
return 0;
}
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 132
9. 12 / 2*3
-> 18, int
15 / 2*3
-> 21, int
15. / 2*3
-> 22.5, double
15.f / 2*3
-> 22.5, float
15.f / 2*3.
-> 22.5, double
15 / 2*3.
-> 21.0, double
12 / (2*3)
-> 2, int
2 * 2+3
-> 7, int
2 * 5%2
-> 0, int
2 * (5%2)
-> 2, int
(float)15/2/3
-> 2.5, float
(float)(15/2/3)
-> 2.0, float
(float)(15/2)/3
-> 2.333333, float
(float)((15/2)/3)
-> 2.0, float
10. c1 = -126
c2 = 126
f1 = -2147483648.000000
f2 = -2147483648.000000
f3 = -2147483645.000000
f4 = -2147483648.000000
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
8. vježbe uz predavanja
1. Što će se ispisati sljedećim odsječkom programa:
char c, c1;
c = 'a' / 2*1.1;
printf("%d\n", c);
c1 = 1 + c++;
printf("%d %d\n", c, c1);
c1 = ++c + 12;
printf("%d %c %d %c\n", c, c, c1, c1);
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 04-OstaliOperatori.pdf - do stranice: 37
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 04-OstaliOperatori.pdf - do stranice: 37
Rješenja
6.
Prvo se izračunava y <= x → 0
Budući je rezultat "laž", izraz ( ++x ) se uopće ne izračunava!
Izračunava se samo ( y+= ++x ), a zatim se rezultat tog izraza pridružuje varijabli z.
Zbog prefiksnog oblika ++ operatora, varijabla x se prvo uvećava za 1, a zatim se njena
vrijednost dalje koristi u izrazu. Uvećana vrijednost varijable x je 3. y += 3 je isto što i y
= y + 3
Konačno, x = 3, y = '4' (odnosno 52), z = '4' (odnosno 52)
Ispisat će se: 3 4 52 4
7.
Prvo se izračunava (b+=c) → b=14, rezultat cijelog izraza (b+=c) je 14
d = a + 14, tj. d = 17
Ispisat će se:
3 14 9 17
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
9. vježbe uz predavanja
1. S tipkovnice u char varijablu c učitajte jedan znak. Ako je učitano veliko slovo,
ispisati poruku "To je veliko slovo". Ako je učitano malo slovo, ispisati poruku "To je
malo slovo". Ako je učitana znamenka (0-9), ispisati poruku "To je znamenka". Ako
nije učitano ni slovo ni znamenka, ispisati poruku "To je neki drugi znak".
2. S tipkovnice u char varijablu z1 učitajte znak. Ako učitani znak nije heksadekadska
znamenka (0-9, A-F, a-f), ispisati poruku "Nije dobra znamenka" i završiti program.
Inače, ispisati dekadski ekvivalent učitane heksadekadske znamenke. Npr. ako je
učitan znak e, treba ispisati 14.
1 1 1 1 1 1
- + - + ... + -
1 2 3 4 999 1000
4. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. S tipkovnice učitavati i
sumirati cijele brojeve dok god su oni djeljivi s 3 ili 7. Na kraju ispisati sumu učitanih
brojeva. Podrazumijeva se da se zadnji broj koji je učitan (onaj zbog kojeg se prekida
učitavanje) ne dodaje u sumu. Vodite računa o tome da već i prvi učitani broj može
biti "neispravan".
6. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. S tipkovnice učitati cijeli broj
n koji mora biti između 0 i 16 (uključivo s granicama). Ako broj nije ispravan, ispisati
odgovarajuću poruku. Ako je broj ispravno upisan, učitati n binarnih znamenki i
ispisati dekadski ekvivalent učitanog binarnog broja (ne primjenjuje se tehnika
dvojnog komplementa, pa je dekadski ekvivalent sigurno pozitivan broj).
9. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. Isto kao prethodni zadatak,
ali za učitani dekadski broj treba ispisati oktalni broj.
10. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. U varijablu tipa int s
tipkovnice učitati nenegativni cijeli broj (ne treba kontrola je li broj nenegativan). Na
zaslon ispisati binarni sadržaj registra te varijable (binarne znamenke se moraju
ispisati ispravnim redoslijedom). Za izdvajanje bitova koristiti bitovni operator & i
operator za posmak bitova prema desno. Može se pretpostaviti da se za pohranu
int tipa podatka koristi 32 bita.
Uputa:
11. Riješiti pomoću petlje s ispitivanjem uvjeta na kraju (do-while). Usporediti s rješenjem
u kojem se koristila petlja s ispitivanjem uvjeta na početku. Izračunati i na zaslon
ispisati sumu:
1 1 1 1 1 1
- + - + ... + -
1 2 3 4 999 1000
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
12. Riješiti pomoću petlje s ispitivanjem uvjeta na kraju (do-while). Usporediti s rješenjem
u kojem se koristila petlja s ispitivanjem uvjeta na početku. S tipkovnice učitavati i
sumirati cijele brojeve dok god su oni djeljivi s 3 ili 7. Na kraju ispisati sumu učitanih
brojeva. Podrazumijeva se da se zadnji broj koji je učitan (onaj zbog kojeg se prekida
učitavanje) ne dodaje u sumu. Vodite računa o tome da već i prvi učitani broj može
biti "neispravan".
13. Riješiti pomoću petlje s ispitivanjem uvjeta na kraju (do-while). Usporediti s rješenjem
u kojem se koristila petlja s ispitivanjem uvjeta na početku. S tipkovnice učitavati i
sumirati cijele brojeve dok god su oni djeljivi s 3 ili 7. Na kraju ispisati sumu učitanih
brojeva. Podrazumijeva se da se zadnji broj koji je učitan (onaj zbog kojeg se prekida
učitavanje) također dodaje u sumu. Vodite računa o tome da već i prvi učitani broj
može biti "neispravan".
14. Napisati dva rješenja. Jedno rješenje pomoću petlje s ispitivanjem uvjeta na početku
i jedno rješenje pomoću petlje s ispitivanjem uvjeta na kraju. Usporediti rješenja. S
tipkovnice učitati nenegativan cijeli broj N (N može biti nula!). Na zaslon ispisati N
kvocijenata (može biti niti jedan) u obliku realnih brojeva ukupne širine 7 znakova, s
pet decimala iza decimalne točke):
1 2 3 N
...
2 3 4 N+1
15. S tipkovnice učitavati cijele brojeve dok god ne bude upisan broj manji ili jednak nuli.
Na zaslon ispisati sumu učitanih pozitivnih brojeva podijeljenu s najvećim do tada
učitanim pozitivnim brojem i pomnoženu s najmanjim do tada učitanim pozitivnim
brojem. Ako nije upisan niti jedan pozitivni broj, ispisati odgovarajuću poruku.
Primjer: ako korisnik utipka brojeve 2 5 3 2 2 -22, program treba ispisati
5.600000
16. Napišite program koji s tipkovnice učitava dva znaka te ispisuje sve znakove ASCII
tablice koji se nalaze između ta dva znaka. Npr., ako se učitaju znakovi d i k,
program ispisuje defghijk.
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
A. a b c d e f .F
B. b c d e f g .G
C. c d e f g h .H
D. d e f g h i .I
... itd.
S. s t u v w x .X
T. t u v w x y .Y
U. u v w x y z .Z
printf("A. a b c d e f .F\n");
printf("B. b c d e f g .G\n");
printf("C. c d e f g h .H\n");
printf("D. d e f g h i .I\n");
... itd.
18. Načinite program kojim će se učitati član niza a1 koji mora biti cijeli broj veći od 1.
Nije potrebno provjeravati ispravnost unesenog broja. Ispisati članove niza a1, a2, a3,
..., an i ukupan broj članova niza. Član niza ai (za i > 1) izračunava se na sljedeći
način:
ako je ai-1 paran, tada je ai = ai-1 / 2
ako je ai-1 neparan, tada je ai = 3 ai-1 + 1
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Rješenja
1. #include <stdio.h>
return 0;
}
#include <stdio.h>
return 0;
}
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
2. #include <stdio.h>
3. #include <stdio.h>
int main (void) {
int i;
float suma, brojnik;
i = 1;
suma = 0.f;
while (i <= 1000) {
brojnik = i % 2 ? 1.f : -1.f;
suma += brojnik / i;
++i;
}
printf("Suma je: %f\n", suma);
return 0;
}
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
4. #include <stdio.h>
int main (void) {
int suma = 0, x;
scanf("%d", &x);
while (x % 3 == 0 || x % 7 == 0) {
suma += x;
scanf("%d", &x);
}
printf("Suma ucitanih brojeva je %d\n", suma);
return 0;
}
5. #include <stdio.h>
int main (void) {
int suma = 0, x;
scanf("%d", &x);
suma += x;
while (x % 3 == 0 || x % 7 == 0) {
scanf("%d", &x);
suma += x;
}
printf("Suma ucitanih brojeva je %d\n", suma);
return 0;
}
6. #include <stdio.h>
int main (void) {
int n, znamenka, dekadski = 0;
scanf("%d", &n);
if (n < 0 || n > 16) {
printf("Upisali ste neispravan broj\n");
}
else {
while (n > 0) {
scanf("%d", &znamenka);
dekadski = dekadski*2 + znamenka;
--n;
}
printf("%d\n", dekadski);
}
return 0;
}
7. #include <stdio.h>
int main (void) {
int n, fakt = 1;
scanf("%d", &n);
if (n < 0) {
printf("Upisali ste neispravan broj\n");
}
else {
while (n > 1) {
fakt *= n;
--n;
}
printf("%d\n", fakt);
}
return 0;
}
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
8. #include <stdio.h>
int main (void) {
int n, ostatak;
scanf("%d", &n);
if (n == 0) {
printf("0\n");
}
else {
while (n > 0) {
ostatak = n % 16;
if (ostatak < 10)
printf("%d", ostatak);
else
printf("%c", 'A' + ostatak - 10);
n = n / 16;
}
}
return 0;
}
9. #include <stdio.h>
int main (void) {
int n, ostatak;
scanf("%d", &n);
if (n == 0)
printf("0\n");
else
while (n > 0) {
ostatak = n % 8;
printf("%d", ostatak);
n = n / 8;
}
return 0;
}
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Tijelo petlje će se sigurno izvršiti točno tisuću puta. Jednako je prikladno koristiti obje vrste petlji.
Napomena: u ovom zadatku bi najprikladnija vrsta petlje bila petlja s poznatim brojem ponavljanja,
koja za sada još nije obrađena na predavanjima i zato se ne koristi u rješenju.
Jedan dio tijela petlje se mora izvršiti barem jednom (scanf), a drugi dio tijela petlje (sumiranje) se
možda neće trebati izvršiti niti jednom. Jednako je (ne)prikladno koristiti obje vrste petlji.
9
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Cijelo tijelo petlje se mora izvršiti barem jednom. U ovom zadatku očito je prikladnije koristiti petlju s
ispitivanjem uvjeta na kraju.
#include <stdio.h>
int main (void) {
int n, i = 1;
scanf("%d", &n);
do {
if (i <= n) {
printf("%7.5f\n", (float)i/(i+1));
++i;
}
} while (i <= n);
return 0;
}
Moguće je da tijelo petlje neće trebati izvršiti niti jednom. U ovom zadatku očito je prikladnije koristiti
petlju s ispitivanjem uvjeta na početku.
Napomena: u ovom zadatku bi najprikladnija vrsta petlje bila petlja s poznatim brojem ponavljanja,
koja za sada još nije obrađena na predavanjima i zato se ne koristi u rješenju.
10
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
11
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 61
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
Potrebno je uočiti da za računanje člana niza fi, treba poznavati članove niza fi-1 i fi-2. U
svakom koraku petlje u kojem se računa član niza fi, iskoristit će se članovi fi-1 i fi-2, a
zatim će se pripremiti "nove" vrijednosti za fi-1 i fi-2, tako što će se stari član fi-1 zapisati u
član fi-2, a netom izračunati član fi zapisati u član fi-1.
U programu se član fi čuva u varijabli f, član fi-1 u varijabli f1, a član fi-2 u varijabli f0.
Naredbom za selekciju osigurava se da se članovi počinju izračunavati prema opisanom
principu tek nakon što se obavi ispis članova niza f0 i f1.
Djelovanje programa može se lakše shvatiti ako se ispiše tablica koja pokazuje kako se
varijable mijenjaju u pojedinim koracima petlje. Prikazan je primjer za učitanu vrijednost
n==5:
f0 f1 f
i nakon koraka nakon koraka nakon koraka Ispis u koraku petlje
petlje petlje petlje
0 1 1 1 Fibonnaci (0) = 1
1 1 1 1 Fibonnaci (1) = 1
2 1 2 2 Fibonnaci (2) = 2
3 2 3 3 Fibonnaci (3) = 3
4 3 5 5 Fibonnaci (4) = 5
5 5 8 8 Fibonnaci (5) = 8
2. U varijablu tipa unsigned nt učitati nenegativni cijeli broj. Na zaslon ispisati binarni
sadržaj registra te varijable (binarne znamenke se moraju ispisati ispravnim
redoslijedom). Za izdvajanje bitova koristiti operaciju broj & 2n, pri čemu se n
mijenja od 31 do 0 (može se pretpostaviti da se za pohranu int tipa podatka koristi
32 bita). Uputa: vrijednost tipa podatka unsigned treba se učitati po formatu %u
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 61
3. S tipkovnice učitati cijeli broj n koji mora biti između 0 i 16 (uključivo s granicama).
Ako broj nije ispravan, ispisati odgovarajuću poruku. Nakon toga učitati n binarnih
znamenki i ispisati dekadski ekvivalent učitanog binarnog broja (ne primjenjuje se
tehnika dvojnog komplementa, pa je dekadski ekvivalent sigurno pozitivan broj).
4. Isto kao prethodni zadatak, ali riješiti pomoću petlje s ispitivanjem uvjeta na kraju.
Zašto takva vrsta petlje nije pogodna za rješavanje ovog zadatka?
5. Načinite program koji će s tipkovnice učitati nenegativni cijeli broj iz intervala [0,
4294967295]. Učitani broj treba ispisati u oktalnom obliku. Npr. za učitani broj 250
treba ispisati 00000000372; za učitani broj 4294967295 treba ispisati 37777777777.
Zadatak riješite tako da grupe od po tri bita pretvarate u oktalne znamenke. Za
određivanje grupa po tri bita koristite operator posmaka u desno (za tri mjesta) i
bitovni operator &. Uputa: vrijednost tipa podatka unsigned treba se učitati po
formatu %u.
6. Isto kao prethodni zadatak, ali učitani dekadski broj treba pretvoriti u heksadekadski.
7. Napišite program koji učitava dva znaka te ispisuje sve znakove ASCII tablice koji se
nalaze između ta dva znaka. Npr., ako se učitaju znakovi d i k, program ispisuje
defghijk.
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 61
printf("A. a b c d e f .F\n");
printf("B. b c d e f g .G\n");
printf("C. c d e f g h .H\n");
printf("D. d e f g h i .I\n");
... itd.
m! / ( n! · (m - n)! )
11. Ispišite sve pitagorine trojke čiji su članovi veći od 0 i manji ili jednaki 100. Ispis treba
izgledati ovako (objašnjenje: oznaka 3^2 u sljedećem ispisu ima značenje 32):
Uputa: zadatak možete riješiti tako da pomoću tri ugniježđene petlje testirate svaku
kombinaciju 3 cijela broja: 1 1 1; 1 1 2; 1 1 3; ... 1 1 99; 1 1 100; 1 2 1; 1 2 2; ...; 1 2
100; 1 3 1; ... Ispišite samo one kombinacije 3 cijela broja koji zadovoljavaju "uvjet
pitagorine trojke".
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 61
Rješenja
Rješenje 2. zadatka
#include <stdio.h>
#include <math.h>
int main (void) {
unsigned int broj, dva_na_ntu;
int n;
scanf("%u", &broj);
printf("Upisali ste broj %u\n", broj);
for (n = 31; n >= 0; --n) {
dva_na_ntu = (unsigned int)pow(2, n);
/* ako u (broj & dva_na_ntu) postoji bit razlicit od 0,
tada ce (broj & dva_na_ntu) biti razlicit od 0, tj. true */
printf("%d", broj & dva_na_ntu ? 1 : 0);
}
printf("\n");
return 0;
}
Petlja s poznatim brojem ponavljanja je najpogodnija za ovaj slučaj jer je u trenutku kad
petlja započinje poznato koliko puta se tijelo te petlje treba obaviti.
Rješenje 3. zadatka
#include <stdio.h>
int main (void) {
int n, i, znamenka, dekadski = 0;
scanf("%d", &n);
if (n < 0 || n > 16) {
printf("Upisali ste neispravan broj\n");
}
else {
for (i = 0; i < n; ++i) {
scanf("%d", &znamenka);
dekadski = dekadski*2 + znamenka;
}
printf("%d\n", dekadski);
}
return 0;
}
Petlja s poznatim brojem ponavljanja je najpogodnija za ovaj slučaj jer je u trenutku kad
petlja započinje poznato koliko puta se tijelo te petlje treba obaviti (uočite, to može biti i
"nula puta", npr. ako u ovom slučaju korisnik za vrijednost varijable n upiše nulu).
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 61
Rješenje 4. zadatka
#include <stdio.h>
int main (void) {
int n, znamenka, dekadski = 0;
scanf("%d", &n);
if (n < 0 || n > 16) {
printf("Upisali ste neispravan broj\n");
}
else {
if (n > 0) {
do {
scanf("%d", &znamenka);
dekadski = dekadski*2 + znamenka;
--n;
} while (n > 0);
}
printf("%d\n", dekadski);
}
return 0;
}
Petlja s ispitivanjem uvjeta na kraju nije pogodna za rješavanje ovog zadatka, jer je moguće da tijelo petlje
neće biti potrebno obaviti niti jednom (onda kada se za vrijednost varijable n učita 0). Zato je if naredbom
potrebno provjeriti treba li uopće započeti s obavljanjem petlje.
Rješenje 5. zadatka
#include <stdio.h>
int main(void) {
unsigned int a;
int i;
printf("Upisite nenegativni cijeli broj a: ");
scanf ("%u", &a); /* za unsigned se kod citanja koristi %u umjesto %d */
for (i = 10; i >= 0; --i) {
printf("%d", a >> 3*i & 0x7);
}
printf ("\n");
return 0;
}
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 61
Rješenje 6. zadatka
#include <stdio.h>
int main(void) {
unsigned int a;
int i, broj;
printf("Upisite nenegativni cijeli broj a: ");
scanf ("%u", &a);
for (i = 7; i >= 0; --i) {
broj = a >> 4*i & 0xF;
if (broj <= 9) {
printf("%d", broj);
/* ili printf("%c", broj + '0'); */
}
else {
printf("%c", broj - 10 + 'A');
}
}
printf ("\n");
return 0;
}
Rješenje 7. zadatka
#include <stdio.h>
int main(void) {
char c1, c2;
char i;
scanf("%c %c", &c1, &c2);
for (i = c1; i <= c2; ++i) Komentirajte: što će se dogoditi
printf("%c", i);
printf("\n"); ako se učitaju znakovi k i d
return 0;
}
Rješenje 8. zadatka
#include <stdio.h>
int main(void) {
char i, j;
for (i = 'A'; i <= 'U'; ++i) {
printf("%c. ", i);
for (j = i + 32; j < i + 32 + 6; ++j) {
printf("%c ", j);
}
printf(".%c\n", i + 5);
}
return 0;
}
Vanjska petlja mijenja vrijednost varijable i od 'A' do 'U'. Na početku svakog retka se ispisuje vrijednost varijable i
(naravno, u formatu %c), a na kraju retka ispisuje se slovo koje se u ASCII tablici nalazi "5 mjesta dalje" od slova koje se
ispisalo na početku retka.
Unutarnja petlja mijenja vrijednost varijable j od "male verzije" slova koje je ispisano na početku retka, do slova koje se u
ASCII tablici nalazi "6 mjesta dalje" od početnog malog slova.
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 61
Rješenje 9. zadatka
#include <stdio.h>
int main(void) {
char i, j;
for (i = 'A'; i <= 'U'; ++i) {
printf("%c. ", i);
for (j = i + 32; j < i + 32 + 6; ++j) {
printf("%c ", j=='a' || j=='e' || j=='i' || j=='o' || j=='u' ? '?' : j);
}
printf(".%c\n", i + 5);
}
return 0;
}
ili
for (j = i + 32; j < i + 32 + 6; ++j) {
if (j=='a' || j=='e' || j=='i' || j=='o' || j=='u')
printf("? ");
else
printf("%c ", j);
}
int main(void) {
int m, n, i;
double brojnik, naziv1, naziv2, mpovrhn;
/* unos vrijednosti za m i n */
printf ("Unesite m i n:");
scanf ("%d %d", &m, &n);
if (m < 0 || n < 0 || m < n)
printf("brojevi su neispravno zadani\n");
else {
brojnik = 1;
for (i = 1; i <= m; ++i)
brojnik *= i;
naziv1 = 1;
for (i = 1; i <= n; ++i)
naziv1 *= i;
naziv2 = 1;
for (i = 1; i <= m-n; ++i)
naziv2 *= i;
mpovrhn = brojnik/(naziv1*naziv2);
printf("%d povrh %d iznosi = %g\n", m, n, mpovrhn);
}
return 0;
}
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 61
int main(void) {
int i, j, k;
int n = 0;
for (i=1; i <= 100; ++i)
for (j=1; j <= 100; ++j)
for (k=1; k <= 100; ++k)
if (i*i + j*j == k*k) {
++n;
printf("%d. trojka: %d^2 + %d^2 = %d^2\n", n, i, j, k);
}
return 0;
}
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 89
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
2. Korisnik uzastopno upisuje cijele brojeve u intervalu [1, 9]. Za svaki učitani broj
ispisati broj riječima. Zanemariti brojeve koji su izvan dopuštenog intervala.
Učitavanje prekinuti kada se upiše broj nula. Naputak: za određivanje "naziva" broja
koristiti naredbu switch. Npr.
3
tri
7
sedam
77
zanemarujem
1
jedan
0
3. Korisnik uzastopno upisuje cijele brojeve u intervalu [1, 9]. Za svaki učitani broj
ispisati od kojih je sve brojeva iz tog intervala učitani broj manji. Zanemariti učitane
brojeve koji su izvan dopuštenog intervala. Učitavanje prekinuti kada se upiše broj
nula. Naputak: koristiti naredbu switch s "propadanjem po labelama". Npr.
3
manji je od 4
manji je od 5
manji je od 6
manji je od 7
manji je od 8
manji je od 9
77
zanemarujem
9
8
manji je od 9
0
4. Napišite program koji će ispisati prvih 25 prostih brojeva (uzimajući u obzir definiciju
prema kojoj broj 1 nije primarni broj).
5. Napišite program koji će ispisati sve proste brojeve iz intervala [1000, 10000].
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 89
6. S tipkovnice učitavati cijele brojeve dok god se naizmjence upisuje jedan pozitivan,
jedan negativan, jedan pozitivan broj, itd. Upisivanje pozitivnog broja nakon
pozitivnog ili upisivanje negativnog broja nakon negativnog ili upisivanje nule smatra
se pogreškom. U slučaju takve pogreške program ispisuje sumu svih do tada
ispravno upisanih brojeva (upisanih prije pogreške) i prekida se njegovo izvršavanje.
Prvi broj koji se upiše s tipkovnice može biti ili pozitivan ili negativan.
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 89
Rješenja
Rješenje 1. zadatka
#include <stdio.h>
int main(void) {
int x;
do {
printf ("Upisite broj :\n");
scanf("%d", &x);
if (x > 100)
printf("Zanemarujem vrijednost\n");
else if (x >= 0)
printf ("Upisani broj je : %d\n", x);
else
printf("Nedopustena vrijednost\n");
} while (x > 0);
return 0;
}
Rješenje 2. zadatka
#include <stdio.h>
int main(void) {
int broj;
do {
scanf("%d", &broj);
if (broj != 0)
switch (broj) {
case 1: printf("jedan\n");
break;
case 2: printf("dva\n");
break;
case 3: printf("tri\n");
break;
case 4: printf("cetiri\n");
break;
case 5: printf("pet\n");
break;
case 6: printf("sest\n");
break;
case 7: printf("sedam\n");
break;
case 8: printf("osam\n");
break;
case 9: printf("devet\n");
break;
default: printf("Zanemarujem\n");
break;
}
} while (broj != 0);
return 0;
}
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 89
Rješenje 3. zadatka
#include <stdio.h>
int main(void) {
int broj;
do {
scanf("%d", &broj);
if (broj != 0)
switch (broj) {
case 1: printf("manji je od 2\n");
case 2: printf("manji je od 3\n");
case 3: printf("manji je od 4\n");
case 4: printf("manji je od 5\n");
case 5: printf("manji je od 6\n");
case 6: printf("manji je od 7\n");
case 7: printf("manji je od 8\n");
case 8: printf("manji je od 9\n");
case 9: break;
default: printf("Zanemarujem\n");
break;
}
} while (broj != 0);
return 0;
}
Rješenje 4. zadatka
#include <stdio.h>
#include <math.h>
ili
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 89
#include <stdio.h>
#include <math.h>
Rješenje 5. zadatka
#include <stdio.h>
#include <math.h>
Rješenje 6. zadatka
#include <stdio.h>
int main(void) {
int suma = 0;
int gotovo = 0;
int prethodni = 0, novi;
do {
scanf("%d", &novi);
if (prethodni == 0 && novi != 0 || prethodni * novi < 0) {
suma += novi;
prethodni = novi;
}
else {
gotovo = 1;
}
} while (!gotovo);
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 89
Rješenje 7. zadatka
#include <stdio.h>
int main(void) {
int n, i = 1;
double f;
scanf("%d", &n);
f = 1.;
opet:
f *= i;
++i;
if (i <= n) goto opet;
printf("%d! = %f\n", n, f);
return 0;
}
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
x x x x x
x x x x x
x x x x x
x x x x x
x x x x x
x x x x x
x x x x x
x x x x x
3. Korisnik odabire dimenzije matrice koju želi učitati (brRed, brStup). Broj redaka koje
korisnik može učitati ne smije biti manji od 1 niti veći od 20, a broj stupaca ne smije
biti manji od 1 niti veći od 10. U matricu treba učitati vrijednosti elemenata i ispisati
matricu. Nakon toga treba retke matrice posmaknuti prema gore: redak i dobiva
vrijednosti iz retka i+1, a posljednji redak matrice dobiva vrijednosti 0-tog retka. Npr.
ako je korisnik učitao: brRed=4, brStup=5, te elemente matrice:
1 2 3 4 5
2 1 3 7 1
8 1 1 4 3
4 2 2 3 3
nakon posmaka redaka, matrica treba izgledati ovako:
2 1 3 7 1
8 1 1 4 3
4 2 2 3 3
1 2 3 4 5
Nakon obavljenog posmaka redaka, ispisati novu matricu. Zadatak riješite bez
upotrebe pomoćnog polja.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
4. Korisnik odabire dimenzije matrice koju želi učitati (brRed, brStup). Broj redaka koje
korisnik može učitati ne smije biti manji od 1 niti veći od 4, a broj stupaca ne smije biti
manji od 1 niti veći od 5. S tipkovnice se učitaju vrijednosti elemenata matrice. Nakon
toga u elemente u retku brRed zapisati sume stupaca, u elemente u stupcu brStup
zapisati sume redaka, a u element (brRed,brStup) sumu svih elemenata matrice.
Ispisati dobivenu matricu. Npr. ako je korisnik učitao:
brRed=4, brStup=5, te elemente matrice:
1 2 3 4 5
2 1 3 7 1
8 1 1 4 3
4 2 2 3 3
Nakon izračuna, ispis matrice izgleda ovako:
1 2 3 4 5 15
2 1 3 7 1 14
8 1 1 4 3 17
4 2 2 3 3 14
15 6 9 18 12 60
Zadatak riješite bez upotrebe pomoćnog polja.
5. S tipkovnice upisati cijeli broj n iz intervala [5, 10]. Generirati kvadratnu matricu
dimenzija n x n kojoj su svi elementi glavne i sporedne dijagonale, elementi prvog i
zadnjeg retka, te prvog i zadnjeg stupca postavljeni na vrijednost 1, a svi ostali
elementi matrice postavljeni na vrijednost 8. Generiranu matricu ispisati na zaslon.
Npr. ako korisnik preko tipkovnice za n unese broj 7, na zaslon treba ispisati:
1 1 1 1 1 1 1
1 1 8 8 8 1 1
1 8 1 8 1 8 1
1 8 8 1 8 8 1
1 8 1 8 1 8 1
1 1 8 8 8 1 1
1 1 1 1 1 1 1
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
matrica:
1 2 3 4 5
2 0 3 7 2
8 1 5 4 3
4 2 2 9 3
polje nps:
1 0 2 4 2
polje npr:
1 0 1 2
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
Rješenja
Rješenje 1. zadatka
#include <stdio.h>
#define MAXRED 4
#define MAXSTUP 3
int main(void) {
int i, j, suma = 0;
int mat[MAXRED][MAXSTUP];
for (i = 0; i < MAXRED; ++i) {
/* u i-tom retku obavi sljedece */
for (j = 0; j < MAXSTUP; ++j) {
/* u j-tom stupcu i-tog retka obavi sljedece */
printf("Upisite clan matrice [%d][%d]->", i, j);
scanf("%d", &mat[i][j]);
suma+=mat[i][j];
}
}
for (i = 0; i < MAXRED; ++i) {
for (j = 0; j < MAXSTUP; ++j) {
printf("%5d", mat[i][j]);
}
printf("\n");
}
printf("Aritm. sredina je %f\n", (float)suma/(MAXRED*MAXSTUP));
return 0;
}
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
Rješenje 2. zadatka
#include <stdio.h>
#define MAXSLOJ 3
#define MAXRED 4
#define MAXSTUP 5
int main(void) {
int i, j, k;
int tridim[MAXSLOJ][MAXRED][MAXSTUP] =
{
{ { 101, 102, 103, 104, 105},
{ 106, 107, 108, 109, 110},
{ 111, 112, 113, 114, 115},
{ 116, 117, 118, 119, 120 }
},
{ { 201, 202, 203, 204, 205},
{ 206, 207, 208, 209, 210},
{ 211, 212, 213, 214, 215},
{ 216, 217, 218, 219, 220 }
},
{ { 301, 302, 303, 304, 305},
{ 306, 307, 308, 309, 310},
{ 311, 312, 313, 314, 315},
{ 316, 317, 318, 319, 320 }
}
};
return 0;
}
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
Rješenje 3. zadatka
#include <stdio.h>
#define MAXRED 20
#define MAXSTUP 10
int main(void) {
int i, j, m, n, pom;
int mat[MAXRED][MAXSTUP];
do {
printf("Upisite m i n:");
scanf("%d %d", &m, &n);
} while (m < 1 || m > 20 || n < 1 || n > 10);
mat[m-1][j] = pom; /* u zadnji redak stavi spaseni j-ti clan iz 0-tog retka */
}
return 0;
}
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
Rješenje 4. zadatka
#include <stdio.h>
#define MAXRED 4
#define MAXSTUP 5
int main(void) {
int i, j, m, n;
int mat[MAXRED+1][MAXSTUP+1] = {0};
/* dimenzije su uvecane za 1 jer treba osigurati
prostor za dodatni redak i stupac */
do {
printf("Upisite m i n:");
scanf("%d %d", &m, &n);
} while (m < 1 || m > MAXRED || n < 1 || n > MAXSTUP);
return 0;
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
Rješenje 5. zadatka
#include <stdio.h>
#define MAXDIM 10
int main(void) {
int i, j, n;
int mat[MAXDIM][MAXDIM];
/* ucitavanje n */
do {
printf("Upisite n:");
scanf("%d", &n);
} while (n < 1 || n > MAXDIM);
/* generiranje matrice */
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
if (i == j || i == n-1-j || j == 0 || i == 0 || j == n-1 || i == n-1)
mat[i][j] = 1;
else
mat[i][j] = 8;
/* ispis matrice */
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j)
printf("%d ", mat[i][j]);
printf("\n");
}
return 0;
}
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 06-Polja.pdf - do stranice: 81
Rješenje 6. zadatka
#include <stdio.h>
#define MAXRED 6
#define MAXSTUP 10
int main(void) {
int i, j, m, n;
int mat[MAXRED][MAXSTUP];
int nps[MAXSTUP], npr[MAXRED];
do {
printf("Upisite m[3,6] i n[4,10]: ");
scanf("%d %d", &m, &n);
} while (m < 3 || m > 6 || n < 4 || n > 10);
printf("\nmatrica:\n");
for (i = 0; i < m; ++i) {
for (j = 0; j < n; ++j)
printf("%4d", mat[i][j]);
printf("\n");
}
printf("\npolje nps:\n");
for (j = 0; j < n; ++j)
printf("%4d", nps[j]);
printf("\n");
printf("\npolje npr:\n");
for (i = 0; i < m; ++i)
printf("%4d", npr[i]);
printf("\n");
return 0;
}
9
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 07-Pokazivaci.pdf - do stranice: 23
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
#include <stdio.h>
int main (void) {
int a = 2, x = 10;
int *p = &a;
x += *p * 3;
printf ("%d %d\n", *p, x);
return 0;
}
#include <stdio.h>
int main (void) {
int a = 10, b = 20, *c = &a, *d = &b;
c = &b;
d = &a;
*c = *d + 5;
*d = *c + 3;
printf ("%d %d %d %d\n", a, b, *c+1, *d+1);
return 0;
}
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 07-Pokazivaci.pdf - do stranice: 23
#include <stdio.h>
int main (void) {
int polje[4] = {3, 6, 9, 12};
int *p1, *p2, *p3;
p1 = &polje[0];
p2 = &polje[1];
p3 = &polje[3];
printf ("%d %d %d %d %d\n", *p1, *p2, *p3, *(p2 - 1), *p2 - 1);
return 0;
}
#include <stdio.h>
int main (void) {
int polje[4][2] = {3, 6, 9, 12, 15, 18, 21, 24};
int *p1, *p2, *p3;
p1 = &polje[0][0];
p2 = &polje[1][0];
p3 = &polje[3][1];
printf ("%d %d %d %d %d\n", *p1, *p2, *p3, *(p1 + 1), *p1 + 1);
return 0;
}
#include <stdio.h>
int main (void) {
int polje[3][2] = {3, 6, 9, 12, 15, 18};
int *p = polje[0];
int i1 = *p;
int i2 = (*p)++;
int i3 = *p;
int i4 = *++p;
int i5 = *p;
int i6 = *p++;
int i7 = *(p-1);
int i8 = *p;
printf ("%d %d %d %d %d %d %d %d\n", i1, i2, i3, i4, i5, i6, i7, i8);
return 0;
}
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 07-Pokazivaci.pdf - do stranice: 23
#include <stdio.h>
int main (void) {
int polje[3][2] = {1, 2, 3, 4, 5, 6};
int *p = &polje[1][1], i = 5;
printf ("%d\n", *(p + --i));
printf ("%d\n", *--p + --i);
return 0;
}
8. Izrazima zamijenite upitnike u printf naredbi kojom će se ispisati članovi glavne dijagonale
matrice x. Članovima matrice mora se pristupati preko pokazivača p:
#include <stdio.h>
int main(void) {
int x[4][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
int *p = &x[0][0];
printf("%d %d %d %d\n", ?, ?, ?, ?);
return 0;
}
9. S tipkovnice upisati cijeli broj n iz intervala [5, 10]. Generirati kvadratnu matricu dimenzija
n x n kojoj su svi elementi glavne i sporedne dijagonale, elementi prvog i zadnjeg retka, te
prvog i zadnjeg stupca postavljeni na vrijednost 1, a svi ostali elementi matrice postavljeni na
vrijednost 8. Generiranu matricu ispisati na zaslon. Elementima matrice pristupati
isključivo pomoću pokazivača. Npr. ako korisnik preko tipkovnice za n unese broj 7, na
zaslon treba ispisati:
1 1 1 1 1 1 1
1 1 8 8 8 1 1
1 8 1 8 1 8 1
1 8 8 1 8 8 1
1 8 1 8 1 8 1
1 1 8 8 8 1 1
1 1 1 1 1 1 1
Ovaj zadatak se od zadatka br. 5 iz prethodne vježbe razlikuje jedino u tome što se
elementima matrice mora pristupati pomoću pokazivača.
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 07-Pokazivaci.pdf - do stranice: 23
10. S tipkovnice, uz kontrolu, učitati broj redaka m i broj stupaca n cjelobrojne matrice. Broj
redaka mora biti iz intervala [3, 6], a broj stupaca iz intervala [4, 10]. Nakon toga učitati
članove matrice. Zatim jednodimenzijsko polje nps napuniti vrijednostima najmanjih članova
matrice u pojedinim stupcima, a jednodimenzijsko polje npr napuniti vrijednostima najmanjih
članova matrice u pojedinim retcima. Ispisati učitanu matricu, a zatim članove polja nps i
članove polja npr. Članovima svih polja mora se pristupati isključivo preko pokazivača.
matrica:
1 2 3 4 5
2 0 3 7 2
8 1 5 4 3
4 2 2 9 3
polje nps:
1 0 2 4 2
polje npr:
1 0 1 2
Ovaj zadatak se od zadatka br. 6 iz prethodne vježbe razlikuje jedino u tome što se elementima
matrice mora pristupati pomoću pokazivača.
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 07-Pokazivaci.pdf - do stranice: 23
Rješenja
Rješenje 3. zadatka
Neispravna je naredba
c = &y;
c je "pokazivač na short", a pridružuje mu se adresa varijable koja je tipa int.
Rješenje 8. zadatka
Kad bi bilo dopušteno članovima polja pristupati pomoću indeksa, tada bi se napisalo:
printf("%d %d %d %d\n", x[0][0], x[1][1], x[2][2], x[3][3]);
Članovima polja se također može pristupiti preko pokazivača. Pokazivač p sadrži adresu
elementa x[0][0]. Do adrese elementa x[1][1] dolazimo tako da preskočimo sve
elemente u prvom retku (ima ih 1*4) i jedan element iz drugog retka, tj. adresi p pribrojimo
1*4+1. Do adrese elementa x[2][2] dolazimo tako da preskočimo sve elemente u prva
dva retka (ima ih 2*4) i dva elementa iz trećeg retka, tj. adresi p pribrojimo 2*4+2. Itd.
printf("%d %d %d %d\n",
*(p+4*0+0), *(p+4*1+1),
*(p+4*2+2), *(p+4*3+3));
ili
printf("%d %d %d %d\n", *(p), *(p+5), *(p+10), *(p+15));
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 07-Pokazivaci.pdf - do stranice: 23
Rješenje 9. zadatka
#include <stdio.h>
#define MAXDIM 10
int main(void) {
int i, j, n;
int mat[MAXDIM][MAXDIM];
int *p = &mat[0][0]; /* ili: int *p = mat[0] */
/* ucitavanje n */
do {
printf("Upisite n:");
scanf("%d", &n);
} while (n < 1 || n > MAXDIM);
/* generiranje matrice */
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
if (i == j || i == n-1-j || j == 0 || i == 0 || j == n-1 || i == n-1)
*(p + i*MAXDIM + j) = 1;
else
*(p + i*MAXDIM + j) = 8;
/* ispis matrice */
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j)
printf("%d ", *(p + i*MAXDIM + j));
printf("\n");
}
return 0;
}
Česta pogreška pri rješavanju ovog zadatka (i sličnih zadataka) jest da se članu matrice
mat[i][j] pokuša pristupiti pomoću izraza
*(p + i*n + j)
To je pogrešno! Redak matrice mat sadrži MAXDIM članova, a ne n članova. Izraz bi bio
dobar jedino u slučaju kada korisnik za n upiše vrijednost jednaku MAXDIM.
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 07-Pokazivaci.pdf - do stranice: 23
#include <stdio.h>
#define MAXRED 6
#define MAXSTUP 10
int main(void) {
int i, j, m, n;
int mat[MAXRED][MAXSTUP], *pmat = &mat[0][0];
int nps[MAXSTUP], *pnps = &nps[0], npr[MAXRED], *pnpr = &npr[0];
do {
printf("Upisite m[3,6] i n[4,10]: ");
scanf("%d %d", &m, &n);
} while (m < 3 || m > 6 || n < 4 || n > 10);
printf("\nmatrica:\n");
for (i = 0; i < m; ++i) {
for (j = 0; j < n; ++j)
printf("%4d", *(pmat + i*MAXSTUP+j));
printf("\n");
}
printf("\npolje nps:\n");
for (j = 0; j < n; ++j)
printf("%4d", *(pnps + j));
printf("\n");
printf("\npolje npr:\n");
for (i = 0; i < m; ++i)
printf("%4d", *(pnpr + i));
printf("\n");
return 0;
}
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 07-Pokazivaci.pdf - do stranice: 23
Česte pogreške pri rješavanju ovog zadatka (i sličnih zadataka) jesu da se članu matrice
mat[i][j] pokuša pristupiti pomoću izraza
*(pmat + i*n + j)
ili
*(pmat + i*MAXRED + j)
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 25
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
U svim zadacima u kojima se traži definiranje funkcije, treba napisati odgovarajući glavni
program (tj. funkciju main) u kojem ćete po potrebi definirati stvarne argumente, s tipkovnice
učitati njihove vrijednosti, pozvati funkciju i ispisati rezultat.
2
1. Napisati funkciju tipa int koja za zadani cijeli broj n (formalni argument je tipa int) vraća n .
2. Provjerite hoćete li dobiti ispravan rezultat kada pomoću funkcije iz 1. zadatka pokušate
izračunati 500002. Objasnite što se dogodilo.
3. Provjerite hoćete li dobiti ispravan rezultat kada pomoću funkcije iz 1. zadatka pokušate
2 2
izračunati 2.0 i 3.5 . Objasnite što se dogodilo.
4. Napisati funkciju tipa double koja za zadani cijeli broj n (formalni argument je tipa int) vraća
n2. Provjerite hoćete li dobiti ispravan rezultat kada s tom funkcijom pokušate izračunati 22,
500002.
5. Koji je tip funkcije i što vraća funkcija f:
f (void) {
;
;
}
6. Napisati funkciju koja na zaslon ispisuje sve pozitivne parne brojeve između 2 i zadanog
cijelog broja n (u obliku 2 4 6 8 ...). Kojeg je ta funkcija tipa?
7. Napisati funkciju koja na zaslon ispisuje tablicu množenja za zadanih m redaka i n stupaca.
Za ispis brojeva koristite format %5d. Npr. ispis za tablicu množenja od 3 retka i 4 stupca je:
1 2 3 4
1 1 2 3 4
2 2 4 6 8
3 3 6 9 12
8. Napisati funkciju tipa double naziva nfakt za računanje n!. Napisati funkciju tipa double
naziva mpovrhn za računanje m povrh n koja će za izračunavanje koristiti funkciju nfakt. U
glavnom programu (main funkciji) učitavati s tipkovnice cijele brojeve m i n dok god su
ispravno zadani, te izračunavati i ispisivati m povrh n. Prekinuti program kad se zadaju
pogrešne vrijednosti za m i n.
9. Napisati funkciju koja na zaslon ispisuje prvih 20 Fibonaccijevih brojeva (svaki član niza u
novi redak na zaslonu).
10. Napisati funkciju koja na zaslon ispisuje prvih n (n se zadaje kao argument funkcije)
Fibonaccijevih brojeva (svaki član niza u novi redak na zaslonu).
11. Napisati funkciju tipa int koja vraća broj bajtova koji se koriste za pohranu podatka tipa int.
Napomena: različiti prevodioci koriste različiti broj bajtova, te se funkcija koja koristi sljedeću
naredbu return ne može smatrati ispravnom:
return 4;
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 25
Rješenja
Rješenje 1. zadatka
#include <stdio.h>
int kvadrat(int n) {
int kv;
kv = n*n;
return kv;
}
int main(void) {
int arg, rez;
printf("Upisite cijeli broj: ");
scanf("%d", &arg);
rez = kvadrat(arg);
printf("%d na kvadrat jest %d\n", arg, rez);
return 0;
}
Rješenje 2. zadatka
Ukoliko korisnik unese 50000, u varijablu kv neće se pohraniti ispravan rezultat (2500000000 se
ne može pohraniti u varijablu kv jer se radi o broju koji prelazi dopušteni raspon za tip int).
Funkcija će vratiti broj -1794967296
Rješenje 3. zadatka
Koristi se ista funkcija, ali drugačiji glavni program, kojim se s tipkovnice učitava realni broj.
int main(void) {
float arg;
int rez;
printf("Upisite realni broj: ");
scanf("%f", &arg);
rez = kvadrat(arg);
printf("%f na kvadrat jest %d\n", arg, rez);
return 0;
}
Ukoliko korisnik unese 2.0, prilikom prijenosa stvarnog argumenta u formalni, obavit će se
konverzija u cijeli broj 2. Funkcija će vratiti cijeli broj 4.
Ukoliko korisnik unese 3.5, prilikom prijenosa stvarnog argumenta u formalni, obavit će se
konverzija u cijeli broj 3. Funkcija će vratiti cijeli broj 9.
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 25
Rješenje 4. zadatka
#include <stdio.h>
double kvadrat(int n) {
double kv;
kv = (double)n*n;
return kv;
}
int main(void) {
int arg;
double rez;
printf("Upisite cijeli broj: ");
scanf("%d", &arg);
rez = kvadrat(arg);
printf("%d na kvadrat jest %f\n", arg, rez);
return 0;
}
Ovdje je eksplicitna konverzija u tip double stavljena radi toga da se množenje obavi u
double domeni. Inače, opet bi se dogodilo da se pri računanju 500002 dobije negativan
cijeli broj, koji bi se kod pridruživanja varijabli kv pretvorio u realni broj (ali prekasno, jer bi
se kao rezultat dobio negativan realni broj). Testirajte: izbacite cast operator (double) iz
funkcije kvadrat.
Rješenje 5. zadatka
Funkcija je tipa int, a rezultat funkcije je nedefiniran, odnosno vraća "smeće" (vrijednost
koju nije moguće unaprijed odrediti).
Rješenje 6. zadatka
#include <stdio.h>
int main(void) {
int arg;
printf("Upisite cijeli broj: ");
scanf("%d", &arg);
ispisiParne(arg);
return 0;
}
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 25
Rješenje 7. zadatka
#include <stdio.h>
/* ispisi tablicu */
for (i = 1; i <= redaka; ++i) {
/* na pocetku svakog retka ispisi redni broj retka */
printf("%5d", i);
int main(void) {
int m, n;
printf("Upisite broj redaka: ");
scanf("%d", &m);
printf("Upisite broj stupaca: ");
scanf("%d", &n);
printf("\nTABLICA MNOZENJA:\n");
ispisiTablicuMnozenja(m, n);
return 0;
}
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 25
Rješenje 8. zadatka
#include <stdio.h>
int main(void) {
int m, n, mn;
do {
printf ("Upisite m i n: ");
scanf("%d %d", &m, &n);
if (m >= 0 && n >= 0 && m >= n) {
mn = mpovrhn(m, n);
printf("%d povrh %d je: %d\n\n", m, n, mn);
}
} while (m >= 0 && n >= 0 && m >= n);
return 0;
}
Rješenje 9. zadatka
#include <stdio.h>
int main(void) {
fibonacci();
return 0;
}
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 25
U funkciji je definirano polje veličine 20 članova. Tako se moglo postupiti zato jer je zadano
da treba ispisati točno 20 članova niza.
#include <stdio.h>
int main(void) {
fibonacci();
return 0;
}
#include <stdio.h>
int main(void) {
fibonacci(30);
return 0;
}
Uočiti: zadatak se ne može riješiti pomoću polja, kao prethodni zadatak, jer se ne zna
unaprijed koliko bi polje u funkciji trebalo biti veliko. Argument n se ne može pri definiciji
polja koristiti kao dimenzija polja jer dimenzija polja pri definiciji mora biti cjelobrojni
konstantni izraz. Dakle, nije dopušteno sljedeće:
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 25
#include <stdio.h>
int kolikoInt(void) {
return sizeof(int);
}
int main(void) {
int brojBajtovaZaInt;
brojBajtovaZaInt = kolikoInt();
printf("Ovaj prevodilac za tip int koristi bajtova: %d\n", brojBajtovaZaInt);
return 0;
}
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 35
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
U svim zadacima u kojima se traži definiranje funkcije, treba napisati odgovarajući glavni
program (tj. funkciju main) u kojem ćete po potrebi definirati stvarne argumente, s tipkovnice
učitati njihove vrijednosti, pozvati funkciju i ispisati rezultat.
1. Napisati funkciju koja za zadani cijeli broj n vraća n2, ali tako da rezultat vraća preko adrese
koju je dobila kao argument. Funkcija ne smije promijeniti stvarni argument n definiran u
pozivajućem programu. Kojeg je tipa funkcija?
2. Napisati funkciju koja sadržaj neke cjelobrojne varijable n iz pozivajućeg programa mijenja u
2
n . Dakle, funkcija treba promijeniti vrijednost neke cjelobrojne varijable koja je definirana u
pozivajućem programu. Kojeg je tipa funkcija?
3. Napišite funkciju tipa double koja za zadanu vrijednost tipa double vraća zadanu vrijednost
(tipa double) uvećanu za 10.0. Hoćete li dobiti ispravan rezultat ako funkciju pozovete sa
stvarnim argumentom tipa int?
4. Napišite funkciju koja zadanoj varijabli tipa double vrijednost uvećava za 10.0. Dakle, funkcija
treba promijeniti vrijednost neke realne (double) varijable koja je definirana u pozivajućem
programu. Hoćete li dobiti ispravan rezultat ako funkciju pozovete sa stvarnim argumentom
koji je pokazivač na varijablu tipa int?
5. Napišite funkciju koja za dvije zadane vrijednosti tipa int u pozivajući program vraća dvije
vrijednosti: prva vraćena vrijednost je veća među zadanim vrijednostima, a druga vraćena
vrijednost je manja među zadanim vrijednostima. Npr. ako se funkciji zadaju vrijednosti 2 i
3*2, funkcija u pozivajući program mora vratiti vrijednosti 6 i 2.
6. Napišite funkciju koja vrijednosti u zadanim varijablama x, y i z (tipa double) poredava po
veličini, od najveće prema najmanjoj. Drugim riječima, očekuje se da će funkcija zamijeniti
vrijednosti u varijablama x, y i z tako da vrijednosti budu poredane od najveće prema
najmanjoj. Npr. ako se funkcija pozove za varijable x=2.0, y=4.0, z=3.0, nakon izvršavanja
funkcije u varijablama x, y, z se moraju nalaziti vrijednosti x=4.0, y=3.0, z=2.0.
7. Napišite funkciju koja prima pokazivače na dvije varijable tipa int, te vraća pokazivač na onu
od njih koja ima veću vrijednost. Ako varijable imaju istu vrijednost, funkcija vraća pokazivač
na prvu varijablu.
8. Napišite funkciju koja prima pokazivače na dvije varijable tipa int, te vraća vrijednost
varijable koja ima veću vrijednost.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 35
Rješenja
Rješenje 1. zadatka
#include <stdio.h>
Funkcija kvad2 kao drugi argument dobija adresu varijable u koju će zapisati rezultat. Jedina
naredba u toj funkciji upravo to i radi: na adresu kamo pokazuje pokazivač rez, zapisuje n2.
Primijetite da pozivajući program za drugi stvarni argument predaje adresu varijable n2. Tip
funkcije je void, jer funkcija pomoću naredbe return ne treba vratiti niti jednu vrijednost.
Ipak, uočite da će uvjet iz programa (da funkcija ne smije promijeniti stvarni argument) biti narušen
ukoliko se funkcija pozove na sljedeći način: kvad2(n, &n);
Rješenje 2. zadatka
#include <stdio.h>
Funkcija kvad3 dobija adresu varijable u kojoj se nalazi cijeli broj čiji kvadrat treba izračunati, ali se
na tu istu adresu također zapisuje i rezultat. Varijabla n iz pozivajućeg programa će biti
promijenjena!
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 35
Rješenje 3. zadatka
#include <stdio.h>
double uvecajZa10(double x) {
return x + 10.;
}
Sada treba testirati što će se dogoditi ako se funkcija pozove s cjelobrojnim argumentom?
Ako se funkcija pozove s cjelobrojnim stvarnim argumentom, dobit će se ispravan rezultat jer se pri
prijenosu stvarnog u formalni argument obavlja implicitna konverzija (int→ double), a pri
pridruživanju rezultata funkcije varijabli rez obavlja se implicitna konverzija (double→ int).
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 35
Rješenje 4. zadatka
#include <stdio.h>
Sada treba testirati što će se dogoditi ako se funkciji umjesto pokazivača na varijablu tipa double
preda pokazivač na varijablu tipa int?
Prevodilac će dojaviti upozorenje, ali će program ipak uspjeti prevesti (ako se radi s gcc
prevodiocem, da bi prevođenje uspjelo u ovom primjeru, treba ispustiti opciju -pedantic-errors) .
Rezultat izvršavanja programa neće biti ispravan. To se moglo očekivati: funkcija je dobila
adresu int varijable (pokazuje na neko područje u memoriji od 4 bajta), a "misli" da je dobila
adresu double varijable (adresu koja pokazuje na područje memorije veličine 8 bajta).
Prekršili smo pravilo koje smo definirali na predavanjima: pokazivač na objekte tipa x smije se
koristiti isključivo za pohranu adresa objekata tipa x.
Za vježbu, provjerite kakve ćete rezultate dobiti ako u funkciji, umjesto tipa double koristite tip float.
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 35
Rješenje 5. zadatka
#include <stdio.h>
Rješenje 6. zadatka
#include <stdio.h>
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 35
Rješenje 7. zadatka
#include <stdio.h>
Rješenje 8. zadatka
#include <stdio.h>
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
1. Napisati prototip (deklaraciju) za svaku funkciju koja se nalazi u rješenjima prethodnih vježbi.
2. U modulu mat2.c napisati funkcije čiji su prototipovi navedeni u nastavku
int binCoeff(int m, int n); /* izracunava "m povrh n" */
int factorial(int n); /* izracunava n! */
int iabsolute(int n); /* izracunava apsolutnu vrijednost */
float fabsolute(float x); /* izracunava apsolutnu vrijednost */
Prototipove navedenih funkcija smjestiti u datoteku s prototipovima mat2.h.
Funkciju main ("glavni program") smjestiti u modul glavni.c U glavnom programu treba
izračunati i na zaslon ispisati rezultate za:
factorial(0)
factorial(25)
factorial(26)
binCoeff(13, 3)
binCoeff(4, 4)
iabsolute(-5)
iabsolute(0)
iabsolute(-5.7f)
fabsolute(-5)
fabsolute(-5.7f)
void fun(void) {
int x = 5;
printf("%d\n", x);
x++;
}
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
void fun(void) {
static int x = 5;
printf("%d\n", x);
x++;
}
void fun(void) {
static int x = 5;
int y = 5;
printf("%d %d\n", ++x, --y);
}
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
void fun1(void) {
static int x = 5;
printf("%d\n", ++x);
}
void fun2(void) {
int x = 10;
printf("%d\n", ++x);
}
void fun3(void) {
printf("%d\n", ++x);
}
fun1();
fun2();
fun3();
return 0;
}
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
8. Napisati funkciju zbroji tipa int koja vraća zbroj dvaju zadanih cijelih brojeva i funkciju
mnozi tipa int koja vraća umnožak dvaju zadanih cijelih brojeva. Svaka od funkcija, osim što
izračunava rezultat i vraća ga u pozivajući program, na zaslon ispisuju koliko je puta bila
pozvana. Npr. ako se u glavnom programu obave naredbe:
printf("2*2=%d\n", mnozi(2,2));
printf("2+3=%d\n", zbroji(2,3));
printf("4+2=%d\n", zbroji(4,2));
printf("2*5=%d\n", mnozi(2,5));
printf("2*3=%d\n", mnozi(2,3));
na zaslonu se treba ispisati:
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
9. Slično kao prethodni zadatak, uz dodatak: svaka od funkcija mora ispisati ne samo koliko je
puta bila pozvana ona sama, nego i koliko puta je bila pozvana bilo koja od funkcija zbroji i
mnozi. Npr. ako se u glavnom programu obave naredbe:
printf("2*2=%d\n", mnozi(2,2));
printf("2+3=%d\n", zbroji(2,3));
printf("4+2=%d\n", zbroji(4,2));
printf("2*5=%d\n", mnozi(2,5));
printf("2*3=%d\n", mnozi(2,3));
na zaslonu se treba ispisati:
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
Rješenja
Rješenje 2. zadatka
modul glavni.c
#include <stdio.h>
#include "mat2.h"
int main(void) {
printf("%d\n", factorial(0));
printf("%d\n", factorial(25));
printf("%d\n", factorial(26)); /* zasto ovdje rezultat nece biti dobar?*/
printf("%d\n", binCoeff(13, 3));
printf("%d\n", binCoeff(4, 4));
printf("%d\n", iabsolute(-5));
printf("%d\n", iabsolute(0));
printf("%d\n", iabsolute(-5.7f));
printf("%3.1f\n", fabsolute(-5));
printf("%3.1f\n", fabsolute(-5.7f));
return 0;
}
modul mat2.c
#include "mat2.h"
int factorial(int n) {
int i, f = 1;
for (i = 2; i <= n; i++) {
f = f * i;
}
return f;
}
int iabsolute(int n) {
return n >= 0 ? n : -n;
}
float fabsolute(float x) {
return x >= 0.0f ? x : -x;
}
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
Rješenje 3. zadatka
Pri svakom pozivu funkcije varijabla x se ponovno inicijalizira. Ispisat će se:
5
5
Rješenje 4. zadatka
Varijabla x se inicijalizira samo jednom, na početku izvođenja programa, a njezina vrijednost ostaje
sačuvana do kraja izvođenja programa (ne gubi se završetkom funkcije). Ispisat će se:
5
6
Rješenje 5. zadatka
Potrebno je uočiti koje su varijable definirane u programu, te na temelju smještajnog razreda kojem
pripadaju odrediti njihovo područje važenja i trajnost.
Varijabla y je automatska varijabla. Varijabla se inicijalizira svaki puta kad se pozove funkcija, a
njezina vrijednost se gubi u trenutku završetka funkcije.
x-trajnost y-trajnost
x-važenje y-važenje
void fun(void) {
static int x = 5;
int y = 5;
printf("%d %d\n", ++x, --y);
}
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
Rješenje 6. zadatka
Ovdje je važno uočiti da postoje dvije varijable naziva i. Na slici koja prikazuje područja važenja i
trajnosti, prva varijabla i (definirana na početku glavnog programa) označena je oznakom i1, a
druga oznakom i2.
i1-trajnost i2-trajnost
i1-važenje
#include <stdio.h>
Rješenje 7. zadatka
Ovdje je važno uočiti da postoji 5 različitih varijabli naziva x. Kad se odredi trajnost i područje
važenja svake od tih varijabli, zadatak je lako riješiti.
9
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
Rješenje 8. zadatka
#include <stdio.h>
10
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 64
Rješenje 9. zadatka
#include <stdio.h>
int ukupniBrojPoziva = 0;
return 0;
}
Nakon što se odredi trajnost i područje važenja svake pojedine varijable, zadatak je lako riješiti.
11
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 78
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
U svim zadacima u kojima se traži definiranje funkcije, treba napisati odgovarajući glavni
program (tj. funkciju main) u kojem ćete po potrebi definirati stvarne argumente, pozvati funkciju
i ispisati rezultat.
2. Napišite funkciju koja u zadanom jednodimenzijskom realnom polju prebroji koliko članova je
veće od 0.0, koliko članova je manje od 0.0 i koliko članova je jednako 0.0. Dobivene
vrijednosti funkcija mora vratiti u pozivajući program. Funkciju, glavni program i prototipove
smjestite u tri zasebne datoteke. Testirati prevođenje na dva načina:
• tako da se oba modula prevedu i povežu samo jednim pozivom prevodioca
• tako da se zasebno prevede svaki modul, a zatim se dobiveni objektni kôd poveže u
izvršni kôd
#include <stdio.h>
int main (void) {
int a = 2, x = 10;
int *p = &a;
x += *p * 3;
printf ("%d %d\n", *p, x);
return 0;
}
#include <stdio.h>
void f (int *p) {
printf ("%d %d\n", *p, *p+1);
}
int main (void) {
int polje[6] = {1, 2, 3, 4, 5, 6};
int *pp;
pp = &polje[0];
f(pp++);
f(pp);
f(++pp);
return 0;
}
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 78
#include <stdio.h>
void f (int *p) {
static int i = 2;
printf ("%d\n", *(p + ++i));
}
#include <stdio.h>
void f (int *p) {
int i = 3;
printf ("%d\n", *(p + --i));
}
int main (void) {
int polje[6] = {1, 2, 3, 4, 5, 6};
f(&polje[0]);
f(&polje[1]);
f(&polje[2]);
return 0;
}
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 78
Rješenja
Rješenje 1. zadatka
glavni.c
#include <stdio.h>
#include "toapsdim.h"
toApsDim(&polje[0], m);
toapsdim.c
#include "toapsdim.h"
toapsdim.h
void toApsDim(int *polje, int n);
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 78
Rješenje 2. zadatka
funkcije.h
void prebroji(float *polje, int n,
int *vecihOdNula, int *manjihOdNula, int *jednakihNula);
funkcije.c
#include "funkcije.h"
void prebroji(float *polje, int n,
int *vecihOdNula, int *manjihOdNula, int *jednakihNula) {
int i;
*vecihOdNula = *manjihOdNula = *jednakihNula = 0;
for (i = 0; i < n; ++i)
if (*(polje + i) < 0.0)
(*manjihOdNula)++;
else if (*(polje + i) == 0.0)
(*jednakihNula)++;
else
(*vecihOdNula)++;
return;
}
test.c
#include <stdio.h>
#include "funkcije.h"
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
U svim zadacima u kojima se traži definiranje funkcije, treba napisati odgovarajući glavni
program (tj. funkciju main) u kojem ćete po potrebi definirati stvarne argumente, pozvati funkciju
i ispisati rezultat.
#include <stdio.h>
#include <stdio.h>
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
#include <stdio.h>
#include <stdio.h>
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Nakon toga pokušajte napisati drugačiji glavni program: definirajte polje od 5 redaka i 5
stupaca, inicijalizirajte sve elemente polja na nulu, pozovite istu funkciju genmat i ispišite
svih 5x5 članova polja. Možete li predvidjeti kako će izgledati ispis? Zašto ispisana tablica ne
izgleda (što bi se možda moglo očekivati) ovako:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 0
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
1 2 3 4
2 4 6 8
3 6 9 12
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
Rješenja
Rješenje 1. zadatka
#include <stdio.h>
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
Rješenje 2. zadatka
#include <stdio.h>
Ovdje je važno uočiti da u ovoj funkciji nije moguće* koristiti pomoćni niz jer nije poznata najveća
dopuštena duljina ulaznog niza (a taj je podatak potreban pri definiciji pomoćnog niza). Tek kad bi
zadatak glasio: napišite funkciju koja iz zadanog niza znakova izbacuje sve samoglasnike, pri čemu
zadani niz sigurno nije dulji od 1000 znakova, tada bi postojala mogućnost u funkciji koristiti
pomoćni niz (tada bi se u funkciji mogao definirati pomoćni niz duljine 1001 znaka).
* moguće je npr. uz korištenje funkcije malloc, međutim ta se funkcija ne razmatra na ovom predmetu
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
Rješenje 7. zadatka
#include <stdio.h>
Rezultat:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Rezultat:
1 0 0 0 0
1 0 0 0 0
1 0 0 0 0
1 0 0 0 0
0 0 0 0 0
Zašto? Funkcija genmat u prvom koraku for petlje upiše vrijednost 1 na adresu *(polje+0+0), a time
zapravo upiše jedinicu u element polja mat[0][0], što je u redu. Međutim, kada u drugom koraku for
petlje upiše vrijednost 1 na adresu *(polje+1+1*4), zapravo je upisala jedinicu u element polja
mat[1][0]. Pojednostavljeno, funkcija (zato što je tako napisana) do prvog člana drugog retka dolazi
tako da se preskoči 4 člana polja (a to je istina samo onda kada se funkciji preda polje koje je
definirano tako da mu je broj stupaca jednak 4). Očito, ako funkcija mora baratati s poljima različitih
dimenzija, mora imati informaciju o stvarnom broju stupaca polja (broju stupaca pri definiciji polja).
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
Rješenje 8. zadatka
#include <stdio.h>
#define MAXRED 15
#define MAXSTUP 15
printf ("Upisite m i n koji su manji ili jednaki %d i %d: ", MAXRED, MAXSTUP);
scanf("%d %d", &m, &n);
/* ovdje bi, naravno, trebalo napraviti provjeru unesenih vrijednosti */
tablica(&polje[0][0], m, n, MAXSTUP);
printf("\nSlijedi ispis tablice mnozenja\n\n");
for (i = 0; i < m; ++i) {
for (j = 0; j < n; ++j)
printf("%5d", polje[i][j]);
printf("\n");
}
return 0;
}
Važna napomena: česta pogreška koja se pronalazi u rješenjima ovakvih zadataka jest da se u
funkciji umjesto formalnog argumenta brclanstup koristi simbolička konstanta MAXSTUP
definirana na početku modula. Zašto to ne valja? Zato jer bi tada funkcija ispravno radila samo s
onim poljima koja su definirana tako da im je broj stupaca jednak MAXSTUP. Npr, ako bi se u
glavnom programu definiralo još jedno polje, drugačijih dimenzija, funkcija u tom polju ne bi mogla
generirati ispravnu tablicu množenja.
int polje2[10][10];
...
tablica(&polje2[0][0], 5, 6, 10);
...
Također, pogrešno je koristiti globalnu ili statičku varijablu za "prijenos" informacije o broju stupaca
u funkciju.
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
Rješenje 9. zadatka
#include <stdio.h>
#define MAXRED 20
#define MAXSTUP 20
return 0;
}
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 102
9
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 122
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
2. Napišite program koji će poslužiti kao primjer kojim ćete "dokazati" da sljedeće macro
definicije nisu ispravno napisane:
#define ZBROJI(a, b) a + b
#define ODUZMI(a, b) (a)-(b)
#define PODIJELI(x, y) (x/y)
#define OPETPODIJELI(x, y) (x)/(y)
Koja pravila pisanja ove macro definicije ne zadovoljavaju? Zatim u svom programu ispravite
navedene macro definicije i ponovo izvedite program.
3. Napisati funkciju traziPrviSamoglas koja u zadanom nizu znakova pronalazi prvi samoglasnik
(malo ili veliko slovo) koji se pojavljuje u nizu. Funkcija u pozivajući program vraća pokazivač
na pronađeni samoglasnik, a ako u nizu nema niti jedan samoglasnik, vraća null pokazivač.
Napisati glavni program koji će pomoću funkcije gets učitati niz znakova ne dulji od 80
znakova, te pomoću funkcije traziPrviSamoglas pronaći te na zaslon ispisati prvi samoglasnik
učitanog niza ili poruku "U nizu nema samoglasnika".
4. Definirati tip podatka tTocka kojim se opisuje jedna točka u pravokutnom koordinatnom
sustavu (x i y su vrijednosti tipa double). Napisati prototip funkcije udaljToc koja za dvije
točke zadane pomoću tipa podatka tTocka izračunava udaljenost među točkama (double).
Definiciju tipa tTocka i prototip funkcije udaljToc napisati u zaglavnoj datoteci geom.h.
Definiciju funkcije udaljToc napisati u modulu geom.c
Napisati glavni program koji će u varijable t1 i t2 tipa tTocka učitati koordinate dviju točaka,
zatim pomoću funkcije udaljToc izračunati njihovu udaljenost, te izračunatu vrijednost ispisati
na zaslon.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 122
Rješenja
Rješenje 2. zadatka
#include <stdio.h>
#define ZBROJI(a, b) a + b
#define ODUZMI(a, b) (a)-(b)
#define PODIJELI(x, y) (x/y)
#define OPETPODIJELI(x, y) (x)/(y)
int main(void) {
int c = ZBROJI(3, 2) * 5;
float z = ODUZMI(3.f, 2.f) * 5.f;
int d = PODIJELI(20, 2*5);
float w = 20.f / OPETPODIJELI(10.f, 2.f);
return 0;
}
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 122
Rješenje 3. zadatka
#include <stdio.h>
Funkcija se može vrlo lako prepraviti tako da pronalazi posljednji samoglasnik u nizu.
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 08-Funkcije.pdf - do stranice: 122
Rješenje 4. zadatka
glavni.c
#include <stdio.h>
#include "geom.h"
int main(void) {
tTocka t1, t2;
geom.h
typedef struct {
double x;
double y;
} tTocka;
geom.c
#include <math.h>
#include "geom.h"
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
U svim zadacima u kojima se traži definiranje funkcije, treba napisati odgovarajući glavni
program (tj. funkciju main) u kojem ćete po potrebi definirati stvarne argumente, pozvati funkciju
i ispisati rezultat.
1. Na svom računalu testirajte primjere s predavanja vezane uz funkcije fabs i abs, te primjer
kojim je prikazana razlika između funkcije exit i naredbe return.
2. S tipkovnice učitati cijeli broj n uz kontrolu da je 3 ≤ n ≤ 20. Na slučajan način odabrati n
velikih slova (među znakovima A-Z) i ispisati ih na zaslon.
3. Generirati 10 000 cijelih brojeva iz zatvorenog intervala [50,60]. Na zaslon ispisati frekvenciju
pojavljivanja svakog od brojeva.
50 se pojavio 1100 puta
51 se pojavio 987 puta
...
60 se pojavio 1083 puta
4. Napisati funkciju koja u zadano dvodimenzijsko cjelobrojno polje "ispaljuje zadani broj
hitaca". Element polja u kojeg pojedini hitac pogađa odabire se na slučajan način (funkcija na
slučajan način odabere redak elementa, a zatim na slučajan način odabere stupac
elementa). Vrijednost elementa polja koji je "pogođen", funkcija uvećava se za jedan.
Funkcija treba inicijalizirati generator pseudoslučajnih brojeva samo pri prvom pozivu, a prije
nego počne "gađati" polje, mora elemente polja inicijalizirati na vrijednost 0.
U glavnom programu definirati polje maksimalnih dimenzija 10x10, s tipkovnice učitati m i n,
te "broj "hitaca h koje u polje dimenzija mxn funkcija treba "ispaliti". Pozvati funkciju te u
obliku tablice ispisati sadržaj polja nakon što je "pogođeno" s h hitaca, a zatim u nastavku
programa to ponoviti (s istim argumentima).
Što će se dogoditi ako funkciju prepravite tako da se generator pseudoslučajnih brojeva
inicijalizira pri svakom pozivu funkcije? Zašto se tada (u najvećem broju slučajeva) dobiju
dva jednaka polja?
5. Napisati funkciju obrniNiz koja obrće niz znakova. Npr. niz znakova "ABCDE" mijenja u niz
znakova "EDCBA". Uputa: 1. znak zamijeniti s n-tim znakom, 2. znak zamijeniti s n-1-vim
znakom, itd.
6. Napisati funkciju umetniZnak koja na početak zadanog niza znakova umeće zadani znak.
Funkcija može računati na to da je za niz u pozivajućem programu rezervirano dovoljno
memorije. U funkciji se ne smiju koristiti funkcije iz <string.h>.
7. Napisati funkciju umetniZnakove koja ispred svakog znaka zadanog niza umeće zadani znak
(npr, ako se funkciji zada niz "Studeni" i znak 'X', funkcija mijenja niz u "XSXtXuXdXeXnXi").
Funkcija može računati na to da je za niz u pozivajućem programu rezervirano dovoljno
memorije. U funkciji se ne smiju koristiti funkcije iz <string.h>.
8. Napisati vlastitu funkciju myStrcpy koja obavlja isto što i funkcija strcpy definirana u string.h.
U funkciji se ne smiju koristiti funkcije iz <string.h>.
9. Napisati vlastitu funkciju myStrlen koja obavlja isto što i funkcija strlen definirana u string.h
(jedina razlika neka bude u tome što myStrlen vraća int, umjesto size_t). U funkciji se ne
smiju koristiti funkcije iz <string.h>.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
10. Napisati vlastitu funkciju myStrcat koja obavlja isto što i funkcija strcat definirana u string.h. U
funkciji se ne smiju koristiti funkcije iz <string.h>.
11. Napisati funkciju koja kao rezultat vraća koliko puta se niz s2 pojavljuje unutar niza s1. U
glavnom programu pomoću funkcije gets učitati dva niza, pozvati funkciju i ispisati rezultat. U
funkciji je dopušteno koristiti funkcije iz biblioteke <string.h>.
12. Što će biti sadržaj nizova znakova s1, s2 i s3 nakon obavljanja odsječka programa:
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
Rješenja
Rješenje 2. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
Rješenje 3. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DG 50
#define GG 60
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
Rješenje 4. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXR 10
#define MAXS 10
printf("\n");
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
Funkcija će pri svakom pozivu ponovo inicijalizirati generator ako se blok naredbi
if (! generatorInicijaliziran) {
srand ((unsigned) time(NULL));
generatorInicijaliziran = 1;
}
zamijeni sa
srand ((unsigned) time(NULL));
Druga inicijalizacija generatora će se tada dogoditi vrlo vjerojatno s istim početnim uvjetima-seed
(jer će se oba poziva funkcije vrlo vjerojatno obaviti unutar iste sekunde), stoga će i nizovi
generiranih pseudoslučajnih brojeva biti jednaki.
Rješenje 5. zadatka
#include <stdio.h>
#define MAX 20
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
Rješenje 6. zadatka
#include <stdio.h>
#include <string.h>
Rješenje 7. zadatka
#include <stdio.h>
#include <string.h>
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
Rješenje 8. zadatka
#include <stdio.h>
Rješenje 9. zadatka
#include <stdio.h>
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
return 0;
}
9
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 38
return 0;
}
10
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 52
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
2. Napisati program koji pomoću funkcije getchar s tipkovnice učitava znakove u niz s1 dok god
ne bude učitan znak 'X' (znak 'X' se ne dodaje u niz s1). Zatim u niz s2 učitava znakove dok
se ne pojavi znak 'Y' (znak 'Y' se ne dodaje u niz s2). Osigurati da nizovi s1 i s2 budu
ispravno terminirani (tj. na kraju niza se nalazi znak '\0'). Nakon učitavanja, pomoću funkcije
putchar ispisati nizove s1 i s2 na zaslon, svaki u svoj redak. Nizovi s1 i s2 sigurno nisu dulji
od 80 znakova.
Primjer: ako se preko tipkovnice unese: Ovo je
neki tekst.XA ovo
je nastavakYOstatak se ne ucitava
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 52
Rješenja
Rješenje 2. zadatka
#include <stdio.h>
int main(void) {
char s1[80+1], s2[80+1], c;
int i;
i = 0;
while((c = getchar()) != 'X')
s1[i++] = c;
s1[i] = '\0';
i = 0;
while((c = getchar()) != 'Y')
s2[i++] = c;
s2[i] = '\0';
i = 0;
while (s1[i] != '\0')
putchar(s1[i++]);
printf("\n");
i = 0;
while (s2[i] != '\0')
putchar(s2[i++]);
return 0;
}
Rješenje 3. zadatka
#include <stdio.h>
#define MAXRED 10
#define MAXSTUP 80
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 77
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
2. Na svom računalu izvedite sljedeći programski odsječak, uz ulazne podatke 1 2 3.0 4.0
int i;
short j;
float x;
double y;
scanf("%d %d %f %f", &i, &j, &x, &y);
printf("%d %d %f %f\n", i, j, x, y);
Jesu li se printf naredbom ispisale ispravne vrijednosti? Objasnite zašto. Što treba
promijeniti u formatu scanf naredbe da bi odsječak radio ispravno? Izvođenjem programa na
svom računalu provjerite svoj odgovor.
3. Koje su vrijednosti svih definiranih varijabli nakon obavljanja sljedećeg odsječka programa:
int rez1, rez2, rez3;
int a, b, c;
short d;
char e;
float x, y;
double z, w;
rez1 = scanf("%3d%d%d %hx%c", &a, &b, &c, &d, &e);
rez2 = scanf("%f%5f", &x, &y);
rez3 = scanf(" %lf %lf", &z, &w); 12345 6
a2m
ako su preko tipkovnice uneseni sljedeći podaci: 11-10 .1+ 3
4. Koje su vrijednosti svih definiranih varijabli nakon obavljanja sljedećeg odsječka programa:
int rez1, rez2;
int a, b;
char s1[10+1], s2[10+1], s3[10+1], s4[10+1];
rez1 = scanf("%3d %d", &a, &b);
rez2 = scanf("%s%s%4s %s", s1, s2, s3, s4);
ako su preko tipkovnice uneseni sljedeći podaci:
12ab Marija
Marica Ana
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 77
5. Napisati program koji će pomoću funkcije scanf iz <stdio.h> učitati dva niza znakova s1 i
s2, čiji se sadržaj unosi preko tipkovnice i to tako da se svaki niz utipka u svojem retku.
Oznaka kraja retka se ne učitava u niz znakova. Npr. sadržaj ulaza može izgledati ovako:
Dva psa.
Jedan macak.
Može se računati da niti jedan redak teksta neće biti dulji od 30 znakova. Program treba
formirati niz s3, čiji sadržaj nastaje spajanjem nizova s1 i s2, te dobiveni niz s3 ispisati na
zaslon. U navedenom primjeru na zaslon treba ispisati:
6. Preko tipkovnice se unose matični brojevi i datumi rođenja osoba. Datum rođenja sadrži redni
broj dana, redni broj mjeseca i redni broj godine. Npr. sadržaj ulaza može izgledati ovako:
101 15.5.1989
1526 17.6.1987
17 9.12.1987
0
Za svaku osobu pomoću funkcije scanf učitati matični broj, redni broj dana, redni broj
mjeseca i redni broj godine. Učitavanje se prekida kada se za matični broj upiše 0. Nakon
završenog učitavanja, ispisati matične brojeve i godine rođenja osoba. Za prikazani primjer
ulaza, izlaz treba izgledati ovako:
101. 1989.
1526. 1987.
17. 1987.
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 77
#include <stdio.h>
int main(void) {
printf("|%d|\n", 10);
printf("|%5d|\n", 10);
printf("|%1d|\n", 10);
printf("|%s|\n", "Ana");
printf("|%5s|\n", "Ana");
printf("|%2s|\n", "Ana");
printf("|%x|\n", 27);
printf("|%6x|\n", 27);
printf("|%o|\n", 9);
printf("|%6o|\n", 9);
printf("|%1o|\n", 9);
return 0;
}
8. Napisati program koji će s tipkovnice pročitati cijeli broj broj n (1 ≤ n ≤ 15). Program treba na
zaslon ispisati "tablicu množenja". Npr. za zadani n=12, ispis na zaslon treba izgledati ovako:
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 77
Rješenja
Rješenje 5. zadatka
#include <stdio.h>
#include <string.h>
#define MAXNIZ 30
printf("%s\n", s3);
return 0;
}
Rješenje 6. zadatka
#include <stdio.h>
#define MAX 100
int main(void) {
int dan, mjesec;
int matBroj, matBrojevi[MAX], godine[MAX];
int brojUcitanih = 0, i;
char tocka;
do {
scanf("%d", &matBroj);
if (matBroj != 0) {
matBrojevi[brojUcitanih] = matBroj;
scanf("%d%c%d%c%d", &dan, &tocka, &mjesec, &tocka,
&godine[brojUcitanih]);
++brojUcitanih;
}
} while (matBroj != 0);
for (i = 0; i < brojUcitanih; ++i)
printf("%4d. %4d.\n", matBrojevi[i], godine[i]);
printf("\n");
return 0;
}
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 09-UgradjeneFunkcije.pdf - do stranice: 77
Rješenje 8. zadatka
#include <stdio.h>
int main(void) {
int n, i, j;
do {
printf("Upisite vrijednost za n: ");
scanf ("%d",&n);
} while (n < 1 || n > 15 );
printf("----+", i);
for (i = 1; i <= n; ++i) {
printf("----", i);
}
printf("\n");
printf("----+", i);
for (i = 1; i <= n; ++i) {
printf("----", i);
}
printf("\n");
return 0;
}
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 23
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
1. Napisati program koji će sadržaj tekstualne datoteke ulaz.txt prepisati na zaslon, ali tako
da se umjesto malih slova ispisuju velika. Za čitanje znakova iz datoteke treba koristiti
funkciju fgetc. Pomoću editora (npr. notepad) prirediti tekstualnu datoteku ulaz.txt,
pohraniti ju unutar nekog kazala (direktorija), npr. c:\tmp, te testirati program.
2. Napisati funkciju broji koja kao argument prima niz znakova koji predstavlja ime
tekstualne datoteke (tip podatka char *). Funkcija treba otvoriti tok podataka za čitanje iz
datoteke sa zadanim imenom (tj. "otvoriti datoteku"), prebrojati samoglasnike (broje se i
"mali" i "veliki" samoglasnici), zatvoriti tok podataka (tj. "zatvoriti datoteku"), te u pozivajući
program vratiti broj samoglasnika. Ako funkcija ne uspije otvoriti datoteku, kao broj
samoglasnika vraća -1. Za čitanje znakova iz datoteke treba koristiti funkciju fgetc. Pomoću
editora (npr. notepad) prirediti jednu tekstualnu datoteku, te napisati glavni program kojim će
se testirati rad funkcije.
3. Slično kao u prethodnom zadatku. Funkcija broji kao argument prima tok podataka (tip
podatka *FILE) koji je već otvoren za tekstualnu datoteku. Glavni program otvara tok
podataka za postojeću tekstualnu datoteku, predaje ga funkciji, a kad funkcija obavi brojanje,
glavni program ispisuje rezultat i zatvara tok podataka.
4. Prepraviti rješenje zadatka 6. (ispis tablice množenja) iz prethodnih vježbi uz predavanja.
Tablicu množenja, umjesto na zaslon, treba zapisati u tekstualnu datoteku čije ime treba
učitati s tipkovnice. Editorom (npr. notepad) provjeriti sadržaj dobivene datoteke.
5. Napisati program koji pomoću funkcije fscanf čita realne brojeve iz tekstualne datoteke
brojevi.txt, te po završetku čitanja (kada se dođe do kraja datoteke ili se pri čitanju
dogodi pogreška) na zaslon ispisuje ili aritmetičku sredinu učitanih brojeva ili poruku "Nije
procitan niti jedan broj". Npr. za sadržaj datoteke:
22 13.5 -2 1
11.0 -3.5
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 23
6. U tekstualnu datoteku osobe.txt editorom upisati podatke o osobama (matični broj, ime,
prezime i datum rođenja). Primjer sadržaja datoteke prikazan je ovdje:
952 Nikolina Medvedec 15.5.1989
101 Iva Vurnek 17.6.1987
412 Natalija Voras 11.6.1988
551 Anatolij Ozimec 24.2.1989
115 Franjo Zdilar 22.11.1986
471 Ivana Suhina 8.6.1988
Napisati program koji će na zaslon ispisati sve podatke o osobama iz datoteke osobe.txt
čije ime sadrži niz znakova na. Za datoteku iz primjera, program treba na zaslon ispisati
sljedeće:
952 Nikolina Medvedec 15.5.1989
551 Anatolij Ozimec 24.2.1989
471 Ivana Suhina 8.6.1988
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 23
8. Ovaj zadatak je važan za razumijevanje funkcije fgets. U predavanjima prvo pažljivo pročitati
što točno radi funkcija fgets.
Uz pretpostavku da je sadržaj datoteke podaci.txt:
abcde
fghijk
lmnoprs
ABCDEFGH
#include <stdio.h>
#include <stdlib.h>
#define MAXLIN 7
return 0;
}
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 23
Rješenja
Rješenje 1. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
if (tokPod == NULL) {
printf("Ne mogu otvoriti %s\n", imeDat);
exit(1);
}
fclose(tokPod);
return 0;
}
Rješenje 2. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXIMEDAT 64
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 23
Rješenje 3. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXIMEDAT 64
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 23
Rješenje 4. zadatka
#include <stdio.h>
int main(void) {
int n, i, j;
char imeDat[64+1];
FILE *tok;
fclose(tok);
return 0;
}
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 23
Rješenje 5. zadatka
#include <stdio.h>
return 0;
}
Rješenje 6. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 23
Rješenje 7. zadatka
#include <stdio.h>
du = fopen("mjerenja.txt", "r");
fclose(du);
return 0;
}
Rješenje 8. zadatka
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 44
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 44
5. Napisati program kojim će se u novu binarnu datoteku slova.bin redom upisati sva velika,
a nakon njih sva mala slova abecede.
6. Funkcijama fseek i ftell odrediti i ispisati na zaslon broj znakova u datoteci slova.bin iz
prethodnog zadatka.
7. Jednim pozivom funkcije scanf u varijablu s učitati vrijednosti svih njenih članova:
struct str1 {
int stanje[2];
};
struct str2 {
struct str1 x;
float k;
} s;
8. Jednim pozivom funkcije scanf u varijablu w učitati vrijednosti svih njenih članova:
struct str1 {
float stanje[2];
};
struct str2 {
struct str1 y;
int k;
char ime[10+1];
} w;
9. Jednim pozivom funkcije scanf u varijablu b učitati vrijednosti svih njenih članova:
struct str1 {
float x;
int k;
};
struct str2 {
struct str1 z1;
struct str1 z2;
} b;
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 44
Rješenja
Rješenje 1. zadatka
#include <stdio.h>
return 0;
}
Rješenje 2. zadatka
#include <stdio.h>
#include <string.h>
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 44
Rješenje 3. zadatka
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#define MIN_N 2
#define MAX_N 8
#define DG 150
#define GG 160
#define BROJ_ZAPISA 20
Rješenje 4. zadatka
#include <stdio.h>
#define MAX_N 8
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 44
Rješenje 5. zadatka
#include <stdio.h>
Rješenje 6. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
fclose (ulTok);
return 0;
}
Rješenje 7. zadatka
scanf("%d%d%f", &s.x.stanje[0], &s.x.stanje[1], &s.k);
/* ispis radi provjere */
printf("%d\n%d\n", s.x.stanje[0], s.x.stanje[1]);
printf("\n");
printf("%f\n", s.k);
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 44
Rješenje 8. zadatka
scanf("%f%f%d%10s", &w.y.stanje[0], &w.y.stanje[1], &w.k, w.ime);
/* ispis radi provjere */
printf("%f\n%f\n", w.y.stanje[0], w.y.stanje[1]);
printf("\n");
printf("%d\n", w.k);
printf("\n");
printf("%s\n", w.ime);
Rješenje 9. zadatka
scanf("%f%d%f%d", &b.z1.x, &b.z1.k, &b.z2.x, &b.z2.k);
/* ispis radi provjere */
printf("%f\n%d\n", b.z1.x, b.z1.k);
printf("\n");
printf("%f\n%d\n", b.z2.x, b.z2.k);
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
Napomene:
- Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja
- Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
1. Napisati program kojim će se u novu binarnu datoteku slova.bin redom upisati sva velika,
nakon njih sva mala slova abecede, a nakon njih sve znamenke.
2. Na slučajan način (funkcijom rand) odabirati pozicije u datoteci slova.bin iz prethodnog
zadatka, sa svake odabrane pozicije pročitati jedan znak i ispisati ga na zaslon. Postupak
završiti nakon što se na zaslon ispiše 40 znakova ili veliki znak 'X'.
3. U tekstualnu datoteku ulaz.txt editorom su upisani podaci o osobama (matični broj, ime,
prezime i datum rođenja). Primjer sadržaja datoteke prikazan je ovdje:
952 Nikolina Medvedec 15.05.1989
101 Davor Vurnek 17.06.1987
205 Zoran Habajec 09.12.1987
412 Davor Voras 11.06.1988
551 Zvonimir Ozimec 24.02.1989
115 Franjo Zdilar 22.01.1986
104 Stipe Pugelnik 03.05.1987
471 Nina Suhina 08.06.1988
Napisati program koji će sadržaj datoteke ulaz.txt prepisati u novu binarnu datoteku
izlaz.bin. Jedan zapis datoteke izlaz.bin sadrži: matični broj (long), ime (15+1 znak),
prezime (15+1 znak), dan rođenja (short), mjesec rođenja (short), godinu rođenja (short).
Koristiti strukture!
4. Napisati program koji će na zaslon ispisati matične brojeve, imena i prezimena svih osoba
koje rođendan imaju u mjesecu lipnju. Podaci o osobama se nalaze u postojećoj binarnoj
datoteci izlaz.bin koja je dobivena kao rezultat obavljanja programa iz prethodnog
zadatka. Koristiti strukture!
Napomena: kod rješavanja ovog, a također i svih sličnih zadataka s datotekama, nije
dopušteno sve zapise "učitati u memoriju", npr. u jedno veliko polje, i onda po tom polju tražiti
zapise koji zadovoljavaju neki uvjet. Umjesto toga, u memoriju učitati prvi zapis, provjeriti
treba li na zaslon ispisati podatke iz tog zapisa, zatim učitati drugi zapis, itd.
5. Koristi se slijedna tekstualna datoteka ulaz.txt opisana u 3. zadatku. Napisati program koji
će na zaslon ispisati prezime i ime za svaki treći zapis iz datoteke, počevši od prvog zapisa
(tj. za prvi zapis, za četvrti zapis, za sedmi zapis, itd).
6. Rezultat ispisa na zaslon (standardni izlaz) iz prethodnog zadatka preusmjeriti u datoteku
c:/tmp/rezultat.txt
7. U direktnoj binarnoj datoteci bodovi nalaze se podaci o 10 studenata i bodovima koje su
dobili za zalaganje na nastavi. Svaki zapis sadrži matični broj (int), prezime i ime (20+1 znak)
i broj bodova (int). Matični brojevi su u rasponu od 1-10, a redni broj zapisa odgovara
matičnom broju. Napisati program kojim će se za jednog slučajno odabranog studenta za
10% povećati dotadašnju vrijednost njegovih bodova. Ograničiti uvećani broj bodova na
maksimalnih 500 bodova.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
8. Napisati program koji na kraj datoteke mjerenja.txt koja je opisana u 7. zadatku iz 23. vježbi
uz predavanja, dodaje jedan novi zapis o mjerenjima temperature. Preko tipkovnice se
učitava redni broj dana, broj mjerenja (ne više od 24) i parovi (sat, temperatura). Ukoliko u
datoteci već postoji zapis o učitanom rednom broju dana, dojavljuje se odgovarajuća poruka.
9. Uz pretpostavku da se dnevno mogu obaviti najviše 24 mjerenja temperature, prepišite
datoteku mjerenje.txt u odgovarajuću direktnu binarnu datoteku mjerenja.bin. Redni broj
zapisa u datoteci mjerenja.bin odgovara rednom broju dana.
10. Napišite program koji za redni broj dana učitan preko tipkovnice, čita zapis iz datoteke
mjerenja.bin i ispisuje vremena mjerenja i temperature izmjerene tog dana. Ukoliko mjerenje
za zadani dan ne postoji, ispisati odgovarajuću poruku.
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
Rješenja
Rješenje 1. zadatka
#include <stdio.h>
Rješenje 2. zadatka
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
srand((unsigned)time(NULL));
do {
/* slucajna pozicija u datoteci: [0, brojZnakova - 1] */
slucajnaPozicija = rand() % brojZnakova;
fseek(ulTok, slucajnaPozicija, SEEK_SET);
fread(&c, sizeof(c), 1, ulTok);
printf("%c", c);
++brojIspisanih;
} while (c != 'X' && brojIspisanih < 40);
printf("\n");
fclose (ulTok);
return 0;
}
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
Rješenje 3. zadatka
#include <stdio.h>
int main (void) {
FILE *ulTok, *izTok;
char tocka;
struct {
long int mbr;
char ime[15+1];
char prez[15+1];
short int dan;
short int mjesec;
short int godina;
} osoba;
Rješenje 4. zadatka
#include <stdio.h>
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
Rješenje 5. zadatka
#include <stdio.h>
Rješenje 6. zadatka
Rješenje 7. zadatka
Zadatak ilustrira kako se na slučajan način odabire redni broj zapisa, kako se čita odabrani zapis iz
direktne tekstualne datoteke, te kako se sadržaj zapisa direktne tekstualne datoteke može
promijeniti. Također ilustrira kako se ista datoteka može koristiti i za čitanje i za pisanje.
NAPOMENA: između operacija čitanja i pisanja u isti tok podataka mora se nalaziti barem jedan
poziv funkcije fseek nad tim tokom podataka (čak i u slučaju kad nam pomak značke nije potreban
jer se značka već nalazi na željenoj poziciji). Između operacija pisanja i čitanja iz istog toka
podataka, mora se nalaziti barem jedan poziv funkcije fseek ili fflush. Funkcija fflush(tokPodataka)
prazni međuspremnike toka podataka. Ne pridržavamo li se tih pravila, mogli bismo izvodeći svoje
programe za vježbu dobiti posve pogrešne rezultate. Na završnom ispitu se neće inzistirati na tom
detalju (neće se "oduzimati bodovi" u slučaju nepoštovanja tih pravila)
Dakle, ako u programu za vježbu imamo pisanje pa čitanje iz istog toka podataka
fwrite(..., tokPodataka);
/* ovdje negdje između se mora nalaziti ili fflush(tokPodataka) ili fseek(tokPodataka, ...) */
fread(..., tokPodataka);
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
fclose(dUlIzl);
return 0;
}
U ovom zadatku je fseek između fread i fwrite ionako bio potreban, pa se nije moglo pogriješiti u
odnosu na prethodnu napomenu.
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
Rješenje 8. zadatka
Zadatak ilustrira kako se na kraj slijedne tekstualne datoteke može dodati zapis.
#include <stdio.h>
#include <stdlib.h>
di = fopen("mjerenja.txt", "a+");
/* ucitati redni broj novog dana */
printf("Upisite redni broj novog dana>");
scanf("%d", &noviDan);
fclose(di);
return 0;
}
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
Rješenje 9. zadatka
Zadatak ilustrira pisanje u direktnu tekstualnu datoteku čiji zapis, između ostalog, sadrži polje.
#include <stdio.h>
du = fopen("mjerenja.txt", "r");
di = fopen("mjerenja.bin", "wb");
return 0;
}
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG
Vježbe uz predavanja 10-Datoteke.pdf - do stranice: 75
#include <stdio.h>
if (zapis.rbrDan == rbrDan) {
printf("mjerenja za dan: %d\n", zapis.rbrDan);
for (i=0; i < zapis.brMjer; ++i) {
printf(" Sat: %2d Temperatura: %5.1f\n",
zapis.sati[i], zapis.temp[i]);
}
}
else {
printf("Nema podataka o mjerenju za zadani dan\n");
}
fclose(du);
return 0;
}
9
FAKULTET ELEKTROTEHNIKE, STROJARSTVA I BRODOGRADNJE
SVEUČILIŠTE U SPLITU
(UVOD U)
RAČUNALA I PROGRAMIRANJE
Laboratorijske vježbe
Listopad, 2010.
KATEDRA ZA MODELIRANJE I INTELIGENTNE RAČUNALNE SUSTAVE (KaMIS)
1. Gottfried, B.: "Schaum's Outline Series: Programming with C", Second Edition, McGraw-Hill,
1996.
2. Vulin, R.: "Zbirka riješenih zadataka iz C-a", Školska knjiga, Zagreb, 2003.
3. Parlante, N.: "Essential C", 2003, http://cslibrary.stanford.edu/101/EssentialC.pdf.
4. Materijali dostupni preko MIT OpenCourseWare projekta:
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/.
2
VJEŽBA 1
Programski jezik C nastao je 1972. godine u Bell laboratorijima, kao rezultat rada računalnog
znanstvenika Dennisa Ritchiea. On je prvi kreirao i primijenio programski jezik C.
Slika 1.1. Računalni znanstvenici Ken Thompson (lijevo) i Dennis Ritchie (desno) [1].
Većina bitnih ideja i koncepata koji su korišteni prilikom razvijanja programskog jezika C došlo je iz
programskog jezika BCPL (engl. Basic Combined Programming Language), ali samo posredno, preko
programskog jezika B kojega je razvio Ken Thompson 1970. godine za prvi UNIX sustav na DEC PDP
računalu (engl. Digital Equipment Corporation Programmed Data Processor).
Dennis Ritchie i Ken Thompson su 1983. godine nagrađeni Turingovom nagradom (za teoretski rad
na području generičkih operacijskih sustava te za implementaciju operacijskog sustava UNIX), što je
jedna od najvećih počasti koju računalni znanstvenici mogu dobiti.
Zašto C?
C jezik bi se mogao nazvati jezikom niže razine sa stajališta objektno-orijentiranog programera, ali
sa stajališta programera koji piše programe u Asembleru (engl. Assembly language) ili (teoretski) u
strojnom jeziku (npr. 00010110 01010111 11111000 10000001), bio bi shvaćen kao jezik više
3
razine. Izrazi "jezik niže razine" te "jezik više razine" su dosta relativni i obično jako vezani uz
kontekst u kojemu se koriste.
1. Programer napiše izvorni kod programa (engl. source code). Datoteke u kojima se nalazi
izvorni kod imaju ekstenziju .c (ako su napisane u C-u), i može ih biti više od jedne.
2. Izvorni kod se prevodi u objektni kod pomoću prevoditelja (engl. compiler). Prevoditelj u
objektni kod posebno prevede svaku datoteku u kojoj se nalazi izvorni kod. Datoteke u
kojima se nalazi objektni kod sadrže kod razumljiv računalu (strojni kod), te imaju ekstenziju
.obj ili .o.
3. Datoteke u kojima se nalazi objektni kod i biblioteke koje su specificirane u njemu se
povezuju u jedinstvenu datoteku pomoću poveznika (engl. linker). Ta jedinstvena datoteka
naziva se izvršna datoteka, i ima ekstenziju .exe.
Važno je napomenuti da je prevođenje izvornog koda u strojni kod jednosmjeran proces, tj. strojni
kod se gotovo nikad u potpunosti ne može uspješno prevesti natrag u izvorni kod.
4
Ukratko o C programima
#include <stdio.h>
#include ...
int main()
{
Naredbe napisane u C-u...
return 0;
}
U programskim jezicima često se nailazi na koncept funkcije. Funkcija je dio programa koji ima
svoje ime, te koji može primati određene argumente i vratiti određeni argument (ako funkcija vrati
nulu, to obično znači da su sve naredbe u njoj uspješno izvršene). Funkcije se koriste kako bi se
povećala preglednost programa, te kako bi programeri mogli koristiti već unaprijed isprogramirana
rješenja za učestale probleme.
Funkcija main() je glavna funkcija u C jeziku. Jedina razlika između ove funkcije i svih ostalih jest što
će se funkcija main() uvijek izvesti prije svih ostalih funkcija. Ostale se funkcije moraju pozvati iz
funkcije main() da bi se uopće mogle izvršiti.
Linija koda int main() kaže da funkcija main() vraća cijeli broj (engl. integer).
Unutar vitičastih zagrada piše se kod programa. Na kraju programa se pomoću naredbe return
može specificirati vrijednost koju će funkcija vratiti. U ovome slučaju funkcija main() vraća nulu.
Nakon svake naredbe stavlja se točka zarez (';'). Ona označava kraj jedne naredbe i početak druge.
Slijedeći program je najmanji i najjednostavniji program koji se može napisati u C-u. Program ne
radi ništa.
5
#include <stdio.h>
int main()
{
return 0;
}
Ako nije potrebno da funkcija vraća neku vrijednost, onda bi se gornji program mogao napisati u
slijedećem (ekvivalentnom) obliku:
#include <stdio.h>
void main()
{
}
Hello World!
Najjednostavniji program napisan u bilo kojem programskom jeziku (osim onih programa koji ne
rade ništa), bio bi program koji na ekran ispisuje nekakav tekst. U računarstvu se tradicionalno za
takav tekst uzima rečenica "Hello World!".
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
Naredba printf("Neki tekst..."); se koristi za ispis teksta na ekran računala. Tekst se piše unutar
navodnika, a ako se nakon teksta još doda i znak '\n', to znači da će kursor nakon ispisa teksta na
ekran prijeći u novu liniju.
Varijable
Varijable su memorijske lokacije čija se vrijednost tijekom izvođenja programa može promijeniti, tj.
varijable su imena koja koristimo za memorijske lokacije na kojima se nalaze vrijednosti s kojima
6
radimo.
Varijable moraju biti prijavljene prije upotrebe, i to najčešće na početku funkcije, prije bilo koje
izvršne naredbe. Kaže se da se varijable deklariraju. Deklaracijom se varijabli pridružuju ime i tip
(npr. određuje se da li će varijabla sadržavati znak ili broj), te se deklarira potrebna količina
memorije (npr. 1 bajt za znak ili 4 bajta za cijeli broj).
int a;
Ovo znači da je deklariran memorijski prostor (imena 'a') u koji će se spremiti cijeli broj.
int varijabla1 = 5;
float varijabla2 = 2.3;
char varijabla3 = 'c';
char a = 'A'; // a = A
char b = 65; // b = A --> u ASCII tablici, znak 'A' je predstavljen sa brojem 65
Imena varijabli sastoje se od slova i znamenki, pri čemu prvi znak mora uvijek biti slovo. Znak
podcrte '_' (engl. underscore) uvažava se kao slovo, što je bitna stvar ako se želi povećati čitljivost
7
programa.
int varijabla;
int druga_varijabla;
int trecaVarijabla;
Operatori u C-u
Relacijski operatori: < (manje), > (veće), <= (manje ili jednako), >= (veće ili jednako), == (jednako),
!= (nije jednako). Relacijski operatori se koriste kod usporedbi.
Operator konverzije tipova: cast. Ako u programskom kodu naiđemo na operator čiji su operandi
različitog tipa (npr. jedan je int, a drugi float), čitav će izraz dobiti konačnu vrijednost po točno
određenim pravilima. Cast operator pretvara izraz bilo kojeg tipa u željeni tip. Općenita formula
glasi: (tip) izraz.
Primjer:
#include <stdio.h>
void main()
{
int x;
char y = 'A';
x = (int) y;
printf("x = %d\n", y);
}
8
ISPIS PROGRAMA:
x = 65
U gornjem primjeru, varijabli x se dodjeljuje ASCII vrijednost varijable y (odnosno znaka A), a to je
65.
Operatori dodjele vrijednosti. Većina binarnih operatora ima odgovarajući operator dodjele
vrijednosti po pravilu: izraz1 operator= izraz2. To je ekvivalentno izrazu: izraz1 = (izraz1) operator
(izraz2). Na primjer, a *= b je ekvivalentno izrazu a = a * b. a *= b je samo kraći način zapisa izraza
a = a * b.
Napomena: obratite pozornost na operator dodjele vrijednosti (=) i operator uspoređivanja dviju
vrijednosti (==). Ovi operatori nisu jednaki! Miješanje ovih dvaju operatora je jedna od najčešćih
grešaka u programiranju! Ovakva se greška naziva logička greška, i prevoditelj vas na nju neće
upozoriti.
Operator '==' uspoređuje dvije varijable i vraća nulu ili jedinicu, ovisno o tome jesu li te varijable
jednake.
9
DODATAK
Svi programi opisani u vježbama iz kolegija (Uvod u) Računala i programiranje mogu se izvršavati u
MS Visual Studio integriranoj razvojnoj okolini (engl. Integrated Development Environment ili IDE).
IDE je razvojna okolina unutar koje programeri pišu i testiraju svoje programe.
10
Da biste mogli napisati i pokrenuti prvi program u C-u, slijedite ove upute:
4. Otvoriti će se novi prozor imena Win32 Application Wizard. Pod Application Settings
odaberite Console application i Empty project, te deselektirajte Precompiled header.
11
5. Kliknite Finish. Otvoriti će se ovakav prozor:
6. Sa lijeve strane možete vidjeti nekoliko datoteka. Desnim klikom miša kliknite na datoteku
imena Source Files, te odaberite Add --> New Item. Odaberite C++ File (.cpp). Novoj datoteci
dodijelite neko ime (npr. mojPrviProgram). Kliknite Add. Otvoriti će se upravo kreirana
tekstualna datoteka.
12
7. U datoteku upišite slijedeći programski kod:
#include <stdio.h>
void main()
{
printf("Hello World!\n");
getchar(); /* program čeka unos znaka sa tipkovnice */
}
Na kraju programa nalazi se poziv funkcije getchar(). Ta funkcija čeka na unos znaka sa
tipkovnice. Da se u programu ne nalazi ova linija koda, prozor sa tekstom Hello World! bi se
zatvorio čim bi se program izvršio (gotovo trenutačno), te ne biste uspjeli vidjeti rezultate
programa.
8. Kliknite Debug --> Build Solution, pa zatim Debug --> Start Debugging. Alternativno možete
pritisnuti F7 (Build Solution) i F5 (Start Debugging).
13
VJEŽBA 2
Komentari u C-u
#include <stdio.h>
void main()
{
printf("Hello World!\n"); /* ispisuje "Hello World!" na ekran */
}
Prilikom prevođenja programa, prevoditelj zanemaruje sve što se nalazi unutar znakova '/*' i '*/'.
Oni označavaju početak i kraj komentara.
/* ovo je komentar */
/*
i ovo je komentar
*/
Ovakva vrsta komentara se danas sve rijeđe koristi. Popularnost im je pala nakon što su u
programiranje uvedeni jednoredni komentari "uvezeni" iz programskog jezika C++.
// komentar
Gornji komentar je jednoredi komentar. Prednost ovakvih komentara je što programer ne mora
paziti na završetak komentara, a nedostatak je taj što su ograničeni na jedan redak.
Komentari su posebno važni kod velikih programa (sa više tisuća linija koda), jer programski kod
postaje pregledniji i razumljiviji.
Escape nizovi
Kombinacije znakova koje započinju sa znakom '\' (engl. backslash), te iza kojih slijedi neki drugi
znak, slovo, ili niz brojeva (ako se koristi oktalni ili heksadecimalni zapis), nazivaju se escape nizovi.
Njihova zadaća jest da promijene značenje određenih znakova ili simbola (Tablica 2.1). Na primjer,
znak 'n' se tretira na jedan način kada predstavlja ime varijable, a na drugi način kada se ispred
njega nalazi znak '\'.
14
(engl. bell code, audible alert)
backspace \b 008
vodoravni tabulator \t 009
okomiti tabulator \v 011
novi red ili LF (engl. Line Feed) \n 010
nova stranica \f 012
CR (engl. Carriage Return) \r 013
navodnik \" 034
jednostruki navodnik (apostrof) \' 039
upitnik \? 063
backslash \\ 092
null znak \0 000
Znakovi pretvorbe
#include <stdio.h>
int main()
{
int a; // deklariramo cjelobrojnu varijablu a
a = 10; // varijabli a pridružujemo vrijednost 10
printf("%d\n", a); // na ekran ispisujemo vrijednost varijable a
return 0; // funkcija vraća nulu
}
U gornjem se primjeru koristi znak %d. Kada se ispred nekih određenih slova (Tablica 2.2) nalazi
znak '%', onda slovo predstavlja znak pretvorbe (engl. conversion character). On označava tip ili
format znaka koji se ispisuje na ekran ili učitava sa tipkovnice (npr. int, float...).
15
podatak može biti zapisan u dekadskom, oktalnom ili heksadecimalnom
brojevnom sustavu
o podatak je oktalna vrijednost, bez vodeće nule
s podatak je niz znakova (engl. string)
null znak ('\0') se automatski dodaje na kraj stringa
u podatak je decimalna vrijednost bez predznaka
x podatak je heksadecimalna vrijednost, bez vodećeg 0x
[. . .] podatak je niz znakova koji može sadržavati razmake
Funkcija printf()
Primjer:
#include <stdio.h>
void main()
{
int a = 5;
float b = 5.1;
Funkcija printf() dozvoljava korištenje ograničenja na minimalnu duljinu niza koji se upisuje (npr. niz
brojeva). Ako je niz veći od minimalne duljine, onda ograničenje nema nikakvog utjecaja na ispis
niza. U programerskim krugovima ta je situacija poznata pod imenom "override". Funkcija printf()
također dozvoljava specifikaciju točnosti nekog broja (npr. zaokruživanje broja na određeni broj
decimala iza decimalne točke).
Primjer:
#include <stdio.h>
void main()
{
16
int a = 12345;
float b = 345.678;
printf("%3d\n", a);
printf("%10d\n\n", a);
printf("%6g\n", b);
printf("%13g\n\n", b);
printf("%13e\n", b);
printf("%16e\n\n", b);
printf("%.4f\n", b);
printf("%.30e\n", b);
getchar();
}
ISPIS PROGRAMA:
Funkcija scanf()
Primjer:
#include <stdio.h>
void main()
{
int a;
float b;
17
scanf("%f", &b);
getchar();
}
Kada se ispred imena varijable nalazi znak &, onda &ime_varijable predstavlja adresu te varijable.
Da bi funkcija scanf() mogla nekoj varijabli promijeniti vrijednost, najprije mora znati na kojoj se
memorijskoj adresi ta varijabla nalazi.
Kao i funkcija printf(), funkcija scanf() omogućava postavljanje ograničenja na duljinu niza koji se
učitava sa tipkovnice.
Primjer:
#include <stdio.h>
void main()
{
int a, b, c;
scanf("%3d %3d %3d", &a, &b, &c);
printf("a = %d b = %d c = %d\n", a, b, c);
}
Unos: 1 2 3
Ispis: a = 1 b = 2 c = 3
Unos: 123456789
Ispis: a = 123 b = 456 c = 789
18
ZADACI
Zadatak 2.1. Napišite program koji ispisuje zauzeće memorije u bajtovima (engl. byte) za sve
standardne tipove programskog jezika C (char, int, short, long, float, double, unsigned short,
unsigned int, unsigned long). Koristite funkciju sizeof().
Rješenje:
#include <stdio.h>
void main ()
{
printf("Sizeof(char) = %d", sizeof(char));
printf("\nSizeof(int) = %d", sizeof(int));
printf("\nSizeof(short) = %d", sizeof(short));
printf("\nSizeof(long) = %d", sizeof(long));
printf("\nSizeof(float) = %d", sizeof(float));
printf("\nSizeof(double) = %d", sizeof(double));
printf("\nSizeof(unsigned short) = %d", sizeof(unsigned short));
printf("\nSizeof(unsigned int) = %d", sizeof(unsigned int));
printf("\nSizeof(unsigned long) = %d\n", sizeof(unsigned long));
getchar();
}
ISPIS PROGRAMA:
Zadatak 2.2. Napišite program u kojem deklarirate integer i char varijablu. Objema pridijelite
vrijednost znakovne konstante (primjerice 'c'). Ispišite vrijednosti varijabli i veličinu memorije koju
zauzimaju. Kako komentirate rezultate?
Rješenje:
#include <stdio.h>
void main()
19
{
int i = 'c';
char n = 'c' ;
getchar();
}
ISPIS PROGRAMA:
Zadatak 2.3. Napišite program koji ispisuje znakove 'z' i 'Z', s tim da su za prvi znak rezervirana 3
mjesta za ispis na ekran, a za drugi 5 mjesta.
Rješenje:
#include <stdio.h>
void main()
{
printf("Slova:\n%3c\n%5c\n", 'z', 'Z');
getchar();
}
Zadatak 2.4. Primjer cjelobrojnog i realnog dijeljenja. Kako komentirate rezultate programa?
#include <stdio.h>
void main()
{
int a = 5;
int b = 2;
20
int d = 5/2; // cjelobrojno dijeljenje – rezultat je 2
float c = a/b; // Iako je c float, vrši se cjelobrojno dijeljenje jer su i a i b cijeli brojevi
printf("c = %f\n",c);
printf("Uzrok problema : 5/2 = %f\n", 5/2);
printf("Popravljeno : 5.0/2.0 = %f\n", 5.0/2.0);
printf("Moze i : 5/2.0 = %f i 5.0/2 = %f \n", 5/2.0, 5.0/2);
printf("Za varijable moramo uvesti cast-ing : %f\n", (float)a/(float)b);
getchar();
}
ISPIS PROGRAMA:
Rješenje:
#include <stdio.h>
void main()
{
int x;
getchar();
getchar();
}
Zadatak 2.6. Napišite program za unos cijelog broja sa tipkovnice. Neka program ispiše kvadrat tog
broja.
Rješenje:
#include <stdio.h>
21
void main()
{
int a, b;
getchar();
getchar();
}
22
DOMAĆI RAD
Zadatak 2.7. Napišite program za unos dva realna broja. Neka program ispiše rezultat njihovog
zbrajanja, oduzimanja, množenja i dijeljenja.
Zadatak 2.8. Napišite program za unos realnog broja. Neka program ispiše kvadrat i korijen tog
broja. Napomena: funkcija za računanje korijena je sqrt() (engl. square root) i definirana je u
biblioteci <math.h>.
Zadatak 2.9. Napišite program koji za proizvoljni radijus računa opseg kruga.
23
DODATAK
ASCII tablica
24
VJEŽBA 3
Naredbe kontrole toka svoje djelovanje zasnivaju na logičkim izrazima. Najčešće se koriste u svrhu
grananja programa, tj. odabira jedne od nekoliko mogućih radnji.
if (logički izraz)
naredba1
if (logički izraz)
naredba 1
else
naredba2
#include <stdio.h>
void main()
{
int a = 7;
int b = 3;
if (a > b)
printf("Vrijednost varijable a = %d.\n", a);
else
printf("Vrijednost varijable b = %d.\n", b);
getchar();
25
}
ISPIS PROGRAMA:
Vrijednost varijable a = 7.
Umjesto if-else konstrukcije ponekad se može koristiti uvjetni operator. Uvjetni operator je
ternarni operator, jer ima tri elementa.
Opći oblik:
Program bi u ovom slučaju ispitao vrijednost logičkog izraza, te ako je ta vrijednost jednaka jedinici
izvršio bi se izraz 1, a ako je jednaka nuli izvršio bi se izraz 2.
Primjer (uvjetni operator): Program provjerava da li je varijabla a veća od nule. Ako jest, postavlja
varijablu b na jedinicu, a ako nije, postavlja varijablu b na nulu. Zatim ispisuje vrijednost varijable b.
#include <stdio.h>
void main()
{
int a = 7;
int b;
(a > 0) ? b = 1 : b = 0;
getchar();
}
ISPIS PROGRAMA:
b=1
Programske petlje
Programske petlje se koriste kada se više puta želi ponoviti ista naredba ili blok naredbi. U
programskom jeziku C postoje tri petlje: for, while i do-while.
26
Primjer (for petlja): Program ispisuje brojeve od 0 do 9.
#include <stdio.h>
void main()
{
int a;
getchar();
}
while (uvjet)
{
blok naredbi
}
#include <stdio.h>
void main()
{
int a = 9;
getchar();
}
do
{
blok naredbi
} while (uvjet);
27
Primjer (do-while petlja): Program ispisuje brojeve od 0-9.
#include <stdio.h>
void main()
{
int a = 0;
do
{
printf("%d\n", a);
a++;
}
while (a < 10);
getchar();
}
Petlje for i while se ne moraju uopće izvršiti (ako uvjet nije ispunjen), ali petlja do-while je
specifična po tome što se ona uvijek izvrši barem jedan put, pa tek nakon prvog izvršavanja
provjerava uvjet.
28
ZADACI
Zadatak 3.1. Napišite program koji prihvaća i uspoređuje bilo koja dva cijela broja unesena sa
tipkovnice. Neka se na ekran ispiše rezultat usporedbe tih brojeva.
Rješenje:
#include <stdio.h>
void main()
{
int a;
int b;
if (a > b)
printf("%d > %d \n", a, b);
else if (a < b)
printf("%d > %d \n", b, a);
else
printf("%d = %d \n", a, b);
getchar();
getchar();
}
Zadatak 3.2. Napišite program koji ispisuje sumu svih brojeva od 1 do 10.
Rješenje:
#include<stdio.h>
void main()
{
int i;
int suma = 0;
29
printf("Suma je %d.\n", suma);
getchar();
}
Zadatak 3.3. Napišite program koji od korisnika traži da unese dvije varijable (tipa int), s tim da
druga varijabla mora biti manja od prve. Zahtjev za unos druge varijable se ponavlja (koristite while
petlju) sve dok korisnik ne unese cijeli broj koji je manji od prvog broja. Program zatim treba
ispisati: "Prva varijabla je (ispisati vrijednost), a druga je (ispisati vrijednost). Druga varijabla je
manja od prve."
Rješenje:
#include <stdio.h>
void main()
{
int a;
int b;
int uvjet = 1;
if (b < a)
uvjet = 0;
}
printf("Prva varijabla je %d, a druga je %d. Druga varijabla je manja od prve.\n", a, b);
getchar();
getchar();
}
Zadatak 3.4. Napišite program u kojem korisnik unosi tri cijela broja, a program ih sortira po veličini
(od najmanjeg prema najvećem) isključivo korištenjem if naredbi. Ne koristite petlje!
Rješenje:
#include <stdio.h>
30
void main()
{
int a, b, c;
int temp;
getchar();
getchar();
}
Zadatak 3.5. Napišite program u kojem korisnik unosi ocjene ispita, sve dok se ne unese 0. Ocjene
izvan dopuštenog raspona ocjena od 1 do 5 se zanemaruju. Program treba ispisati koliko je na
31
ispitu bilo pozitivnih (prolaznih), a koliko negativnih (nedovoljnih) ocjena, te kolika je bila prosječna
ocjena ispita.
Rješenje:
#include <stdio.h>
void main ()
{
int ocjena, brPoz = 0, brNeg = 0, suma = 0;
float prosjek;
do
{
printf("Unesite ocjenu: \n");
scanf("%d", &ocjena);
else
{
suma += ocjena;
if (ocjena == 1)
brNeg++;
32
Zadatak 3.6. Što je rezultat izvođenja slijedećih programa? Ispišite sve međurezultate do cilja!
a) b) c)
d) e) f)
printf("%d\n", suma);
}
Rješenja:
a) b) c)
0 4 5
1 3 4
2 2 3
3 1 2
4 0 1
d) e) f)
Izlaz B 4 4
33
DODATNI ZADACI
Zadatak 3.7. Napišite program koji pomoću for petlje ispisuje kvadrate, kubove i korijene prvih 20
prirodnih brojeva. Napomena: funkcija za računanje korijena je sqrt (engl. square root) i nalazi se u
standardnoj biblioteci <math.h>.
Zadatak 3.8. Napišite program koji generira i ispisuje deset slučajnih brojeva. Napomena: koristite
standardne biblioteke <stdlib.h> i <time.h>, te funkcije srand() i rand().
Zadatak 3.9. Napišite program za pogađanje broja generiranog od strane računala. Broji se broj
pokušaja, a pri svakom pokušaju računalo daje informaciju da li je broj veći, manji ili pogođen. Ako
je broj pogođen, izlazi se iz programa, uz ispis pogođenog broja te ukupnog broja pokušaja.
Napomena vezana uz zadatke 3.8 i 3.9: U programiranju ne postoje stvarno slučajni brojevi, već
samo pseudoslučajni. Generator pseudoslučajnih brojeva će za istu ulaznu vrijednost uvijek
generirati iste pseudoslučajne brojeve. Funkcija srand() postavlja inicijalnu vrijednost za generator
slučajnih brojeva koji je implementiran u funkciji rand(). Ako se ne koristi srand(), rand() će
izgenerirati uvijek isti niz pseudoslučajnih brojeva [2].
DOMAĆI RAD
Zadatak 3.10. Napišite program u kojem korisnik unosi četiri cjelobrojne varijable, a program ih
sortira po veličini (od najveće prema najmanjoj) isključivo korištenjem if naredbi (biti će vam
potrebno šest if naredbi). Ne koristite petlje!
Zadatak 3.11. a) Napišite program koji ispisuje cijelu ASCII tablicu. b) Napišite program u kojem
korisnik unosi neki znak (slovo ili broj) a program onda ispisuje sva ostala slova ili brojeve koji se u
ASCII tablici nalaze iza unesenog znaka. Na primjer, ako korisnik upiše broj '7', program treba
ispisati '8 9'. Ako korisnik unese 'b', program treba ispisati ostatak abecede. Razlikujte mala i velika
slova! Ignorirajte sve unesene znakove koji ne predstavljaju slovo ili broj! Napomena: možete
koristiti funkcije isdigit(), isupper() i islower() za provjeru unesenih znakova, ali onda morate
uključite biblioteku <ctype.h>.
Zadatak 3.12. Napišite program koji ispisuje rješenja kvadratne jednadžbe. Neka korisnik unese
koeficijente kvadratne jednadžbe. Podsjetnik:
2
ax bxc=0
−b± b2 −4ac
x=
2a
34
VJEŽBA 4
Naredba switch-case
Ako u izvornom kodu postoji posebno dugačak lanac if-else naredbi, dobra je praksa takve naredbe
zamijeniti sa naredbom switch-case. Naredba switch-case je preglednije zapisana if-else naredba.
Najčešće se koristi za stvaranje izbornika (engl. menu) [3]. Na primjer, ako korisnik unese broj '1',
izvrši se jedna naredba, a ako unese '2', izvrši se neka druga naredba.
switch (izraz)
{
case 'vrijednost izraza 1':
...
break;
case 'vrijednost izraza 2':
...
break;
...
default: // izvršava se ako nijedan drugi uvjet nije zadovoljen
...
}
#include <stdio.h>
void main()
{
int a;
switch (a)
{
case 0:
printf("Uneseni broj je jednak nuli.\n");
break;
case 1:
case 3:
case 5:
case 7:
case 9:
35
printf("Uneseni broj je neparan.\n");
break;
case 2:
case 4:
case 6:
case 8:
printf("Uneseni broj je paran.\n");
break;
default:
printf("Dozvoljen je unos samo jednoznamenkastih brojeva.\n");
break;
}
getchar();
getchar();
}
Primijetite da je nakon više case naredbi izostavljena naredba break. To znači da će se za sve te
case naredbe izvršiti isti blok programskog koda (prvi na koji program naiđe tijekom izvođenja).
Ovakva je situacija poznata pod imenom "propadanje" kroz switch-case naredbu (engl. fall-
through).
Naredba break se koristi za prekid izvršavanja neke petlje. Slično, naredba continue se koristi za
prekid jedne iteracije neke petlje, te skok na iduću iteraciju.
#include <stdio.h>
void main()
{
int i;
getchar();
}
36
ISPIS PROGRAMA:
Unutar petlje...
Izasli smo iz petlje!
#include <stdio.h>
void main()
{
int i;
getchar();
}
ISPIS PROGRAMA:
Prvi tekst...
Prvi tekst...
Prvi tekst...
Naredba goto
Naredba goto je naredba bezuvjetnog skoka. Izvršavanjem naredbe goto program se grana na
zadanu programsku liniju [3].
Opći oblik:
#include <stdio.h>
void main()
{
ime_labele:
...programski kod...
goto ime_labele;
}
37
Primjer (goto naredba):
#include <stdio.h>
void main()
{
int i = 0;
start: // start je ime labele
printf("Beam me up, Scotty!\n");
if (i == 0)
{
i = 1;
goto start; // program skače na labelu start
}
getchar();
}
ISPIS PROGRAMA:
Beam me up, Scotty!
Beam me up, Scotty!
Većina programera izbjegava korištenje goto naredbe, budući da ona najčešće smanjuje
preglednost i razumljivost programskog koda. U programskim jezicima više razine ova se naredba
gotovo nikad ne koristi, a neki je jezici čak i zabranjuju. Sve što se može napraviti sa naredbom
goto, može se napraviti i sa standardnim petljama u C-u.
End-of-File (EOF)
End-of-File (EOF) označava stanje u kojem se nađe operacijski sustav kada na standardnom ulazu
ponestane znakova za čitanje. EOF je implementiran kao cjelobrojna konstanta koja ovisi o
operacijskom sustavu, i na Windows-ima je definirana kao -1.
Ako koristite neki drugi operacijski sustav, na slijedeći način možete provjeriti vrijednost konstante
EOF:
#include <stdio.h>
void main()
{
printf("%d\n", EOF);
getchar();
}
38
Funkcija getchar()
Prototip funkcije:
int getchar(void);
Primjer:
#include <stdio.h>
void main()
{
int i;
int brojac = 0;
getchar();
}
Umjesto da pritišću Ctrl-Z ili Ctrl-D kada žele prekiniti unos znakova, programeri često koriste
makro naredbe.
Primjer:
#include <stdio.h>
#define EOF '\n' // makro naredba koja EOF u programskom kodu zamjenjuje sa \n
void main()
{
int i;
int brojac = 0;
39
while ((i = getchar()) != EOF)
brojac++;
getchar();
}
U ovome programu više nije potrebno pritisnuti Ctrl-Z ili Ctrl-D za prekid unosa znakova, već je
potrebno samo prijeći u novu liniju, tj. stisnuti enter.
Napomena: jedna od čestih grešaka u programiranju jest dodjela vrijednosti koju vraća funkcija
getchar() nekoj znakovnoj varijabli, te onda uspoređivanje te varijable sa EOF.
Primjer:
#include <stdio.h>
void main()
{
getchar();
}
Sada pretpostavimo da char varijabla može sadržavati jednu od 128 znakovnih konstanti (u ASCII
tablici je 128 znakova). Funkcija getchar() može vratiti cjelobrojnu vrijednost bilo koje od tih 128
znakovnih konstanti, ali može vratiti i -1 kada naiđe na EOF. Dakle, funkcija getchar() može vratiti
ukupno 129 mogućih cjelobrojnih vrijednosti.
U gornjem primjeru, kada se cjelobrojna vrijednost koju vraća funkcija getchar() (ukupno 129
mogućih vrijednosti) pokuša mapirati u char varijablu (ukupno 128 mogućih vrijednosti), mora doći
do kolizije.
Ako se slučajno -1 konvertira u 65 (znak 'A' u ASCII tablici), program može prestati sa čitanjem
znakova iz datoteke ili sa standarnog ulaza kada naiđe na znak 'A', jer će pomisliti da je riječ o
oznaci za EOF. Da je pak varijabla 'i' bila deklarirana kao unsigned char, EOF se nikada ne bi
konvertirao u negativnu vrijednost, pa bi program zaglavio u beskonačnoj petlji.
Međutim, ovakve vas stvari trebaju zabrinjavati samo kada niste sigurni koliko memorije zauzimaju
40
int i char varijable. U današnje su vrijeme uglavnom i jedna i druga dovoljno velike da, bez kolizije
sa nekom drugom vrijednošću, prihvate vrijednost koju vraća funkcija getchar(). Ipak, kada se radi o
uspoređivanju te vrijednosti sa EOF, uvijek se preporučuje koristiti int varijablu umjesto char
varijable. Ako se pak ipak odlučite za char, morate pripaziti da uvijek bude deklarirana kao char ili
signed char, a nikada unsigned char!
41
ZADACI
Zadatak 4.1. Napišite program koji oponaša rad jednostavnog kalkulatora koji podržava operacije
zbrajanja, oduzimanja, množenja i dijeljenja. Korisnik programu zadaje izraz, primjerice 9 * 5, a
program ispisuje rezultat tog izraza. Koristite naredbu switch-case.
Rješenje:
#include <stdio.h>
void main()
{
int broj1 = 0, broj2 = 0;
float rezultat;
char operator1;
switch (operator1)
{
case '+':
rezultat = broj1 + broj2;
printf("%d %c %d = %.4f\n", broj1, operator1, broj2, rezultat);
break;
case '-':
rezultat = broj1 - broj2;
printf("%d %c %d = %.4f\n", broj1, operator1, broj2, rezultat);
break;
case '*':
rezultat = broj1 * broj2;
printf("%d %c %d = %.4f\n", broj1, operator1, broj2, rezultat);
break;
case '/':
if (broj2 == 0)
{
printf("Greska: dijeljenje sa nulom!\n");
break;
}
else
{
rezultat = (float)broj1 / broj2;
42
printf("%d %c %d = %.4f\n", broj1, operator1, broj2, rezultat);
break;
}
default:
printf("Nepoznata operacija!\n");
break;
}
getchar();
getchar();
}
Zadatak 4.2. Napišite program koji od korisnika traži da unese dva cijela broja, te zatim ispisuje tri
broja koja se nalaze između njih. Ako je udaljenost brojeva manja od tri, program treba ispisati
odgovarajuću poruku.
Rješenje:
#include <stdio.h>
void main ()
{
int x, y, i;
oznaka:
if (y >= x)
{
if ((y - x) < 4)
{
printf("Brojevi su nedovoljno udaljeni!\n");
}
else
{
printf("Brojevi unutar zadanih granica: ");
for (i = x + 1; i < x + 4; i++)
printf("%d ", i);
}
}
else
{
43
// ako je y > x zamijenimo im vrijednosti
int t = x;
x = y;
y = t;
goto oznaka;
}
getchar();
getchar();
}
Zadatak 4.3. Napišite program u kojem korisnik unosi deset cijelih brojeva (koristite for petlju), a
program vraća njihovu aritmetičku sredinu.
Rješenje:
#include <stdio.h>
void main()
{
int broj = 0;
int brojac = 10;
int suma = 0;
int i;
float prosjek = 0;
prosjek = (float)suma/brojac;
getchar();
getchar();
}
44
Zadatak 4.4. Napišite program koji, uz pomoć petlji, na ekran ispisuje:
a) b)
* ABBB
** AABB
*** AAAB
**** AAAA
Rješenje (a):
#include <stdio.h>
void main()
{
char znak = '*';
int i, j;
printf("\n");
}
getchar();
}
Rješenje (b):
#include <stdio.h>
void main()
{
char a = 'A';
char b = 'B';
int i, j, k;
45
printf("%c", b);
printf("\n");
}
getchar();
}
Zadatak 4.5. Napišite program koji, uz pomoć naredbe getchar(), broji ukupan broj riječi koje unese
korisnik. Prekid unosa znakova neka bude pritisak na tipku enter. Napomena: da bi izbjegli
višestruke praznine, za definiciju riječi uzmite znak ili niz znakova kojima prethodi praznina.
Rješenje:
#include <stdio.h>
void main()
{
prethodniZnak = znak;
}
getchar();
}
46
DODATNI ZADACI
Zadatak 4.6. Napišite program koji računa n-tu faktorijelu. Napomena: n se unosi pomoću scanf()
funkcije, i ne može biti veći od 12.
Zadatak 4.7. Napišite program koji ispisuje sve vrijednosti funkcije y = 15 * x + 76, za sve cijele
parne brojeve x iz intervala [-7, 7].
1
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
DOMAĆI RAD
Zadatak 4.9. Napišite program koji zadanu vrijednost duljine u centimetrima pretvara u inche.
(x(in) = x(cm) / 2,54).
Zadatak 4.10. Napišite program koji za učitanu ocjenu ispisuje njezin opis. Na primjer, ako korisnik
unese 5, program ispisuje "Izvrstan". Ako korisnik unese broj izvan intervala [1,5], program treba
ispisati odgovarajuću poruku. Koristite switch-case naredbu.
Zadatak 4.11. Napišite program koji ispisuje sve parne brojeve iz intervala od 0 do 100.
47
VJEŽBA 5
Nizovi
Kolekcija varijabli istog tipa i zajedničkog imena zove se polje ili niz (engl. array). Niz u memoriji
zauzima kontinuirani niz memorijskih lokacija [2], a deklaracijom niza rezervira se memorija
potrebna za njegove članove. Nizovi mogu biti višedimenzionalni, a ime bilo kojeg niza predstavlja
adresu prvog elementa njegovog elementa.
Opći oblik glasi: tip ime_niza[izraz], gdje je izraz pozitivni cijeli broj.
Polja ili nizovi u programiranju su slični vektorima i matricama u matematici. Ako se želi pristupiti
članu nekog niza, to se radi pomoću indeksiranja.
Primjer:
#include <stdio.h>
void main()
{
int a[] = {1, 4, 7, 8, 17};
getchar();
}
ISPIS PROGRAMA:
1 17
48
Niz znakova
Niz znakova (engl. string) je polje koje se sastoji od niza znakova i koje završava oznakom kraja niza
'\0' (engl. string terminator).
D a l m a c i j a \0
X[0] = 'D'
X[1] = 'a'
X[2] = 'l'
X[3] = 'm'
X[4] = 'a'
X[5] = 'c'
X[6] = 'i'
X[7] = 'j'
X[8] = 'a'
X[9] = '\0'
Programski kod:
#include <stdio.h>
void main()
{
char X[10] = "Dalmacija";
printf("Znakovni niz glasi: %s.\n", X);
getchar();
}
ISPIS PROGRAMA:
Znakovni niz glasi: Dalmacija.
49
Višedimenzionalni nizovi
Opći oblik:
float tablica[50][50];
char stranica[24][80];
static double zapisi [x][y][z];
Primjer (dvodimenzionalni niz): Program ispisuje dvodimenzionalni niz od tri retka i četiri stupca.
#include <stdio.h>
void main()
{
int niz[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
int i, j;
50
}
ISPIS PROGRAMA:
51
ZADACI
Zadatak 5.1. Napišite program koji jednodimenzionalni niz od sedam članova inicijalizira na nulu.
Rješenje:
#include <stdio.h>
void main()
{
int i;
int niz[7];
getchar();
}
Zadatak 5.2. Napišite program koji učitava niz od deset cijelih brojeva, te ih ispisuje na ekran
korištenjem for petlje.
Rješenje:
#include <stdio.h>
void main()
{
int i = 0;
int a;
int niz[10];
printf("\n");
52
for (i = 0; i < 10; i++)
printf("%d. broj: %d\n", i+1, niz[i]);
getchar();
getchar();
}
Zadatak 5.3. Napišite program koji učitava znakovni niz sa tipkovnice i zatim ga ispisuje na ekran.
Rješenje:
#include <stdio.h>
void main()
{
char niz[80];
getchar();
getchar();
}
Zadatak 5.4. Napišite program u kojemu korisnik unosi niz od 10 cijelih brojeva. Program od tog
niza napravi dva druga niza: jedan koji sadrži samo parne brojeve iz originalnog niza, te drugi koji
sadrži samo neparne brojeve iz originalnog niza.
Rješenje:
#include <stdio.h>
void main()
{
int i = 0;
int a;
int niz[10];
int parni[10];
int neparni[10];
int brojac_parni = 0;
int brojac_neparni = 0;
53
{
printf("Unesite %d. broj: ", i+1);
scanf("%d", &a);
niz[i] = a;
}
printf("\n");
else // neparni
{
neparni[brojac_neparni] = niz[i];
brojac_neparni++;
}
}
getchar();
getchar();
}
Zadatak 5.5. Napišite program za zbrajanje matrica dimenzija 3x3. Matrice inicijalizirajte na
proizvoljne vrijednosti unutar programskog koda.
54
Primjer zbrajanja matrica [4]:
1 3 2 0 0 5 10 30 25 1 3 7
1 0 0 7 5 0 = 17 05 00 = 8 5 0
1 2 2 2 1 1 12 21 21 3 3 3
Rješenje:
#include <stdio.h>
void main()
{
int A[3][3] = {{1, 3, 2}, {1, 0, 0}, {1, 2, 2}};
int B[3][3] = {{0, 0, 5}, {7, 5, 0}, {2, 1, 1}};
int C[3][3];
int i, j;
// zbrajanje matrica
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
C[i][j] = A[i][j] + B[i][j];
getchar();
getchar();
}
ISPIS PROGRAMA:
55
Zadatak 5.6. Napišite program za množenje dviju matrica. Neka prva matrica ima dimenzije 2x3, a
druga 3x2. Matrice inicijalizirajte na proizvoljne vrijednosti unutar programskog koda.
3 1
1 0 2⋅
−1 3 1
2 1 =
1 0
1⋅30⋅22⋅1 1⋅10⋅12⋅0 = 5 1
−1⋅33⋅21⋅1 −1⋅13⋅11⋅0 4 2
Rješenje:
#include <stdio.h>
void main()
{
int A[2][3] = {{1, 0, 2}, {-1, 3, 1}};
int B[3][2] = {{3, 1}, {2, 1}, {1, 0}};
int C[2][2] = {{0, 0}, {0, 0}};
int i, j, k;
// mnozenje matrica
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
{
for (k = 0; k < 3; k++)
C[i][j] = C[i][j] + A[i][k] * B[k][j];
}
getchar();
}
ISPIS PROGRAMA:
56
Zadatak 5.7. Napišite program u kojem korisnik unosi elemente kvadratne matrice dimenzija 5x5.
Program treba ispisati sve elemente matrice koji se nalaze ispod glavne dijagonale, te zatim te
elemente prebaciti u jednodimenzionalni niz i onda ispisati i taj niz.
Rješenje:
#include <stdio.h>
void main()
{
int i, j, k = 0;
int const n = 5;
int niz[n][n];
int novi_niz[10];
printf("\n");
printf("\n");
}
printf("\n");
57
printf("\n");
}
printf("\n");
printf("\n");
getchar();
getchar();
}
58
DODATNI ZADACI
Zadatak 5.8. Napišite program koji učitava dva niza znakova i ispituje da li su ti nizovi jednaki. Kraj
učitavanja niza određen je oznakom za prijelaz u novi redak ('\n').
Zadatak 5.9. Napišite program koji učitava redak teksta i pretvara mala slova u velika. Redak mora
biti ograničen na 80 znakova. Napomena: za pretvaranje malih slova u velika koristite funkciju
toupper() iz biblioteke <ctype.h>, a za unošenje retka funkciju gets().
DOMAĆI RAD
Zadatak 5.10. Napišite program koji učitava ime i prezime korisnika, dob i godinu rođenja, te
ispisuje te informacije na ekran.
Zadatak 5.11. Napišite program u kojem korisnik unosi niz od deset cijelih brojeva, a program
ispisuje njihovu aritmetičku sredinu.
Zadatak 5.12. Napišite program za zbrajanje matrica. Elemente matrice unosi korisnik, a svaka
matrica može imati najviše 20 redaka i stupaca. Napomena: zbrajati se mogu samo matrice istih
dimenzija.
59
VJEŽBA 6
Bubble sort algoritam je algoritam za sortiranje članova nekog niza. Ovo je jedan od
najjednostavnijih, ali ujedno i najsporijih, algoritama za sortiranje.
U slijedećem primjeru prikazan je način rada bubble sort algoritma. Algoritam u svakom koraku
uspoređuje dva susjedna broja, i u slučaju da je prvi broj veći od drugog, zamjenjuje im mjesta.
Napomena: podebljani brojevi su oni koji se trenutno uspoređuju.
1. prolaz algoritma:
• (0 8 1 3 2) --> (0 8 1 3 2) // 0 < 8 --> nema zamjene
• (0 8 1 3 2) --> (0 1 8 3 2) // 8 > 1 --> zamjena
• (0 1 8 3 2) --> (0 1 3 8 2) // 8 > 3 --> zamjena
• (0 1 3 8 2) --> (0 1 3 2 8) // 8 > 2 --> zamjena
2. prolaz algoritma:
• (0 1 3 2 8) --> (0 1 3 2 8) // 0 < 1 --> nema zamjene
• (0 1 3 2 8) --> (0 1 3 2 8) // 1 < 3 --> nema zamjene
• (0 1 3 2 8) --> (0 1 2 3 8) // 3 > 2 --> zamjena
• (0 1 2 3 8) --> (0 1 2 3 8) // 3 < 8 --> nema zamjene
3. prolaz algoritma:
• (0 1 2 3 8) --> (0 1 2 3 8) // 0 < 1 --> nema zamjene
• (0 1 2 3 8) --> (0 1 2 3 8) // 1 < 2 --> nema zamjene
• (0 1 2 3 8) --> (0 1 2 3 8) // 2 < 3 --> nema zamjene
• (0 1 2 3 8) --> (0 1 2 3 8) // 3 < 8 --> nema zamjene
Iako je niz bio sortiran na kraju drugog prolaza algoritma, algoritam se je morao još jednom izvršiti
da bi "znao" da je niz sortiran. Drugim riječima, algoritmu je potreban jedan prolaz bez ijedne
zamjene da bi bio siguran da je algoritam sortiran.
Pod analizom algoritma podrazumijeva se procjena vremena izvršavanja tog algoritma. Vrijeme se
poistovjećuje s brojem operacija koje odgovarajući program treba obaviti [5], i izražava se kao
funkcija oblika O(n) (engl. Order(n)). Na primjer, za ulazni niz brojeva (0 8 1 3 2), n bi bio jednak pet.
Da bi bubble sort algoritam uspio sortirati taj niz, u najboljem slučaju bi mu bilo potrebno O(n)
operacija (u ovom slučaju 5), a u najgorem slučaju O(n2) operacija (u ovom slučaju 25). Kako se n
povećava, najgore vrijeme izvršavanja algoritma eksponencijalno raste. Upravo zbog ovog
60
problema, bubble sort algoritam nije dobar za sortiranje nizova sa velikim brojem podataka. Drugi
algoritmi kao što su heap sort i mergesort imaju puno bolje vrijeme izvršavanja – u najboljem
slučaju O(n), u najgorem slučaju O(nlogn) – ali su ipak nešto kompliciraniji.
61
ZADACI
Zadatak 6.1. Napišite program koji u niz sprema maksimalno 20 cijelih brojeva koje unosi korisnik.
Program sortira brojeve po veličini i ispisuje sortirani niz. Koristite bubble sort algoritam.
Rješenje:
#include <stdio.h>
void main ()
{
int niz[20];
int n;
int temp;
int i, j;
62
printf("\n");
getchar();
getchar();
}
ISPIS PROGRAMA:
Zadatak 6.2. Pomoću for petlje unesite prosječne mjesečne temperature za jednu godinu. Ispišite
maksimalnu, minimalnu i prosječnu godišnju temperaturu.
Rješenje:
#include <stdio.h>
void main()
{
float godina[12];
int i;
float prosjecnaTemperatura = 0;
float max, min;
printf("\n");
63
prosjecnaTemperatura = prosjecnaTemperatura / 12;
max = godina[0];
min = godina[0];
getchar();
getchar();
}
Zadatak 6.3. Napišite program koji učitava proizvoljan broj znakova, te ispisuje koliko ima slova,
brojeva i ostalih znakova. Kraj učitavanja niza određen je oznakom za prijelaz u novi redak ('\n'). Za
unos znakova koristite funkciju getchar().
Rješenje:
#include <stdio.h>
void main()
{
int slova = 0;
int brojevi = 0;
int ostaliZnakovi = 0;
int znak;
64
if ((znak >= 'a' && znak <= 'z') || (znak >= 'A' && znak <= 'Z'))
slova++;
else if (znak >= '0' && znak <= '9')
brojevi++;
else
ostaliZnakovi++;
}
getchar();
}
Zadatak 6.4. Zadatak je sličan prethodnome. Napišite program koji učitava proizvoljni broj znakova,
te ispisuje koliko ima slova, brojeva i ostalih znakova. Koristite funkcije getchar(), isdigit(), isupper()
i islower(). Uključite biblioteku <ctype.h>.
Rješenje:
#include <stdio.h>
#include <ctype.h>
void main()
{
int slova = 0;
int brojevi = 0;
int ostaliZnakovi = 0;
int znak;
65
getchar();
}
66
DODATNI ZADACI
Zadatak 6.5. Napišite program koji za neku predefiniranu riječ broji koliko ona ima samoglasnika, te
tu informaciju ispisuje na ekran.
Zadatak 6.6. Napišite program koji dozvoljava unos proizvoljnog broja znakova (koristite while
petlju i funkciju getchar() za unos znakova). Kraj unosa određen je oznakom za prijelaz u novi redak
('\n'). Program treba ispisati ukupan broj unesenih znakova. Napomena: prazna mjesta se također
broje kao znakovi.
DOMAĆI RAD
Zadatak 6.7. Napišite program koji učitava niz od deset cijelih brojeva, te ih u obrnutom redoslijedu
sprema u novi niz. Program treba ispisati taj novi niz.
Zadatak 6.8. Napišite program koji učitava niz od deset cijelih brojeva, te ispisuje samo one koji su
parni. Ako u nizu ne postoji nijedan parni broj, program treba ispisati odgovarajuću poruku.
67
VJEŽBA 7
Funkcije
Funkcija je programski modul koji obavlja neke specifične, točno definirane zadaće.
Svaki C program sastoji se od jedne ili više funkcija, pri čemu se jedna mora zvati main(). Od main()
funkcije program počinje obradu. Sve se ostale funkcije, posredno ili neposredno, pozivaju iz
funkcije main().
Funkcija izvede programiranu radnju svaki put kad je "pozvana" iz bilo kojeg dijela programa. Po
povratku iz funkcije programski tok nastavlja se tamo odakle je funkcija bila pozvana. U pravilu,
funkcija prihvaća skup argumenata (jedan ili više), a vraća samo jednu vrijednost.
Opći oblik:
Napomena: lista argumenata može biti i prazna, a tip povratne informacije može biti void.
Argumenti se unutar funkcije nazivaju i formalnim argumentima, jer predstavljaju samo preslike
podataka koji su u funkciju poslani iz pozivnog dijela programa. Također, koristi se i naziv parametri.
Argumente koji su u funkciju poslani nazivamo stvarnim argumentima ili parametrima.
Informacija se iz funkcije vraća u pozivni dio programa preko naredbe return. Ta naredba također
vraća programski tok na mjesto odakle je funkcija pozvana.
Ako se iz funkcije main() poziva neka druga funkcija, onda se ta funkcija mora ili definirati prije
funkcije main(), ili se prije funkcije main() mora nalaziti prototip te funkcije (tijelo funkcije se onda
može nalaziti poslije funkcije main()).
Kada se pozove neka funkcija, ona će napraviti kopije argumenata koji su joj predani, tj. od stvarnih
argumenata (parametara) će napraviti formalne. U isto vrijeme funkcija će osigurati memorijski
prostor za eventualnu povratnu vrijednost.
Kada se šalje neka varijabla kao stvarni argument u funkciju, njena vrijednost se preslika u formalni
argument u pozvanoj funkciji. Takav način proslijeđivanja argumenata funkciji nazivamo
proslijeđivanjem preko vrijednosti (engl. call by value). Ovakav način proslijeđivanja ima svoje
prednosti i nedostatke. Prednost je u tome što argument kroz funkciju ne mijenja svoju vrijednost,
68
a nedostatak je u tome što se na ovaj način preko argumenata ne može prenijeti informacija natrag
iz funkcije.
Kada se šalje niz kao stvarni argument u funkciju, njegova vrijednost se preslika u formalni
argument u pozvanoj funkciji. Kako je niz predstavljen početnom adresom niza, preslikana
vrijednost početne adrese pristupa istim podacima. Ovakav način proslijeđivanja argumenta
funkciji nazivamo proslijeđivanjem preko adrese (engl. call by reference). Ovakav način
proslijeđivanja podrazumijeva da je svaka promjena argumenta u funkciji vidljiva i u dijelu
programa koji je funkciju pozvao.
Ukratko, ako se koristi proslijeđivanje preko vrijednosti, stvarni argumenti ostaju nepromijenjeni.
Ako se pak koristi proslijeđivanje preko adrese, stvarni argumenti mogu biti promijenjeni.
69
ZADACI
Zadatak 7.1. Napišite program koji iz funkcije main() poziva funkciju zbroji() i prosljeđuje joj dva
proizvoljna cijela broja. Funkcija zbroji() mora vratiti rezultat zbrajanja ta dva broja.
#include <stdio.h>
void main()
{
int a;
int b;
int rezultat;
#include <stdio.h>
70
}
void main()
{
int a;
int b;
int rezultat;
getchar();
getchar();
}
Zadatak 7.2. Napišite program koji učitava niz od deset cijelih brojeva, te zatim proslijeđuje taj niz
funkciji koja vraća aritmetičku sredinu članova niza.
Rješenje:
#include <stdio.h>
return aritmeticka_sredina;
}
void main()
{
int niz[10], i;
float rezultat;
71
for (i = 0; i < 10; i++)
{
printf("Unesite %d. clan niza: \t", i+1);
scanf("%d", &niz[i]);
}
printf("\n");
rezultat = aritmetickaSredina(niz);
getchar();
getchar();
}
Zadatak 7.3. Napišite program koji učitava malo slovo, te ga pretvara u veliko slovo pomoću
funkcije malo_u_veliko().
Rješenje:
#include <stdio.h>
return rezultat;
}
void main()
{
char maloSlovo, velikoSlovo;
72
else
printf("Niste unijeli malo slovo.\n");
getchar();
getchar();
}
73
DODATNI ZADACI
Zadatak 7.4. Napišite program u kojem korisnik unosi broj sekundi, a program preračunave
sekunde u sate, minute i sekunde. Na primjer, ako korisnik unese 3670, program treba ispisati: 1
sat, 1 minuta i 10 sekundi.
DOMAĆI RAD
Zadatak 7.5. Napišite program u kojem korisnik unosi brojčani iznos u kunama, a program
preračunava kune u eure (1 euro = 7.26 kuna). Preračunavanje se mora obaviti u posebnoj funkciji.
Zadatak 7.6. Napišite program koji za deset predefiniranih brojeva računa aritmetičku sredinu, te
traži najveći broj u nizu.
74
VJEŽBA 8
Doseg funkcije
Kada govorimo o dosegu funkcije, govorimo o imenima varijabli koje koristimo. Doseg je dio
programa unutar kojeg se neka varijabla može koristiti.
• lokalne (automatske)
• globalne (vanjske)
• statičke
• registarske
Lokalne (automatske) varijable su prijavljene unutar neke funkcije i vidljive su jedino u toj funkciji.
Ako im se pokuša pristupiti iz neke druge funkcije, program će javiti grešku.
Dvije lokalne varijable u različitim funkcijama s istim imenima nezavisne su jedna od druge.
Sve varijable su lokalne ako se to drugačije ne navede.
Lokalne varijable ne zadržavaju vrijednost nakon što programski tok ode iz funkcije u kojoj je
varijabla definirana.
Suprotno lokalnim varijablama, globalne varijable nisu vezane za neku funkciju. Njihov doseg seže
od mjesta definicije kroz ostatak programa. Čak štoviše, katkad povezuju ne samo funkcije nego i
cjelokupni program.
Promjena globalne varijable u bilo kojoj funkciji biti će vidljiva u svakom dijelu programa.
Inicijalizacija globalne varijable mora biti inicijalizirana konstantom, a nikako izrazom.
Statičke varijable
Doseg statičkih varijabli, kao i doseg lokalnih varijabli, seže samo unutar funkcije u kojoj su
definirane. Ako programski tok izađe iz funkcije, pa se opet vrati u nju, statička će varijabla dobiti
onu vrijednost koju je imala na izlazu iz funkcije. To znači da se statičke varijable ne uništavaju
nakon izlaska programskog toka iz neke funkcije, već ostaju sačuvane u memoriji.
Statičke varijable se označavaju sa ključnom riječi static.
Registarske varijable
75
moraju spremati i čitati iz memorije, već tijekom čitavog izvođenja programa ostaju u registrima.
Označavaju se sa ključnom riječi register.
Ako se lokalne varijable definiraju unutar nekog programskog pod-bloka, biti će dostupne samo u
tome pod-bloku. Pokušaj pristupa nekoj od njih izvan tog programskog bloka uzrokovati će grešku.
Primjer 1.
#include <stdio.h>
void main()
{
int a = 0;
do
{
int b = 1;
...programski kod...
} while(...);
Primjer 2.
#include <stdio.h>
void main ()
{
int brojac1 = 1; // deklariran u VANJSKOM bloku
do
{
int brojac2 = 0; // deklariran u UNUTARNJEM bloku
++brojac2;
printf("\nbrojac1 = %d brojac2 = %d", brojac1, brojac2);
} while (++brojac1 <= 8);
getchar();
76
}
ISPIS PROGRAMA:
Primjer 3.
#include <stdio.h>
void main()
{
int brojac = 0; // deklariran u VANJSKOM bloku
do
{
int brojac = 0; // ovo je druga varijabla nazvana brojac
++brojac; // ovo se odnosi na UNUTARNJI brojac
printf("brojac = %d\n", brojac);
} while (++brojac <= 8); // ovo mijenja VANJSKI brojac
getchar();
}
ISPIS PROGRAMA:
77
ZADACI
Zadatak 8.1. (Lokalne varijable) Proučite i objasnite kako radi slijedeći program:
#include <stdio.h>
void test()
{
// funkcija test() ne vidi varijablu a
// ako se varijabla a pokuša koristiti u ovoj funkciji, program će javiti grešku
void main()
{
int a; // a je lokalna varijabla u funkciji main()
a = 2;
printf("Funkcija main(): %d\n", a);
test();
getchar();
}
ISPIS PROGRAMA:
Funkcija main(): 2
Funkcija test(): ovdje ne postoji varijabla a
Zadatak 8.2. (Globalne varijable) Proučite i objasnite kako radi slijedeći program:
#include <stdio.h>
void test()
{
printf("Funkcija test(): %d\n", x);
}
void main()
{
printf("Funkcija main(): %d\n", x);
test();
getchar();
}
78
ISPIS PROGRAMA:
Funkcija main(): 7
Funkcija test(): 7
Zadatak 8.3. (Statičke varijable) Proučite i objasnite kako radi slijedeći program:
#include <stdio.h>
void test()
{
static int a = 0; // statička varijabla a
a = a + 2;
printf("%d. poziv funkcije test(). \t a = %d\n", brojac, a);
brojac++;
}
void main()
{
int i; // lokalna varijabla i
for (i = 0; i < 10; i++)
test();
getchar();
}
ISPIS PROGRAMA:
79
DODATNI ZADACI
Zadatak 8.4. Napišite program koji ispisuje prvih 10 znamenki Fibonaccijevog niza (koristite while
ili for petlju). Napomena: Fibonaccijev niz je niz brojeva koji započinje sa nulom i jedinicom, a svaki
slijedeći broj je zbroj prethodna dva. Prvih nekoliko znamenki Fibonaccijevog niza: 0 1 1 2 3 5 8 13
21 34 55 89 144 ...
DOMAĆI RAD
Zadatak 8.5. Napišite program u kojem korisnik unosi dva cijela broja, a program ispisuje sve proste
brojeve koji se nalaze unutar zadanog intervala. Napomena: prosti brojevi ili prim-brojevi su svi
prirodni brojevi djeljivi bez ostatka samo sa brojem 1 i sami sa sobom, a veći od broja 1.
Zadatak 8.6. Napišite program koji računa sumu svih brojeva od 1 do 100 koji su djeljivi sa 5.
80
VJEŽBA 9
Bitznačajni operatori
Bit je najmanja jedinica informacije, ili 0 ili 1, a bitznačajni operatori (engl. bitwise operators) se
koriste za manipulaciju bitovima (odnosno za programiranje na najnižoj mogućoj razini). Bitznačajni
operatori se najčešće koriste u kriptografiji i u sažimanju podataka.
Bitznačajni operatori:
• & binarno I (AND)
• | binarno ILI (OR)
• ^ binarno ekskluzivno ILI (XOR)
• ~ jedinični komplement (NOT)
• << pomak u lijevo (SHIFT LEFT)
• >> pomak u desno (SHIFT RIGHT)
a ~a
0 1
1 0
Jedinični komplement (~) je unarni operator koji se koristi za inverziju bitova nekog operanda
(jedinice postaju nule, a nule jedinice). Operand se najčešće predstavlja u oktalnoj ili u
heksadecimalnoj formi, iako ovo nije formalno pravilo [6].
81
Primjer:
Bitznačajni pomak u lijevo odgovara množenju operanda sa potencijama broja dva. Na primjer,
ako operand pomaknemo za jedno mjesto u lijevo dobiti ćemo isti rezultat kao da smo ga
pomnožili sa 2.
Primjeri:
Bitznačajni pomak u desno odgovara cjelobrojnom dijeljenju operanda sa potencijama broja dva.
Na primjer, ako operand pomaknemo za jedno mjesto u desno dobiti ćemo isti rezultat kao da smo
ga podijelili sa 2.
Primjeri:
Maskiranje bitova
Bitznačajni operator I (AND) se najčešće koristi za maskiranje bitova. Maskiranje bitova je proces
važan za računalnu sigurnost, grafiku i kriptografiju.
Primjer:
82
#include <stdio.h>
void main()
{
unsigned n = 0x6db7; // dekadski brojevni sustav - 28087
unsigned maska = 0xF; // dekadski brojevni sustav – 15
// korištenje znaka '#' uzrokuje pojavu znakova '0x' ispred keksadecimalnog broja
printf("Vrijednost od n (n = %#x), maskirana sa %#x, je: %#x\n", n, maska, n & maska);
getchar();
}
83
ZADACI
Zadatak 9.1. Napišite program u kojem korisnik unosi neki cijeli broj, a program ispisuje njegov
binarni ekvivalent.
Rješenje:
#include <stdio.h>
void main()
{
int x, i, n, b;
printf("\n");
getchar();
getchar();
}
84
Ako je bilo koji od operanada jednak nuli, rezultat logičke operacije AND je također jednak nuli:
00000000 00000000 00000000 00000010 & 00 = 0.
Dakle: b = (0) != 0;
0 != 0 nije točno, pa je čitav izraz jednak logičkoj nuli. MSB bit ima vrijednost nula.
Napomena: != ima veći prioritet od =. Zato se u izrazu "b = (0) != 0;" prvo izvrši usporedba (0) != 0,
pa se tek onda rezultat usporedbe dodijeli varijabli b.
Budući da je izraz (00000000 00000000 00000000 00000010 & (10)) != 0 istinit, bit sa težinskom
vrijednošću jedan jednak je jedinici.
Zadatak 9.2. Napišite program u kojemu su definirana dva cjelobrojna niza. Elementi nizova mogu
biti samo binarne znamenke, tako da čitavi niz zapravo predstavlja neki binarni broj. Pokažite
djelovanje AND, OR i XOR operatora nad članovima tih nizova.
Rješenje:
#include <stdio.h>
void main()
{
int a[4] = {1,1,0,1}; // 13
int b[4] = {1,0,1,0}; // 10
int rezultat[4];
int i;
// AND
for (i = 0; i < 4; i++)
rezultat[i] = a[i] & b[i];
// OR
85
for (i = 0; i < 4; i++)
rezultat[i] = a[i] | b[i];
// XOR
for (i = 0; i < 4; i++)
rezultat[i] = a[i] ^ b[i];
getchar();
getchar();
}
Zadatak 9.3. Napišite program i definirajte neki cijeli broj u heksadecimalnom obliku. Korisnik
unosi redni broj bita čiju vrijednost želi saznati, i program vraća nulu ili jedinicu, ovisno o tome koji
se bit nalazi na mjestu kojeg je specificirao korisnik.
Rješenje:
#include <stdio.h>
void main ()
{
int x = 0x2; // dekadski isto 2
int n;
getchar();
getchar();
}
86
DODATNI ZADACI
Zadatak 9.4. Napišite program u kojem korisnik unosi neki cijeli broj, a program ispisuje njegov
binarni ekvivalent. Binarni ekvivalent se sprema u niz binarni_ekvivalent[32]. Postavite sve bitove
binarnog ekvivalenta na nulu (koristite XOR operaciju).
DOMAĆI RAD
Zadatak 9.5. Napišite program koji za predefinirani cijeli broj ispisuje težinsku vrijednost svakog
bita koji je jednak jedinici. Na primjer, za cijeli broj 11 (binarno 1011), program bi trebao ispisati 1,
2 i 8.
1 0 1 1
2 1 0
23=8 2 =4 2 =2 2 =1
87
DODATAK
15610=? 2
Prvi način (broj u dekadskom brojevnom sustavu se dijeli sa 2, a ostatak dijeljenja se zapisuje u
poseban stupac):
156 : 2 = 78 0
78 : 2 = 39 0
39 : 2 = 19 1
19 : 2 = 9 1
9:2=4 1
4:2=2 0
2:2=1 0
1:2=0 1
Rješenje se dobije tako da se ostaci dijeljenja sa 2 napišu obrnutim redoslijedom. Rješenje bi bilo:
1001 1100.
156 – 128 = 28 1 (128 je najveća potencija broja 2 koja "stane" u broj 156)
28 – 64 = -36 0 (64 je iduća niža potencija broja 2, ali 64 ne "stane" u 28)
28 – 32 = -4 0 (32 je iduća niža potencija broja 2, ali 32 ne "stane" u 28)
28 – 16 = 12 1 (16 je iduća niža potencija broja 2)
12 – 8 = 4 1 (8 je iduća niža potencija broja 2)
4–4=0 1 (4 je iduća niža potencija broja 2)
0 – 2 = -2 0 (2 je iduća niža potencija broja 2)
0 – 1 = -1 0 (1 je iduća niža potencija broja 2)
Napomena: ako je rezultat oduzimanja negativan, za binarnu znamenku se uzima nula. Ako je
rezultat pozitivan, uzima se jedinica.
100111002 =?10
MSB LSB
1 0 0 1 1 1 0 0
7 6 5 4 3 2 1
2 =128 2 =64 2 =32 2 =16 2 =8 2 =4 2 =2 2 0=1
1⋅1280⋅640⋅321⋅161⋅81⋅40⋅20⋅1=1281684=156
88
Pretvaranje iz dekadskog brojevnog sustava u oktalni brojevni sustav
15610=? 8
156 najprije podijelimo sa najvećom potencijom broja 8 koja "stane" u broj 156 (a to je 64).
28 : 8 = 3 (ostatak 4) 8=81
4:1=4 (ostatak 0) 1=8
0
Rezultat: 234.
2 1 0
2∗8 3∗8 4∗8 =128244=156
15610=? 16
156 najprije podijelimo sa najvećom potencijom broja 16 koja "stane" u broj 156 (a to je 16).
Rezultat: 9C.
9C16=? 10
1 0
9∗16 12∗16 =14412=156
89
VJEŽBA 10
MATLAB
MATLAB (engl. MATrix LABoratory) je aplikacija i programski jezik (sličan C-u) za znanstvena
istraživanja. MATLAB korisniku pruža velik broj funkcija, grupiranih tematski u “toolbox-ove”, te
namijenjenih rješavanju problema vezanih za kontrolu i optimizaciju sustava, kao i za obradu
signala.
Pokretanje MATLAB-a
Na Windows Desktop-u kliknite na Start --> All Programs --> Matlab --> Matlab. Otvoriti će se
osnovni prozor MATLAB-a (Slika 10.1) koji po default-u sadrži naredbeni prozor (engl. Command
Window), prozor povijesti naredbi (engl. Command History), prozora tekućih datoteka (engl.
Current Directory) i prozor sa sadržajem radnog prostora (engl. Workspace).
Osnovne operacije
MATLAB koristi jednostavnu sintaksu. Naredbe u MATLABu se upisuju u posljednju, aktivnu liniju
naredbenog prozora koja počinje sa oznakom '>>'.
Nardbe (i operacije) koje se upisuju u komandnu liniju izvršavaju se nakon pritiska na <enter>. Na
primjer:
324⋅5
9 3 .
−8
2
90
Slika 10.1. Osnovni prozor MATLAB-a
Primijetili ste da se rezultat ispisuje na pod nazivom ans (engl. answer). Ukoliko želimo vrijednosti
dodijeliti ime (ime konstante), ispred izraza napišemo ime i stavljamo znak jednakosti.
Na taj način konstanta k se ne ispisuje na ekranu, ali ostaje definirana u programu dok joj se ne
dodijeli nova vrijednost, odnosno izraz.
91
Matrice i operacije sa matricama
Rješavanje nekih problema (pogotovo onih vezanih za matrice i općenito za matematiku), puno je
jednostavnije i brže u Matlabu nego u nekim drugom programskim jezicima (npr. C-u).
Matrica je dvodimenzionalno polje brojeva, i usput osnovni podatak za rad u MATLAB-u. Matrica
dimenzija [1,1] naziva se skalar, a matrica koja sadrži samo jedan stupac ili samo jedan redak
naziva se vektor.
Matrica se definira navođenjem njezinih redaka. Elementi redaka se razdvajaju zarezom ili praznim
mjestom. Dva retka se razdvajaju simbolom ; na kraju retka.
ili
16 3 2 13
5 10 11 8
A=
9 6 7 12
4 15 14 1
Nad matricama se primjenjuju matematičke operacije kao što su zbrajanje (oznaka je +),
oduzimanje (-), množenje (*) i dijeljenje (množenje jedne matrice sa inverznom drugom matricom)
(/). Napomena: prilikom množenja ili dijeljenja matrica treba voditi računa o uzajamnoj
usklađenosti veličine matrica.
MATLAB poznaje standardne matrične operacije i funkcije kao što su transponiranje, potenciranje,
nalaženje inverzne matrice i određivanje determinante. Na primjer, slijedeće naredbe
>> B'
>> B^2
>> inv(B)
>> det(B)
92
Posebne operacije sa matricama
Ako su matrice A i B istih dimenzija, i ukoliko je ⊕ binarna operacija, tada je . ⊕ posebna operacija
koja se može primijeniti na matrice.
Karakteristične posebne operacije (element sa elementom) su: množenje redaka (.*), dijeljenje
redaka (./) i potenciranje redaka (.^).
Primjer:
>> A = [2 4 6; 1 2 3];
>> B = [1 1 1; 2 2 2];
>> A.*B % A * B bi generiralo grešku
Indeksiranje matrica, odnosno izdvajanje vektora redka ili vektora stupca ili pojedinih elemenata
vrši se korištenjem simbola dvotočke ':'. Prvi indeks se odnosi na redak, a drugi indeks na stupac.
Primjer:
Napomene
Varijable se iz MATLAB-ove memorije brišu naredbama clear ime_varijable ili clear all. Naredbom
clc se isprazni komandni ekran.
93
Vektori
MATLAB omogućava definiranje vektora čiji elementi imaju konstantan međusoban razmak. Na
primjer, definirajmo vektor na intervalu [0, 100] sa korakom 10.
>> x = 0 : 10 : 100;
Polinomi
Polinomi se definiraju preko vektora koeficijenata polinoma, od koeficijenta ispred najvišeg stupnja
polinoma do slobodnog elementa. Na primjer, polinom 2x3 − x 23 se u MATLAB-u definira na
slijedeći način:
>> a = [2 -1 0 3]
Inverzna naredba roots naredbe je poly. Naime, ukoliko znamo korijene polinoma, primjenom
naredbe poly, dobivamo koeficijente polinoma. Na primjer:
94
Rješavanje sustava linearnih jednadžbi
>> A = [1 3; 2 -5]
>> B = [7; -8]
>> X = inv(A)*B
Crtanje funkcija
MATLAB posjeduje različite funkcije za grafički prikaz dobivenih rezultata. Najčešće korištena
naredba za grafički prikaz funkcija je plot, sa sintaksom:
plot(x, y, 'opcije')
Na primjer:
>> x = -1 : 0.01 : 1;
>> plot(x, exp(x)+1)
Alternative MATLAB-u
95
ZADACI
−2 3 1 2 4 8 1 1 1
M= 1 5 6 N = −1 2 9 O= 2 2 2
7 4 1 2 3 2 3 3 3
Izdvojite:
a) posljednji stupac matrice M,
b) prva dva elementa drugog reda matrice N
c) drugi i treći element prvog stupca matrice O
d) drugi redak matrice M
e) prva dva elementa trećeg stupca zbroja matrica M + N
Rješenje:
1. x 2y=3
2. −x y4z=7
3. 2x3y−z=5
Rješenje:
A = [1 2 0; -1 1 4; 2 3 -1];
B = [3; 7; 5];
x = inv(A) * B
ISPIS PROGRAMA:
15
-6
7
96
Zadatak 10.3. Riješite sustav jednadžbi:
4. −x 1x 3=1
5. x 1− x 2=−1
6. x 2 x 3=1
7. x 1 x 4=3
Rješenje:
A = [-1 0 1 0; 1 -1 0 0; 0 1 1 0; 1 0 0 1];
B = [1; -1; 1; 3];
x = inv(A) * B
ISPIS PROGRAMA:
-0.50000
0.50000
0.50000
3.50000
Rješenje:
y = [-3 4 0 -1 3];
roots(y)
Zadatak 10.5. Na istoj slici iscrtati grafove funkcija y 1=x 32x 2−4 i y 2=−5x 23, na intervalu (-
5,5), sa korakom 0.01. Neka graf funkcije y 1 bude iscrtan žutom bojom, a graf funkcije y 2 zelenom
bojom.
Rješenje:
x = -5 : 0.01 : 5;
y1 = x.^3 + 2.*x – 4;
y2 = -5.*x.^2 + 3;
plot(x, y1, 'y', x, y2, 'g')
97
ex
Zadatak 10.6. Nacrtajte graf funkcije y= 1 , na intervalu (-5,5), sa korakom 0.02.
1 x
1e
Rješenje:
x = -5 : 0.02 : 5;
y = exp(x)./(1 + exp(1./(1 + x)));
plot(y)
ex
Zadatak 10.7. Nacrtajte graf funkcije y= 1 , na intervalu (-5,5), sa korakom 0.5. Neka graf
1e 1 x
bude zelene boje, i neka sve točke na grafu budu označeve kružićima. Napomena: dodatne opcije
za crtanje grafa funkcije objašnjene su u dodatku.
Rješenje:
x = -5 : 0.5 : 5;
y = exp(x)./(1 + exp(1./(1 + x)));
plot(y, '-og')
98
DOMAĆI RAD
sinx cosx
Zadatak 10.9. Na istoj slici iscrtati grafove funkcija y 1= i y 2= , na intervalu (0,10), sa
x x
korakom 0.01. Neka graf funkcije y 1 bude iscrtan žutom bojom, a graf funkcije y 2 zelenom bojom.
99
DODATAK VJEŽBI 10
Grafovi
U MATLAB-u se može specificirati tip linije kojom se iscrtava graf, te se mogu prikazati oznake za
željene točke na grafu.
100
Boje grafova
U MATLAB-u postoji osam predefiniranih boja za grafove. Sve su prikazane u tablici 10.3.
Na primjer, naredbom plot(x, y, '-.or') bi se iscrtao graf sa linijom tipa '-.' (engl. dash-dot line), a
točke na grafu bi bile označeve kružićima ('o'). I graf i kružići bi bili crvene boje ('r') [7].
101
POPIS OZNAKA I KRATICA
102
LITERATURA
103
Петар Спалевић
Бранимир Јакшић
Стефан Панић
ИЗ ПРОГРАМСКОГ ЈЕЗИКА C
I ДЕО
Аутори: Петар Спалевић, ванредни професор Факултета техничких наука у Косовској Митровици
Бранимир Јакшић, асистент на Факултету техничких наука у Косовској Митровици
Стефан Панић, доцент Природно-математичког факултета у Косовској Митровици
Издавач:
Штампа:
НАПОМЕНА: Фотокопирање или умножавање на било који начин или поновно објављивање
ове књиге – у целини или деловима – није дозвољено без претходне сагласности и писменог одобрења
издавача.
Предговор
Ова збирка задатака је помоћни уџбеник за учење програмирања на језику С. Задаци прате
градиво које одговара предмету Програмирање 2 којег слушају студенти у оквиру студијског
програма Електротехничко и рачунарско инжењерство на Факултету техничких наука у Косовској
Митровици. Збирку могу користити и студенти других факултета који у оквиру својих предмета
изучавају језик С, као и ученици средњих школа.
Збирка је тако конципирана да је могу користити и почетници у програмирању. Задаци су у
свакој области изложени по тежини, од најлакших ка тежим. Кроз задатке, поред елемената самог
језика, приказане су најчешће коришћени поступци у програмирању: претраживање и уређивање
низова, обрада знаковних података, рад са показивачима и структурама, као и рад са датотекама.
Решења свих задатака су потпуна у смислу да се дати програмски кодови могу ивршавати на
рачунари. Сви задаци су урађени, проверени и тестирани коришћењем програма DEV C/C++. Поред
самих програмских кодова дати су изгледи на екрану након тестирања програма. За сложене задатке
дата су објашњења у виду текста или пропратног кометара у програмском коду.
Збирка је подељена у два дела. Први део обухвата основне елементе и конструкције језика С:
просте линијске структуре, грањање у програму, петље, скокови, улаз-излаз, функције, низови и
матрице.
Други део је наставак градива из претходног дела, који обухвата и нешто сложеније задатке:
стрингови, показивачи (обухватајући и рад са показивачима кроз све елементе језика из првог дела
збирке), динамичка зона меморије, структуре и рад са датотекама.
1 ОСНОВНЕ КОНСТРУКЦИЈЕ
ПРОГРАМСКОГ ЈЕЗИКА С
1
Збирка решених задатака из Програмског језика С – I део
Декларација константи:
const tip_podatka ime_promenljive = vrednost_konstante;
нпр: const double e=2.71828182845905;
2
Збирка решених задатака из Програмског језика С – I део
a) Коректно.
б) Некоректно, не могу да се коментари гнезде један унутар другог.
в) Коректно.
г) Некоректно, коментар треба започети са /* и завршити са */.
3
Збирка решених задатака из Програмског језика С – I део
1.2 Оператори
4
Збирка решених задатака из Програмског језика С – I део
5
Збирка решених задатака из Програмског језика С – I део
а) 24 г) 0 е) 5
б) 1 д) 3 ж) 5.25
в) 3 ђ) 5.25
1.8. Ако је а=5, колике ће бити вредности променљивих а и b након израчунавања израза:
а) b=++a б) b=a++ в) b=--a г) b=a--
а) 3+4. → 3.+4. → 7.
б) 5/4*3. → (5/4)*3. → 1*3. → 1.*3. → 3.
в) 3.*5/4 → (3.*5)/4 → (3.*5.)/4 → 15./4 → 15./4. → 3.75
1.11. Коју вредност ће имати променљива y после извршавања следећег блока наредби:
а) int y; б) float y; в) float y;
float x=3.14; y=10/4; y=(float)10/4;
y=x;
а) 3 б) 2 в) 2.5
а) 5>7 → 0
б) 10<=20 → 1
в) 8==13>5 → 8==(13>5) → 8==1 → 0
г) 14>5<3 → (14>5)<3 → 1<3 → 1
д) а<b<5 → (а<b)<5 → (0 ili 1)<5 → 1
6
Збирка решених задатака из Програмског језика С – I део
1.14. Које се вредности добијају након извршавања следећих операција над битовима за случај
када су подаци типа int и имају 16 битова:
а) 0x1234 & 0x5678 г) ! 0x1234 е) 000001 << 5
б) 0x1234 | 0x5678 д) 022222 & 055555 ж) 0х3801 << 4
в) 0x1234 ^ 0x5678 ђ) 022222 && 055555 з) 0xff56 >> 4
г) ~ 0x1234
а) 0x1230 г) 0 е) 000040
б) 0x567с д) 000000 ж) 0х8010 (прекорачење!)
в) 0x444с ђ) 1 з) 0xfff5
г) 0xedcb
7
Збирка решених задатака из Програмског језика С – I део
2 ПРОГРАМИ СА ПРОСТОМ
ЛИНИЈСКОМ СТРУКТУРОМ
8
Збирка решених задатака из Програмског језика С – I део
2.1. Саставити програм који на екрани исписује текст: Od danas programiramo u jeziku
C.
#include <stdio.h>
main()
{
printf("Od danas programiramo u jeziku C.");
getche();
return 0;
}
9
Збирка решених задатака из Програмског језика С – I део
#include<stdio.h> значи да
укључујемо стандарну улазно-
излазну библиотеку података.
printf(); је функција која исписује текст на екрану, тј. конзоли. Текст који се исписује
ставља се под наводницима.
getche(); чека знак са тастатуре, а тек након тога излази из програма. Ово нам користи да
видимо шта исиписује наш програм.
return 0; враћа оперативном систему како је извршавање протекло без проблема. У случају
да се врати вредност 1 ОС зна да је дошло до грешке.
} означава крај блока наредби. Број отворених заграда мора бити једнак броју затворених.
main() main()
{ {
printf("Pozdrav svima!"); printf("\nPozdrav svima!\n");
getche(); getche();
return 0; return 0;
} }
в) г)
#include <stdio.h> #include <stdio.h>
main() main()
{ {
printf("\nPozdrav\nsvima!\n"); printf("\nDobrodosli ");
getche(); printf("u jezik C\n\n");
return 0; getche();
} return 0;
}
д) ђ)
#include <stdio.h> #include <stdio.h>
main() main()
{ {
printf("\nDobrodosli \n\n\tu jezik C\n\n"); printf("\nABCDEF\n");
getche(); printf("A");
return 0; printf("BC");
} printf("DEF");
printf("\nA\nBC\nDEF\n");
getche();
return 0;
}
10
Збирка решених задатака из Програмског језика С – I део
а) б)
Испис на екрану
Испис на екрану
в) г)
д) ђ)
Испис на екрану
Испис на екрану
11
Збирка решених задатака из Програмског језика С – I део
а) printf("%d", x);
б) printf("%f %f", x, y);
в) printf("%d %o %x", x, x, x);
г) printf("%c", x);
2.5. Саставити програм којим се учитавају и приказују један цео и један реалан број.
#include <stdio.h>
main()
{
int ceo;
float realan;
printf("Unesite jedan ceo broj: ");
scanf("%d",&ceo);
printf("Unesite jedan realan broj: ");
scanf("%f",&realan);
printf("\nCeo broj: %d", ceo);
printf("\nRealan broj: %f", realan);
getche();
return 0;
}
Испис на екрану
2.6. Саставити програм којим се реални број унет са тастатуре заокружује на две децимале.
#include <stdio.h>
main()
{
float a;
printf("Unesite jedan realan broj: ");
scanf("%f",&a);
printf("\nBroj zaokruzen na dve decimale je: %.2f", a);
getche();
return 0;
}
Испис на екрану
12
Збирка решених задатака из Програмског језика С – I део
2.7. Саставити програм који омогућује унос целог броја са тастатуре и његов приказ у
децималном, окталном и хексaдецималном облику.
#include <stdio.h>
main()
{
int a;
printf("Unesite ceo broj: ");
scanf("%d",&a);
printf("\nDecimalni oblik: %d", a);
printf("\nOktalni oblik: %o", a);
printf("\nHeksadecimalni oblik: %x", a);
getche(); Испис на екрану
return 0;
}
2.8. Саставити програм који омогућује унос реалног броја са тастатуре и његов приказ у
различитим облицима.
#include <stdio.h>
main()
{
double a;
printf("Unesite jedan realan broj: ");
scanf("%lf",&a);
printf("\nOblik sa decimalnom tackom: %f", a);
printf("\nOblik sa eksponentom: %e", a);
printf("\nU naucnoj notaciji: %g", a);
getche();
return 0;
}
Испис на екрану
2.9. Како изгледа испис на екрану после извршавања следећег програмског кода:
#include <stdio.h>
main()
{
const int a=987;
const double b=1.2345;
printf("%10d\n", a);
printf("%-10d\n\n", a);
printf("%10f\n", b);
printf("%-10f\n", b);
printf("%10.2f\n", b);
printf("%.2f\n", b); Испис на екрану
getche();
return 0;
}
13
Збирка решених задатака из Програмског језика С – I део
2.10. Саставити програм којим се на екрану исписује распоред слова као што је приказано на
слици.
#include <stdio.h>
main()
{
printf("%c\n%2c\n%3c\n%4c\n%5c", 'A', 'B', 'C', 'D', 'E');
getche();
return 0;
}
Испис на екрану
2.11. Саставити програм који омогућује унос три знаковне променљиве са тастатуре, а затим
приказује њихове вредности и њихов одговарајући АSCII код.
#include <stdio.h>
main()
{
char x, y, z;
printf("Unesite tri znaka:\n");
scanf("%c %c %c",&x,&y,&z);
printf("Promenljiva\t ASCII kod\n");
printf("%c\t\t %d\n",x, x);
printf("%c\t\t %d\n",y, y);
printf("%c\t\t %d\n",z, z); Испис на екрану
getche();
return 0;
}
2.12. Саставити програм који омогућује унос једне знаковне променљиве, приказује њену вредност
и њен ASCII код, а затим у следећа три реда приказује променљиве чији је код за један већи од
претходне.
#include <stdio.h>
main()
{
char x;
char ch;
printf("Unesite znak: ");
scanf("%c",&x);
printf("\n\nZnak\tASCII kod\n");
printf("%c \t %d \n", x, x);
printf("%c \t %d \n", x+1, x+1);
printf("%c \t %d \n", x+2, x+2); Испис на екрану
printf("%c \t %d \n", x+3, x+3);
getche();
return 0;
}
14
Збирка решених задатака из Програмског језика С – I део
2.13. Саставити програм који приказује величину у бајтовима следећих типова података: char,
unsigned char, int, unsigned int, long, unsigned long, float, double.
#include <stdio.h>
main()
{
printf("\nTip CHAR = %d B memorije.", sizeof(char));
printf("\nTip UNSIGNED CHAR = %d B memorije.", sizeof(unsigned char));
printf("\nTip INT = %d B memorije.", sizeof(int));
printf("\nTip UNSIGNED INT = %d B memorije.", sizeof(unsigned int));
printf("\nTip LONG = %d B memorije.", sizeof(long));
printf("\nTip UNSIGNED LONG = %d B memorije.", sizeof(unsigned long));
printf("\nTip FLOAT = %d B memorije.", sizeof(float));
printf("\nTip DOUBLE = %d B memorije.", sizeof(double));
getche();
return 0;
}
Испис на екрану
15
Збирка решених задатака из Програмског језика С – I део
2.14. Саставити програм којим се замењују вредности два унета цела броја.
#include <stdio.h>
main()
{
int a, b, pomocna;
printf("Unesite prvi broj a= ");
scanf("%d", &a);
printf("Unesite drugi broj b= ");
scanf("%d", &b);
printf("\nPre zamene:\ta=%d, b=%d",a,b);
pomocna = a;
Испис на екрану
a = b;
b = pomocna;
printf("\nPosle zamene:\ta=%d, b=%d\n\n", a, b);
getche();
return 0;
}
16
Збирка решених задатака из Програмског језика С – I део
2.15. Саставити програм који учитава два цела броја са тастатуре и исписује њихов збир.
Први начин:
#include <stdio.h>
main()
{
int a, b, c;
printf("Unesite prvi broj: ");
scanf("%d", &a);
printf("Unesite drugi broj: ");
scanf("%d", &b); Испис на екрану
c = a + b;
printf("Zbir unetih brojeva je: %d\n", c);
getche();
return 0;
}
Други начин:
#include <stdio.h>
main()
{
int a, b;
printf("Unesite prvi broj: ");
scanf("%d", &a);
printf("Unesite drugi broj: ");
scanf("%d", &b);
printf("Zbir unetih brojeva je: %d\n", a+b);
getche();
return 0;
}
2.16. Саставити програм који учитава два цела броја и исписује њихов збир, разлику, производ,
целобројни количник, реални количник и остатак при целобројном дељењу.
#include <stdio.h>
main()
{
int a, b;
printf("Unesite prvi broj: ");
scanf("%d", &a);
printf("Unesite drugi broj: ");
scanf("%d", &b);
printf("Zbir a+b je: %d\n", a+b);
printf("Razlika a-b je: %d\n", a-b);
printf("Proizvod a*b je: %d\n", a*b);
printf("Celobrojni kolicnik a/b je: %d\n", a/b);
printf("Realni kolicnik a/b je: %f\n", (float)a/(float)b);
printf("Ostatak pri deljenju a/b je: %d\n", a%b);
getche();
return 0;
}
17
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
2.17. Саставити програм који за унете странице правоугаоника исписује његов обим и површину.
#include <stdio.h>
main()
{
float a, b, o, p;
printf("Stranica a= ");
scanf("%f", &a);
printf("Stranica b= ");
scanf("%f", &b); Испис на екрану
o=2*a+2*b;
p=a*b;
printf("\nObim: %.2f",o);
printf("\nPovrsina: %.2f",p);
getche();
return 0;
}
2.18. Саставити програм који за унети полупречник круга исписује његов обим и површину.
#include <stdio.h>
#define PI 3.14
main()
{
double r;
printf("Unesite poluprecnik kruga: ");
scanf("%lf", &r);
printf("Obim: %.3f\n", 2*r*PI);
printf("Povrsina: %.3f\n", r*r*PI); Испис на екрану
getche();
return 0;
}
18
Збирка решених задатака из Програмског језика С – I део
2.19. Саставити програм који за унети полупречник основице и висине ваљка исписује његову
површину и запремину. (Површина: P=2*r*π*(r+h) , Запремина: V=r2*π*h)
#include <stdio.h>
#define PI 3.14
main()
{
double p,r,h,v;
printf("Unesite visinu valjka: ");
scanf("%lf",&h);
printf("Unesite poluprecnik valjka: ");
scanf("%lf",&r);
p = 2*r*PI*(r+h);
v = r*r*PI*h;
printf("Povrsina valjka: %.4f\n", p);
printf("Zapremina valjka: %.4f\n",v);
getche();
return 0;
}
Испис на екрану
main()
{
int temp;
double fahr, celsius;
printf("\nUnesite T u stepenima F <ceo broj od 0 do 300>: ");
scanf("%d",&temp);
fahr=(double)temp;
celsius=(5.0/9.0)*(fahr-32.0);
printf("\n%d F = %.2f C\n\n", temp, celsius);
getche();
return 0;
}
Испис на екрану
19
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
main()
{
float X, A, B;
printf("A = ");
scanf("%f", &A);
printf("B = ");
scanf("%f",&B);
Испис на екрану
X=-B/A;
printf("Jednacina ima oblik %.2fX + %.2f = 0\n", A, B);
printf("Resenje X= %.2f\n", X);
getche();
return 0;
}
main() main()
{ {
float x, y; Испис на екрану float x, y;
printf("Unesite x: "); printf("Unesite x: ");
scanf("%f", &x); scanf("%f", &x);
y=sqrt(x+ x*x + x*x*x); y=sqrt(x+ pow(x,2) + pow(x,3));
printf("\y = %.2f", y); printf("\y = %.2f", y);
getche(); getche();
return 0; return 0;
} }
2.23. Саставити програм који исписује вредност модула комплексног броја z = a + bi за унете
вредности а и b. Модул се рачуна по формули z = a 2 + b 2 .
#include <stdio.h>
#include <math.h>
main()
{
float a, b, m;
printf("a= "); scanf("%f",&a);
printf("b= "); scanf("%f",&b);
m=sqrt(a*a+b*b); Испис на екрану
printf("Modul kompleksnog broja %.2f+%.2fi je %.2f ", a, b, m);
getche();
return 0;
}
20
Збирка решених задатака из Програмског језика С – I део
2.24. Саставити програм који за унете реалне и имагинарне делове два комплексна броја исписује
та да два броја у облику z1 = a + bi и z 2 = c + di , а затим рачуна њихов збир и разлику
z1 ± z 2 = (a + c) ± i(b + d ) .
#include <stdio.h>
#include <math.h>
main()
{
float a1,b1,a2,b2,rz,rr,iz,ir;
printf("a1 = "); scanf("%f",&a1);
printf("b1 = "); scanf("%f",&b1);
printf("a2 = "); scanf("%f",&a2);
printf("b2 = "); scanf("%f",&b2);
rz=a1+a2;
rr=a1-a2;
iz=b1+b2;
ir=b1-b2;
printf("\nz1 = %.2f + %.2fi \nz2 = %.2f + %.2fiИспис
\n",a1,b1,a2,b2);
на екрану
printf("\nz1+z2 = %.2f + %.2fi", rz, iz);
printf("\nz1-z2 = %.2f + %.2fi", rr, ir);
getche();
return 0;
}
main()
{
double x1, x2, y1, y2, z1, z2, d;
printf("Unesite koordinate prve tacke <x1,y1,z1>: \n");
scanf("%lf %lf %lf",&x1,&y1,&z1);
printf("Unesite koordinate druge tacke <x2,y2,z2>: \n");
scanf("%lf %lf %lf",&x2,&y2,&z2);
d=sqrt(pow(x2-x1,2)+pow(y2-y1,2)+pow(z2-z1,2));
printf("\nRastojanje d = %.2f\n", d);
getche();
return 0;
}
Испис на екрану
21
Збирка решених задатака из Програмског језика С – I део
2.26. Саставити програм за исписивање површине троугла ако су задате координате његових
темена. Површину троугла рачунати помоћу следећих формула:
( xB − xC ) − ( yB − yC ) , ( xC − x A ) − ( yC − y A ) , a = ( xA − xB ) − ( y A − yB )
2 2
a= b=
2 2 2 2
a+b+c P = S ( S − a )( S − b )( S − c )
S= ,
2
#include<stdio.h>
#include <math.h>
main()
{
double xA, yA, xB, yB, xC, yC, a, b, c, s, P;
printf("Koordinate temena trougla\n");
printf("- prvo teme <xA,yA>: "); scanf("%lf%lf",&xA,&yA);
printf("- drugo teme <xB,yB>: "); scanf("%lf%lf",&xB,&yB);
printf("- trece teme <xC,yC>: "); scanf("%lf%lf",&xC,&yC);
a=sqrt(pow(xB-xC,2)+pow(yB-yC,2));
b=sqrt(pow(xC-xA,2)+pow(yC-yA,2));
c=sqrt(pow(xA-xB,2)+pow(yA-yB,2));
s=(a+b+c)/2;
P=sqrt(s*(s-a)*(s-b)*(s-c));
printf("\nPovrsina trougla: %.2f\n", P);
getche();
return 0;
}
Испис на екрану
2.27. Саставити програм који за унети троцифрени број исписује његове цифре и суму цифара.
#include <stdio.h>
main()
{
int xyz, x, y, z;
printf("Unesite trocifreni broj: ");
scanf("%d",&xyz);
x=xyz/100;
y=(xyz/10)%10; Испис на екрану
z=xyz%10;
printf("\nCifre broja %d su %d, %d, %d", xyz,x,y,z);
printf("\nSuma cifara je: %d", x+y+z);
getche();
return 0;
}
22
Збирка решених задатака из Програмског језика С – I део
2.28. Саставити програм који учитава вредност производа у динарима, а затим израчунава и
приказује колико је потребно новчаница од 500 дин., 100 дин. и 1 дин. за плаћање тог производа.
#include<stdio.h>
main()
{
int n, n500, n100, n1;
printf("Unesite cenu proizvoda: ");
scanf("%d",&n);
n500=n/500;
n100=(n%500)/100; Испис на екрану
n1=(n%500)%100;
printf("\nBr.novcanica od 500: %d",n500);
printf("\nBr.novcanica od 100: %d",n100);
printf("\nBr.novcanica od 1: %d",n1);
getche();
return 0;
}
2.29. Саставити програм који за унети временски интервал у секундама и исписује га у облику
дани : часови : минуте : секунде.
#include<stdio.h>
main()
{
long sec, d, h, m, s;
printf("Unesite vreme u sekundama: ");
scanf("%ld",&sec);
s=sec%60;
Испис на екрану
m=sec/60;
h=m/60;
m=m%60;
d=h/24;
h=h%24;
printf("\n(d:h:m:s) %ld:%ld:%ld:%ld\n",d,h,m,s);
getche();
return 0;
}
2.30. Саставити програм који одређује и исписује број степени, минута и секунди у углу који је
задат у радијанима.
#include<stdio.h>
#define PI 3.141592
main()
{
double x;
int stepen,minut,sekund;
printf("Unesite ugao u radijanima: ");
scanf("%lf",&x);
x*=180/PI; /*konverzija u stepene*/
23
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
main()
{
int x, y;
int a=0, b=0;
printf("Na pocetku : \na = %d\nb = %d\n", a, b);
a++;
++b;
printf("\nPosle : a++; ++b; \na = %d\nb = %d\n", a, b);
x = ++a;
y = b++;
printf("\nPosle : x = ++a; \na = %d\nx = %d\n", a, x);
printf("\nPosle : y = b++; \nb = %d\ny = %d\n", b, y);
getche();
return 0;
}
Испис на екрану
24
Збирка решених задатака из Програмског језика С – I део
main()
{
int a = 3, b = 3;
printf("\n a b \n");
printf("\n %d %d\n", a--, --b);
printf("\n %d% d\n", a--, --b);
printf("\n %d% d\n\n", a--, --b);
getche();
return 0;
}
Испис на екрану
#include<stdio.h>
main()
{
int x=1, y=2, z=3;
printf("Vrednost izraza x==1 je logicka %d.\n", x==1);
printf("Vrednost izraza y!=2 je logicka %d.\n", y!=2);
printf("Vrednost izraza x<=y je logicka %d.\n", x<=1);
printf("Vrednost izraza x>=z je logicka %d.\n", x>=1);
printf("Vrednost izraza x+y==z je logicka %d.\n", x+y==z);
printf("Vrednost izraza x>y*z je logicka %d.\n", x>y*z);
getche();
return 0;
}
Испис на екрану
main()
{
int a = 5<3, b = 5>3, c = 3==5, d = 3!=5;
printf("5<3 - %d\n5>3 - %d\n3==5 - %d\n3!=5 - %d\n", a, b, c, d);
printf("Konjunkcija : 3>5 && 5>3 - %d\n", a && b);
printf("Disjunkcija : 3>5 || 5>3 - %d\n", a || b);
printf("Negacija : !(3>5) - %d\n", !a);
getche();
return 0;
}
25
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
2.35. Саставити програм који тестира операторе над битовима за два унета броја у
хексадецималном облику и броја помераја.
#include<stdio.h>
main()
{
int x, y, n;
printf("Unesite dva heksadecimalna broja: ");
scanf("%i %i", &x, &y);
printf("Unesite broj pomeraja: ");
scanf("%d", &n);
printf("%#x & %#x = %#x\n", x, y, x&y);
printf("%#x | %#x = %#x\n", x, y, x|y);
printf("%#x ^ %#x = %#x\n", x, y, x^y);
printf("%#x << %d = %#x\n", x, n, x<<n);
printf("%#x >> %d = %#x\n", y, n, y>>n);
getche();
return 0;
}
Испис на екрану
26
Збирка решених задатака из Програмског језика С – I део
3 ГРАЊАЊЕ У ПРОГРАМУ
3.1. Саставити програм који исписује обавештење да ли је унети цео број паран или непаран.
Први начин:
#include <stdio.h>
main()
{
int broj;
printf("Unesite broj: ");
scanf("%d", &broj);
if (broj%2 == 0) Испис на екрану
printf("\nUneti broj je paran.\n");
else
printf("\nUneti broj je neparan.\n");
getche();
return 0;
}
main()
{
int broj;
printf("Unesite broj: "); scanf("%d", &broj);
(broj%2 == 0) ? printf("\nUneti broj je paran.\n")
: printf("\nUneti broj je neparan.\n");
getche();
return 0;
}
27
Збирка решених задатака из Програмског језика С – I део
3.2. Саставити програм који исписује обавештење да ли је унети број позитиван, негативан или је
једнак нули.
Први начин:
#include <stdio.h>
main()
{
int a;
printf("Unesite ceo broj: ");
scanf("%d", &a);
if(a < 0) Испис на екрану
printf("\nBroj je negativan.\n");
else if(a > 0)
printf("\nBroj je pozitivan.\n");
else
printf("\nBroj je nula.\n");
getche();
return 0;
}
main()
{
int a;
printf("Unesite ceo broj: "); scanf("%d", &a);
if(a == 0)
printf("\nBroj je nula.\n");
else
(a > 0) ? printf("\nBroj je pozitivan.\n")
: printf("\nBroj je negativan.\n");
getche();
return 0;
}
3.3. Саставити програм који за два унета цела броја исписује какав постоји релациони однос
између њих (једнаки су, први већи од другог или први је мањи од другог).
Први начин:
#include <stdio.h>
main()
{
int a, b;
printf("Unesite broj a= ");
scanf("%d", &a);
printf("Unesite broj b= ");
scanf("%d", &b); Испис на екрану
if(a == b)
printf("Brojevi su jednaki.\n");
28
Збирка решених задатака из Програмског језика С – I део
else if (a > b)
printf("Broj a je veci od b.\n");
else
printf("Broj a je manji od b.\n");
getche();
return 0;
}
main()
{
int a, b;
printf("Unesite broj a= ");
scanf("%d", &a);
printf("Unesite broj b= ");
scanf("%d", &b);
if(a == b)
printf("Brojevi su jednaki.\n");
else
(a > b) ? printf("Broj a je veci od b.\n")
: printf("Broj a je manji od b.\n");
getche();
return 0;
}
3.4. Саставити програм који за три унета цела броја исписује највећи.
#include <stdio.h>
main()
{
int a, b, c, max;
printf("Unesite tri cela broja: ");
scanf("%d%d%d", &a, &b, &c); Испис на екрану
max=a;
if(b>max)
max=b;
if(c>max)
max=c;
printf("Najveci je %d\n", max);
getche();
return 0;
}
29
Збирка решених задатака из Програмског језика С – I део
3.5. Саставити програм који три унета реална броја уређује у неопадајућем редоследу.
#include <stdio.h>
main()
{
double x, y, z, p;
printf("Unesite tri realna broja: ");
scanf("%lf%lf%lf", &x, &y, &z);
if(x>y)
{
p=x; x=y; y=p;
}
if(x>z)
{
p=x; x=z; z=p;
}
if(y>z)
{
Испис на екрану
p=y; y=z; z=p;
}
printf("Uredjeni brojevi: %.2f %.2f %.2f\n", x, y, z);
getche();
return 0;
}
3.6. Саставити програм који проверава и исписује да ли се на k-том месту унетог броја n налази
бит који има вредност 1 или 0.
#include <stdio.h>
main()
{
int n,k;
printf(" Unesite broj: ");
scanf("%d",&n);
printf(" Unesite poziciju tog broja koju zelite da proverite: ");
scanf("%d",&n);
if((n & (1 << k))!=0)
printf(" Bit je 1\n");
else
printf(" Bit je 0\n");
getche();
return 0;
}
Испис на екрану
30
Збирка решених задатака из Програмског језика С – I део
3.7. Саставити програм који ће на основу унетих броја поена (од нула до 100) исписати
одговарајућу оцену (0-50 пет, 51-60 шест, 61-70 седам, 71-80 осам, 81-90 девет, 91-100 десет).
#include <stdio.h>
main()
{
int a;
printf("Unesite broj bodova: ");
scanf ("%d", &a); Испис на екрану
if (a>90)
printf("Ocena je 10\n");
else if (a>80)
printf("Ocena je 9\n");
else if (a>70)
printf("Ocena je 8\n");
else if (a>60)
printf ("Ocena je 7\n");
else if (a>50)
printf("Ocena je 6\n");
else
printf("Ocena je 5\n");
getche();
return 0;
}
3.8. Саставити програм који ће за унети опсег позитивних целих бројева од а до b исписати да ли
се у задатом опсегу налази квадрат броја х (број х се уноси са тастатуре).
Први начин:
#include <stdio.h>
main()
{
int a, b, x;
printf("Unesite donju i gornju granicu opsega: ");
scanf("%d %d", &a, &b);
printf("Unesite ceo broj x= ");
scanf("%d", &x);
if((a <= x*x) && (x*x <= b))
printf("\nx*x=%d pripada oblasti [%d,%d]", x*x, a, b);
else
printf("\nx*x=%d ne pripada oblasti [%d,%d]", x*x, a, b);
getche();
return 0;
}
Испис на екрану
31
Збирка решених задатака из Програмског језика С – I део
main()
{
int a, b, x;
printf("Unesite donju i gornju granicu opsega: ");
scanf("%d %d", &a, &b);
printf("Unesite ceo broj x= ");
scanf("%d", &x);
((a <= x*x) && (x*x <= b))
? printf("\nx*x=%d pripada oblasti [%d,%d]", x*x, a, b)
: printf("\nx*x=%d ne pripada oblasti [%d,%d]", x*x, a, b);
getche();
return 0;
}
3.9. Саставити програм који ће учитати два броја и од већег одузети мањи и приказати резултат.
Први начин:
#include <stdio.h>
main()
{
int x, y;
printf("Unesite dva cela broja: ");
scanf("%d %d", &x, &y);
if(x<y) Испис на екрану
printf("\nRezultat = %d", y-x);
else
printf("\nRezultat = %d", x-y);
getche();
return 0;
}
main()
{
int x, y;
printf("Unesite dva cela broja: ");
scanf("%d %d", &x, &y);
printf("\nRezultat = %d", (x<y)? y-x : x-y);
getche();
return 0;
}
32
Збирка решених задатака из Програмског језика С – I део
3.10. Саставити програм за одређивање сигнум функције и исписивање резултата за унети реалан
−1 , x<0
број х. y = sgn( x ) = 0 , x=0
1 , x>0
Први начин: Други начин (условни оператор):
#include <stdio.h> #include <stdio.h>
main() main()
{ {
float x; float x;
int y; int y;
printf("Unesite x= "); printf("Unesite x= ");
scanf("%f", &x); scanf ("%f", &x);
if(x==0) y = (x>0)? 1 : (x<0)? -1 : 0;
y=0; printf("\ny= %d", y);
else if(x>0) getche();
y=1; return 0;
else }
y=-1;
printf("\ny= %d", y);
getche();
return 0;
}
Испис на екрану
#include <stdio.h>
main()
{
33
Збирка решених задатака из Програмског језика С – I део
int x, y, z;
printf("Unesite x= "); scanf("%d", &x);
printf ("Unesite y= "); scanf("%d", &y);
if(y < 0)
{
if((x*x)<(y*y)) z=y*y;
else z=x*x;
}
else
{
if(x<y) z=x; Испис на екрану
else z=y;
}
printf("\nz= %.d\n", z);
getche();
return 0;
}
#include <stdio.h>
main()
{
float a,b,c,p,s;
printf("Unesi stranice trougla \na= "); scanf("%f",&a);
printf("b= "); scanf("%f",&b);
printf("c= "); scanf("%f",&c);
if (a+b>c && a+c>b && b+c>a)
{
s=(a+b+c)/2;
p=sqrt(s*(s-a)*(s-b)*(s-c));
printf("Ѕtranice formiraju trougao povrsine p= %.2f\n", p);
}
else printf("Ѕtranice ne formiraju trougao.\n");
getche();
return 0;
}
Испис на екрану
34
Збирка решених задатака из Програмског језика С – I део
3.14. Саставити програм који исписује дужину страница и величину углова троугла на основу
унетих координата темена. Уколико се троугао не може формитати штампати одговарајуће
обавештење.
( xB − xC ) − ( y B − yC ) , b= ( xC − xA ) − ( yC − yA )
2 2
Користити следеће формуле: a =
2 2
,
a+b+c
c= ( x A − xB ) − ( y A − y B ) P = S ( S − a )( S − b )( S − c )
2 2
, S= ,
2
#include <stdio.h>
#include <math.h>
#define PI 3.141592
main()
{
double xa, ya, xb, yb, xc, yc, a, b, c, alfa, beta, gama;
printf("Unesite koordinate tacke A(x,y): ");
scanf("%lf%lf",&xa,&ya);
printf("Unesite koordinate tacke B(x,y): ");
scanf("%lf%lf",&xb,&yb);
printf("Unesite koordinate tacke C(x,y): ");
scanf("%lf%lf",&xc,&yc);
a = sqrt(pow(xb-xc,2) + pow(yb-yc,2));
b = sqrt(pow(xa-xc,2) + pow(ya-yc,2));
c = sqrt(pow(xa-xb,2) + pow(ya-yb,2));
printf("\nStranice:\n");
printf("a= %f\n", a);
printf("b= %f\n", b);
printf("c= %f\n", c);
if(a+b>c && a+c>b && b+c>a)
{
alfa = acos( (b*b+c*c-a*a) / (2*b*c) );
beta = acos( (c*c+a*a-b*b) / (2*c*a) );
gama = acos( (a*a+b*b-c*c) / (2*a*b) );
alfa *= 180/PI;
beta *= 180/PI;
gama *= 180/PI;
printf("\nUglovi:\n");
printf("Alfa = %.2f stepeni\n", alfa);
printf("Beta = %.2f stepeni\n", beta);
printf("Gama = %.2f stepeni\n", gama);
}
еlse printf("Ne moze se kreirati trougao.\n");
getche();
return 0;
}
35
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
main()
{
double a1, a2, b1, b2, x, y;
printf("Unesite koeficijente:\na1= "); scanf("%lf", &a1);
printf("b1= "); scanf("%lf", &b1);
printf("a2= "); scanf("%lf", &a2);
printf("b2= "); scanf("%lf", &b2);
printf("\nPrave:\ny=%.2fx+%.2f\ny=%.2fx+%.2f\n", a1, b1, a2, b2);
if(a1==a2)
{
if(b1==b2) printf("\nPrave su podudarne.");
else printf("\nPrave su paralelne.");
}
else
{
x=(b2-b1)/(a1-a2);
y=a1*x+b1;
printf("\nTacka preseka je x= %.2f, y= %.2f\n", x, y);
}
getche();
return 0;
}
36
Збирка решених задатака из Програмског језика С – I део
3.16. Саставити програм којим се решава нелинеарна једначина a ⋅ x + b ↔ 0 где је ↔ знак < или >,
и а≠0. Коефицијенти а и b и знак се уносе са тастатуре.
#include <stdio.h>
main()
{
char z;
double a, b, x;
printf("Unesite znak [<,>]: "); scanf("%c", &z);
printf("Unesite koeficijente:\na= "); scanf("%lf", &a);
printf("b= "); scanf("%lf", &b);
printf("\nNejednacina ima oblik: %.2fx+%.2f%c0\n", a, b, z);
x=-b/a;
if(a>0) printf("\nResenje x%c%.2f", z, x);
else printf("\nResenje .2f%c%x", z, x);
getche(); return 0;
}
#include <stdio.h>
main()
{
double a1, b1, c1, a2, b2, c2, D, Dx, Dy, x, y;
printf ("Unesite koeficijente prve jednacine:\na1= ");
scanf("%lf", &a1);
printf("b1= "); scanf("%lf", &b1);
printf("c1= "); scanf("%lf", &c1);
printf("Unesite koeficijente druge jednacine:\na2= ");
scanf("%lf", &a2);
printf("b2= "); scanf("%lf", &b2);
printf("c2= "); scanf("%lf", &c2);
D = a1 * b2 - a2 * b1;
Dx = c1 * b2 - c2 * b1;
Dy = a1 * c2 - a2 * c1;
if(D != 0)
{
x=Dx/D;
y=Dy/D;
printf ("\nResenje sistema:\nx= %.2f\n", x);
37
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
#include <stdio.h>
#include <math.h>
main()
{
double a, b, c, D, x1, x2;
printf("Unesite koeficijente:\na= "); scanf("%lf",&a);
printf("b= "); scanf("%lf",&b);
printf("c= "); scanf("%lf",&c);
if(a!=0)
{
D=b*b-4*a*c;
if(D>0)
{
x1=(-b+sqrt(D))/(2*a);
x2=(-b-sqrt(D))/(2*a);
38
Збирка решених задатака из Програмског језика С – I део
printf("n\Resenja:\nx1=%.2f, x2=%.2f",x1,x2);
}
else if(D==0)
{
x1=(-b/(2*a));
printf("\nResenje:\nx1=x2=%.2f",x1);
}
else
{
x1=-b/(2*a);
x2=sqrt(-D)/(2*a);
printf("\nKompleksna resenja:\n");
printf("x1=%.2f+i%.2f, x2=%.2f-i%.2fi",x1,x2,x1,x2);
}
}
else
{
if(b!=0)
{
x1=-c/b;
printf("\nResenje:\nx=%.2f",x1);
}
else printf("Sistem nema resenja.");
}
getche();
return 0;
}
Испис на екрану
39
Збирка решених задатака из Програмског језика С – I део
4 FOR ПЕТЉА
4.1. Саставити програм који ће пет пута исписати реченицу Pozdrav svima! употребом FOR
петље.
#include <stdio.h>
main()
{
int i;
for(i=1; i<6; i++)
printf("Pozdrav svima!\n");
getche();
return 0;
} Испис на екрану
а) #include <stdio.h>
main()
{
int i;
for(i=1; i<=10; i=i+1)
printf("%d\n", i);
getche();
return 0;
} Испис на екрану б)
б) #include <stdio.h>
Испис на екрану а)
main()
{
int i;
for (i=1; i<=10; i=i+2)
printf("%d\n", i);
getche();
return 0;
}
40
Збирка решених задатака из Програмског језика С – I део
в)
#include <stdio.h>
main()
{
int i;
for(i=10; i>=1; i=i-1)
printf("%d\n", i);
getche();
return 0;
}
Испис на екрану в)
4.3. Које вредности i и j имају након сваке промене унутар FOR петље у следећем програмском
коду:
#include <stdio.h>
main()
{
int i, j;
for(i=1; i<3; i++)
for(j=1; j<4; j++)
printf("i=%d, j=%d\n", i, j);
printf("\n");
for(i=1; i<4; i++)
for(j=1; j<3; j++)
printf("i=%d, j=%d\n", i, j);
getche();
return 0;
}
Испис на екрану
4.4. Саставити програм који за унето n исписује збир првих n целих позитивних бројева.
#include <stdio.h>
main()
{
int n, s, i;
printf("Unesite n= ");
scanf("%d", &n);
s=0; Испис на екрану
for(i=1; i<=n; i++)
s+=i;
printf("Suma= %d\n", s);
getche();
return 0;
}
41
Збирка решених задатака из Програмског језика С – I део
4.5. Саставити програм који за унето n учитава n реалних бројева и приказује њихов збир и
аритметичку средину.
#include <stdio.h>
main()
{
int n, i;
float a, s, ars;
s=0;
printf("n= ");
scanf("%d",&n);
printf(" Unesite %d brojeva:\n", n);
for(i=1; i<=n; i++)
{
scanf("%f",&a);
s+=a;
}
ars=s/n;
printf("\n Suma zadatih brojeva je %.2f", s);
printf("\n Aritmeticka sredina zadatih brojeva je %.2f", ars);
getche();
return 0;
}
Испис на екрану
4.6. Саставити програм који за унети цео број n приказује његов факторијел.
#include <stdio.h>
main()
{
int i,n;
long faktorijel=1;
printf("n= ");
scanf("%d",&n); Испис на екрану
for(i=1;i<=n;i++)
faktorijel=faktorijel*i;
printf("Faktorijel = %ld\n", faktorijel);
getche();
return 0;
}
42
Збирка решених задатака из Програмског језика С – I део
4.7. Саставити програм којим се за унети природан број n израчунава суму: S =1!+2!+3!+...+n!.
#include <stdio.h>
main()
{
int i,n;
long f=1, s=0;
printf("n= ");
scanf("%d",&n); Испис на екрану
for(i=1; i<=n; i++)
{
f*=i;
s+=f;
}
printf("\ns= %ld\n", s);
getche();
return 0;
}
4.8. Саставити програм којим се, за дате природне бројеве m и n, израчунава израз:
а) S = n ( n + m )( n + 2 m ) ... ( n + m ⋅ m )
1 1 1 1
− ... ( −1)
m +1
б) S = − +
n + m n + 2m n + 3m n + m⋅m
а) #include <stdio.h> б) #include <stdio.h>
main() main()
{ {
int i, m, n; int i, m, n, znak;
long s; float s;
printf("n= "); printf("n= ");
scanf("%d",&n); scanf("%d",&n);
printf("m= "); printf("m= ");
scanf("%d",&m); scanf("%d",&m);
s=1; s=0;
for(i=0;i<=m;i++) znak=1;
s=s*(n+i*m); for(i=1;i<=m;i++)
printf("\ns= %ld\n", s); {
getche(); s=s+(float)znak/(n+i*m);
return 0; znak=-znak;
} }
printf("\ns= %.5f\n", s);
getche();
return 0;
}
43
Збирка решених задатака из Програмског језика С – I део
main() main()
{ {
int i, n, fakt; int i, n, fakt, znak;
float s, q; float s, q;
printf("n= "); printf("n= ");
scanf("%d",&n); scanf("%d",&n);
s=0; s=0;
q=0; q=0;
fakt=1; fakt=1;
for(i=1; i<=n; i++) znak=1;
{ for(i=1; i<=n; i++)
fakt=fakt*i; {
q=q+1./(1+i); fakt=fakt*i;
s=s+fakt/q; q=q+i;
} s=s+znak*q/(float)fakt;
printf("\ns= %.5f\n", s); znak=-znak;
getche(); }
return 0; printf("\ns= %.5f\n", s);
} getche();
return 0;
}
в) #include <stdio.h>
#include <math.h>
main()
{
int i, n;
float s, p, q;
printf("n= ");
scanf("%d",&n);
s=1;
p=0; Испис на екрану а) Испис на екрану б)
q=0;
for(i=1; i<=n; i++)
{
p=p+cos(i);
q=q+sin(i);
s=s*p/(float)q;
}
printf("\ns= %.5f\n", s);
getche();
return 0;
}
Испис на екрану в)
44
Збирка решених задатака из Програмског језика С – I део
4.10. Саставити програм којим се, за дати природни број n и реалан број х, израчунава израз:
а) S = sin ( x ) + sin 2 ( x ) + ... + sin n ( x )
( ) ( )
б) S = cos ( x ) + cos x 2 + ... + cos x n
main() main()
{ {
int i, n; int i, n;
float s, p, x; float s, p, x;
printf("n= "); printf("n= ");
scanf("%d",&n); scanf("%d",&n);
printf("x= "); printf("x= ");
scanf("%f",&x); scanf("%f",&x);
s=0; s=0;
p=1; p=1;
for(i=1; i<=n; i++) for(i=1; i<=n; i++)
{ {
p=p*sin(x); p=p*x;
s=s+p; s=s+cos(p);
} }
printf("\ns= %.5f\n", s); printf("\ns= %.5f\n", s);
getche(); getche();
return 0; return 0;
} }
main()
Код последњег фактора квадратни корен је {
примењен n пута. int i, n;
float s, p;
printf("n= "); scanf("%d",&n);
s=1; p=0;
for(i=1; i<=n; i++)
{
p=sqrt(p+2);
s=s/(float)p;
}
Испис на екрану printf("\ns= %.5f\n", s);
getche();
return 0;
}
45
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
main()
{
int i, n;
float br, max;
printf("\nn= ");
scanf("%d",&n);
printf("\nUnesite 1. broj: ");
scanf("%f",&br);
max=br;
for(i=2; i<=n; i++)
{ Испис на екрану
printf("Unesite %d. broj: ",i);
scanf("%f",&br);
if(br>max) max=br;
}
printf("\nNajveci: %.2f", max);
getche();
return 0;
}
4.13. Саставити програм који ће исписати све бројева прве стотине који су дељиви са 6 и њихову
суму.
#include <stdio.h>
main()
{
int i, s=0;
printf("Brojevi deljivi sa 6:\n");
for(i=1; i<=100; i++)
{
if(i%6 == 0)
{
s=s+i;
printf("\n%d", i);;
}
}
printf("\n\nSuma: %d\n", s);
getche();
return 0;
}
Испис на екрану
46
Збирка решених задатака из Програмског језика С – I део
4.14. Саставити програм који исписује све троцифрене бројеве код којих је друга цифра за 2 већа
од прве, а трећа за 1 већа од друге.
#include <stdio.h>
main()
{
int a, b, c;
for(a=1; a<=9; a++)
for(b=3; b<=9; b++)
for(c=4; c<=9; c++)
if(b == a+2 && c == b+1)
printf("%d%d%d\n", a, b, c);
getche(); Испис на екрану
return 0;
}
4.15. Саставити програм којим се исписују сви троцифрени Амстронгови бројеви. Троцифрени
број је Амстронгов ако је једнак збиру кубова својих цифара.
#include <stdio.h>
#include <math.h>
main()
{
int a, b, c, broj;
printf("Amstrongovi brojevi:\n");
for(a=1; a<=9; a++)
for(b=0; b<9; b++) Испис на екрану
for(c=0; c<9; c++)
{
broj=100*a+10*b+c;
if(broj == pow(a,3)+pow(b,3)+pow(c,3))
printf("\n%d", broj);
}
getche();
return 0;
}
4.16. Саставити програм којим се исписују сви троцифрени бројеви АВС који имају својство
(АВС)= (АВ)2-С2, где су непознате цифре 1 ≤ A ≤ 9 , 0 ≤ B ≤ 9 , 0 ≤ C ≤ 9 . На пример: 147=142-72.
#include <stdio.h>
main()
{
int a, b, c, broj;
for(a=1; a<=9; a++)
for(b=0; b<9; b++)
for(c=0; c<9; c++) Испис на екрану
{
broj=100*a+10*b+c;
if(broj == ((10*a+b)*(10*a+b)-c*c))
printf("\n%d", broj);
}
getche(); return 0;
}
47
Збирка решених задатака из Програмског језика С – I део
4.17. Саставити програм којим се исписују сви троцифрени бројеви који имају особину да су
дељиви бројем који се добија избацивањем средње цифре.
#include <stdio.h>
main()
{
int a, b, c, broj, dvocif;
for(a=1;a<=9;a++)
for(b=0;b<9;b++)
for(c=0;c<9;c++)
{
broj=100*a+10*b+c;
dvocif=10*a+c;
if(broj%dvocif == 0)
printf("%d, ", broj);
}
getche();
return 0;
}
Испис на екрану
4.18. Саставити програм који рачуна суму троцифрених природних бројева чији је збир цифара
једнак 5. Исписати и обавештење колико бројева има такву особину.
#include <stdio.h>
main()
{
int a, b, c, s=0, br, n=0;
for(a=1; a<=9; a++)
for(b=0; b<9; b++)
for(c=0; c<9; c++) Испис на екрану
{
br=100*a+10*b+c;
if (a+b+c == 5)
{
n++;
s+=br;
}
}
printf("Suma: %d\n", s);
printf("Ukupno brojeva: %d\n", n);
getche();
return 0;
}
48
Збирка решених задатака из Програмског језика С – I део
main()
{
int i, n;
printf("n= ");
scanf("%d",&n);
printf("\nDelioci:");
for(i=1; i<=n; i++)
{
if(n%i == 0)
printf("\n%d ", i);
}
getche();
return 0; Испис на екрану
}
4.20. Саставити програм који ће исписати обавештење да ли је унети број n савршен. Број је
савршен ако је једнак суми својих делиоца искључујући њега самог. На пример, 28=1+2+4+7+14.
#include <stdio.h>
main()
{
int n, i, suma=0;
printf("n= ");
scanf("%d",&n);
for(i=1; i<n; i++)
{ Испис на екрану
if(n%i==0)
suma+=i;
}
if(suma==n)
printf("Broj %d jeste savrsen broj.\n",n);
else
printf("Broj %d nije savrsen broj.\n",n);
getche();
return 0;
}
4.21. Саставити програм који ће учитати оцене за n ученика и исписати просечну оцену свих
ученика и број ученика који имају оцену 1.
#include <stdio.h>
main()
{
int i, br=0, n, ocena;
float s,srednja;
printf("Broj ucenika n= ");
scanf("%d",&n);
for(i=1; i<=n; i++)
49
Збирка решених задатака из Програмског језика С – I део
{
printf("Unesi ocenu %d. ucenika: ",i);
scanf("%d",&ocena);
s+=ocena;
if(ocena==1) br++;
}
srednja=s/n;
printf("\nSrednja ocena: %.2f", srednja);
printf("\nBroj negativnih: %d", br);
getche();
return 0;
}
Испис на екрану
4.22. Електронски сат показује време у сатима, минутима и секундама. Саставити програм који ће
исписати све моменте времена у току једног дана такве да је сума цифара на сату једнака датом броју
n. Испис треба да је у облику (n=33):
0 sat 11 min 31 sec
1 sat 32 min 0 sec .
#include <stdio.h>
main()
{
int sat, min, sec, n;
printf("n= ");
scanf("%d",&n);
for(sat=0; sat<=23; sat++)
for(min=0; min<=59; min++)
for(sec=0; sec<=59; sec++)
{
if(n==(sat/10+sat%10+min/10+min%10+sec/10+sec%10))
printf("\n%d sat %d min %d sec", sat, min, sec);
}
getche();
return 0;
}
50
Збирка решених задатака из Програмског језика С – I део
2x +1
4.23. Саставити програм за табелирање функције y = у опсегу од xmin до xmax са кораком
x2 − 1
dx.
#include <stdio.h>
main()
{
double xmin, xmax, dx, x, y;
printf("xmin= ");
scanf("%lf", &xmin);
printf("xmax= ");
scanf("%lf", &xmax);
printf("dx= ");
scanf("%lf", &dx);
printf("\n x y\n ===================\n");
for(x=xmin; x<=xmax; x+=dx)
{
y=(2*x+1)/(x*x-1);
printf ("%10.3f%10.3f\n", x, y);
}
getche();
return 0;
}
4.24. ( ) ( )
Саставити програм за табелирање функције y = (1 + x ) ⋅ 1 + x 2 ⋅ ... ⋅ 1 + x n у опсегу од xmin
до xmax са кораком dx. Степен функције n се уноси са тастатуре.
51
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
main()
{
double xmin, xmax, dx, x, y=1, p=1;
int i, n;
printf("n= ");
scanf("%d", &n);
printf("xmin= ");
scanf("%lf", &xmin);
printf("xmax= ");
scanf("%lf", &xmax);
printf("dx= ");
scanf("%lf", &dx);
printf("\n x y\n");
printf("===================\n");
for(x=xmin;x<=xmax;x+=dx)
{
for(i=1; i<=n; i++)
{
p*=x;
y*=(1+p);
} Испис на екрану
printf("%10.6f %11.6f\n",x,y);
p=1;
y=1;
}
getche();
return 0;
}
#include <stdio.h>
#include <math.h>
#define PI 3.141592
main()
{
double dx=0, UgaoRad, UgaoSte;
printf("Unesite korak u stepenima: ");
scanf("%lf",&dx);
printf("\n x sin(x)");
printf("\n=======================\n");
for(UgaoSte=0; UgaoSte<=90; UgaoSte+=dx)
{
UgaoRad = (PI*UgaoSte)/180.0;
printf("%f \t%f\n",UgaoSte, sin(UgaoRad));
}
getche();
return 0;
} Испис на екрану
52
Збирка решених задатака из Програмског језика С – I део
4.26. Саставити програм који за унети позитиван цео број n исцртава облик приказан на слици, на
слици је n=5.
a) **********
б) 0123456789
********** 0123456789
********** 0123456789
********** 0123456789
********** 0123456789
а) б)
#include <stdio.h> #include <stdio.h>
main() main()
{ {
int i, j, n; int i, j, n;
printf(" n= "); printf(" n= ");
scanf("%d", &n); scanf("%d", &n);
printf("\n"); printf("\n");
for(i=0; i<n; i++) for(i=0; i<n; i++) Испис на екрану а)
{ {
for(j=0; j<2*n; j++) for(j=0; j<2*n; j++)
printf("*"); printf("%d", j);
printf("\n"); printf("\n");
} }
getche(); getche();
return 0; return 0;
} }
Испис на екрану б)
4.27. Саставити програм који за унете позитивне целе бројеве m и n исцртава правоугаоник
формиран од знака чији се ASCII код уноси са тастатуре.
#include <stdio.h>
main()
{
int i, j, m, n, a;
printf(" m= ");
scanf("%d", &m);
printf(" n= ");
scanf("%d", &n);
printf(" ASCII= ");
scanf("%d", &a);
printf("\n");
Испис на екрану
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
printf("%c", a);
printf("\n");
}
getche();
return 0;
}
53
Збирка решених задатака из Програмског језика С – I део
4.28. Саставити програм који за унети позитиван цео број n исцртава облик приказан на слици, на
слици је n=5.
а) б) в) г)
* * * * * ***** * *
* * * * * * * * * **
* * * * * * * * ** * *
* * * * * * * * *** * *
* * * * * ***** * **** *****
д) ђ) е) ж)
main() main()
{ {
int i, j, n; int i, j, n;
printf(" n= "); printf(" n= ");
scanf("%d", &n); scanf("%d", &n);
printf("\n"); printf("\n");
for(i=1; i<=n; i++) for(i=1; i<=n; i++)
{ {
for(j=1; j<=n; j++) for(j=1; j<=i; j++)
printf("* "); printf("* ");
printf("\n"); printf("\n");
} }
getche(); getche();
return 0; return 0;
} }
54
Збирка решених задатака из Програмског језика С – I део
main() main()
{ {
int i, j, n; int i, j, n;
printf(" n= "); printf(" n= ");
scanf("%d", &n); scanf("%d", &n);
printf("\n"); printf("\n");
for(i=1; i<=n; i++) for(i=1; i<=n; i++)
{ {
for(j=1; j<=n; j++) for(j=1; j<=i; j++)
{ {
if(i==1 || i==n) if(i==n)
printf("* "); printf("* ");
else if (j==1 || j==n) else if (j==1 || j==i)
printf("* "); printf("* ");
else printf(" "); else printf(" ");
} }
printf("\n"); printf("\n");
} }
getche(); getche();
return 0; return 0;
} }
main()
main()
{
{
int i, j, n;
int i, j, n;
printf(" n= ");
printf(" n= ");
scanf("%d", &n); scanf("%d", &n);
printf("\n"); printf("\n");
for(i=1; i<=n; i++)
for(i=1; i<=n; i++)
{ {
for(j=n; j>=i; j--)
for(j=n; j>=i; j--)
{
printf("* ");
if(i==1) printf("* ");
printf("\n");
else if(j==n || j==i)
}
printf("* ");
getche();
return 0; else printf(" ");
} }
printf("\n");
}
getche();
return 0;
}
55
Збирка решених задатака из Програмског језика С – I део
main() main()
{ {
int i, j, n, k; int i, j, n, k;
printf(" n= "); printf(" n= ");
scanf("%d", &n); scanf("%d", &n);
printf("\n"); printf("\n");
for(i=1; i<=n; i++) for(i=n; i>=1; i--)
{ {
for(k=n; k>i; k--) for(k=n; k>i; k--)
printf(" "); printf(" ");
for(j=1; j<=i; j++) for(j=1; j<=i; j++)
printf("* "); printf("* ");
printf("\n"); printf("\n");
} }
getche(); getche();
return 0; return 0;
} }
4.29. Саставити програм који за унети позитивни цео број n исцртава облик приказан на слици, на
слици је n=5.
#include <stdio.h>
main()
{
int n, i, j, k;
printf("n= "); scanf("%d", &n);
printf("\n");
for(i=1; i<=n; i++)
{
for(k=n; k>i; k--)
printf(" ");
for(j=0; j<i; j++)
printf("* ");
printf("\n");
} Испис на екрану
for(i=n-1; i>0; i--)
{
for(k=n; k>i; k--)
printf(" ");
for(j=0; j<i; j++)
printf("* ");
printf("\n");
}
getche(); return 0;
}
56
Збирка решених задатака из Програмског језика С – I део
4.30. Саставити програм који за унети позитиван цео број n (од 1 до 9) исцртава облик приказан на
слици, на слици је n=5.
#include <stdio.h>
main()
{
int n, i, j, k, m;
printf("n= "); scanf("%d",&n);
printf("\n");
for(i=n; i>0; i--)
{
m=i;
for(k=n; k>i; k--)
printf(" ");
for(j=0; j<i; j++)
printf("%d ", m);
printf("\n");
Испис на екрану
}
for(i=2; i<=n; i++)
{
m=i;
for(k=n; k>i; k--)
printf(" ");
for(j=0; j<i; j++)
printf("%d ", m);
printf("\n");
}
getche();
return 0;
}
4.31. Саставити програм који за унети цео позитиван број n исцртава облик приказан на слици, на
слици је n=7. Подразумева се да се уноси непаран број.
#include <stdio.h>
main()
{
int i, j, n;
printf("n= ");
scanf("%d", &n);
printf("\n");
for(i=1; i<=n; i++)
{
if(i%2==0) printf(" ");
if(i%4==3) printf(" ");
for(j=1; j<=n; j++)
printf("* ");
printf("\n");
}
getche();
return 0;
}
Испис на екрану
57
Збирка решених задатака из Програмског језика С – I део
4.32. Саставити програм који за унети позитиван цео број n исцртава облик приказан на слици, на
слици је n=5.
#include <stdio.h>
main()
{
int n, i, j, nzv, nrz, kor=1;
printf(" n= ");
scanf("%d", &n);
printf("\n");
nzv=n,
nrz=n-1;
for(i=1; i<=2*n-1; i++)
{
for(j=1; j<=nrz; j++)
printf(" ");
for(j=1; j<=nzv; j++)
printf("* ");
printf("\n");
if(i==n) kor = -1;
nzv += kor;
nrz -= kor;
}
getche();
return 0;
}
Испис на екрану
4.33. Саставити програм који за унето непарно и позитивно n исцртава стрелицу приказану на
слици, на слици је n=3.
#include <stdio.h>
main()
{
int n, i, j, nzv=0, kor=1;
char rep = ' ';
printf(" n= ");
scanf("%d", &n);
printf("\n");
for(i=1; i<=3*n; i++)
{
nzv+=kor;
for(j=1; j<=3*n; j++)
printf("%c", rep);
for(j=1; j<=nzv; j++)
printf("*");
printf("\n");
if(i==n) rep='*';
if(i==3*n/2+1) kor=-1;
if(i==2*n) rep = ' ';
}
getche();
return 0;
}
Испис на екрану
58
Збирка решених задатака из Програмског језика С – I део
4.34. Саставити програм који за унети цео позитиван и непаран број n исцртава облик приказан на
слици, на слици је n=7. Укупна ширина je 2n-1.
#include <stdio.h>
main()
{
int i, j, n;
printf(" n= "); scanf("%d", &n);
printf("\n");
for(i=0;i<2*n-1;i++)
{
if(i==0 || i==n-1 || i==2*n-2)
printf("+");
else printf("-");
}
printf("\n");
for(j=0;j<n-2;j++)
{
for(i=0; i<2*n-1; i++)
{
if(i==0 || i==n-1 || i==2*n-2)
printf("|");
else printf(" ");
}
printf("\n");
}
for(i=0;i<2*n-1;i++)
Испис на екрану
{
if(i==0 || i==n-1 || i==2*n-2)
printf("+");
else printf("-");
}
printf("\n");
getche();
return 0;
}
4.35. Саставити програм који за унети цео позитиван и непаран број n исцртава облик приказан на
слици, на слици је n=9.
#include <stdio.h>
main()
{
int i, j, n;
printf(" n= ");
scanf("%d", &n);
printf ("\n");
printf("+");
for(i=0;i<n-2;i++)
printf("-");
printf("+\n");
for(i=1; i<n-1; i++)
{
printf("|");
for(j=1; j<n-1; j++)
if(i==n/2 && j==n/2) printf("+");
59
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
4.36. Саставити програм који за унети цео позитиван и непаран број n исцртава облик приказан на
слици, на слици је n=7.
#include <stdio.h>
main()
{
int i, j, n;
printf(" n= ");
scanf("%d", &n);
printf("\n");
printf("+");
for(i=0; i<n-2; i++)
printf("-");
printf ("+\n");
printf ("+");
Испис на екрану for(i=0; i<n-2; i++)
printf ("-");
printf("+\n");
getche();
return 0;
}
60
Збирка решених задатака из Програмског језика С – I део
4.37. Саставити програм који за унети цео позитиван и непаран број n исцртава облик приказан на
слици, на слици је n=7.
#include <stdio.h>
main()
{
int n, i, j;
printf(" n= ");
scanf("%d", &n);
printf("\n");
printf("+");
for(i=0;i<n-2;i++)
printf("-");
printf("+\n");
printf("+");
for(i=0; i<n-2; i++)
printf("-");
Испис на екрану
printf("+\n");
getche();
return 0;
}
61
Збирка решених задатака из Програмског језика С – I део
5 WHILE ПЕТЉА
5.1. Саставити програм који ће пет пута исписати реченицу Pozdrav svima! употребом
WHILE петље.
#include <stdio.h>
main()
{
int i;
i=1;
while(i<=5)
{
printf("Pozdrav svima!\n");
Испис на екрану
i++;
}
getche();
return 0;
}
main() main()
{ {
int i; int i;
i=1; i=2;
while(i<=10) while(i<=10)
{ {
printf("%d\n", i); printf("%d\n", i);
i++; i+=2;
} }
getche(); getche();
return 0; return 0;
} }
62
Збирка решених задатака из Програмског језика С – I део
Испис на екрану б)
Испис на екрану a)
в) #include <stdio.h>
main()
{
int i;
i=10;
while(i<=10 & i>0)
{
printf("%d\n", i);
i--;
}
getche();
return 0;
Испис на екрану в)
}
#include <stdio.h>
main()
{
int n, i=1, suma=0;
printf("n= ");
scanf("%d",&n);
while(i <= n)
{ Испис на екрану
suma+= i;
i++;
}
printf("Suma prirodnih brojeva od 1 do %d je: %d\n", n, suma);
getche();
return 0;
}
63
Збирка решених задатака из Програмског језика С – I део
5.4. Саставити програм за исписивање суме сваког трећег природног броја од 1 до n. Број n се
уноси са тастатуре.
#include <stdio.h>
main()
{
int i=1, suma=0, n;
printf(" n= ");
scanf("%d",&n);
while(i<=n)
{ Испис на екрану
suma=suma+i;
i=i+3;
}
printf(" Suma svakog treceg broja, od 1 do %d, je %d\n", n,suma);
getche();
return 0;
}
#include <stdio.h>
#include <math.h>
main()
{
int i=1, n;
float s=0;
printf(" n= "); scanf("%d", &n);
while(i<=n)
Испис на екрану
{
s+=1./pow(2*i+1,2);
i++;
}
printf("\n s= %f\n", s);
getche();
return 0;
}
5.6. Саставити програм за израчунавање суме s квадрата парних и кубова непарних природних
бројева од n до m (n<m).
#include <stdio.h>
#include <math.h>
main()
{
int i, n, m;
long s=0;
64
Збирка решених задатака из Програмског језика С – I део
main() main()
{ {
int i=3, n, fpp=1, fp=1, fn; int i=3, n, fpp=1, fp=1, fn,s=2;
printf(" n= "); printf(" n= ");
scanf("%d", &n); scanf("%d", &n);
printf("\n f1= 1\n f2= 1\n"); while(i<=n)
while(i<=n) {
{ fn=fp+fpp;
fn=fp+fpp; s=s+fn;
fpp=fp; fpp=fp;
fp=fn; fp=fn;
printf(" f%d= %d\n", i, fn); i++;
i++; }
} printf("\n s= %d\n", s);
getche(); getche();
return 0; return 0;
} }
Испис на екрану б)
Испис на екрану а)
65
Збирка решених задатака из Програмског језика С – I део
5.8. Саставити програм за исписивање n-тог степена броја а. Оба броја се уносе са тастатуре.
#include <stdio.h>
main()
{
int a, n, i=1, stepen=1;
printf(" a= ");
scanf("%d",&a);
printf(" n= ");
scanf("%d",&n);
Испис на екрану
while(i<=n)
{
stepen*=a;
i++;
}
printf("\n Broj %d na %d-ti stepen je: %d\n",a,n,stepen);
getche();
return 0;
}
5.9. Саставити програм за израчунавање средње вредности унетих реалних бројева. Користити
број 0 као STOP кôд за крај учитавања.
#include <stdio.h>
#define STOP 0
main()
{
int n=0;
float x, suma=0;
printf("\n Unesite niz realnih brojeva (0 za kraj):\n\n");
scanf("%f",&x);
while(x!=STOP)
{
suma += x;
n++;
scanf("%f",&x);
}
if (n==0)
printf("\n Nije zadat niz realnih brojeva.\n\n");
else
printf("\n Aritmeticka sredina zadatog niza je %.3f\n",suma/n);
getche();
return 0;
}
Испис на екрану
66
Збирка решених задатака из Програмског језика С – I део
5.10. Саставити програм који ће учитавати један за другим низ бројева. Крај уноса означен је
нулом. Наћи и исписати аритметичку средину учитаних бројева узимајући у обзир само оне бројеве
који су већи или једнаки 2 и мањи или једнаки 6.
#include <stdio.h>
main()
{
int i=0;
float x, suma=0, sredina;
printf("\n Unesite niz realnih brojeva (0 za kraj):\n\n");
while(1)
{
scanf("%f",&x);
if(x==0)
{
sredina=suma/i;
printf(" Aritmeticka sredina: %.3f\n", sredina);
}
if(x>=2 && x<=6)
{
suma+=x;
i++;
}
}
getche();
return 0;
}
Испис на екрану
5.11. Саставити програм који ће учитати природне бројеве m и n (m>n). Уколико услови приликом
уноса нису испуњени поновити учитавање. Наћи и исписати биномни коефицијент:
m m!
b=
( − n )!
n n ! m
#include <stdio.h>
main()
{
int m=0, n, i, brojilac=1, imenilac=1;
while(m<1 || n<1 || n>m)
{
printf("\n Unesite m i n: ");
scanf("%d%d",&m,&n);
}
for(i=m;i>m-n;i--)
brojilac=brojilac*i;
for(i=1;i<=n;i++) Испис на екрану
imenilac=imenilac*i;
brojilac=brojilac/imenilac;
printf("\n Binomni koeficijent b= %d \n ", brojilac);
getche();
return 0;
}
67
Збирка решених задатака из Програмског језика С – I део
5.12. Саставити програм који ће учитати два броја m и n. Оба броја треба да буду природна. Ако
тај услов није испињен, учитавање треба поновити. Ако је n<m, заменити m са n. Наћи и исписати
суму квадратних корена свих непарних бројева од m до n.
#include <stdio.h>
#include <math.h>
main()
{
int m=0, n, pomoc, i;
float suma=0, koren;
printf("\n Unesite m i n [0<m<n]: ");
while(m<1 || n<1)
scanf("%d%d",&m,&n);
if(m>n)
{
pomoc=n;
n=m;
m=pomoc;
}
if(m%2==0) m++;
for(i=m;i<=n;i=i+2)
{
koren=sqrt(i); Испис на екрану
suma+=koren;
}
printf("\n Suma korena je %.3f\n", suma);
getche();
return 0;
}
1 1 1 n −1 1
5.13. Саставити програм којим се за унето n рачуна сума: S = 1 − + − + ... + ( −1)
2 3 4 n
#include <stdio.h>
main()
{
int znak=1, i=1, n;
float suma=0;
printf("\n n= ");
scanf("%d",&n);
while(i<=n) Испис на екрану
{
suma+=(float)znak/i;
i++;
znak=-znak;
}
printf("\n S= %.3f\n", suma);
getche();
return 0;
}
68
Збирка решених задатака из Програмског језика С – I део
∞
1 1 1 1
5.14. Саставити програм којим се приближно рачуна сума: S = 2
+ 2 + 2 + ... = ∑ 2
1 2 3 n =1 n
Сумирање вршити све док је општи члан већи од 10-4.
#include <stdio.h>
main()
{
int n=1;
float suma=0, clan;
clan=1/(n*n);
while(clan>1e-4) Испис на екрану
{
suma=suma+clan;
n++;
clan=1.0/(n*n);
}
printf("\n S= %.3f\n", suma);
getche();
return 0;
}
x x2 n x
n
5.15. Саставити програм којим за унто х приближно рачуна сума: S = 1 − + − ... + ( −1) + ...
1! 2! n!
Сумирање вршити до члана (укључујући и њега) који је по апсолутној вредности мањи од задатог
броја ерѕ. Исписати и колико је елемената сумирано.
#include <stdio.h>
main()
{
double suma=1.0, x, eps, clan;
int n=1, i;
printf("\n x= ");
scanf("%lf",&x);
printf("\n eps= ");
scanf("%lf",&eps);
clan=x;
Испис на екрану
while(abs(clan)>=eps)
{
suma+=clan;
clan=x;
n++;
for(i=2;i<=n;i++)
clan=-clan*(-x/i);
}
printf("\n S= %lf", suma);
printf("\n Br.elemenata= %d\n", n);
getche();
return 0;
}
69
Збирка решених задатака из Програмског језика С – I део
main()
{
double suma=1.0, x, a, eps, clan;
int i=0;
printf("\n x= ");
scanf("%lf",&x);
printf("\n a= ");
scanf("%lf",&a);
printf("\n eps= ");
scanf("%lf",&eps); Испис на екрану
clan=x;
while(fabs(clan)>=eps)
{
i++;
clan=clan*(a-i+1)*x/i;
suma=suma+clan;
}
printf("\n S= %lf\n", suma);
getche();
return 0;
}
5.17. Саставити програм којим се исписује највећи заједнички делилац (NZD) бројева a и b
помоћу Еуклидовог алгоритма:
- ако је a=b, тада је NZD=a и то је крај алгоритма;
- ако је а≠b, тада од већег броја одузимамо мањи и враћамо се на први корак.
#include <stdio.h>
main()
{
int a, b;
printf(" a= ");
scanf("%d",&a);
printf(" b= ");
scanf("%d", &b); Испис на екрану
while(a!=b)
{
if(a>b) a-=b;
else b-=a;
}
printf("\n NZD=: %d\n",a);
getche();
return 0;
}
70
Збирка решених задатака из Програмског језика С – I део
5.18. Саставити програм који испитује да ли је унети број Нивенов. Нивенов број је број који је
дељив са сумом својих цифара.
#include <stdio.h>
main()
{
int n, k, suma=0;
printf(" n= ");
scanf("%d", &n);
k=n;
while(k > 0)
{ Испис на екрану
suma+=k%10;
k /= 10;
}
if(k%suma==0)
printf("\n Broj %d jeste Nivenov\n", n);
else
printf("\n Broj %d nije Nivenov\n", n);
getche();
return 0;
}
5.19. Саставити програм који за унети природни број исписује број чије су цифре у обрнутом
редоследу унетог броја.
#include <stdio.h>
main()
{
int n, obrnuti=0;
printf(" n= ");
scanf("%d", &n);
while(n > 0)
Испис на екрану
{
obrnuti = obrnuti*10 + n%10;
n /= 10;
}
printf("\n Obruti: %d\n", obrnuti);
getche();
return 0;
}
5.20. Саставити програм којим се дати природни број раставља на просте факторе. На пример, за
28 треба исписати: 2 2 7.
#include <stdio.h>
main()
{
int m, n, k;
printf(" n= ");
71
Збирка решених задатака из Програмског језика С – I део
scanf("%d",&n);
printf("\n\n Prosti faktori:");
m=n/2;
for (k=2;k<=m;k++)
{
while(n%k==0)
{
printf("\n%3d", k);
n/=k;
}
}
getche(); Испис на екрану
return 0;
}
#include <stdio.h>
main()
{
int a, b, c, zbir;
printf(" Pitagorini brojevi:\n");
for(a=1;a<=20;a++)
{
for(b=1;b<=20;b++)
{
zbir=a*a+b*b;
c=1;
while(c*c<=zbir)
{
if(c*c==zbir)
printf(" a=%2d b=%2d c=%2d\n", a,b,c);
c++;
}
}
}
getche();
return 0;
}
Испис на екрану
72
Збирка решених задатака из Програмског језика С – I део
6 DO...WHILE ПЕТЉА
6.1. Саставити програм који ће пет пута исписати реченицу Pozdrav svima! употребом DO
WHILE петље.
#include <stdio.h>
main()
{
int i;
i=1;
do
{
printf("Pozdrav svima!\n");
i++;
} Испис на екрану
while(i<=5);
getche();
return 0;
}
а) #include <stdio.h>
main()
{
int i;
i=1;
do
{
printf("%d\n", i);
i++;
}
while(i<=10);
getche();
return 0; Испис на екрану а) Испис на екрану в)
}
73
Збирка решених задатака из Програмског језика С – I део
б) в)
#include <stdio.h> #include <stdio.h>
main() main()
{ {
int i; int i;
i=2; i=10;
do do
{ {
printf("%d\n", i); printf("%d\n", i);
i+=2; Испис на екрану б) i--;
} }
while(i<=10); while(i<=10 & i>0);
getche(); getche();
return 0; return 0;
} }
6.3. Саставити програм који омогућује унос целих бројева све док препозна број чији квадрат
припада првој стотини.
#include <stdio.h>
main()
{
int n;
do
{
printf(" n= ");
scanf("%d", &n);
}
Испис на екрану
while(n*n<=0 || n*n>100);
printf("\n Kvadrat broja %d [%d] pripada prvoj stotini.\n", n, n*n);
getche();
return 0;
}
6.4. Саставити програм којим се исписују сви степени броја 2 који нису већи од унете вредности
променљиве границе, а која је већа од броја 2.
#include <stdio.h>
main()
{
int stepen,granica;
printf(" Unesite granicu: ");
scanf("%d",&granica);
stepen=1;
do
{
printf(" %d\n",stepen);
stepen*=2; Испис на екрану
}
while(stepen <= granica);
getche();
return 0;
}
74
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
#include <math.h>
main()
{
float znak=-1.0;
int i=1;
float clan=1.0, suma=1.0, eps;
Испис на екрану
printf(" eps= ");
scanf("%f", &eps);
do
{
clan=(float)znak/(2*i+1);
suma+=clan;
znak=-znak;
i++;
}
while(fabs(clan) > eps);
printf("\n Pi= %f", 4*suma);
getche();
return 0;
}
1 1 1
6.6. Саставити програм којим се међу бројевима 1, 1+ , 1+ + , ... проналази први већи од
2 2 3
задатог броја а.
#include <stdio.h>
main()
{
float a, i=0, s=0;
printf(" a= ");
scanf("%f",&a);
do
Испис на екрану
{
i++;
s=s+1/i;
}
while(s<a);
printf("\n S=%.3f", s);
getche();
return 0;
}
75
Збирка решених задатака из Програмског језика С – I део
6.7. Саставити програм који ће израчунати квадратни корен Њутновом методом са задатом
1 x
тачношћу. Њутнова формула гласи: yi +1 = yi + , где је х број чији се тражи корен, а почетна
2 yi
итерација y0 = x + 1 .
#include <stdio.h>
#include <math.h>
main()
{
float x, y, z, eps;
printf(" Unesite broj x= ");
scanf("%f", &x);
printf(" Unesite tacnost eps= "); Испис на екрану
scanf("%f", &eps);
y=x+1;
do
{
z=y;
y=0.5*(y+x/y);
}
while(fabs(z-y) > eps);
printf("\n Koren iz %.3f je %.3f", x, y);
getche();
return 0;
}
6.8. Саставити програм који на основу задатог опсега унутар прве стотине исписује бројеве
дељиве са 4. Уколико се не зада коректна граница програм треба да захтева поновни унос. У сваком
реду исписати по десет бројева.
#include <stdio.h>
main()
{
int x, a, b, brojac=0;
do
{
printf(" Unesite granice opsega [cele brojeve od 1 do 100]: ");
scanf("%d%d",&a,&b);
}
while(a<1 || a>b || b<=a || b>100);
printf("\n Brojevi u opsegu od %d do %d deljivi sa 4:\n", a, b);
for(x=a;x<=b;x++)
{
if(x%4==0)
{
printf(" %d ", x);
brojac++;
}
if(brojac%10==0)
printf("\n");
}
getche();
return 0;
}
76
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
6.9. Саставити програм којим се врши сабирање и исписује сума свих троцифрених бројева
дељивих са 64. Колико има таквих бројева?
#include <stdio.h>
main()
{
int i=100,s=0,br=0;
do
{
if(i%64==0) Испис на екрану
{
s+=i;
br++;
}
i++;
}
while (i<=999);
printf("\n Suma= %d", s);
printf("\n Brojeva= %d", br);
getche();
return 0;
}
6.10. Саставити програм који ће прво да учита број m. Тај број мора бити већи од 0 и мањи од 10.
Ако тај услов није испуњен учитавање поновити. Програм треба даље да учитава низ бројева, а унос
се завршава са нулом. Програм треба наћи и исписати број n који показује колико међу учитаним
бројевима има оних код којих је прва цифра m.
Испис на екрану
77
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
#include<math.h>
main()
{
int m, n, k, br=0;
float x;
do
{
printf("\n m= ");
scanf("%d", &m);
}
while (m<=0 || m>=10);
printf ("\n Unesite cele brojeve [0 za kraj]:\n");
scanf("%d",&k);
do
{
n=log10 (k); /*Nadji prvu cifru.*/
/*Moze i ovako: n=k; while(n>9) n/=10;.....*/
n=k/pow(10,n); /*... n je prva cifra*/
if(n==m) br++;
scanf("%d",&k);
}
while(k!=0);
printf("\n %d brojeva ima prvu cifru %d ", br, m);
getche();
return 0;
}
78
Збирка решених задатака из Програмског језика С – I део
7 СКОКОВИ
7.1 BREAK
main()
{
int i;
for(i=1;i<=10;i++)
{
if(i==5) break;
printf(" i=%d \n",i); Испис на екрану а)
}
getche();
return 0;
}
б) #include <stdio.h>
main()
{
int i, j;
for(i=1;i<=5;i++)
for(j=1;j<=10;j++)
{
if(j==3) break;
printf("i=%d j=%d\n",i,j);
}
getche();
return 0; Испис на екрану б)
}
79
Збирка решених задатака из Програмског језика С – I део
7.2. Саставити програм који ће учитавати позитивне целе бројеве и исписивати њихове квадрате
све док не причита негативни број.
#include <stdio.h>
main()
{
int i;
while(1)
{
printf(" i= "); scanf("%d",&i);
if (i<0) break;
printf(" i*i= %d\n\n", i*i);
}
getche();
return 0;
}
Испис на екрану
7.3. Саставити програм који са тастатуре копира на екран низ целих бројева све док се не унесе
100 или број 0 као STOP код.
#include <stdio.h>
#define STOP 0
main()
{
int i,x;
printf(" Unesite cele brojeve [100 njih ili 0 za kraj unosa]:\n\n");
for(i=0; i<=100; i++)
{
scanf("%d",&x);
if(x==STOP)
break;
printf("\n% d",x);
}
getche();
return 0;
}
Испис на екрану
80
Збирка решених задатака из Програмског језика С – I део
7.4. Саставити програм који ће исписати први број (ако постоји) који је мањи од 500, а дељив са
бројевим 3, 4, 5 и 7.
#include <stdio.h>
main()
{
int i;
for(i=1; i<=500; i++) Испис на екрану
if(i%3==0 && i%4==0 && i%5==0 && i%7==0)
{
printf("%d\n", i);
break;
}
getche();
return 0;
}
n
1
7.5. Саставити програм који за унето n рачуна суму s = ∑i
i =1
2
. Програм треба да ради за
произвољан број уноса n све док за његову вредност не прочита нулу или негативни број..
#include <stdio.h>
main()
{
int n, i;
float s;
while(1)
{
printf(" n= ");
scanf("%d", &n);
if(n <= 0) break;
s=0;
for(i=1; i<=n; i++)
s+=1./(i*i);
printf (" S= %.6f\n\n", s);
}
getche();
return 0; Испис на екрану
}
7.6. Саставити програм који ће прво учитати број n који означава број елемената низа, а затим
учитава елементе низа. Када прочита елементе треба израчунати и исписати аритметичку средњу
1 n 1 n 2 2
вредност s = ∑
n i =1
ai и стандардну девијацију d = ∑ ai − si . Програм треба да обрађује
n i =1
произвољан број комплета све док за број елемената низа не прочита нулу или негативни број.
81
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
main()
{
while(1)
{
double a, s, d;
int n,i;
printf("\n n= ");
scanf("%d", &n); Испис на екрану
if(n <= 0) break;
printf(" Elementi: ");
s=0, d=0;
for(i=1; i<=n; i++)
{
scanf("%lf",&a);
s+=a;
d+=a*a;
}
s/=n;
d=sqrt(d/n-s*s);
printf(" s= %.4f\n", s);
printf(" d= %.4f\n", d);
}
getche();
return 0;
}
7.7. Саставити програм који ће исписати све просте бројеве од 1 до 100. Број је прост ако је
дељив само са 1 и самим собом.
#include <stdio.h>
main()
{
int i,j,m;
float x;
for(i=1; i<=100; i=i+1)
{
x=i;
m=sqrt(x);
for(j=2; j<=m; j++)
if(i%j==0) break;
if(i==2 || i%j!=0)
printf(" %2d",i);
}
getche();
return 0;
}
Испис на екрану
82
Збирка решених задатака из Програмског језика С – I део
7.2 CONTINUE
main()
{
int i;
for(i=1;i<=10;i++)
{
if(i==5) continue;
printf(" i=%d \n",i);
}
getche();
return 0;
} Испис на екрану а)
б) #include <stdio.h>
main()
{
int i, j;
for(i=1;i<=4;i++)
for(j=1;j<=4;j++)
{
if(j==2) continue;
printf("i=%d j=%d\n",i,j);
}
getche();
return 0;
}
Испис на екрану б)
7.9. Саставити програм користећи наредбу continue који ће исписати парне бројеве прве
десетице.
#include <stdio.h>
main()
{
int i;
for(i=1;i<10; i++)
{
if((i%2)!=0) continue;
printf(" %d\n", i); Испис на екрану
}
getche();
return 0;
}
83
Збирка решених задатака из Програмског језика С – I део
7.10. Које вредности променљиве х се исписују на екран након извршавања следећег програма:
а)
#include <stdio.h>
main()
{
int i, x=0;
for(i=1; i<20; i++)
{
if(i%5==0) continue;
x++;
if(i==10) break;
printf("\n x=%d", x);
}
getche();
return 0;
}
Испис на екрану а)
б) #include <stdio.h>
main()
{
int i,x=0;
for(i=1; i<20; i++)
{
if(i%8==0) continue;
x++;
if(i==8||i==12||i==16) break;
printf ("\n x=%d", x);
}
getche();
Испис на екрану б)
return 0;
}
7.11. Саставити програм који исписује све бројеве мање од 20 који нису дељиви са бројем 3.
#include <stdio.h>
main()
{
int i;
for(i=1; i<=20; i++)
{
if(i%3==0) continue;
printf(" %d\n", i);
}
getche();
return 0;
}
Испис на екрану
84
Збирка решених задатака из Програмског језика С – I део
n
1
7.12. Саставити програм за рачунање суме s = ∑i
i =1
2
за позитивне вредности n. За сваки негативни
#include <stdio.h>
main()
{
int n, i;
float s;
while(1)
{
printf ("\n n= ");
scanf("%d", &n);
if(n == 0) break;
if(n < 0) continue;
s=0;
for(i=1; i<=n; i++)
s+=1./(i*i);
printf (" s= %.6f\n", s);
}
getche();
return 0;
}
Испис на екрану
7.3 GOTO
7.13. Шта ће се исписати на екрану, уколико се унесу бројеви 5, 7 и 3 након извршавања следећег
програма: #include <stdio.h>
main()
{
int opcija;
start: printf(" Birati opciju od 1 do 3: ");
scanf("%d", &opcija);
if(opcija<1 || opcija>3)
goto start;
else if(opcija==1)
goto Num1;
else if(opcija==2)
goto Num2;
else if(opcija==3)
goto Num3;
Num1: printf(" Izabrana je opcija A.\n");
goto End;
Num2: printf(" Izabrana je opcija B.\n");
goto End;
Num3: printf(" Izabrana je opcija C.\n");
goto End;
End:;
getche();
return 0;
}
85
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
7.14. Саставити програм који ће понављати захтев за уношење броја све док се број не унесе у
задатом опсегу, и који ће цртати хистограм вредности ако је у задатом опсегу.
#include <stdio.h>
main()
{
int i, n;
start: printf(" Unesite ceo broj od 0 do 10: ");
scanf("%d", &n);
if(n<0 || n>10)
goto start;
else if (n==0)
goto Loc0;
else
goto Loc1;
Loc0: printf("\n Izabran je broj 0 za KRAJ.\n\n");
goto End;
Loc1: for(i=0;i<n;i++)
printf("X");
printf("\n\n");
goto start;
End: ;
getche();
return 0;
}
Испис на екрану
86
Збирка решених задатака из Програмског језика С – I део
7.15. Саставити програм који ће исписати бројеве прве десетице помоћу goto наредбе.
#include <stdio.h>
main()
{
int i=1;
poc: printf(" %d", i); Испис на екрану
i++;
if(i<=10)
goto poc;
getche();
return 0;
}
7.16. Саставити програм који ће за унети природан број n исписати производ његових цифара.
#include <stdio.h>
main()
{
int n, a, p=1;
printf(" n= ");
scanf("%d",&n); Испис на екрану
poc: a=n%10;
p=p*a;
n=n/10;
if(n!=0)
goto poc;
printf(" p= %d", p);
getche();
return 0;
}
7.17. Саставити програм којим се дати природни број раставља на просте факторе. На пример, за
28 треба исписати: 2 2 7.
#include <stdio.h> else
{
main() f++;
{ goto poc;
int n, f=2; }
printf(" n= "); }
scanf("%d",&n); getche();
printf(" %d=1",n); return 0;
poc: if(n!=1) }
{
if(n%f==0)
{
printf("*%d",f);
n=n/f;
goto poc;
} Испис на екрану
87
Збирка решених задатака из Програмског језика С – I део
7.18. Саставити програм који ће учитавати реалне бројеве све док се не учита нула. Затим треба
исписати колико је бројева учитано, колико је међу учитаним бројевима позитивно, а колико
негативно и аритметичку средину учитаних бројева.
#include <stdio.h>
main()
{
float n, br=0, poz=0, neg=0, s=0, as;
poc: printf("\ Ucitaj broj: ");
scanf("%f",&n);
if(n!=0)
{
br++;
s=s+n;
if(n>0) poz++;
else neg++;
goto poc;
} Испис на екрану
as=s/br;
printf("\n Ucitano: %.0f brojeva.", br);
printf("\n Pozitivnih: %.0f brojeva. ", poz);
printf("\n Negativnih: %.0f brojeva. ", neg);
printf("\n Aritmeticka sredina: %.3f", as);
getche();
return 0;
}
7.19. Саставити програм који за унету редни број од 1 до 7 исписати одговрајући дан у недељи.
#include <stdio.h> case 5:
printf("\n petak");
main() break;
{ case 6:
int x; printf("\n subota");
printf(" n= "); break;
scanf("%d",&x); case 7:
switch(x) printf("\n nedelja");
{ break;
case 1: default:
printf("\n ponedeljak"); printf("\n GRESKA");
break; break;
case 2: }
printf("\n utorak"); getche();
break; return 0;
case 3: }
printf("\n sreda");
break;
case 4:
printf("\n cetvrtak");
break; Испис на екрану
88
Збирка решених задатака из Програмског језика С – I део
7.20. Саставити програм који исписује на екрану да ли је унето слова самогласник или сугласник.
#include <stdio.h>
main()
{
char x;
printf(" Unesite slovo: ");
Испис на екрану
scanf("%c",&x);
switch (x)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
printf(" %c je samoglasnik",x);
break;
default:
printf(" %c je suglasnik",x);
}
getche();
return 0;
}
main()
{
int a=6, b=4;
switch (a%b)
{ Испис на екрану
case 0:
a++;
b++;
case 1:
a++;
b++;
break;
case 2:
a--;
b--;
case 3:
a--;
b++;
break;
}
printf (" a=%d, b=%d", a, b);
getche();
return 0;
}
89
Збирка решених задатака из Програмског језика С – I део
7.22. Саставити програм који за унети знак операције (+, -, *, /) и два реална операнда исписује
резултат операција.
#include <stdio.h>
main()
{
float op1,op2;
char op;
printf(" Operator: ");
scanf ("%c", &op);
printf(" Operand1: ");
scanf ("%f", &op1);
printf(" Operand2: ");
scanf ("%f", &op2); Испис на екрану
switch(op)
{
case '+':
printf("Vrednost: %.2f\n", op1 + op2);
break;
case '-':
printf("Vrednost: %.2f\n", op1 - op2);
break;
case '*':
printf("vrednost: %.2f\n", op1 * op2);
break;
case '/':
if (op2 == 0)
printf("Greska! Deljenje nulom!\n");
else
printf("\n Rezultat: %.2f\n", op1 / op2);
break;
default:
printf(" Greska! Pogresan operator\n");
}
getche();
return 0;
}
Испис на екрану
7.23. Саставити програм који ће учитати дужине страница правоугаоника, а затим на основу
избора опција, рачуна и исписује обим O = 2(a + b) , површину P = ab или дужину дијагонале
d = a 2 + b 2 тог правоугаоника.
#include <stdio.h>
#include <math.h>
main()
{
int i;
float a, b, O, P, d;
printf("\n a= ");
scanf("%f", &a);
printf(" b= ");
scanf("%f", &b);
if(a>0 && b>0)
{
printf("\n\n Zelite da izracunate:");
90
Збирка решених задатака из Програмског језика С – I део
7.24. Саставити програм који за унету годину и редни број месеца у години исписује број дана у
том месецу. Узети у обзир преступне године.
#include <stdio.h>
main()
{
int mesec, godina, BrDana;
printf(" Unesite godinu: ");
scanf("%d", &godina);
printf(" Unesite redni broj meseca u godini: ");
scanf("%d", &mesec);
switch(mesec)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
BrDana=31;
break;
case 4: case 6: case 9: case 11:
BrDana=30;
break;
case 2:
BrDana=28+(godina%4==0 && godina%100!=0 || godina%400==0);
break;
default:
BrDana=0;
break;
}
if(BrDana!=0)
printf(" Mesec ima %d dana.\n", BrDana);
getche();
return 0;
}
91
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
7.25. Саставити програм за исписивање наредног датума у односу на задати дан. Програм треба да
чита датуме и исписује резултате све док за једну компоненту датума не прочита нулу.
#include <stdio.h>
main()
{
int dan, mesec, godina, d;
while (1)
{
printf(" Danasnji dan: ");
scanf("%d%d%d", &dan, &mesec, &godina);
if(dan==0 || mesec==0 || godina==0) break;
switch (mesec)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
d=31;
break;
case 4: case 6: case 9: case 11:
d=30;
break;
case 2:
d=28+(godina%4==0 && godina%100!=0 || godina%400==0);
break;
}
if(dan<d) dan++;
else
{
dan=1;
if(mesec<12) mesec++;
else
{
mesec=1;
godina++;
}
}
printf(" Sutrasnji dan: %2.2d %2.2d %d\n\n", dan, mesec, godina);
}
getche();
return 0;
}
92
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
7.26. Дато је n инструкција кретања учитавањем n вредности променљиве a ∈ {1, 2,3, 4} . Ако 1
представља кретање на север, 2 на исток, 3 на југ, 4 на запад, саставити програм који исписује
позиције тачке која полази из координатног почетка. Свака инструкција задаје кретање за дужину d.
#include <stdio.h>
main()
{
int i, n, a;
float x=0, y=0, d;
printf(" n= ");
scanf("%d", &n);
printf(" d= ");
scanf("%f", &d);
printf(" Unesite kod pravca kretanja");
printf("\n 1-sever, 2-istok, 3-jug, 4-zapad\n");
for(i=1;i<=n;i++)
{
printf (" Kod= ");
scanf ("%d", &a);
switch (a)
{
case 1:
y=y+d;
break;
case 2:
x=x+d;
break;
case 3:
y=y-d;
break;
case 4:
x=x-d; Испис на екрану
break;
}
}
printf (" Polozaj: x= %2.2f y= %2.2f\n", x, y);
getche();
return 0;
}
93
Збирка решених задатака из Програмског језика С – I део
8 КАРАКТЕРИ –
ЗНАКОВНИ УЛАЗ И ИЗЛАЗ
Табела 8.1: Функције за читање и писање знакова без конверзије дефинисане у библиотеци <stdio.h>
функција значење
getchar() Функција чита следећи знак, укључујући и беле знакове са главног улаза
рачунара (тастатуре). Вредност функције је кôд прочитаног знака или
симболичка константа EOF (end of file) уколико је прочитани сигнал за крај
датотеке као и у случају грешке у току читања. Резултат је типа int. Сигнал
за крај датотеке преко тастатуре под оперативним системом MS-DOS се
задаје управљачким знаком ctrl+Z.
putchar(c) Функција исписује знак с на главном излазу рачунара (екрану). Тип
аргумента је int. Вредност функције је кôд исписаног знака или
симболичка константа EOF у случају грешке. Резултат је типа int.
gets(s) Функција чита ред текста (до знака за прелазак у нови ред \n) са главног
улаза рачунара (тастатуре) и смешта га, као бочни ефекат у ниску s (типа
char[], односно char*). Уместо знака \n у низ s се поставља знак \0.
Вредност функције у случају наилска на крај датотеке, или у случају
откривања грешке у току читања, једнака је симболичкој константи NULL,
односно почетној адреси низа ѕ у случају успешног читања.
puts(s) Функција исписује ред ниске s (типа char[], односно char*) до
завршног знака \0 као ред текста на главном излазу рачунара (екрану),
додајући знак за прелазак у нови ред (\n) иза последњег знака. Ако текст у
низу s садржи и знакове \n, резултат ће бити више исписаних редова.
Вредност функције (типа int) је не-негативни број, односно симболичка
константа EOF у случају откривања грешке у току испитивања.
* Функције gets(s)и puts(s)применићемо у област о стринговима.
94
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
main()
{
putchar('\n');
putchar('a');
putchar('\n'); Испис на екрану
putchar(97); (Задатак 2а)
putchar('\n'); Испис на екрану Са тастатуре је унето: А
putchar('A'+ 10); (Задатак 1)
putchar('\n');
putchar('a'+ 3);
getche();
return 0;
}
Испис на екрану
(Задатак 2б)
Са тастатуре је унето:
Programski jezik C
main() main()
{ {
int c; int c;
c=getchar(); while(c!=EOF)
putchar(c); {
getche(); c=getchar();
return 0; putchar(c);
} }
getche();
return 0;
}
95
Збирка решених задатака из Програмског језика С – I део
а)
#include <stdio.h>
main()
{
int c, n=0;
c=getche();
while(c != '.')
{ Испис на екрану а)
Са тастатуре је унето:
c=getche(); Programski jezik C.
n++;
}
printf("\n Broj karaktera %d.\n", n);
getche();
return 0;
}
б) #include <stdio.h>
main()
{
int c, n=0;
while((c=getchar()) != EOF)
n++;
printf("\n Broj karaktera: %d.\n",n);
getche(); Испис на екрану б)
return 0; Са тастатуре је унето:
} Programski jezik C.
8.4. Саставити програм који броји децималне цифре у улазном тексту до ознаке за крај уноса
ЕОF.
96
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
Са тастатуре је унето:
Broj 1 i broj 156
8.5. Саставити програм који броји празне знакове (размак, хоризонтални табулатор и нови ред),
слова, децималне цифре као и све знакове улазног текста до ознаке за крај уноса ЕОF.
Први начин:
#include <stdio.h>
main()
{
int c, nk=0, nr=0, nb=0, ns=0;
while((c=getchar()) != EOF)
{
if ((c==' ') || (c=='\t') || (c=='\n')) nr++;
if (c>='0' && c<='9') nb++;
if ((c>='a' && c<='z') || (c>='A' && c<='Z')) ns++;
nk++;
}
printf(" Razmaci: %d\n", nr);
printf(" Cifre: %d\n", nb);
printf(" Slova: %d\n", ns);
printf(" Ukupno: %d\n",nk);
getche();
return 0;
}
Други начин:
#include <stdio.h>
#include <ctype.h>
main()
{
int c, nk=0, nr=0, nb=0, ns=0;
while((c=getchar()) != EOF)
{
if (isspace(c)) nr++;
if (isdigit(c)) nb++;
if (isalpha(c)) ns++;
Испис на екрану
nk++;
}
printf(" Razmaci: %d\n", nr);
printf(" Cifre: %d\n", nb);
printf(" Slova: %d\n", ns);
printf(" Ukupno: %d\n",nk);
getche();
return 0;
}
97
Збирка решених задатака из Програмског језика С – I део
8.6. Саставити програм за одређивање броја самогласника и сугласника у улазном тексту. Унос
текста се завршава сигналом ЕОF.
#include <stdio.h>
main()
{
int c, sugl=0, samog=0;
while((c=getchar()) != EOF)
{
if((c>='a' && c<='z') || (c>='A' && c<='Z'))
if(c=='a' || c=='e' || c=='i' || c=='o' || c=='u'
|| c=='A' || c=='E' || c=='I' || c=='O' || c=='U')
samog++;
else
sugl++;;
}
printf("Samoglasnika: %d\n", samog);
printf("Suglasnika: %d\n", sugl);
getche();
return 0;
} Испис на екрану
Са тастатуре је унето:
Programski jezik C
8.7. Саставити програм за одређивање броја великих слова, малих слова и цифара у улазном
тексту. Унос текста се завршава сигналом ЕОF.
Први начин:
#include <stdio.h>
main()
{
int c, veliko=0, malo=0, cifra=0;
while((c = getchar()) != EOF)
{
if(c >= 'A' && c <= 'Z') veliko++;
if(c >= 'a' && c <= 'z') malo++;
if(c >= '0' && c <= '9') cifra++; Испис на екрану
} Са тастатуре је унето:
printf(" Velika: %d\n", veliko); 1 Programski jezik C 33
printf(" Mala: %d\n", malo);
printf(" Cifre: %d\n", cifra);
getche();
return 0;
}
Други начин:
#include <stdio.h>
#include <ctype.h>
main()
{
int c, veliko=0, malo=0, cifra=0;
while((c = getchar()) != EOF)
{
veliko += isupper(c) != 0;
malo += islower(c) != 0;
cifra += isdigit(c) != 0;
98
Збирка решених задатака из Програмског језика С – I део
}
printf(" Velika: %d\n", veliko);
printf(" Mala: %d\n", malo);
printf(" Cifre: %d\n", cifra);
getche();
return 0;
}
8.8. Саставити програм за одређивање броја појављивања слова А у улазном тексту и изразити ту
вредност процентуално у односу на све унете знаке. Унос текста се завршава сигналом ЕОF.
#include <stdio.h>
main()
{
int c, n=0, u=0;
float p;
while((c = getchar()) != EOF)
{
u++;
if(c=='A') n++;
}
Испис на екрану
p=(float)n/u*100;
Са тастатуре је унето:
printf("\n Ukupno znakova: %d", u); Slova A A A
printf("\n Ukupno slovo A: %d", n);
printf("\n U procentima: %.2f%\n", p);
getche();
return 0;
}
8.9. Саставити програм за одређивање броја празних карактера, као и броја знакова: тачка, зарез,
двотачка и тачка-зарез. Унос текста се завршава сигналом ЕОF.
#include <stdio.h>
main()
{
int c, razmak=0, n=0;
while((c=getchar())!=EOF)
switch(c)
{
case ' ':
razmak++;
break;
case '.':
case ',':
case ':':
case ';':
n++; Испис на екрану
break; Са тастатуре је унето:
Razni znakovi: ; , .
default:
break;
}
printf("\nRazmaci: %d", razmak);
printf("\nOstali trazeni: %d", n);
getche();
return 0;
}
99
Збирка решених задатака из Програмског језика С – I део
8.10. Саставити програм који броји карактере улазног текста до прве децималне цифре. Унос
текста се завршава сигналом EOF.
#include <stdio.h>
#include <ctype.h>
main()
{
int c, n=0;
while((c=getchar()) != EOF)
Испис на екрану
{ Са тастатуре је унето:
if(isdigit(c)) break; Petak je 5-ti dan u sedmici.
n++;
}
printf("Broj znakova: %d\n", n);
getche();
return 0;
}
8.11. Саставити програм који броји карактере улазног текста различите од децималних цифара.
Унос текста се завршава сигналом EOF.
#include <stdio.h>
#include <ctype.h>
main()
{
int c, n=0;
while((c=getchar()) != EOF)
{
if(isdigit(c)) continue; Испис на екрану
Са тастатуре је унето:
n++; Ovo je broj 5, a ovo 33.
}
printf("Broj znakova koji nisu cifre: %d\n", n);
getche();
return 0;
}
8.12. Саставити програм који испитује да ли су у унетом тексту заграде“(“ и “ )“ добро упарене.
Унос текста се завршава сигналом ЕОF.
#include <stdio.h>
main()
{
int c;
int otv=0;
while((c=getchar()) != EOF)
{
switch(c)
{ Испис на екрану
case '(': Са тастатуре је унето:
otv++; Danas je petak ((osamnaesti).
break;
100
Збирка решених задатака из Програмског језика С – I део
case ')':
otv--;
if (otv<0)
{
printf("Visak zatvorenih zagrada\n");
break;
}
}
}
if (otv==0)
printf("Zagrade su u redu\n");
else
printf("Visak otvorenih zagrada\n");
getche();
return 0;
}
8.13. Саставити програм који врши конверзију унетих великих слова у мала. Унос текста се
завршава сигналом ЕОF.
Први начин: Други начин:
#include <stdio.h>
#include <stdio.h>
main() #include <ctype.h>
{
int c; main()
while((c=getchar()) != EOF) {
{ int c;
if(c >= 'A' && c <= 'Z') while((c=getchar()) != EOF)
c = c -'A' + 'a'; putchar(tolower(c));
putchar(c); getche();
} return 0;
getche(); }
return 0;
}
Испис на екрану
Са тастатуре је унето:
Jezik C
101
Збирка решених задатака из Програмског језика С – I део
8.14. Саставити програм који врши конверзију унетих малих слова у велика. Унос текста се
завршава сигналом ЕОF.
Испис на екрану
Са тастатуре је унето:
Jezik C
8.15. Саставити програм који врши конверзију првог слова у велико, а сва остала у мала унете
реченице. Унос текста се завршава сигналом ЕОF.
#include <stdio.h>
#include <ctype.h>
main()
{
int c, prvi=0;
while((c=getchar()) != EOF)
{ Испис на екрану
if(isalpha(c))
{
if(prvi==0)
putchar(toupper(c));
else putchar(tolower(c));
}
else putchar(c);
prvi=1;
}
getche();
return 0;
}
102
Збирка решених задатака из Програмског језика С – I део
8.16. Саставити програм којим се копира улазни текст на екран уз раздвајање речи по једним
знаком размака. Речи су на улазу раздвојене произвољним бројем знакова размака и/или табулације.
Текст се завршава сигналом ЕОF.
#include <stdio.h>
#define NIJE_PRAZNO 'a'
#define PRAZNO ' '
#define HOR_TAB '\t'
main()
{
int c, predh_c=NIJE_PRAZNO; Испис на екрану
while((c=getchar()) != EOF)
{
if(c==HOR_TAB)
c=PRAZNO;
if(c != PRAZNO || predh_c != PRAZNO)
putchar(c);
predh_c=c;
}
getche();
return 0;
}
8.17. Саставити програм који копира улазни текст на екран, где сваку реч приказује у једној
линији. Унос текста се завршава сигналом ЕОF.
#include <stdio.h>
#define U_RECI 1
#define VAN_RECI 0
main()
{
int c, poz=VAN_RECI;
while((c=getchar()) != EOF)
{
if(c==' ' || c=='\n' || c=='\t')
Испис на екрану
{
if(poz==U_RECI)
{
putchar('\n');
poz=VAN_RECI;
}
}
else
{
poz=U_RECI;
putchar(c);
}
}
getche();
return 0;
}
103
Збирка решених задатака из Програмског језика С – I део
8.18. Саставити програм који учитава текст са улаза, и при том броји речи. Под речју се
подразумева низ не-бланко карактера (бланко карактери су ' ', '\n' и '\t').
104
Збирка решених задатака из Програмског језика С – I део
9 ФУНКЦИЈЕ
9.1. Саставити функцију која врши сабирање два цела броја, а затим саставити програм који
тестира функцију и исписује резултат.
9.2. Саставити функције за рачунање збира, производа и количника два реална броја, као и
функције за израчунавање квадрата и куба реалног броја. Затим саставити програм за израчунавање
x
израза z1 = x + y 2 , z 2 = x 3 − и z3 = ( x * y ) + ( 5 − y ) , користећи претходно формиране функције.
y
Променљиве х и у се уносе са тастатуре. Исписати резултате.
105
Збирка решених задатака из Програмског језика С – I део
/*Funkcija kvadrata*/
float kvadrat(float a)
{
return(a*a);
}
Испис на екрану
9.3. Саставити функцију за одређивање максимума два цела броја, а затим саставити програм
који ће за унета четири цела броја одредити највећи користећи претходну функцију, а затим
исиписати резултат.
#include <stdio.h>
106
Збирка решених задатака из Програмског језика С – I део
а)
#include <stdio.h>
void fun1(int a)
{
scanf("%d", &a);
printf("\n a= %d\n", a);
}
б) в)
#include <stdio.h> #include <stdio.h>
Испис на екрану б)
Испис на екрану в)
double Povrsina(double r)
{
return(4*r*r*PI);
}
107
Збирка решених задатака из Програмског језика С – I део
double Zapremina(double r)
{
return((4./3.)*r*r*r*PI);
}
main()
{
double r, p, v;
printf(" r= ");
scanf("%lf", &r);
p=Povrsina(r);
v=Zapremina(r);
Ispis(p,v);
getche(); Испис на екрану
return 0;
}
9.6. Саставити програм за израчунавање површине троугла ако су задате координате његовог
темена. Површину троугла рачунати помоћу следећих формула:
a= ( xB − xC ) − ( yB − yC ) b= ( xC − xA ) − ( yC − y A ) c= ( x A − xB ) − ( y A − y B )
2 2 2 2 2 2
, ,
a+b+c
S= , P = S ( S − a )( S − b )( S − c ) . За израчунавање дужине страница a, b и c
2
формирати одговарајућу функцију.
#include <stdio.h>
#include <math.h>
main()
{
double xA, yA, xB, yB, xC, yC, a, b, c, s, P;
printf("Koordinate temena trougla\n");
printf("- prvo teme <xA,yA>: ");
scanf("%lf%lf",&xA,&yA);
printf("- drugo teme <xB,yB>: ");
scanf("%lf%lf",&xB,&yB);
printf("- trece teme <xC,yC>: ");
scanf("%lf%lf",&xC,&yC);
a=Stranica(xB,xC,yB,yC);
b=Stranica(xC,xA,yC,yA);
c=Stranica(xA,xB,yA,yB);
s=(a+b+c)/2; Испис на екрану
P=sqrt(s*(s-a)*(s-b)*(s-c));
printf("\nPovrsina trougla: %.2f\n", P);
getche();
return 0;
}
108
Збирка решених задатака из Програмског језика С – I део
9.7. Саставити програм за израчунавање и исписивање суме квадрата свих бројева, само парних и
само непарних за унете границе интервала. Користити функције за израчунавање збира квадрата.
#include <stdio.h>
9.8. Саставити програм који исписује суму цифара за унете границе интервала. За рачунање суме
цифара формирати одговарајућу функцију.
#include <stdio.h>
#include <math.h>
int Suma(int a)
{
int s=0;
while (a!=0)
{
109
Збирка решених задатака из Програмског језика С – I део
s+=a%10;
a/=10;
}
return s;
}
main()
{
int i, d, g;
printf(" Donja granica= ");
scanf("%d", &d);
printf(" Gornja granica= ");
scanf("%d", &g);
for(i=d; i<=g; i++)
printf("\n%4d\t%3d", i, Suma(fabs(i)));
getche();
return 0;
} Испис на екрану
9.9. Саставити програм који коришћењем функција одређује највећи заједнички делилац и
најмањи заједнички садржалац два природна броја. Програм треба да захтева унос све док не
прочита нулу за један од два унета природна броја.
#include <stdio.h>
main()
{
unsigned a, b;
while(1)
{
printf ("\n a= "); scanf ("%u", &a);
printf (" b= "); scanf ("%u", &b);
if (a==0 || b==0) break;
printf (" nzd= %u", nzd(a,b));
printf ("\n nzs= %u", nzs(a,b));
printf ("\n\n");
}
getche();
return 0;
}
110
Збирка решених задатака из Програмског језика С – I део
9.10. Саставити функцију за рачунање факторијела, затим саставити програм који рачуна и
n n!
исписује број комбинација Cn ,k = = , за дато n и k помоћу функције за рачунање
k k !( n − k ) !
факторијела.
#include <stdio.h>
long Fakt(int n)
{
long i, f=1;
for(i=1; i<=n; i++)
f *= i;
return f;
} Испис на екрану
main()
{
int n, k, c;
printf(" n= ");
scanf("%d", &n);
printf(" k= ");
scanf("%d", &k);
c=Fakt(n)/(Fakt(k)*Fakt(n-k));
printf("\n c= %d", c);
getche();
return 0;
}
9.11. Саставити програм који за дато n рачуна и исписује суму S = 1! + 2! + 3! + ... + n!. За
рачунање факторијела користити одговарајућу функцију.
#include <stdio.h>
long Fakt(int n)
{
long i, f=1;
for(i=1; i<=n; i++)
f *= i;
return f;
} Испис на екрану
main()
{
long n, s=0;
int i;
printf(" n= ");
scanf("%ld",&n);
for(i=1; i<=n; i++)
s+=Fakt(i);
printf("\n S= %ld\n", s);
getche();
return 0;
}
111
Збирка решених задатака из Програмског језика С – I део
9.12. Саставити програм којим се исписују сви троцифрени бројеви (ако их има) који су једнаки
суми факторијела својих цифара.
#include <stdio.h>
long Fakt(int n)
{
long i, f=1;
for(i=1; i<=n; i++)
f *= i;
return f;
}
main()
{
int a, b, c; Испис на екрану
for(a=1; a<=9; a++)
for(b=0; b<=9; b++)
for(c=0; c<=9; c++)
{
if((a*100+b*10+c)==(Fakt(a)+Fakt(b)+Fakt(c)))
printf("\n %d", a*100+b*10+c);
}
getche();
return 0;
}
9.13. Саставити функцију за степеновање бројева. Затим саставити програм који помоћу
формиране функције врши рачунање за дати број и степен и исписује резултат.
#include <stdio.h>
main()
{
int n;
double x, s;
printf("\n Osnova: ");
scanf("%lf", &x);
printf("\n Stepen: ");
scanf("%d", &n);
s=Stepen(x,n);
printf("\n Rezultat= %.2f", s);
getche();
return 0;
}
112
Збирка решених задатака из Програмског језика С – I део
9.14. Саставити програм за рачунање и исписивање месечне рате за отплату кредита по формули
A⋅ p ⋅ k
r= , где је A = (1 + k ) , р – позајмица (износ кредита), k – месечна камата (нпр, за 6% уноси
m
A −1
се 0.06), m – број месечних рата. За рачунање вредности А формирати одговарајућу функцију.
#include <stdio.h>
main()
{ Испис на екрану
int m;
double p, k, r, A;
printf("\n Iznos kredita: "); scanf("%lf", &p);
printf("\n Mesecna kamata: "); scanf("%lf", &k);
printf("\n Broj mesecnih rata: "); scanf("%d", &m);
A=Stepen(1+k,m);
r=(A*p*k)/(A-1);
printf("\n Mesecna rata= %.2f", r);
getche();
return 0;
}
9.15. Саставити програм који исписује све просте бројеве мање од 500. Користити функцију за
одређивање простих бројева.
#include <stdio.h>
Пошто у С-у не постоји логички тип
int Prost(int broj)
података, уколико се ради о некој функцији која
{
int i; треба да врати вредност тачно или нетачно, као
for(i=2; i<broj; i++) што је случај са овом, тада је она типа int и
if(broj%i == 0) враћа 1 ако треба да врати тачно, а 0 ако треба
return 0;
return 1; да врати нетачно. Из тог разлога ова функција је
} типа int и у зависности од (не)испуњења
услова враћа се вредност 0 или вредност 1.
main()
{
int i;
for(i=1; i<=500; i++)
if(Prost(i) == 1)
printf("%d\t", i);
getche();
return 0;
}
113
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
9.16. Саставити програм који рачуна и исписује вредност Ојлерове функције позитивног целог
броја унетог са улаза. Под Ојлеровом функцијом φ(n) подразумевамо број бројева m, таквих да је
1≤m<n и да су m и n узајамно прости. Ојлерова функција, као и NZD(m,n) рачунати у посебним
функцијама.
9.17. Саставити програм којим се исписују сви троцифрени Амстронгови бројеви. Троцифрени
број је Амстронгов ако је једнак суми кубова својих цифара. Формирати две функције, једна за
рачунање суме кубова, а друга за одређивање да ли је дати број Амстронгов (ако јесте враћа 1, ако
није враћа 0).
#include <stdio.h>
#include <math.h>
int SumaKubova(int n)
{
int suma=0 ;
for( ; n>0; n/=10)
suma += pow(n%10,3);
return suma;
}
114
Збирка решених задатака из Програмског језика С – I део
int Amstrongov(int n)
{
if(n==SumaKubova(n))
return 1;
return 0;
}
Испис на екрану
main()
{
int i;
for(i=100; i<=999; i++)
if(Amstrongov(i))
printf("%d\t", i);
getche();
return 0;
}
9.18. Саставити програм којим се исписују сви Нивенови бројеви друге стотице. Нивенов број је
број који је дељив са сумом својих цифара. Формирати две функције, једна за рачунање суме цифара,
а друга за одређивање да ли је дати број Нивенов (ако јесте враћа 1, ако није враћа 0).
#include <stdio.h> main()
#include <math.h> {
int i;
int SumaCifara(int n) for(i=101; i<=200; i++)
{ if(Nivenov(i))
int suma=0 ; printf("%d\t", i);
for( ; n>0; n/=10) getche();
suma += n%10; return 0;
return suma; }
}
int Nivenov(int n)
{
if(n % SumaCifara(n) == 0)
return 1;
return 0;
}
Испис на екрану
115
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
#include <math.h>
float R, C, U0;
float uc(float t)
{
return U0*(1-exp(-t/(R*C)));
}
float ur(float t)
{
return U0-uc(t);
}
main()
{
float t;
printf("\n R[kOhm]= ");
scanf("%f",&R); Испис на екрану
printf("\n C[uF]= ");
scanf("%f",&C);
printf("\n U0[V]= ");
scanf("%f",&U0);
R*=1e3;
C*=1e-6;
printf("\n Vreme N a p o n n a ");
printf("\n [ms] kondenzatoru otporniku");
for(t=0; t<=R*C; t=t+R*C/10)
printf("\n%7.2f %9.3f %9.3f",t*1e3,uc(t),ur(t));
getche();
return 0;
}
sin ( x )
9.20. Саставити програм који ће табеларно приказати вредности функција f1 ( x ) = и
x
sin ( x )
2
x
(xmin<1) тако да се свако наредно x смањи за учитану вредност корака dx (dx <0.1).
#include <stdio.h>
#include <math.h>
float f1(float x)
{
return sin(x)/x;
}
float f2(float x)
{
return f1(x)*f1(x);
}
Испис на екрану
main()
116
Збирка решених задатака из Програмског језика С – I део
{
printf("\n xmin[xmin<1] = ");
scanf("%f",&xmin);
printf("\n dx[xkor<0.1] = ");
scanf("%f",&dx);
printf("\n x f1(x) f2(x)");
for(x=1; x>=xmin; x-=dx)
printf("\n%5.2f%9.5f%9.5f",x,f1(x),f2(x));
getche();
return 0;
}
#include <stdio.h>
#include <math.h>
float a, b;
float f(float x)
{
return(a*x*fabs(sin(b*x)));
}
main()
{ Испис на екрану
int n;
float x, x1, x2, dx, S, P;
printf(" Parametar a= "); scanf("%f",&a);
printf(" Parametar b= "); scanf("%f",&b);
printf(" Broj tacaka n= "); scanf("%d",&n);
printf(" Pocetak intervala x1= "); scanf("%f",&x1);
printf(" Kraj intervala x2= "); scanf("%f",&x2);
dx=(x2-x1)/n;
S=(f(x1)+f(x2))/2;
117
Збирка решених задатака из Програмског језика С – I део
9.22. Напон на неком потрошачу се мења временски по функцији u ( t ) = e − b⋅t ⋅ sin ( a ⋅ t ) док отпор
u
потрошача зависи од напона по функцији r ( u ) = r0 + ln 1 + . Саставити програм који ће учитати
10
параметре a, b и r0, као и почетно и крајње време t1 и t2 и наћи и исписати енергију утрошену на
потрошачу у временском интервалу од t1 до t2.
Енергија је временски интеграл напона и струје, па треба наћи површину испод криве
(u (t ))
2
f (t ) = у интервалу од t1 до t2.
r (t )
#include <stdio.h>
#include <math.h>
float a, b, r0;
float u(float t)
{
return exp(-b*t)*sin(a*t);
}
float r(float t)
{ Испис на екрану
return r0+log(1+fabs(u(t)/10));
}
float f(float t)
{
return u(t)*u(t)/r(t);
}
main()
{
int n;
float t1, t2, t, dt, E;
printf(" Parametar a= "); scanf("%f",&a);
printf(" Parametar b= "); scanf("%f",&b);
printf(" Parametar r0= "); scanf("%f",&r0);
printf(" Vremenski interval [t1,t2]= "); scanf("%f%f",&t1,&t2);
printf(" Broj tacaka n= "); scanf("%d",&n);
dt=(t2-t1)/n;
E=f(t1)+f(t2);
for(t=t1+dt; t<=t2-dt; t+=dt)
E+=2*f(t);
E=2*E*dt;
printf("\n Energija= %.4f",E);
getche();
return 0;
}
118
Збирка решених задатака из Програмског језика С – I део
9.23. Саставити функцију која израчунава еx на основу првих неколико (n) чланова Тејлоровог
∞
xi x1 x2 x3 x4
реда e x = ∑ i ! = 1 + 1! + 2! + 3! + 4! + ... , а затим саставити главни програм који за дато n и х
i =0
користећи претходну функцију рачуна и исписује вредност израза, а затим одређује апсолутну
грешку између добијене вредности и тачне вредности (за тачну вредност користити уграђену
функцију exp() за исто х).
#include <stdio.h>
#include <math.h>
n n n t n
9.24. Саставити програм за рачунање суме S = − + − ... + ( −1) и
k k + 1 k + 2 k +t
n
исписивање њене вредности за дато n, k и t употребом функције за рачунање комбинација .
k
#include <stdio.h>
119
Збирка решених задатака из Програмског језика С – I део
main()
{
float s;
int n, k, i, t, znak=1;
printf (" n= ");
scanf ("%d", &n);
printf (" k= ");
scanf ("%d", &k);
printf (" t= ");
scanf ("%d", &t);
for(i=0; i<t; i++)
{
s += znak*Komb(n,k);
znak=-znak; Испис на екрану
}
printf("\n S= %.2f", s);
getche();
return 0;
}
1 1 1
9.25. Саставити програм којим се рачуна сума S = 1 + − + − ... рачунајући до члана који
2!! 3!! 4!!
је по апсолутној вредности мањи од ерѕ. Двоструки факторијел рачунати коришћењем функције:
n ⋅ ( n − 2 ) ⋅ ... ⋅ 3 n непарно
dfakt ( n ) = n !! =
n ⋅ ( n − 2 ) ⋅ ... ⋅ 4 ⋅ 2 n парно
#include <stdio.h>
int DFakt(int n)
{
int p=1;
while(n>=2)
{
p=p*n;
n=n-2;
}
return p; Испис на екрану
}
main()
{
int i=2, znak=1;
float s=1, clan=1, eps;
printf (" eps= ");
scanf ("%f", &eps);
printf("\n");
while(fabs(clan)>=eps)
{
clan=(float)znak/DFakt(i);
s=s+clan;
i++;
znak=-znak;
}
printf(" S= %.4f", s);
getche();
return 0;
}
120
Збирка решених задатака из Програмског језика С – I део
9.26. Саставити програм који помоћу функције исцртава правоугаоник дужине а и ширине b од
знакова чији је ASCII код 254. После цртања правоугаоника поставља се питање '' Da li zelite
novo crtanje?[D/N]:'' и понавља исти поступак.
#include <stdio.h>
main()
{
int a, b, ch;
ch='D';
while(ch=='D') Испис на екрану
{
printf(" a= ");
scanf("%d",&a);
printf(" b= ");
scanf("%d",&b);
Crtaj(a,b);
printf("\n\n Da li zelite novo crtanje?[D/N]: ");
ch=getchar();
ch=toupper(ch);
while(ch!='D'&& ch!='N')
{
ch=getchar();
ch=toupper(ch);
}
}
getche();
return 0;
}
9.27. Саставити програм који ће исцртати оквир приказан на слици за унету дужину и ширину. За
цртање вертикалних и хоризонталних делова оквира формирати одговарајуће функције. На слици је
приказан оквир дужине 6 и ширине 2.
121
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
#define HLIN '-'
#define VLIN '|'
#define UGAO '+'
#define PRAZNO ' '
void Hokvir(int k)
{
putchar(UGAO);
Znakovi(k, HLIN); Испис на екрану
putchar(UGAO);
putchar('\n');
}
void Vokvir(int k)
{
putchar(VLIN);
Znakovi(k, PRAZNO);
putchar(VLIN);
putchar('\n');
}
main()
{
int i, duzina, sirina;
do
{
printf(" Unesite duzinu okvira (od 1 do 20): ");
scanf("%d", &duzina);
}
while(duzina<1 || duzina>20);
do
{
printf(" Unesite sirinu okvira (od 1 do 20): ");
scanf("%d", &sirina);
}
while(sirina<1 || sirina>20);
Hokvir(duzina); /*Stampanje gornjeg dela okvira*/
for(i=0; i<sirina; i++)
Vokvir(duzina); /*Stampanje srednjeg dela okvira*/
Hokvir(duzina); /*Stampanje donjeg dela okvira*/
getche();
return 0;
}
122
Збирка решених задатака из Програмског језика С – I део
9.28. а) Саставити функцију која врши конверзију малих слова у велика. Затим тестирати
функцију за унети текст. Унос текста се завршава сигналом EOF.
б) Саставити функцију која врши конверзију великих слова у мала. Затим тестирати
функцију за унети текст. Унос текста се завршава сигналом EOF.
main() main()
{ {
int c; int c;
while((c=getchar()) != EOF) while((c=getchar()) != EOF)
putchar(UVeliko(c)); putchar(UMalo(c));
getche(); getche();
return 0; return 0;
} }
Испис на екрану
Испис на екрану
9.29. Саставити рекурзивну функцију за одређивање факторијела целог броја, а затим је тестирати
у главном програму за унети цео број n и исписати добијени резултат.
#include <stdio.h>
int Faktorijel(int n)
{
if(n == 1) return 1;
return n*Faktorijel(n-1);
} Испис на екрану
main()
{
int n;
printf("n= ");
scanf("%d", &n);
printf("%d!= %d", n, Faktorijel(n));
getche();
return 0;
}
123
Збирка решених задатака из Програмског језика С – I део
9.30. Саставити рекурзивну функцију која степеновање целог броја на целобројни изложилац, а
затим тестирати функцију за дати природни број и изложилац и исписати добијени резултат.
#include <stdio.h>
9.31. Саставити рекурзивну функцију која врши сабирање првих n бројева, а затим тестирати
функцију за дато n и исписати добијени резултат.
#include <stdio.h>
int Suma(int n)
{
if(n==0)
return 0;
else
return(n + Suma(n-1));
} Испис на екрану
main()
{
int s,n;
printf(" n= ");
scanf("%d", &n);
s=Suma(n);
printf("\n s= %d\n",s);
getche();
return 0;
}
124
Збирка решених задатака из Програмског језика С – I део
9.32. Саставити рекурзивну функцију која исписује првих n бројева у обрнутом редолседу, а затим
тестирати функцију за дато n.
#include <stdio.h>
9.33. Саставити рекурзивну функцију за одређивање највећег заједничког делилаца за два цела
броја. Затим тестирати функцију у главном програму и исписати добијени резултат.
#include <stdio.h>
125
Збирка решених задатака из Програмског језика С – I део
9.34. Саставити рекурзивну функцију која сабира декадне цифре целог броја. Затим тестирати
функцију у главном програму за унети цео број и исписати добијени резултат.
#include <stdio.h>
#include <stdlib.h>
int SaberiCifre(int x)
{
if(x<0) x=abs(x);
if(x<10) return x;
return(x%10 + SaberiCifre(x/10));
} Испис на екрану
main()
{
int n;
printf("\n Unesite ceo broj: ");
scanf("%d",&n);
printf("\n Suma cifara broja %d je %d\n", n, SaberiCifre(n));
getche();
return 0;
}
9.35. Саставити рекурзивну функцију која одређује и исписује n-ти члан Фибоначијевог низа, а
затим тестирати функцију за дато n. Фибоначијев низ: f1=1, f2=1, fi=fi-1+fi-2, i=3, 4, 5, ...
#include <stdio.h>
int Fib(int n)
{
if((n==0)||(n==1))
return 1;
else
return(Fib(n-1)+Fib(n-2)); Испис на екрану
}
main()
{
int n;
printf(" n= ");
scanf("%d", &n);
printf(" Fib[%d]= %d", n, Fib(n-1));
getche();
return 0;
}
126
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
/*Glavni program.*/
main ()
{
int n, i, j, k;
printf("\n n= ");
scanf("%d", &n);
for(i=0; i<=n; i++) Испис на екрану
{
for(j=0; j<n-i; j++)
printf (" ");
for(k=0; k<=i; k++)
printf ("%4d", BinKoefREK(i, k));
printf("\n");
}
getche();
return 0;
}
9.37. Ханојске куле: Дата су три штапа, и на једном од њих n дискова различитих пречника,
поређаних тако да мањи диск лежи на већем. Потребно је преместити све дискове на трећи штап у
истом поретку, тако што се премешта један по један диск, коришћењем сва три штапа, и у сваком
тренутку на сваком од штапова диск може да лежи само на већем диску.
Саставити рекурзивну функцију која омогућује пребацивање дискова по горе наведеном
правилу, а затим тестирати функцију за унети број (n) дискова.
#include <stdio.h>
Prebaci(n-1,i,k);
Prebaci(1,i,j);
Prebaci(n-1,k,j);
}
return;
}
main()
{
int broj;
printf(" Unesite broj diskova: ");
scanf("%d", &broj);
Prebaci(broj, 1, 3); Испис на екрану
getche();
return 0;
}
128
Збирка решених задатака из Програмског језика С – I део
10 НИЗОВИ
а) Променљиве (низови) a и b се разликују у дужини. Низ a има 15 елемената где прва три имају
вредности 1, 2 и 3, док су остали имају вредности нуле. Низ b има три елемента са вредностима 1, 2 и
3.
б)
int a[17], b[3], i;
a[0]=1; a[1]=2; a[2]=3;
for(i=3;i<15;i++) a[i]=0;
b[0]=1; b[1]=2; b[2]=3;
в) Низ а има 10 елемената чије су вредности непознате (цели бројеви). Низ b има 10 елемената и сви
имају вредности нула.
main()
{
int i, n, niz[MAX];
printf(" n= ");
scanf("%d", &n);
for(i=0; i<n; i++)
{
printf(" %d. element niza: ", i+1);
129
Збирка решених задатака из Програмског језика С – I део
scanf("%d", &niz[i]);
}
for(i=0; i<n; i++)
printf("\n %d. element niza: %d", i+1, niz[i]);
getche();
return 0;
}
Испис на екрану
main()
{
int i, j, niz[]={15,3,9,7,11};
printf("\nR.Br.\tIndeks\tVrednost\n");
for(i=0; i<MAX; i++)
printf("\n%d\t%d\t%d", i+1, i, niz[i]);
getche();
return 0; Испис на екрану
}
10.4. Саставити програм који ће учитати низ од n елемената и исписати их оним редоследом којим
су учитани.
#include <stdio.h>
#define MAX 100
main()
{
int niz[MAX], i,n;
printf(" n= ");
scanf("%d", &n);
printf(" Unesite %d elemenata: ",n); Испис на екрану
for(i=0 ; i<n ; i++)
scanf("%d", &niz[i]);
printf("\n Uneti niz: ");
for(i=0 ; i<n ; i++)
printf(" %d", niz[i]);
getche();
return 0;
}
130
Збирка решених задатака из Програмског језика С – I део
10.5. Саставити програм који ће учитати низ од n елемената и исписати их обрнутим редоследом.
#include <stdio.h>
#define MAX 100
main()
{
int niz[MAX];
int i,n;
printf(" n= "); Испис на екрану
scanf("%d", &n);
printf(" Unesite %d elemenata: ",n);
for(i=0; i<n; i++)
scanf("%d", &niz[i]);
printf("\n Obrnuto: ");
for(i=n-1; i>=0; i--)
printf(" %d", niz[i]);
getche();
return 0;
}
main()
{
int niz[MAX];
printf("\n Niz zauzima %d bajtova.", sizeof(niz));
getche();
return 0;
}
б)
#include <stdio.h>
main()
{
int i, BrElem;
int niz[] = {1, 2, 3, 4, 5, 6};
BrElem = sizeof(niz)/sizeof(int);
for(i=0; i<BrElem; i++)
printf(" niz[%d]=%d\n",i, niz[i]);
getche();
return 0;
}
131
Збирка решених задатака из Програмског језика С – I део
10.7. Саставити програм за израчунавање и исписивање аритметичке средине задатог низа (дужине
n) целих бројева.
#include <stdio.h>
#define MAX 100
main()
{
int i, n, niz[MAX], suma=0;
printf(" Broj elemenata: ");
scanf("%d", &n);
printf(" Elementi niza: "); Испис на екрану
for(i=0; i<n; i++)
{
scanf ("%d", &niz[i]);
suma+=niz[i];
}
printf(" SRV= %.2f\n", (float)suma/n);
getche();
return 0;
}
10.8. Саставити програм који за унети низ (дужине n) целих бројева израчунава и исписуеј
аритметичку средину оних елемената низа који су дељиви са 3.
#include <stdio.h>
#define MAX 100
main()
{
int i, n, k=0, niz[MAX];
double suma=0;
printf(" Broj elemenata: ");
scanf("%d", &n); Испис на екрану
printf(" Elementi niza: ");
for(i=0; i<n; i++)
{
scanf("%d", &niz[i]);
if(niz[i]%3 == 0)
{
suma+=niz[i];
k++;
}
}
printf(" SRV= %.3f\n", suma/k);
getche();
return 0;
}
132
Збирка решених задатака из Програмског језика С – I део
10.9. Саставити програм који ће за унети низ (дужине n) целих бројева одредити и исписати:
а) суму парних и суму непарних бројева;
б) суму елемената са парним индексима и суму елемената са непарним индексима.
а) #include <stdio.h>
#define MAX 100
main()
{
int i, n, niz[MAX], sumap=0, suman=0;
printf(" Broj elemenata: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
{
scanf("%d", &niz[i]);
if(niz[i]%2==0)
sumap += niz[i];
else
suman += niz[i]; Испис на екрану
}
б)
#include <stdio.h>
#define MAX 100
main()
{
int i, n, niz[MAX], sumap=0, suman=0;
printf(" Broj elemenata: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
{
scanf("%d", &niz[i]);
if(i%2==0)
sumap += niz[i];
else
suman += niz[i]; Испис на екрану
}
10.10. Саставити програм који прочита два низа, дужине n, са реалним компонентама,
n −1
A = ( A1 , A2 ,..., An ) и B = ( B1 , B2 ,..., Bn ) израчунава њихов скаларни производ s = ∑ Ai Bi и
i=0
исписује добијени резултат.
133
Збирка решених задатака из Програмског језика С – I део
#include <stdio.h>
#define MAX 100
main()
{
int i, n;
double proizvod=0, niz1[MAX], niz2[MAX];
printf(" Broj elemenata: ");
scanf("%d", &n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
scanf("%lf", &niz1[i]);
printf(" Elementi niza B: ");
for(i=0; i<n; i++)
scanf("%lf", &niz2[i]);
for(i=0; i<n; i++) Испис на екрану
proizvod+=niz1[i]*niz2[i];
printf (" Skalarni proizvod= %.3f\n", proizvod);
getche();
return 0;
}
10.11. Саставити програм који учита елементе низа A = ( A1 , A2 ,..., An ) дужине n и низа
B = ( B1 , B2 ,..., Bm ) дужине m и спаја у један низ C = ( A1 , A2 ,..., An , B1 , B2 ,..., Bm ) дужине n+m.
Исписати новокреирани низ.
#include <stdio.h>
#define MAX 100
main()
{
int i, n, m, nizA[MAX], nizB[MAX], nizC[MAX];
printf(" Broj elemenata niza A: ");
scanf("%d", &n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
scanf("%d", &nizA[i]);
printf(" Broj elemenata niza B: ");
scanf("%d", &m);
printf(" Elementi niza B: ");
for(i=0; i<m; i++)
scanf("%d", &nizB[i]);
printf(" Elementi niza C: ");
for(i=0; i<(n+m); i++)
{
if (i<n) nizC[i]=nizA[i];
else nizC[i]=nizB[i-n];
printf("%d ",nizC[i]);
}
getche(); Испис на екрану
return 0;
}
134
Збирка решених задатака из Програмског језика С – I део
10.12. Саставити програм који учита елементе два низа низа дужине n A = ( A1 , A2 ,..., An ) и
B = ( B1 , B2 ,..., Bn ) и формира и исписује нови низ чији су елементи
C = ( A1 + B1 , A2 + B2 ,..., An + Bn ) .
#include <stdio.h>
#define MAX 100
main()
{
int i, n, nizA[MAX], nizB[MAX], nizC[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
scanf("%d", &nizA[i]);
printf(" Elementi niza B: ");
for(i=0; i<n; i++)
scanf("%d", &nizB[i]);
printf(" Elementi niza C: ");
for(i=0; i<n; i++)
{
nizC[i]=nizA[i]+nizB[i];
printf("%d ",nizC[i]);
}
getche();
return 0;
} Испис на екрану
10.13. Саставити програм за формирање низа С од два задата низа реалних бројева А и В (сваки
(A )
3
main()
{
float nizA[MAX], nizB[MAX], nizC[MAX];
int i;
printf (" Elementi niza A: ");
for(i=0; i<MAX; i++)
scanf ("%f", &nizA[i]);
printf (" Elementi niza B: ");
for(i=0; i<MAX; i++)
scanf ("%f", &nizB[i]);
printf ("\n Elementi niza C: ");
for(i=0; i<MAX; i++)
{
nizC[i]=pow(nizA[i],3)/3+2*nizA[i]*nizB[i];
printf ("%.2f ", nizC[i]);
}
getche();
return 0;
}
135
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
10.14. Саставити програм за формирање низа С од два задата низа целих бројева А и В (сваки
дужине 5) на следећи начин: А[0]+B[4],…,A[4]+B[0]. Исписати низ С.
#include <stdio.h>
#define MAX 5
main()
{
int nizA[MAX], nizB[MAX], nizC[MAX], i;
printf (" Elementi niza A: ");
for(i=0; i<MAX; i++)
scanf ("%d", &nizA[i]);
printf (" Elementi niza B: ");
for(i=0; i<MAX; i++)
scanf ("%d", &nizB[i]);
printf (" Elementi niza C: ");
for(i=0; i<MAX; i++)
{
nizC[i]=nizA[i]+nizB[MAX-1-i];
printf ("%d ", nizC[i]);
}
getche();
return 0;
} Испис на екрану
10.15. Саставити програм који учита елементе низа A = ( A1 , A2 ,..., An ) дужине n и низа
B = ( B1 , B2 ,..., Bm ) дужине m, а затим формира и исписује низ С који се састоји од парних елемената
низа А и низа В.
#include <stdio.h>
#define MAX 100
main()
{
int i, n, m, k=0, nizA[MAX], nizB[MAX], nizC[MAX];
printf(" Broj elemenata niza A: ");
scanf("%d", &n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
scanf("%d", &nizA[i]);
printf(" Broj elemenata niza B: ");
scanf("%d", &m);
printf(" Elementi niza B: ");
for(i=0; i<m; i++)
scanf("%d", &nizB[i]);
printf("\n Elementi niza C: ");
for(i=0; i<n; i++)
if(nizA[i]%2==0)
136
Збирка решених задатака из Програмског језика С – I део
{
nizC[k]=nizA[i];
k++;
}
for(i=0; i<m; i++)
if(nizB[i]%2==0)
{
nizC[k]=nizB[i];
k++;
}
for(i=0; i<k; i++) Испис на екрану
printf("%d ",nizC[i]);
getche();
return 0;
}
10.16. Саставити програм који ће учитати два низа целих бројева А и В једнаких дужина n и на
основу њих формирати низ С тако да i-ти елемент низа С буде једнак мањем од i-тих елемената низа
А и В. Ако су i-ти елементи низа А и В једнаки онда i-ти елемент низа С треба да добије вредност
нула. Исписати низ С.
#include <stdio.h>
#define MAX 100
main()
{
int i, n, nizA[MAX], nizB[MAX], nizC[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
scanf("%d", &nizA[i]);
printf(" Elementi niza B: ");
for(i=0; i<n; i++)
scanf("%d", &nizB[i]);
printf("\n Elementi niza C: ");
for(i=0; i<n; i++) Испис на екрану
{
if (nizA[i]<nizB[i]) nizC[i]=nizA[i];
else if(nizA[i]>nizB[i]) nizC[i]=nizB[i];
else nizC[i]=0;
printf("%d ",nizC[i]);
}
getche();
return 0;
}
10.17. Саставити програм који за учитани низ целих бројева А дужине n формира и исписује два
низа: низ В који садржи негативне елементе низа А и низ С који садржи позитивне елементе и нуле
низа А.
#include <stdio.h>
#define MAX 100
main()
{
int nizA[MAX], nizB[MAX], nizC[MAX];
int n, i, j=0 ,k=0;
printf(" Broj elemenata niza A: ");
137
Збирка решених задатака из Програмског језика С – I део
scanf("%d", &n);
printf(" Elemneti A: ");
for(i=0; i<n; i++)
scanf ("%d", &nizA[i]);
for(i=0; i<n; i++)
{
if (nizA[i]<0)
{
nizB[j]=nizA[i];
j++;
}
else
{
nizC[k]=nizA[i];
k++;
}
}
printf("\n Elementi B: ");
for(i=0; i<j; i++)
printf ("%d ", nizB[i]);
printf("\n Elementi C: ");
for(i=0; i<k; i++)
printf ("%d ", nizC[i]);
getche(); Испис на екрану
return 0;
}
10.18. Саставити програм који за унети низ реланих бројева А дужине n формира и исписује нови
низ В кога чине елементи низа А који су већи од аритемтичке средине свих елемената низа А.
#include <stdio.h>
#define MAX 100
main()
{
float s=0, as, nizA[MAX], nizB[MAX];
int i, j=0, n;
printf(" Broj elemenata niza A: ");
scanf("%d", &n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
{
scanf("%f", &nizA[i]);
s+=nizA[i];
}
as=s/n;
printf("\n Sredina= %.2f", as);
printf("\n Elementi niza B: ");
for(i=0; i<n; i++)
{
if (nizA[i]>as)
{
nizB[j]=nizA[i];
printf("%.2f ",nizB[j]);
j++;
}
}
getche();
return 0; Испис на екрану
}
138
Збирка решених задатака из Програмског језика С – I део
10.19. Саставити програм који за унети низ целих бројева А, дужине n, формира и исписује нови
низ В чији се елементи формирају по следећем принципу: В0=А0, В1=А0+А1, В2=А0+А1+А2, ...,
Bi=A0+A1+A2+...+Ai.
#include <stdio.h>
#define MAX 100
main()
{
int i, n, s=0, nizA[MAX], nizB[MAX];
printf(" Broj elemenata niza A: ");
scanf("%d", &n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
{
scanf("%d", &nizA[i]);
s+=nizA[i];
nizB[i]=s;
}
printf("\n Elementi niza B: ");
for(i=0; i<n; i++)
printf("%d ",nizB[i]);
getche();
return 0; Испис на екрану
}
main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
printf("sizeof(a) - u okviru main : %d\n", sizeof(a));
StampaNiz(a, sizeof(a)/sizeof(int));
getche();
return 0;
}
139
Збирка решених задатака из Програмског језика С – I део
10.21. Саставити функцију за израчунавање скаларног производа два низа реалних бројева
n −1
s = ∑ Ai Bi , а затим саставити главни програм који ће учитати два низа једнаких дужина n и
i=0
применом формирани функције исписати скаларни производ два низа.
#include <stdio.h>
#define MAX 100
main()
{ Испис на екрану
double nizA[MAX],nizB[MAX];
int i, n;
printf(" Broj elemenata niza: ");
scanf("%d",&n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
scanf("%lf",&nizA[i]);
printf(" Elementi niza B: ");
for(i=0; i<n; i++)
scanf("%lf",&nizB[i]);
printf("\n A*B= %.2f", SkalPro(nizA,nizB,n));
getche();
return 0;
}
10.22. Саставити функцију којом се одређује број различитих елемената у задатом целобројном
низу. Затим саставити програм који чита низ целих бројева, и одређује број различитих елемената
користећи претходну функцију и исписује резултат.
#include <stdio.h>
#define MAX 100
main()
{
int niz[MAX], n, i;
printf(" Broj elemenata niza: ");
Испис на екрану
scanf("%d", &n);
printf(" Elementi niza: ");
for (i=0; i<n; i++)
scanf ("%d",&niz[i]);
printf ("\n Broj razl. elemenata je %d", Razliciti(niz,n));
getche();
return 0;
}
10.23. Саставити програм за израчунавање статистике полагања испита која обухвата следеће
функције: израчунавање укупне просечне оцене (сви који су полгали испит), израчунавање просечне
оцене оних који су положили (оцена већа од 5), израчунавање броја који су положили испит,
израчунавање броја који нису положили испит и израчунавање броја који имају оцену већу од
просечне. У главном програму се уноси број студената и оцене студената у облику низа. Исписати
добијене резултате
#include <stdio.h>
#define MAX 100
141
Збирка решених задатака из Програмског језика С – I део
int i, broj=0;
for(i=0; i<n; i++)
if(x[i]>5)
broj++;
return broj;
}
/*Glavni program*/
main()
{
int student[MAX], ocena[MAX];
int i, n;
Испис на екрану
printf(" Broj studenata: ");
scanf("%d",&n);
printf(" Ocene studenata [5 do 10]: \n");
for(i=0; i<n; i++)
{
printf(" Ocena studenta %d = ",i);
scanf("%d",&ocena[i]);
}
printf("\n Ukupno polozenih na ispitu: %d\n",
BrojPolozenih(ocena,n));
printf(" Ukupno nepolozenih na ispitu: %d\n",
BrojNepolozenih(ocena,n));
printf(" Prosek ocena na ispitu: %.2f\n", Prosek(ocena,n));
printf(" Prosek ocena polozenih na ispitu: %.2f\n",
ProsekPolozenih(ocena,n));
printf(" Broj studenata iznad proseka: %d\n",
BrojNadprosecnih(ocena, student, n, Prosek(ocena,n)));
getche();
return 0;
}
142
Збирка решених задатака из Програмског језика С – I део
10.24. Саставити функцију која генерише првих n чланова Фибоначијевог низа и функцију која
исписује чланове низа, а затим те функције тестирати у главном програму.
Фибоначијев низ: f1=1, f2=1, fi=fi-1+fi-2, i=3, 4, 5, ...
#include <stdio.h>
#define MAX 100
10.25. Саставити рекурзивну функцију за израчунавање скаларног производа два низа реалних
n −1
бројева s = ∑ A B , а затим саставити главни програм који ће учитати два низа једнаких дужина n и
i=0
i i
main()
{
float nizA[MAX],nizB[MAX];
int i, n;
printf(" Broj elemenata niza: ");
scanf("%d",&n);
printf(" Elementi niza A: ");
for(i=0; i<n; i++)
scanf("%f",&nizA[i]); Испис на екрану
printf(" Elementi niza B: ");
143
Збирка решених задатака из Програмског језика С – I део
10.26. Саставити рекурзивну функцију која исписује све пермутације скупа {1, 2, …, n}. Затим
тестирати функцију у главном програму за унету дужину пермуатција n.
#include <stdio.h>
#define MAX 100
144
Збирка решених задатака из Програмског језика С – I део
main()
{
int n, a[MAX];
printf("\n Unesite duzinu permutacije: ");
scanf("%d", &n);
if(n < 0 || n >= MAX)
{
printf("Duzina permutacije mora biti broj od 0 dо %d!\n", MAX);
return 1;
}
printf(" Permutacije: \n");
Permutacija(a,1,n);
getche();
return 0;
}
10.27. Саставити програм који за унети низ реалних бројева, дужине n, исписује елемент највеће
вредности, као и његове позиције у низу.
#include <stdio.h>
#define MAX 100
main()
{
double niz[MAX], max;
int n, i, imax=0;
printf(" Broj elemenata niza: ");
scanf("%d", &n);
Испис на екрану
printf (" Elementi niza: ");
for (i=0; i<n; i++)
scanf ("%lf", &niz[i]);
max=niz[0];
for(i=1; i<n; i++)
if(niz[i] > max)
{
max=niz[i];
imax=i;
}
printf ("\n MAX= %.2f", max);
printf ("\n Pozicija= %d", imax+1);
getche();
return 0;
}
145
Збирка решених задатака из Програмског језика С – I део
10.28. Саставити програм који учита низ реалних бројева, дужине n, налази најмањи и највећи члан
низа, xmin и xmax, и исписује све елементе низа који су мањи од xmax/2 и већи од xmin*2.
#include <stdio.h>
#define MAX 100
main()
{
int n, i;
float x[MAX], xmin, xmax;
printf(" Broj elemenata niza: ");
scanf("%d",&n);
printf(" Elementi niza: ");
for(i=0; i<n; i++) Испис на екрану
scanf("%f",&x[i]);
xmin=x[0];
xmax=x[0];
for(i=1; i<n; i++)
{
if(x[i]<xmin) xmin=x[i];
if(x[i]>xmax) xmax=x[i];
}
printf("\n Elementi [xmin*2<x<xmax/2]: ");
for(i=0; i<n; i++)
if(x[i]<xmax/2 && x[i]>xmin*2) printf("\n %.2f ",x[i]);
getche();
return 0;
}
10.29. Саставити програм који за унети низ целих бројева, дужине n, исписује елемент најмање
вредности међу парним бројевима.
#include <stdio.h>
#define MAX 100
main()
{
int niz[MAX], i, n, min;
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: "); Испис на екрану
for(i=0; i<n; i++)
scanf ("%d",&niz[i]);
for(i=0; i<n; i++)
if(niz[i]%2==0)
{
min=niz[i];
break;
}
if(i==n) printf("\n Nema parnih brojeva!");
else
{
for(i=0; i<n; i++)
if(niz[i]%2==0 && niz[i]<min) min=niz[i];
printf("\n Najmanji parni element: %d", min);
}
getche();
return 0;
}
146
Збирка решених задатака из Програмског језика С – I део
10.30. Саставити програм који за унети низ целих бројева, дужине n, проналази и на екрану
исписује елементе на парним позицијама и међу њима проналази онај који има максималну
вредност. Минимална дужина низа је 2.
#include <stdio.h>
#define MAX 100
main()
{
int niz[MAX], i, n, max;
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf ("%d",&niz[i]);
max=niz[1];
printf("\n Parne pozicije: ");
for(i=0; i<n; i++)
if(i%2!=0 )
{
printf("%d ",niz[i]);
if(niz[i]>max) max=niz[i];
}
printf("\n MAX= %d", max);
getche();
return 0;
} Испис на екрану
10.31. Саставити програм који исписује обавештење да ли учитани низ бројева одговара
Фибоначијевом низу. Низ бројева који се уноси мора имати најмање три елемента.
Фибоначијев низ: f1=1, f2=1, fi=fi-1+fi-2, i=3, 4, 5, ...
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, pom=2, niz[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: "); Испис на екрану
while(n>=3 && n<=MAX)
{
for(i=1; i<=n; i++)
{
scanf("%d", &j);
niz[i-1]=j;
}
for(i=2; i<n; i++)
{
if(niz[i]==(niz[i-1]+niz[i-2]))
pom++;
else
{
printf("\n Niz nije Fibonacijev!");
break;
}
147
Збирка решених задатака из Програмског језика С – I део
}
if(pom==n)
printf("\n Niz jeste Fiboacijev!");
break;
}
getche();
return 0;
}
10.32. Саставити програм који за унети низ целих бројева, дужине n, проналази позицију траженог
елемента или исписује обавештење да тражени елемент не постоји у низу. Користити методу
Линеарног претраживања:
а) без употреба функција;
б) коршћењем функције која линеарно претражује низ.
а) #include <stdio.h>
#define MAX 100
main()
{
int i, n, broj, nadjen=0, niz[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf("%d", &niz[i]);
printf(" Trazena vrednost: ");
scanf("%d", &broj);
for(i=1; i<n; i++)
if(niz[i] == broj)
{ Испис на екрану
nadjen=1;
printf ("\n Vrednost %d ima %d. element niza.", broj, i+1);
}
if(!nadjen)
printf ("\n Vrednost %d nije nadjena u nizu.", broj);
getche();
return 0;
}
б)
#include <stdio.h>
#define MAX 100
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf("%d", &niz[i]);
printf(" Trazena vrednost: ");
scanf("%d", &broj);
i=Trazi(niz, n, broj);
if(i==-1)
printf("\n Vrednost %d nije nadjena u nizu.", broj);
else
printf("\n Vrednost %d ima %d. element niza.", broj, i+1);
getche();
return 0;
}
10.33. Саставити програм који за унети низ целих бројева, дужине n, проналази позицију траженог
елемента или исписује обавештење да тражени елемент не постоји у низу. Претпоставља се да је низ
уређен у растућем поретку. Користити методу Бинарног претраживања:
а) без употреба функција;
б) коршћењем функције која бинарно претражује низ;
в) коршћењем рекурзивне функције која бинарно претражује низ.
а)
#include <stdio.h>
#define MAX 100
main()
{
int i, iSrednji, iMin=0, iMax;
int n, broj, nadjen=0, niz[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf("%d", &niz[i]);
printf(" Trazena vrednost: ");
scanf("%d", &broj);
iMax=n-1;
while(iMin<=iMax)
{
iSrednji = (iMin+iMax)/2;
if(broj==niz[iSrednji])
{
nadjen=1;
printf("\n Vrednost %d je %d. element.", broj, iSrednji+1);
break;
}
else if(broj<niz[iSrednji])
iMax=iSrednji-1;
else
iMin=iSrednji+1;
149
Збирка решених задатака из Програмског језика С – I део
}
if(!nadjen)
printf ("\n Vrednost %d nije nadjena u nizu.", broj);
getche();
return 0;
}
б)
#include <stdio.h>
#define MAX 100
main()
{
int i, n, broj, niz[MAX];
printf (" Broj elemenata niza: ");
scanf ("%d", &n);
printf (" Elementi niza: ");
for(i=0; i<n; i++) Испис на екрану
scanf ("%d", &niz[i]);
printf (" Trazena vrednost: ");
scanf ("%d", &broj);
i=Trazi(niz, n, broj);
if(i==-1)
printf("\n Vrednost %d nije nadjena u nizu.", broj);
else
printf("\n Vrednost %d ima %d. element niza.", broj, i+1);
getche();
return 0;
}
150
Збирка решених задатака из Програмског језика С – I део
в)
#include <stdio.h>
#define MAX 100
main()
{
int i, n, broj, niz[MAX];
printf (" Broj elemenata niza: ");
scanf ("%d", &n);
printf (" Elementi niza: ");
for(i=0; i<n; i++)
scanf ("%d", &niz[i]);
printf (" Trazena vrednost: ");
scanf ("%d", &broj);
i=Trazi(niz, 0, n-1, broj);
if(i==-1)
printf("\n Vrednost %d nije nadjena u nizu.", broj);
else
printf("\n Vrednost %d ima %d. element niza.", broj, i+1);
getche();
return 0;
}
151
Збирка решених задатака из Програмског језика С – I део
10.34. Саставити програм који од унетог низа А целих бројева дужине n формира и исписује низ В
са обрнутим распоредом елемената.
#include <stdio.h>
#define MAX 100
main()
{
int a[MAX], i, n;
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza A: "); Испис на екрану
for(i=0; i<n; i++)
scanf("%d",&a[i]);
printf("\n Elementi niza B: ");
for(i=n-1; i>=0; i--)
printf("%d ", a[i]);
getche();
return 0;
}
10.35. Саставити програм за циклично премештање елемената задатог низа целих бројева дужине n
за једно место у лево и исписивање новодобијеног низа.
#include <stdio.h>
#define MAX 100
main()
{
int niz[MAX], i, n, pom;
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf("%d",&niz[i]);
pom=niz[0];
for(i=0; i<n-1; i++)
niz[i]=niz[i+1];
niz[n-1]=pom;
printf("\n Novi niz: ");
for(i=0; i<n; i++)
printf("%d ", niz[i]);
getche();
return 0; Испис на екрану
}
10.36. Саставити програм који за унети низ целих бројева дужине n врши ротирање чланова низа за
x места у лево и исписује новодбијени низ.
#include <stdio.h>
#define MAX 100
152
Збирка решених задатака из Програмског језика С – I део
int i;
for(i=0; i<n; i++)
scanf("%d",&a[i]);
}
main()
{
int i, x, n, a[MAX];
printf(" Broj elemenata niza: ");
scanf("%d",&n);
printf(" Elementi niza: ");
CitajNiz(a, n);
printf(" Broj mesta za rotaciju: ");
scanf("%d",&x);
for(i=0; i<x; i++)
Rotiraj(a, n);
printf("\n Rotirani niz za %d mesta: ", x);
PisiNiz(a, n);
getche();
return 0;
}
10.37. Саставити програм који за унети низ целих бројева дужине n врши замену суседних
елемената низа на парним и непарним позицијама и исписује новодобијени низ.
#include <stdio.h>
#define MAX 100
int i, pom;
for(i=0; i<n-1; i+=2)
{
pom=a[i];
a[i]=a[i+1];
a[i+1]=pom;
}
}
Испис на екрану
main()
{
int i, x, n, a[MAX];
printf(" Broj elemenata niza: ");
scanf("%d",&n);
printf(" Elementi niza: ");
CitajNiz(a, n);
Zameni(a, n);
printf("\n Novi niz: ");
PisiNiz(a, n);
getche();
return 0;
}
10.38. Саставити програм који за унети низ целих бројева дужине n формира и приказује нови низ
који је састављен од елемената без понављања унетог низа.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, nadjeniIsti, a[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf ("%d", &a[i]);
printf("\n Novi niz: ");
for(i=0; i<n-1; i++)
{
nadjeniIsti=0;
for(j=i+1; j<n; j++)
if(a[i] == a[j])
{
nadjeniIsti=1;
break;
}
if(!nadjeniIsti)
printf ("%d ",a[i]);
}
printf ("%d ",a[n-1]);
getche();
return 0;
} Испис на екрану
154
Збирка решених задатака из Програмског језика С – I део
10.39. Саставити програм за сортирање унетог низа целих бројева дужине n у неопадајући поредак
методом избора (Selection Sort). Исписати сортирани низ.
Selection Sort подразумева да минимални елемент низа размени са a[0], минимални елемент
одсечка a[1], a[2], …, a[n-1] разменити са a[1], минимални елемент одсечка a[2], a[3], …, a[n-1]
разменити са a[2]; исти поступак применити на преостале елементе осим последњег који се налази на
свом месту.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, pom, niz[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf ("%d", &niz[i]);
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(niz[i] > niz[j])
{
pom=niz[i];
niz[i]=niz[j];
niz[j]=pom;
}
printf(" Sortirani niz: ");
for(i=0; i<n; i++)
printf ("%d ",niz[i]);
getche();
return 0; Испис на екрану
}
10.40. Саставити програм за сортирање унетог низа целих бројева дужине n у неопадајући поредак
методом уметања (Insert Sort). Исписати сортирани низ.
Insert Sort: Нека је првих k елемената већ уређено у неопадајућем поретку, тада се узима
(k+1)-ви елемент и умеће на одговарајуће место међу првих k елемената тако да првих k+1
елемената буде уређено. Овај се метод примењује за k од 0 до n-2.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, pom, niz[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf("%d", &niz[i]);
for(i=1; i<n; i++)
{
pom=niz[i];
for(j=i-1; j>=0; j--)
if (niz[j] > pom)
niz[j+1]=niz[j];
else break;
155
Збирка решених задатака из Програмског језика С – I део
niz[j+1]=pom;
}
printf (" Sortirani niz: ");
for(i=0; i<n; i++)
printf ("%d ",niz[i]);
getche();
return 0;
} Испис на екрану
10.41. Саставити програм за сортирање унетог низа целих бројева дужине n у неопадајући поредак
методом мехурића (Bubble Sort). Исписати сортирани низ.
Bubble Sort: Пролазимо кроз низ редом поредећи суседне елементе, и при том их замењујући
ако су у погрешном поретку. Овим се највећи елемент попут мехурића истискује на "површину", тј.
на крајњу десну позицију. Након тога је потребно овај поступак поновити над низом а[0],...,а[n-2], тј.
над првих n-1 елемената низа без последњег који је постављен на праву позицију. Након тога се исти
поступак понавља над све краћим и краћим префиксима низа, чиме се један по један истискују
елемененти на своје праве позиције.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, pom, niz[MAX];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf("%d", &niz[i]);
for(i=n-1; i>0; i--)
for(j=0; j<i; j++)
if(niz[j] > niz[j+1])
{
pom=niz[j];
niz[j]=niz[j+1];
niz[j+1]=pom;
}
printf(" Sortirani niz: ");
for(i=0; i<n; i++)
printf("%d ",niz[i]);
getche();
return 0; Испис на екрану
}
10.42. Саставити програм којим се у уређени низ бројева умеће нови број тако да низ и даље буде
уређен. Исписати новодобијени низ.
#include <stdio.h>
#define MAX 100
main()
{
int i, n, b, niz[MAX+1];
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
156
Збирка решених задатака из Програмског језика С – I део
10.43. Саставити програм који учитава два низа целих бројева који су уређени по неопадајућем
редоследу (различитих дужина) и исписује њихову фузију која је такође неопадајућа.
#include <stdio.h> else
#define MAX 100 {
for(ic=0; ic<nc; ic++)
main() {
{ if(nizA[ia]<=nizB[ib])
int nizA[MAX], nizB[MAX], nizC[2*MAX]; {
int na, nb, nc, ia, ib, ic; nizC[ic]=nizA[ia];
printf(" Broj elemenata niza A: "); ia++;
scanf("%d", &na); }
printf(" Elemneti A: "); else
for(ia=0; ia<na; ia++) {
scanf ("%d", &nizA[ia]); nizC[ic]=nizB[ib];
printf(" Broj elemenata niza B: "); ib++;
scanf("%d", &nb); }
printf(" Elemneti B: "); }
for(ib=0; ib<nb; ib++) }
scanf("%d", &nizB[ib]); printf("\n Elementi niza C: ");
nc=na+nb; for(ic=0; ic<nc; ic++)
ia=0; printf("%d ", nizC[ic]);
ib=0; getche();
if(na==0) return 0;
{ }
for(ic=0; ic<nc; ic++)
nizC[ic]=nizB[ic];
}
else if (nb==0)
{
for(ic=0; ic<nc; ic++)
nizC[ic]=nizA[ic];
}
Испис на екрану
157
Збирка решених задатака из Програмског језика С – I део
10.44. Саставити програм који исписује број који се највећи број пута појављује у низу целих
бројева, као и број појављивања. Прво сортирати низ у растућем поретку, а затим пронаћи најдужу
секвенцу једнаких елемената. Низ се уноси са тастатуре.
#include <stdio.h>
#define MAX 100
main()
{
int a[MAX], i, j, n, indeks=-1, duzina=-1, brojac;
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++)
scanf("%d", &a[i]);
Sortiraj(a,n);
printf("\n Sortiran niz: ");
for(i=0; i<n; i++)
printf("%d ", a[i]);
for(i=0; i<n; i++)
{
brojac=1;
for(j=i+1; j<n && a[i]==a[j]; j++)
brojac++;
if(brojac > duzina)
{
duzina=brojac;
indeks=i;
}
}
printf("\n Najveci broj puta se pojavljuje broj %d i to %d puta.",
a[indeks], duzina);
getche();
return 0;
}
Испис на екрану
158
Збирка решених задатака из Програмског језика С – I део
10.45. Саставити програм који испистује да ли у унетом низу целих бројева постоје два елемента
чији је збир једнак датом броју. Користити бинарну претрагу за проналажење допуне до датог броја.
Елементи низа се уносе са тастатуре.
#include <stdio.h>
#define MAX 100
main()
{
int a[MAX], n, i, zbir, drugi, nadjen =0;
printf(" Broj elemenata niza: ");
scanf("%d", &n);
printf(" Elementi niza: ");
for(i=0; i<n; i++) scanf("%d", &a[i]);
Sortiraj(a, n);
printf(" Vrednost zbir dva elementa: ");
scanf("%d", &zbir);
/*Uslov drugi>i stoji samo da bi se izbegla nepotreban ponavljanja u ispisu.*/
for(i=0; i< n; i++)
if((drugi=BinarnaPretraga(a, n, zbir-a[i])) != -1 && drugi>i)
{
printf("\n Trazeni zbir se moze formirati od elemenata: %d i %d",
a[i], a[drugi]);
nadjen++;
}
if(!nadjen) printf(" Trazeni zbir se ne moze dobiti!\n");
getche();
return 0;
}
159
Збирка решених задатака из Програмског језика С – I део
11 МАТРИЦЕ
11.1. Саставити програм који учитава, а затим исписује елементе матрице mxn. Елементи матрице
су цели бројеви.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, m, n, mat[MAX][MAX];
printf(" Vrsta m= ");
scanf("%d", &m);
printf(" Kolona n= ");
scanf("%d", &n);
/*Citanje matrice sa tastature*/
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{
printf(" element[%d][%d] = ",i,j);
scanf("%d", &mat[i][j]);
}
/*Prikaz matrice*/
printf("\n Uneta matrica:\n");
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
printf(" %d", mat[i][j]);
printf("\n"); Испис на екрану
}
getche();
return 0;
}
160
Збирка решених задатака из Програмског језика С – I део
11.2. Саставити програм који за унету матрицу димензија nxn врши сабирање њених елеменета и
исписује добијени резултат. Елементи су цели бројеви.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, s=0, mat[MAX][MAX];
printf(" n= ");
scanf("%d", &n);
printf(" Elementi:\n");
for(i=0; i<n; i++)
for(j=0; j<n; j++)
scanf("%d", &mat[i][j]);
for(i=0; i<n; i++) Испис на екрану
for(j=0; j<n; j++)
s+=mat[i][j];
printf("\n suma= %d", s);
getche();
return 0;
}
11.3. Саставити програм који учита матрицу димензија mхn, а затим врши сабирање елемената
који су парни бројеви. На крају исписати суму парних бројева и број елемената који су једнаки нули.
Елементи матрице су цели бројеви од 0 до 9.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, m, n, s=0, nule=0, mat[MAX][MAX];
printf(" m= ");
scanf("%d",&m);
printf(" n= ");
scanf("%d", &n);
printf("\n Uneta matrica:\n");
for(i=0; i<m; i++)
for(j=0; j<n; j++)
scanf("%d",&mat[i][j]);
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{
if(mat[i][j]%2==0) s+=mat[i][j];
if(mat[i][j]==0) nule++;
} Испис на екрану
printf("\n Suma parnih elemenata: %d", s);
printf("\n Broj elemenata jednakih nuli: %d", nule);
getche();
return 0;
}
161
Збирка решених задатака из Програмског језика С – I део
11.4. Саставити програм који учита две матрице целих бројева, a и b, обе димензија mхn, а затим
врши сабирање ове две матрице и исписује нову матрицу с. Матрице се сабирају тако што се
сабирају елементи матрица са истим индексима.
a11 a12 K a1n b11 b12 L b1n
a a22 K a2 n b21 b22 L b2 n
c = a + b = 21 + =
M M
am1 am 2 K amn bm1 bm 2 L bmn
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, m, mat1[MAX][MAX], mat2[MAX][MAX];
printf(" m= ");
scanf("%d", &m);
printf(" n= ");
scanf("%d", &n);
printf("\n Elementi prve matrice: \n");
for(i=0; i<m; i++)
for(j=0; j<n; j++)
scanf("%d", &mat1[i][j]);
printf("\n Elementi druge matrice: \n");
for(i=0; i<m; i++)
for(j=0; j<n; j++)
scanf("%d", &mat2[i][j]);
printf("\n Zbir dve matrice:\n");
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
printf(" %d", mat1[i][j]+mat2[i][j]);
printf("\n");
}
getche(); Испис на екрану
return 0;
}
11.5. Саставити програм који ће учитати матрицу димензија nxn, а затим исписати матрицу у
облику таблице, исписати све елементе на главној и споредној дијагонали, као и суме елемената на
главној и споредној дијагонали. Елементи матрице су цели бројеви.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, sgd=0, ssd=0, mat[MAX][MAX];
printf(" n= ");
scanf("%d", &n);
162
Збирка решених задатака из Програмског језика С – I део
printf(" Elementi:\n");
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
printf(" element[%d][%d] = ", i, j);
scanf("%d", &mat[i][j]);
}
printf("\n Uneta matrica:\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf(" %d",mat[i][j]);
printf("\n");
}
printf("\n Elementi glavne dijagonale: ");
for(i=0; i<n; i++)
{
printf("%d ",mat[i][i]);
sgd+=mat[i][i];
}
printf("\n Suma glavne dijagonale = %d", sgd);
printf("\n Elementi sporedne dijagonale: ");
for(i=0; i<n; i++)
{
printf("%d ",mat[i][n-i-1]);
ssd+=mat[i][n-i-1];
}
printf("\n Suma sporedne dijagonale = %d", ssd);
getche();
return 0;
}
Испис на екрану
163
Збирка решених задатака из Програмског језика С – I део
11.6. Саставити програм који учита матрицу димензија nxn, а затим је исписује у облику таблице и
израчунава и исписује суму елемената у свакој врсти. Елементи матрице су цели бројеви.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, s=0, mat[MAX][MAX];
printf(" n= ");
scanf("%d", &n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
printf(" element[%d][%d] = ", i, j);
scanf("%d", &mat[i][j]);
}
printf("\n Uneta matrica:\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf(" %d", mat[i][j]);
printf("\n"); Испис на екрану
}
printf("\n Suma elememenata vrste:\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
s+=mat[i][j];
printf(" %d", s);
}
getche();
return 0;
}
11.7. Саставити програм који учита матрицу димензија mxn, а затим је исписује у облику таблице
и на основу унетог редног броја врсте врши сабирање елемената у тој врсти. Елементи матрице су
цели бројеви.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, m, vrsta, s=0, mat[MAX][MAX];
printf(" m= ");
scanf("%d", &m);
printf(" n= ");
scanf("%d", &n);
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{
printf(" element[%d][%d] = ", i, j);
scanf("%d", &mat[i][j]);
}
printf("\n Uneta matrica:\n");
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
printf(" %d", mat[i][j]);
164
Збирка решених задатака из Програмског језика С – I део
printf("\n");
}
printf("\n Redni broj vrste ciji zbir elemenata zelite: ");
scanf("%d",&vrsta);
for(j=0; j<n; j++)
s=s+mat[vrsta-1][j];
printf("\n Zbir elememenata %d. vrste: %d", vrsta, s);
getche();
return 0;
}
Испис на екрану
11.8. Саставити програм који учита матрицу целих бројева А димензија mxn, а затим исписује
њене елементе у редоследу као што је приказано на следећој слици:
#include <stdio.h>
#define MAX 100
main()
{
int i, j, m, n, a[MAX][MAX];
printf(" m= ");
scanf("%d", &m);
printf(" n= ");
scanf("%d", &n);
printf(" Matrica:\n");
for(i=0; i<m; i++)
for(j=0; j<n; j++)
scanf("%d", &a[i][j]);
165
Збирка решених задатака из Програмског језика С – I део
printf("\n Elementi:\n");
for(j=0;j<n;j++)
{
if(j%2==0)
for(i=0; i<m; i++)
printf(" %d",a[i][j]);
else
for(i=m-1; i>=0; i--)
printf(" %d",a[i][j]);
}
getche();
return 0;
} Испис на екрану
11.9. Саставити програм који учита матрицу реалних бројева А димензија nxn, а затим формира
нову матрицу тако што све чланове врсте (укључујући и дијагонални) дели са дијагоналним чланом.
Уколико је дијагонални члан једнак нули, све чланове у том реду поставља на нулу, осим
дијагоналног који поставља на 1. Исписати добијену матрицу.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n;
float a[MAX][MAX], t;
printf(" n= ");
scanf("%d", &n);
printf(" Matrica:\n");
for(i=0; i<n; i++)
for(j=0; j<n; j++)
scanf("%f",&a[i][j]);
for(i=0; i<n; i++)
if(a[i][i]!=0)
{ Испис на екрану
t=a[i][i];
for(j=0; j<n; j++)
a[i][j]/=t;
}
else
{
for(j=0; j<n; j++)
a[i][j]=0;
a[i][i]=1;
}
printf("\n Nova matrica:\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf(" %.2f",a[i][j]);
printf("\n");
}
getche();
return 0;
}
166
Збирка решених задатака из Програмског језика С – I део
11.10. Саставити програм који учита један цео број х и матрицу целих бројева А димензија nxn, а
затим формира нову матрицу тако што све елементе испод главне дијагонала увећа за вредност х, а
елементе изнад главне дијагонале увећава за 2х. Елементи на главној дијагонали се не мењају.
Исписати добијену матрицу.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, x, a[MAX][MAX];
printf(" x= ");
scanf("%d",&x);
printf(" n= ");
scanf("%d", &n);
printf("\n Uneta matrica: \n");
for(i=0; i<n; i++)
for(j=0; j<n; j++)
scanf("%d",&a[i][j]);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
if(i>j) a[i][j]+=x; Испис на екрану
if(i<j) a[i][j]+=2*x;
}
printf("\n Nova matrica:\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf(" %d",a[i][j]);
printf("\n");
}
getche();
return 0;
}
11.11. Саставити програм који учита матрицу целих бројева А димензија mxn, а затим исписује
матрицу у облику таблице и врши замену места двема колонама на основу унета два цела броја који
представљају редне бројеве колона.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, m, k1, k2, pom, a[MAX][MAX];
printf(" m= ");
scanf("%d", &m);
printf(" n= ");
scanf("%d", &n);
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{
printf(" element[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
printf("\n Zadata matrica:\n");
167
Збирка решених задатака из Програмског језика С – I део
Испис на екрану
168
Збирка решених задатака из Програмског језика С – I део
11.12. Саставити програм који учита матрицу целих бројева А димензија nxn, а затим исписује
матрицу у облику таблице и врши њено транспоновање. Танспонована матрица је матрица која се
добија када се врсте почетне матрице поређају по колонама.
а) без употребе функција;
б) употребом функција за учитавања, исписивање и транспоновање матрице.
Исписати транспоновану матрицу.
а)
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, pom, mat[MAX][MAX];
printf(" n= ");
scanf("%d", &n);
printf("\n");
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
printf(" element[%d][%d] = ", i, j);
scanf("%d", &mat[i][j]);
}
printf("\n Zadata matrica: \n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf(" %d",mat[i][j]);
printf("\n");
}
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
{
pom=mat[i][j];
mat[i][j]=mat[j][i];
mat[j][i]=pom;
}
printf ("\n Transponovana matrica:\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf(" %d",mat[i][j]);
printf("\n");
}
getche();
return 0;
}
б)
#include <stdio.h>
#define MAX 100
}
}
main()
{
int i, j, n, pom, mat[MAX][MAX];
printf(" n= ");
scanf("%d", &n);
printf("\n");
Citaj(mat,n);
printf("\n Zadata matrica: \n");
Pisi(mat,n);
Transp(mat,n);
printf ("\n Transponovana matrica:\n");
Pisi(mat,n);
getche();
return 0;
}
11.13. Саставити програм који учита матрицу целих бројева А димензија nxn, а затим исписује
матрицу у оквиру таблице. Програм треба да одређује највећи и најмањи елемент у свакој врсти и
колони, а добијене елементе сместити у једнодимензионалне низове. Исписати формиране низове.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, a[MAX][MAX];
int maxv[MAX], minv[MAX], maxk[MAX], mink[MAX];
printf(" n= ");
scanf("%d", &n);
printf("\n");
for(i=0; i<n; i++)
for(j=0; j<n; j++)
170
Збирка решених задатака из Програмског језика С – I део
{
printf(" element[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
printf("\n Zadata matrica: \n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf(" %d",a[i][j]);
printf("\n");
}
for(i=0; i<n; i++)
{
minv[i]=a[i][0];
maxv[i]=a[i][0];
mink[i]=a[0][i];
maxk[i]=a[0][i];
for(j=1; j<n; j++)
{
if(a[i][j]<minv[i]) minv[i]=a[i][j];
if(a[i][j]>maxv[i]) maxv[i]=a[i][j];
if(a[j][i]<mink[i]) mink[i]=a[j][i];
if(a[j][i]>maxk[i]) maxk[i]=a[j][i]; Испис на екрану
}
}
printf("\n Najveci u vrstama: ");
for(i=0; i<n; i++)
printf("%d ", maxv[i]);
printf("\n Najmanji u vrstama: ");
for(i=0; i<n; i++)
printf("%d ", minv[i]);
printf("\n Najveci u kolonama: ");
for(i=0; i<n; i++)
printf("%d ", maxk[i]);
printf("\n Najmanji u kolonama: ");
for(i=0; i<n; i++)
printf("%d ", mink[i]);
getche();
return 0;
}
11.14. Саставити програм који учита две матрице целих бројева, А димензија nxm, и матрицу B
димензија mxk, а затим формира и исписује матрицу C добијену множењем матрица А и В.
a11b11 + a12 b21 + K + a1m bm1 L a11b1k + a12 b2 k + K + a1m bmk c11 c12 L c1n
a b + a b + K + a b L a 21b1k + a 22 b2 k + K + a 2 m bmk c 21 c 22 L c 2 n
21 11 22 21 2 m m1
=
M M
a n1b11 + a n 2 b21 + K + a nm bm1 K a n1b1k + a n 2 b2 k + K + a nm bmk c m1 cm2 L c mn
171
Збирка решених задатака из Програмског језика С – I део
Две матрице могу да се множе ако је број врсти друге матрице једнак броју колона прве
матрице.
#include <stdio.h>
#define MAX 100
main()
{
int a[MAX][MAX], b[MAX][MAX];
int c[MAX][MAX], d[MAX][MAX];
int i, j, n, m, k, t;
printf(" Broj vrsta matrice A: ");
scanf("%d",&n);
printf(" Broj kolona matrice A: ");
scanf("%d",&m);
printf(" Broj kolona matrice B: ");
scanf("%d",&k);
printf("\n Matrica A:\n");
Citaj(a,n,m);
printf("\n Matrica B:\n");
Citaj(b,m,k);
for(i=0; i<n; i++)
for(j=0; j<k; j++)
{
c[i][j]=0; Испис на екрану
for(t=0; t<m; t++)
c[i][j]=c[i][j]+a[i][t]*b[t][j];
}
printf("\n Matrica A:\n");
Pisi(a,n,m);
printf("\n Matrica B:\n");
Pisi(b,m,k);
printf("\n Matrica C:\n");
Pisi(c,n,k);
getche();
return 0;
}
172
Збирка решених задатака из Програмског језика С – I део
11.15. Саставити програм који учита матрицу целих бројева A димензија nxn, а затим исписује
матрицу која представља производ АхА.
#include <stdio.h>
#define MAX 100
main()
{
int i, j, n, k;
int a[40][40],b[40][40];
printf("\n n= ");
scanf("%d",&n);
printf("\n Matrice %dx%d\n", n,n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
scanf("%d",&a[i][j]);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{ Испис на екрану
b[i][j]=0;
for(k=0; k<n; k++)
b[i][j]+=a[i][k]*a[k][j];
}
printf("\n Matrica AxA:\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf(" %4d ", b[i][j]);
printf("\n");
}
getche();
return 0;
}
11.16. Саставити програм који учита матрицу целих бројева A димензија mxm и цео број n, а затим
исписује матрицу која представља n-ти производ матрице А (n-ти степен матрице А).
#include <stdio.h>
#define MAX 100
main()
{
int i, j, m, n, k, p;
int a[MAX][MAX], b[MAX][MAX], c[MAX][MAX];
printf("\n Stepen n= ");
scanf("%d",&n);
printf(" Dimanzija m= ");
scanf("%d",&m);
printf("\n Matrica %dx%d:\n", m,m);
for(i=0; i<m; i++)
for(j=0; j<m; j++)
{
scanf("%d",&a[i][j]);
b[i][j]=a[i][j];
}
173
Збирка решених задатака из Програмског језика С – I део
/*Ispis matrice*/
printf("\n Rezultujuca matrica:\n");
for(i=0; i<m; i++) Испис на екрану
{
for(j=0; j<m; j++)
printf("%6d ",c[i][j]);
printf("\n");
}
getche();
return 0;
}
11.17. Саставити програм који учита матрицу реалних бројева A димензија nxn и, а затим дату
матрицу своди на горњу десну троугласту. Исписати новодобијену матрицу.
#include <stdio.h>
#define MAX 100
main()
{
float a[MAX][MAX], z, xm;
int n, i, j, k, s=1;
printf("\n n= ");
scanf("%d",&n);
printf("\n Matrica %dx%d:\n",n,n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
scanf("%f",&a[i][j]);
/*Iteracija za svaku kolonu: svodjenje na nulu clanova ispod dijagonale*/
for(k=0; k<n-1; k++)
{
if(a[k][k]==0)
/*Potrebno je izvrsiti zamenu vrsti; nadji clan u k-toj koloni razlicit
od nule; ako ga nema, ispisi poruku*/
{
for(i=k+1; i<n-1 && a[i][k]==0; i++)
if(i==n-1 && a[i][k]==0)
{
printf("\n Matrica se ne moze svesti na gornju trouglastu.");
return 1;
}
/*Zameniti i-tu i k-tu vrstu*/
174
Збирка решених задатака из Програмског језика С – I део
/*Ispis rezultata*/
printf("\n Gornja trouglasta matrica:\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf("%7.2f",a[i][j]);
printf("\n");
}
getche();
return 0;
}
Испис на екрану
175
Збирка решених задатака из Програмског језика С – I део
11.18. Саставити програм који учита матрицу целих бројева димензија mxn, а затим врши
уређивање колона матрице по неопадајућем редоследу збирова елемената по колонама. Исписати
новодобијену матрицу.
#include <stdio.h>
#define MAX 100
main()
{
int mat[MAX][MAX], s[MAX], p;
int m, n, i, j, min;
printf(" m= ");
scanf("%d", &m);
printf(" n= ");
scanf("%d", &n);
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{
printf(" element[%d][%d] = ", i, j);
scanf("%d", &mat[i][j]);
}
176
Збирка решених задатака из Програмског језика С – I део
{
for(j=0; j<n; j++)
printf(" %d", mat[i][j]);
printf("\n");
}
printf("\n Suma po kolonama:\n");
for(j=0; j<n; j++)
printf("% d", s[j]);
getche();
return 0;
}
177
ЛИТЕРАТУРА
[1] Brian W. Kernighan, Dennis M. Ritchie: The C Programming Language, New Jersey, 1988.
[2] Laslo Kraus: Programski jezik C sa rešenim zadacima, Akademska misao, Beograd, 2006.
[3] Laslo Kraus: Rešeni zadaci iz programskog jezika C, Akademska misao, Beograd, 2005.
[5] Jozo J. Dujmović: Programski jezici i metode programiranja, Naučna knjiga, Beograd,
1990.
[6] B. S. Gottfired: Theory and Problems of Programming with C, Schaum’s outline series,
McGraw-Hill, 1996.
[7] Clovis Tondo, Scott Gimpel: Programski jezik C – rešenja zadataka, CET, Beograd, 2004.
[9] Igor ðurović, Slobodan ðukanović, Vesna Popović: Programski jezik C sa zbirkom
riješenih zadataka, ETF Podogorica, Podgorica, 2006.
[11] Milan Čabarapa, Stanka Matković: C/C++ zbirka zadataka, Krug, Beograd, 2003.
[12] Milan Čabarkapa, Nevenka Spalević: Metodička zbirka zadataka iz programiranja, Sova,
Novi Beograd, 1997.
[13] Абрамов С.А., Гнездилова Г.Г., Капустина Е.Н., Селљун М.И.: Задачи по
программированию, Наука, Москва, 1988.
[14] Абрамов В.Г., Тирфонов Н.П, Трифонава Г.Н., Введение в язык Паскалъ, Наука,
Москва, 1988.
Osnovi programiranja
Programski jezik C
— Zadaci sa vežbi —
2
Sadržaj
1 Programski jezik C 5
1.1 Zdravo svete! . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Imena promenljivih . . . . . . . . . . . . . . . . . . . 6
1.3 Deklaracije . . . . . . . . . . . . . . . . . . . . . . . 6
1.4 Tipovi i veličina podataka . . . . . . . . . . . . . . . 6
1.5 Funkcije printf i scanf . . . . . . . . . . . . . . . . . . 7
1.6 Aritmetički operatori . . . . . . . . . . . . . . . . . . 9
1.7 Operatori i izrazi dodeljivanja vrednosti . . . . . . . 11
1.8 Inkrementacija i dekrementacija . . . . . . . . . . . . 12
1.9 Relacioni i logički operatori . . . . . . . . . . . . . . 13
1.10 Kontrola toka — if, while, do - while, for . . . . . . . 14
1.10.1 if . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.10.2 Else-if . . . . . . . . . . . . . . . . . . . . . . 15
1.10.3 while . . . . . . . . . . . . . . . . . . . . . . . 17
1.10.4 do-while . . . . . . . . . . . . . . . . . . . . . 17
1.10.5 for . . . . . . . . . . . . . . . . . . . . . . . . 17
1.11 Switch . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.12 Uslovni izraz . . . . . . . . . . . . . . . . . . . . . . . 19
1.13 Simboličke konstante . . . . . . . . . . . . . . . . . . 20
1.14 Enumeracija . . . . . . . . . . . . . . . . . . . . . . . 21
1.15 Funkcije . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.16 Nizovi . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.17 Konstante . . . . . . . . . . . . . . . . . . . . . . . . 27
1.18 Konverzija . . . . . . . . . . . . . . . . . . . . . . . . 28
1.18.1 Automatska konverzija . . . . . . . . . . . . . 28
1.18.2 Eksplicitna konverzija . . . . . . . . . . . . . 28
1.18.3 Funkcije koje vrše konverziju . . . . . . . . . . 29
1.19 Operator sizeof() . . . . . . . . . . . . . . . . . . . 30
1.20 Znakovni ulaz i izlaz . . . . . . . . . . . . . . . . . . 31
1.21 Nizovi . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.22 Dvostruka for petlja . . . . . . . . . . . . . . . . . . 39
1.23 Formiranje HTML dokumenta . . . . . . . . . . . . . 40
3
4 SADRŽAJ
4
Glava 1
Programski jezik C
main()
/*iskazi f-je main su zatvoreni u zagrade */
{
/*poziv f-je printf da odstampa poruku*/
printf("hello, world\n");
}
Primer 1.1.2 Program štampa poruku ”hello, world”
#include <stdio.h>
main()
{
printf("hello, ");
printf("world");
printf("\n");
}
Specijalni znaci:
\n novi red
\t tabulator
\\ kosa crta
\" navodnici
\a zvuk
\’ jednstruki navodnik
5
6 Milena Vujošević–Janičić
1.3 Deklaracije
Da bi se promenljiva mogla upotrebljavati ona se mora na početku
programa deklarisati. Prilikom deklaracije može se izvršiti i početna
inicijalizacija.
6
1.5 Funkcije printf i scanf 7
Važi
main()
{
/*deklaracija vise promenljivih
istog tipa */
int rez,pom1,pom2;
pom1=20;
pom2=15;
rez=pom1-pom2;
/*ispisivanje rezultata*/
printf("Rezultat je %d-%d=%d\n",pom1,pom2,rez);
}
Izlaz iz programa:
Rezultat je 20-15=5
Iskaz dodele:
pom1=20;
pom2=15;
Individualni iskazi se zavrsavaju sa ;
7
8 Milena Vujošević–Janičić
Primer 1.5.1
#include <stdio.h>
main()
{
printf("Slova:\n%3c\n%5c\n", ’z’ , ’Z’);
}
Izlaz iz programa:
Slova:
z
Z
%c je za stampanje karaktera
%3c je za stampanje karaktera na tri pozicije
Isto tako smo mogli i %3d za stampanje broja na tri pozicije ili %6d
za stampanje broja na 6 pozicija.
Pravila:
%d stampaj kao ceo broj
%6d stampaj kao ceo broj sirok najvise 6 znakova
%f stampaj kao realan broj
%6f stampaj kao realan broj sirok najvise 6 znakova
%.2f stampaj kao realan broj sa dve decimale
%6.2f stampaj kao realan broj sirok najvise 6 znakova a od toga 2
iza decimalne tacke
%c karakter
%s string
%x heksadecimalni broj
%% je procenat
main()
{
int x;
printf("Unesi ceo broj : ");
8
1.6 Aritmetički operatori 9
main()
{
int a, b, c;
printf("Unesi prvi broj : ");
scanf("%d", &a);
printf("Unesi drugi broj : ");
scanf("%d", &b);
c = a + b;
printf("%d + %d = %d\n", a, b, c);
}
Ulaz:
Unesi prvi broj : 2 <enter>
Unesi drugi broj : 3 <enter>
Izlaz:
2 + 3 = 5
9
10 Milena Vujošević–Janičić
scanf("%d",&b);
Ulaz:
Unesi prvi broj : 2 <enter>
Unesi drugi broj : 3 <enter>
Izlaz:
Zbir a+b je : 5
Razlika a-b je : -1
Proizvod a*b je : 6
Celobrojni kolicnik a/b je : 0
Progresan pokusaj racunanja realnog kolicnika a/b je : 0.000000
Realni kolicnik a/b je : 0.666667
Ostatak pri deljenju a/b je : 2
Primer 1.6.2 Program ilustruje celobrojno i realno deljenje.
#include <stdio.h>
main()
{
int a = 5;
int b = 2;
int d = 5/2; /* Celobrojno deljenje - rezultat je 2 */
float c = a/b; /* Iako je c float, vrsi se celobrojno
deljenje jer su i a i b celi */
10
1.7 Operatori i izrazi dodeljivanja vrednosti 11
printf("c = %f\n",c);
printf("Uzrok problema : 5/2 = %f\n", 5/2);
printf("Popravljeno : 5.0/2.0 = %f\n", 5.0/2.0);
printf("Moze i : 5/2.0 = %f i 5.0/2 = %f \n", 5/2.0, 5.0/2);
printf("Za promenljive mora kastovanje : %f\n", (float)a/(float)b);
Izlaz iz programa:
c = 2.000000
Uzrok problema : 5/2 = 2.000000
Popravljeno : 5.0/2.0 = 2.500000
Moze i : 5/2.0 = 2.500000 i 5.0/2 = 2.500000
Za promenljive mora kastovanje : 2.500000
Moze i za:
+ - * / % << >> ^ |
izraz1 op = izraz2
je ekvivalnetno sa
izraz1 = (izraz1) op (izraz2)
11
12 Milena Vujošević–Janičić
y=(x++)*(++z);
Izlaz iz programa:
Na pocetku:
a = 0
b = 0
Posle : a++; ++b;
a = 1
b = 1
Posle : x = ++a;
12
1.9 Relacioni i logički operatori 13
a = 2
x = 2
Posle : y = b++;
b = 2
y = 1
(3<5)
(a<=10)
a < 5 != 1 <=> (a < 5)!=1
Logicki operatori:
! unarna negacija (najvisi prioritet)
&& logicko i (visi prioritet od ili)
|| logicko ili izracunavaju se sleva na desno!
main()
{
int a = 3>5, /* manje */
b = 5>3, /* vece */
c = 3==5, /* jednako */
d = 3!=5; /* razlicito */
13
14 Milena Vujošević–Janičić
Izlaz iz programa:
3>5 - 0
5>3 - 1
3==5 - 0
3!=5 - 1
Konjunkcija : 3>5 && 5>3 - 0
Disjunkcija : 3>5 || 5>3 - 1
Negacija : !(3>5) - 1
main()
{
int b;
printf("Unesi ceo broj:");
scanf("%d", &b);
if (b < 0)
printf("Broj je negativan\n");
14
1.10 Kontrola toka — if, while, do - while, for 15
}
Else se odnosi na prvi neuparen if, voditi o tome računa, ako
želimo drugačije moramo da navedemo vitičaste zagrade.
if (izraz)
if (izraz1) iskaz 1
else iskaz
ovo else se odnosi na drugo if a ne na prvo if!
if (izraz)
{
if (izraz1) iskaz 1
}
else iskaz
tek sada se else odnosi na prvo if!!!
1.10.2 Else-if
if (izraz1)
iskaz1
else if (izraz2)
iskaz2
else if (izraz3)
iskaz3
else if (izraz4)
iskaz4
else iskaz
npr if (a<5)
printf("A je manje od 5\n");
else if (a=5)
printf("A je jednako 5\n");
else if (a>10)
printf("A je vece od 10\n");
else if (a=10)
printf("A je jednako 10\n");
else printf("A je vece od pet i manje od 10\n");
Primer 1.10.2 Program ilustruje if-else konstrukciju i ispituje znak
broja.
#include <stdio.h>
15
16 Milena Vujošević–Janičić
main()
{
int b;
printf("Unesi ceo broj : ");
scanf("%d", &b);
if (b < 0)
printf("Broj je negativan\n");
else if (b == 0)
printf("Broj je nula\n");
else
printf("Broj je pozitivan\n");
}
Ulaz:
Unesi ceo broj:-5
Izlaz:
Broj je negativan
Ulaz:
Unesi ceo broj:5
Izlaz:
Broj je pozitivan
main()
{
int b;
printf("Unesi ceo broj : ");
scanf("%d", &b);
16
1.10 Kontrola toka — if, while, do - while, for 17
Ulaz:
Unesi ceo broj:-5
Izlaz:
Broj je pozitivan
1.10.3 while
while(uslov) { ... }
Uslov u zagradi se testira i ako je ispunjen telo petlje se izvrsava.
Zatim se uslov ponovo testira i ako je ispunjen ponovo se izvrsava
telo petlje. I tako sve dok uslov ne bude ispunjen. Tada se izlazi iz
petlje i nastavlja sa prvom sledecom naredbom u programu.
Ukoliko iza while sledi samo jedna naredba nema potrebe za
zagradama.
while (i<j)
i=2*i;
1.10.4 do-while
Ovo je slično paskalskom repeat-until izrazu.
do iskaz while (izraz)
main()
{
int x;
x = 1;
do
{
printf("x = %d\n",x);
x++; /* x++ je isto kao i x=x+1 */
} while (x<=10);
}
1.10.5 for
Primer 1.10.5 Program ilustruje petlju - for.
17
18 Milena Vujošević–Janičić
#include <stdio.h>
main()
{
int x;
}
Izlaz:
1
2
3
4
1.11 Switch
switch (iskaz) {
case konstantan_izraz1: iskazi1
case konstantan_izraz2: iskazi2
...
default: iskazi
}
main() {
char x;
scanf("%c",&x);
switch (x)
{
case ’a’:
case ’e’:
case ’i’:
case ’o’:
case ’u’: printf(" x je samoglasnik");
18
1.12 Uslovni izraz 19
break;
case ’r’: printf(" x je r");
break;
default: printf(" x je suglasnik");
}
}
Primer 1.11.2 Ilustracija switch konstrukcije.
#include<stdio.h>
main()
{
int n;
printf("Unesi paran broj manji od 10\n");
scanf("%d",&n);
switch(n) {
case 0:
printf("Uneli ste nulu\n");
break;
case 2:
printf("Uneli ste dvojku\n");
break;
case 4:
printf("Uneli ste cetvorku\n");
break;
case 6:
printf("Uneli ste sesticu\n");
break;
case 8:
printf("Uneli ste osmicu\n");
break;
defalut:
printf("Uneli ste nesto sto nije paran broj\n");
}
}
Ulaz:
Unesi paran broj manji od 10
2
Izlaz:
Uneli ste dvojku
19
20 Milena Vujošević–Janičić
z = (a<b)? a : b; /*z=min(a,b)*/
max = (a>b)? a : b;
#define POCETAK 0
#define KRAJ 20
#define KORAK 10
main()
{
int a;
a = POCETAK;
while (a <= KRAJ)
{
printf("%d cm = %f in\n", a, a/2.54);
a += KORAK; /* isto sto i a = a + KORAK; */
}
}
Izlaz:
0 cm = 0.000000 in
10 cm = 3.937008 in
20 cm = 7.874016 in
main()
20
1.14 Enumeracija 21
{
int a;
for (a = POCETAK; a <= KRAJ; a += KORAK)
printf("%d cm = %f in\n", a, a/2.54);
}
Izlaz:
0 cm = 0.000000 in
10 cm = 3.937008 in
20 cm = 7.874016 in
1.14 Enumeracija
Izvesna alternativa za define
enum boolean {NO, YES};
enum meseci {JAN = 1, FEB, MAR, APR, MAJ, JUN,
JUL, AVG, SEP, OKT, NOV, DEC}
enum boje {CRVENA, ZELENA=5, PLAVA,
LJUBICASTA=10, ZUTA, CRNA}
koriscenje:
int x=0;
boje b;
b=ZELENA;
x=b+CRNA; /* 5 + 12=17*/
21
22 Milena Vujošević–Janičić
1.15 Funkcije
Primer 1.15.1 sum - najjednostavnija funkcija koja sabira dva broja
/* Definicija funkcije */
int sum(int a, int b)
{
int c;
c = a + b;
return c;
/* Ovo je krace moglo da bude napisano
kao return a+b; */
}
main()
{
int c;
/* Poziv funkcije */
c = sum(3,5);
printf("%d\n", c);
main()
{
/* Poziv funkcije */
printf("%d\n", zbir(3,5));
}
/* Definicija funkcije */
int zbir(int a, int b)
{
return a+b;
}
22
1.15 Funkcije 23
return rezultat;
}
if (negativan)
k = -k;
main()
{
/* Poziv funkcije */
float s = power(2.0,8);
printf("%f\n", s);
}
23
24 Milena Vujošević–Janičić
#include <stdio.h>
main()
{
/* Funkcija izracunaj() ce biti pozvana
samo za parne vrednosti a */
int a;
for (a = 0; a < 10; a++)
if (a%2 == 0 && izracunaj())
printf("Uslov ispunjen : a = %d, b = %d\n", a, b);
else
printf("Uslov nije ispunjen : a = %d, b = %d\n", a, b);
printf("----------------------------\n");
24
1.16 Nizovi 25
1.16 Nizovi
Deklaracija niza:
int niz[5]; /* niz od 5 elemenata tipa int*/
Pristupanje elementima niza:
niz[0] = 4;
niz[1] = 2 * niz[0]; /*niz[1] = 8*/
niz[2] = niz[0] * niz[1]; /*niz[2] = 32*/
niz[3] = 5;
niz[4] = 7;
Unos vrednosti elemenata niza sa tastature:
for(i=0; i<5; i++)
scanf("%d", &a[i]);
Stampanje elemenata niza
for(i=0; i<5; i++)
printf("%d ", a[i]);
Brojanje elemenata niza je od nule!
Pristupanje elementu niza, indeks može da bude proizvoljan izraz
celobrojne vrednosti: niz[i*2]=5.
Primer 1.16.1 Program ilustruje korišćenje nizova. Ispisuje 10
unetih brojeva unazad.
#include <stdio.h>
main()
{
int a[10];
int i;
for (i = 0; i<10; i++)
{
printf("a[%d]=",i);
scanf("%d",&a[i]);
}
printf("Unazad : \n");
25
26 Milena Vujošević–Janičić
/* Pronalazimo maksimum */
max = a[0];
for (i = 1; i < BR_ELEM; i++)
if (a[i]>max)
max = a[i];
/* Ispisujemo maksimum */
printf("Max = %d\n",max);
}
main()
{
int a, max, i;
scanf("%d",&a);
max = a;
for (i = 1; i < BR_ELEM; i++)
{
scanf("%d",&a);
if (a>max)
max = a;
}
26
1.17 Konstante 27
1.17 Konstante
Koji su tipovi konstanti?
Celobrojna konstanta 1234 je tipa int.
Da bi konstanta bila long navodi se iza nje slovo L ili l, npr 123456789L.
Ako želimo da nam je konstanta unsigned onda na kraju pišemo U
ili u.
Može i 1234567ul.
dvostrukih navodnika!
Posebni znaci su znak za kraj reda, tab i slično.
Znakovna konstanta ’\0’ predstavlja znak čija je vrednost nula,
treba ga razlikovati od ’0’ koja je znak čija je vrednost 48.
Konstantna niska: ”Ja sam niska”
ili
”” /*prazna niska*/
Navodnici nisu deo niske već se koriste da bi je ograničili. Ako ih
želimo unutar niske, oni se navode sa \".
Konstantna niska je polje znakova. Da bi se znalo gde je kraj
niske, fizičko memorisanje liste zahteva da postoji jedan znak više
koji označava kraj, to je ’\0’. Da bi se odredila dužina niske mora
se proći kroz celu nisku.
!!!Važno:
27
28 Milena Vujošević–Janičić
int main()
{
printf("Duzina ove niske
je: %d \n",strlen("Duzina ove niske je:"));
return 0;
}
1.18 Konverzija
1.18.1 Automatska konverzija
Ako je jedan od operanada razližličit vrši se konverzija, uvek u smeru
manjeg ka većem tipu
Naredba dodele:
int i=5;
float f=2.3;
f=i; /* f ce imati vrednost 5.0*/
obrnuto:
int i=5;
float f=2.3;
i=f; /* i ce imati vrednost 2*/
float x;
x=2.3+4.2; /* x ce imati vrednost 6.5 */
x=(int)2.3+(int)4.2; /* x ce imati vrednost 6 */
28
1.18 Konverzija 29
29
30 Milena Vujošević–Janičić
main()
{
char c;
printf("Unesi neko veliko slovo:\n");
scanf("%c", &c);
printf("Odgovarajuce malo slovo je %c\n", lower(c));
}
main()
{
int n;
n = atoi("234");
printf("\nN je : %d\n",n);
}
30
1.20 Znakovni ulaz i izlaz 31
#include<stdio.h>
main()
{
int i;
float f;
int n[10];
printf("sizeof(int)=%d\n", sizeof(int));
printf("sizeof(long)=%d\n", sizeof(long));
printf("sizeof(short)=%d\n", sizeof(short));
printf("sizeof(signed)=%d\n", sizeof(signed));
printf("sizeof(unsigned)=%d\n", sizeof(unsigned));
printf("sizeof(char)=%d\n", sizeof(char));
printf("sizeof(float)=%d\n", sizeof(float));
printf("sizeof(double)=%d\n", sizeof(double));
printf("sizeof(i)=%d\n", sizeof(i));
printf("sizeof(f)=%d\n", sizeof(f));
printf("sizeof(n)=%d\n", sizeof(n));
printf("Broj elemenata niza n : %d\n", sizeof(n)/sizeof(int));
31
32 Milena Vujošević–Janičić
main()
{
int c; /* Karakter - obratiti paznju na int */
c = getchar(); /* cita karakter sa standardnog ulaza */
putchar(c); /* pise karakter c na standardni izlaz */
32
1.20 Znakovni ulaz i izlaz 33
main()
{
/*Koristi se int a ne char zato sto zelimo
da razlikujemo kraj ulaza od vazecih znakova*/
int c;
main()
{
int c;
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
/* %ld odnosi se na tip long. */
33
34 Milena Vujošević–Janičić
printf("%ld\n", nc);
}
main()
{
double nc;
34
1.20 Znakovni ulaz i izlaz 35
Primer 1.20.8 Program prepisuje ulaz na izlaz pri čemu više blanko
znakova zamenjuje jednim.
#include <stdio.h>
main()
{
int znak; /*tekuci znak sa ulaza*/
int preth; /*znak koji prethodi tekucem */
preth=’a’; /* inicijalizujemo vrednost prethodnog
da bi prvi prolazak kroz petlju bio ispravan*/
while ( (znak=getchar() ) !=EOF)
{
if (znak !=’ ’ || preth != ’ ’) putchar(znak);
preth=znak;
}
}
main()
{
int c;
int br_cifara = 0;
while ((c = getchar()) != EOF)
if (’0’<=c && c<=’9’)
br_cifara++;
35
36 Milena Vujošević–Janičić
main()
{
int c;
int br_0=0, br_1=0, br_2=0;
1.21 Nizovi
Primer 1.21.1 Program ilustruje inicijalizaciju nizova.
#include <stdio.h>
main()
{
/* Niz inicijalizujemo tako sto mu navodimo vrednosti
36
1.21 Nizovi 37
/* Ispisujemo nizove */
int i;
for (i = 0; i < a_br_elem; i++)
printf("a[%d]=%d\n",i, a[i]);
}
Primer 1.21.2 Program uvodi niske karaktera terminisane nulom.
#include <stdio.h>
main()
{
/* Poslednji bajt niske karaktera se postavlja na ’\0’ tj. 0 */
char s[] = {’a’, ’b’, ’c’, ’\0’ };
37
38 Milena Vujošević–Janičić
main()
{
/* Niz brojaca za svaku od cifara */
int br_cifara[10];
int i, c;
/* Resetovanje brojaca */
for (i = 0; i < 10; i++)
br_cifara[i] = 0;
/* Ispis rezultata */
for (i = 0; i < 10; i++)
printf("Cifra %d se pojavila %d put%s\n",
i, br_cifara[i], br_cifara[i] == 1 ? "" : "a");
}
Primer 1.21.4 Brojanje reči
#include <stdio.h>
38
1.22 Dvostruka for petlja 39
main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == ’\n’)
++nl;
/*Operator || znaci OR*/
if (c == ’ ’ || c == ’\n’ || c == ’\t’)
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}
39
40 Milena Vujošević–Janičić
{
for(j=1; j<=10; j++)
printf("%d * %d = %d\t", i, j, i*j);
printf("\n");
}
}
40
1.23 Formiranje HTML dokumenta 41
#include <stdio.h>
main()
{
int i;
printf("<HTML><head><title>Engleski alfabet</title><head>\n");
printf("<body><ul>");
for(i=0;i<=25;i++)
printf("<li> %c %c \n",’A’+i,’a’+i);
printf("</ul></body></HTML>\n"); }
Primer 1.23.3 Napisati program koji generise html dokument koji
prikazuje tablicu mnozenja za brojeve od 1 do 10.
#include<stdio.h>
main()
{
int i,j;
printf("<html><head><title>Mnozenje</title></head>");
printf("<body><h3 align=center> Rezultat </h3>");
printf("<table border=1>\n");
printf("</tr>");
}
printf("</table>");
printf("</body></html>");
}
41
42 Milena Vujošević–Janičić
int prost(int p)
{
int i, koren, ind;
koren=sqrt(p);
ind=(p%2) || (p==2);
i=3;
while (ind && i<=koren)
{
ind=p%i;
i+=2;
}
return ind;
}
main()
{
int k;
for(k=2;k<=100;k++)
if (prost(k)) printf("%d ",k);
}
Primer 1.24.2
#include <stdio.h> /* Ilustruje vidljivost imena*/
int i=10;
void main() {
{
int i=3;
{
int i=1;
printf("%d\n", i);
}
printf("%d\n",i);
}
42
1.24 Funkcije — prenos parametara po vrednosti 43
printf("%d\n",i);
}
main()
{
int x=3;
f(x);
printf("%d\n", x);
}
main()
{
/* Obavezno je alocirati memoriju za niz karaktera */
char s[100];
get_word(s);
printf("%s\n", s);
}
43
44 Milena Vujošević–Janičić
main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
44
1.25 Break i continue 45
main()
{
print_string("Zdravo\n");
}
iteraciju u petlji.
Primer 1.25.2
for(i=0; i<n; i++)
{
if (a[i]==0) continue;
... /* obradi pozitivne elemente nekako*/
}
45
46 Milena Vujošević–Janičić
return i;
}
main()
{
char s[] = "Zdravo svima";
string_reverse(s);
printf("%s\n", s);
}
/*
Izlaz:
amivs ovardZ
*/
Primer 1.26.2 strlen, strcpy, strcat, strcmp, strchr, strstr
- manipulacija niskama karaktera. Vezbe radi, implementirane su
funkcije biblioteke string.h
#include <stdio.h>
46
1.26 Rad sa niskama karaktera 47
47
48 Milena Vujošević–Janičić
48
1.26 Rad sa niskama karaktera 49
/* Nije nadjeno */
return -1;
/*
Koristeci string_length :
return -1;
*/
}
main()
{
49
50 Milena Vujošević–Janičić
char s[100];
char t[] = "Zdravo";
char u[] = " svima";
string_copy(s, t);
printf("%s\n", s);
string_concatenate(s, u);
printf("%s\n", s);
printf("%d\n",string_char("racunari", ’n’));
printf("%d\n",string_last_char("racunari", ’a’));
printf("%d\n",string_string("racunari", "rac"));
printf("%d\n",string_string("racunari", "ari"));
printf("%d\n",string_string("racunari", "cun"));
printf("%d\n",string_string("racunari", "cna"));
}
/*
Izlaz:
Zdravo
Zdravo svima
4
5
0
5
2
-1*/
1.27 Makroi
#define ime tekst_zamene
50
1.27 Makroi 51
main()
{
printf("sum(3,5) = %d\n", sum(3,5));
printf("square_w(5) = %d\n", square_w(5));
printf("square_w(3+2) = %d\n", square_w(3+2));
printf("square(3+2) = %d\n", square(3+2));
printf("min(1,2,3) = %d\n", min(1,2,3));
printf("min(1,3,2) = %d\n", min(1,3,2));
printf("min(2,1,3) = %d\n", min(2,1,3));
printf("min(2,3,1) = %d\n", min(2,3,1));
printf("min(3,1,2) = %d\n", min(3,1,2));
printf("min(3,2,1) = %d\n", min(3,2,1));
}
Izlaz iz programa:
sum(3,5) = 8
square_w(5) = 25
square_w(3+2) = 11
square(3+2) = 25
min(1,2,3) = 1
min(1,3,2) = 1
min(2,1,3) = 1
min(2,3,1) = 1
min(3,1,2) = 1
min(3,2,1) = 1
Primer 1.27.2
#define max(A, B) ((A)>(B) ? (A) : (B))
na osnovu ovoga će linija
x=max(p+q, r+s)
51
52 Milena Vujošević–Janičić
main()
{
int x=2,y=3;
52
1.28 Bitski operatori 53
/* x = 3, y = 5 */
swapint(x,y);
swap(int,x,y);
printf( "x = %d, y = %d\n", x, y );
/* x = 3, y = 5 */
}
Izlaz:
max1(x,y) = 3
max1(x=5,y) = 3
max1(x++,y++) = 4
x = 3, y = 5
x = 5, y = 3
x = 3, y = 5
main()
{ printf("%o %o\n",255,15);
printf( "255 & 15 = %d\n", 255 & 15 );
printf( "255 | 15 = %d\n", 255 | 15 );
printf( "255 ^ 15 = %d\n", 255 ^ 15 );
printf( "2 << 2 = %d\n", 2 << 2 );
printf( "16 >> 2 = %d\n", 16 >> 2 );
}
53
54 Milena Vujošević–Janičić
void print_bits(int x)
{
/* Broj bitova tipa unsigned */
int wl = sizeof(int)*8;
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
main()
{
print_bits(127);
print_bits(128);
print_bits(0x00FF00FF);
print_bits(0xFFFFFFFF);
54
1.28 Bitski operatori 55
Izlaz iz programa:
00000000000000000000000001111111
00000000000000000000000010000000
00000000111111110000000011111111
11111111111111111111111111111111
main()
{
int n,k;
printf("Unesite broj i poziciju tog broja koju zelite da proverite:\n");
scanf("%d%d",&n,&k);
if ((n & (1 << k))!=0)
printf("Bit je 1\n");
else
printf("Bit je 0\n");
}
void print_bits(int x)
{
/* Broj bitova tipa unsigned */
int wl = sizeof(int)*8;
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
55
56 Milena Vujošević–Janičić
main(){
int n,k;
printf("Unesite broj i poziciju tog broja koju zelite da promenite:\n")
scanf("%d%d",&n,&k);
printf("Binarno, une\v seni broj je\n");
print_bits(n);
printf("Novi broj je %d\n",(n |(1<<k)));
printf("Binarno, novi broj je\n");
print_bits((n |(1<<k)));
}
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
int sum_of_bits(unsigned x)
{
int br;
for (br = 0; x; x>>=1)
if (x&1)
br++;
return br;
56
1.28 Bitski operatori 57
main()
{
printf("Binarni zapis broja 127 je\n");
print_bits(127);
printf("Suma bitova broja 127 je %d\n",sum_of_bits(127));
printf("Binarni zapis broja 128 je\n");
print_bits(128);
printf("Suma bitova broja 128 je %d\n",sum_of_bits(128));
printf("Binarni zapis broja 0x00FF00FF je\n");
print_bits(0x00FF00FF);
printf("Suma bitova broja 0x00FF00FF je %d\n",sum_of_bits(0x00FF00FF));
printf("Binarni zapis broja 0xFFFFFFFF je\n");
print_bits(0xFFFFFFFF);
printf("Suma bitova broja 0xFFFFFFFF je %d\n",sum_of_bits(0xFFFFFFFF));
}
Izlaz iz programa:
Binarni zapis broja 127 je
00000000000000000000000001111111
Suma bitova broja 127 je 7
Binarni zapis broja 128 je
00000000000000000000000010000000
Suma bitova broja 128 je 1
Binarni zapis broja 0x00FF00FF je
00000000111111110000000011111111
Suma bitova broja 0x00FF00FF je 16
Binarni zapis broja 0xFFFFFFFF je
11111111111111111111111111111111
Suma bitova broja 0xFFFFFFFF je 32
Primer 1.28.6 get bits, set bits, invert bits - izdvajanje, postavl-
janje i invertovanje pojedinacnih bitova
#include <stdio.h>
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
57
58 Milena Vujošević–Janičić
putchar(’\n’);
}
58
1.28 Bitski operatori 59
main()
{
unsigned x = 0x0AA0AFA0;
print_bits(x);
Izlaz iz programa:
00001010101000001010111110100000
00000000000000000000000010101111
00001010101000001111111110100000
00001010101000000101000010100000
Primer 1.28.7 right rotate bits, mirror bits - rotiranje i simetrija
bitova.
#include <stdio.h>
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
59
60 Milena Vujošević–Janičić
x |= last_bit<<wl-1;
}
return x;
}
60
1.29 Linearna i binarna pretraga 61
y |= x & 1;
}
return y;
}
main()
{
unsigned x = 0xFAF0FAF0;
print_bits(x);
print_bits(mirror(x));
print_bits(right_rotate(x, 2));
}
Izlaz iz programa:
11111010111100001111101011110000
00001111010111110000111101011111
00111110101111000011111010111100
return -1;
}
main()
{
61
62 Milena Vujošević–Janičić
62
1.30 Razni zadaci 63
/* Element je nadjen */
return -1;
}
main()
{
int a[] = {3, 5, 7, 9, 11, 13, 15};
int x;
int i;
if (i==-1)
printf("Elementa %d nema\n", x);
else
printf("Pronadjen na poziciji %d\n", i);
}
63
64 Milena Vujošević–Janičić
#include <stdio.h>
#include <string.h>
main()
{
int n=-44;
char nst[100];
itoa(n,nst);
printf("%s\n",nst);
}
64
1.30 Razni zadaci 65
#include <stdio.h>
#include <ctype.h>
Npr.
cifra ’B’ u osnovi 16 ima vrednost 11
cifra ’8’ nije validna u osnovi 6
*/
return -1;
}
return sum;
65
66 Milena Vujošević–Janičić
main()
{
char bin[] = "11110000";
char hex[] = "FF";
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
}
66
1.30 Razni zadaci 67
i = 0;
while ((to[i] = from[i]) != ’\0’)
++i;
}
i = 0;
while (--lim > 0 && (c=getchar()) != EOF && c != ’\n’)
s[i++] = c;
if (c == ’\n’)
s[i++] = c;
s[i] = ’\0’;
return i;
}
67
68 Milena Vujošević–Janičić
{
double val, power;
int i, sign;
if (s[i] == ’.’)
i++;
sum = 0;
while (getline(line, MAXLINE) > 0)
printf("\t%g\n", sum += atof(line));
}
68
1.30 Razni zadaci 69
#include <stdio.h>
main()
{
char niz[20];
char c;
printf("Unesi karakter\n\n");
scanf("%c", &c);
scanf("%s", niz);
squeeze(niz, c);
printf("%s\n", niz);
}
69
Osnovi programiranja
Programski jezik C
— Zadaci sa vežbi, drugi semestar —
2
Sadržaj
1 Programski jezik C 7
1.1 Sortiranje . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 Rekurzija . . . . . . . . . . . . . . . . . . . . . . . . 18
1.3 Životni vek i oblast važenja promenjivih, statičke promenljive 21
1.4 Pokazivači . . . . . . . . . . . . . . . . . . . . . . . . 24
1.5 Pokazivači i argumenti funkcija . . . . . . . . . . . . 26
1.6 Pokazivači i nizovi (polja) . . . . . . . . . . . . . . . 28
1.7 Alokacija memorije . . . . . . . . . . . . . . . . . . . 35
1.8 Niz pokazivača . . . . . . . . . . . . . . . . . . . . . 37
1.9 Pokazivači na funkcije . . . . . . . . . . . . . . . . . 39
1.10 Matrice . . . . . . . . . . . . . . . . . . . . . . . . . 40
1.11 Strukture . . . . . . . . . . . . . . . . . . . . . . . . 47
1.11.1 Operator typedef . . . . . . . . . . . . . . . . 50
1.12 qsort . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
1.13 Sortiranje — generička funkcija . . . . . . . . . . . . 59
1.14 qSort funkcija iz standardne biblioteke . . . . . . . . 66
1.15 Generičko sortiranje reči . . . . . . . . . . . . . . . . 68
1.16 Argumenti komandne linije . . . . . . . . . . . . . . . 71
1.17 Datoteke . . . . . . . . . . . . . . . . . . . . . . . . . 72
1.18 Liste . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
1.18.1 Red . . . . . . . . . . . . . . . . . . . . . . . 78
1.18.2 Kružna lista . . . . . . . . . . . . . . . . . . . 86
1.18.3 Stek . . . . . . . . . . . . . . . . . . . . . . . 87
1.18.4 Dvostruko povezane liste . . . . . . . . . . . . 92
1.19 Drvo . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
1.20 Grafovi . . . . . . . . . . . . . . . . . . . . . . . . . . 112
1.21 Razno . . . . . . . . . . . . . . . . . . . . . . . . . . 117
3
4 SADRŽAJ
4
Predgovor
Milena Vujošević-Janičić
www.matf.bg.ac.yu/~milena
5
6 SADRŽAJ
6
Glava 1
Programski jezik C
1.1 Sortiranje
Primer 1.1.1 U prvom prolazu se razmenjuju vrednosti a[0] sa onim
članovima ostatka niza koji su veći od njega. Na taj način će se posle
prvog prolaza kroz niz a[0] postaviti na najveći element niza.
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Niz od maksimalno MAXDUZ elemenata*/
int a[MAXDUZ];
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
exit(1);
}
7
8 Milena Vujošević–Janičić
scanf("%d",&a[i]);
}
/*Sortiranje*/
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(a[i]<a[j])
{
pom=a[i];
a[i]=a[j];
a[j]=pom;
}
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
putchar(’\n’);
return 0;
}
Primer 1.1.2 sort2
Modifikacija prethodnog rešenja radi dobijanja na efikasnosti. Ne
vrše se zamene svaki put već samo jednom, kada se prona e odgo-
int main()
{
8
1.1 Sortiranje 9
scanf("%d",&n);
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
exit(1);
}
return 0;
9
10 Milena Vujošević–Janičić
svih susednih parova najmanji od njih će isplivati na kraj niza. Zbog
toga se ovaj metod naziva metod mehurića. Da bi se najmanji broj
nesortiranog dela niza doveo na svoje mesto treba ponoviti postupak.
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Dimenzija niza, pomocna promenljiva
i brojacke promenljive */
int n,pom,i,j;
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
exit(1);
}
/*Sortiranje */
for(i=n-1; i>0; i--)
for(j=0; j<i; j++)
if(a[j]<a[j+1])
{
pom=a[j];
a[j]=a[j+1];
a[j+1]=pom;
10
1.1 Sortiranje 11
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
}
Primer 1.1.4 bbsort2
Unapredjujemo prethodni algoritam kako bismo obezbedli da se ne
vrše provere onda kada je niz već sortiran nego da se u tom slučaju
prekine rad.
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Dimenzija niza, pomocna promenljiva
i brojacke promenljive */
int n,pom,i,j;
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
11
12 Milena Vujošević–Janičić
exit(1);
}
/*Sortiranje */
for(zam=1,i=n-1; zam && i>0; i--)
for(zam=0,j=0; j<i; j++)
if(a[j]<a[j+1])
{
/* Zamena odgovarajucih clanova niza */
pom=a[j];
a[j]=a[j+1];
a[j+1]=pom;
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
return 0;
}
Primer 1.1.5 isort
Insert sort, u svakom trenutku je početak niza sortiran a sortiranje
se vrši tako što se jedan po jedan element niza sa kraja ubacuje na
odgovarajuće mesto.
#include<stdio.h>
#define MAXDUZ 100
12
1.1 Sortiranje 13
int main()
{
/* Dimenzija niza, pomocna
i brojacke promenljive */
int n,pom,i,j;
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n!\n");
exit(1);
}
/*Sortiranje*/
for(i=1; i<n; i++)
for(j=i; (j>0) && (a[j]>a[j-1]); j--)
{
pom=a[j];
a[j]=a[j-1];
a[j-1]=pom;
}
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
putchar(’\n’);
return 0;
}
13
14 Milena Vujošević–Janičić
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Dimenzija niza,pomocna i brojacke
promenljive */
int n,pom,i,j;
/*Sortiranje*/
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(a[i]>a[j])
{
pom=a[i];
a[i]=a[j];
a[j]=pom;
}
/* Unos elementa binarne pretrage */
printf("Unesite element koji se trazi\n");
scanf("%d",&x);
14
1.1 Sortiranje 15
donji = 0;
gornji = n-1;
pozicija = -1;
while(donji<=gornji)
{
srednji = (donji + gornji)/2;
if(a[srednji] == x)
{
pozicija = srednji;
break;
}
else
if(a[srednji] < x)
donji = srednji + 1;
else
gornji = srednji -1;
}
/* Ispis rezultata */
if(pozicija == -1)
printf("Trazeni broj se ne nalazi u nizu!\n");
else
printf("Broj %d se nalazi na %d poziciji
sortiranog niza! \n",x,pozicija+1);
putchar(’\n’);
return 0;
}
Primer 1.1.7 Sabiranje dva velika broja, njihovo pore enje, unos i
#include<stdio.h>
#define MAXDUZ 1000
15
16 Milena Vujošević–Janičić
c=getchar();
while ( brcifara < maxduz && c >= ’0’ && c <= ’9’)
{
cifre[brcifara++]=c-’0’;
c=getchar();
}
return brcifara;
}
16
1.1 Sortiranje 17
return 0;
}
cifre[i] = pom%10;
pamtim = pom/10;
}
if (pamtim)
{
cifre[i]=pamtim;
brcifara=i+1;
}
else brcifara=i;
17
18 Milena Vujošević–Janičić
return brcifara;
}
return pbrcifara;
}
int main()
{
int d1,d2,d;
int broj1[MAXDUZ], broj2[MAXDUZ], zbir[MAXDUZ];
d1=unos_broja(broj1,MAXDUZ);
d2=unos_broja(broj2,MAXDUZ);
obrni(broj1,d1);
obrni(broj2,d2);
d=saberi(broj1,d1,broj2,d2,zbir);
ispisi(zbir,d);
return 0;
}
1.2 Rekurzija
C funkcije se mogu rekurzivno koristiti, što znači da funkcija može
pozvati samu sebe direktno ili indirektno.
18
1.2 Rekurzija 19
int main()
{
long int b=-1234;
printb(b);
putchar(’\n’);
return 0;
}
Kad funkcija rekurzivno pozove sebe, svakim pozivom pojavljuje
se novi skup svih automatskih promenljivih, koji je nezavisan od
prethodonog skupa. Prva funkcija printb kao argument dobija broj
-12345, ona prenosi 1234 u drugu printb funkciju, koja dalje prenosi
123 u treću, i tako redom do poslednje koja prima 1 kao argument.
Ta funkcija štampa 1 i završava sa radom tako da se vraća na
prethodni nivo, na kome se štampa dva i tako redom.
Primer 1.2.2 Računanje sume prvih n prirodnih brojeva.
#include<stdio.h>
int suma(int n)
{
if(n!=0)
return( n + suma(n-1) );
else return n;
}
main()
{
int S,n;
printf("Unesite n\n");
19
20 Milena Vujošević–Janičić
scanf("%d",&n);
S=suma(n);
printf("S=%d",S);
putchar(’\n’);
}
main()
{
int n;
unsigned long f;
printf("Unesite n\n");
scanf("%d",&n);
f=fakt(n);
printf("f=%d",f);
putchar(’\n’);
}
int main()
{
int Fn,n;
printf("Unesite n\n");
scanf("%d",&n);
Fn=fibr(n);
printf("F[%d]=%d",n,Fn);
20
1.3 Životni vek i oblast važenja promenjivih, statičke promenljive 21
putchar(’\n’);
return 0;
}
#include <stdio.h>
/* Globalna promenjiva */
int a = 0;
21
22 Milena Vujošević–Janičić
void nonstatic_var()
{
/* Nestaticke promenjive ne cuvaju vrednosti kroz pozive funkcije */
int s=0;
s++;
printf("nonstatic::s=%d\n",s);
}
void static_var()
{
/* Staticke promenjive cuvaju vrednosti kroz pozive funkcije.
Inicijalizacija se odvija samo u okviru prvog poziva. */
static int s=0;
s++;
printf("static::s=%d\n",s);
}
main()
{
/* Promenjive lokalne za funkciju main */
int i;
int x = 3;
22
1.3 Životni vek i oblast važenja promenjivih, statičke promenljive 23
increase();
decrease();
/* Globalna promenjiva a */
printf("main::a = %d\n", a);
Izlaz iz programa:
main::x = 3
for::x = 5
for::x = 5
for::x = 5
main::x = 3
increase::a = 1
decrease::a = -1
main::a = 1
nonstatic::s=1
nonstatic::s=1
nonstatic::s=1
static::s=1
static::s=2
static::s=3
23
24 Milena Vujošević–Janičić
void f()
{
static int a;
a++;
printf("%d\n",a);
}
main()
{
int i;
for (i=0; i<=10; i++)
f();
}
1.4 Pokazivači
Pokazivač je promenljiva koja sadrži adresu promenljive.
24
1.4 Pokazivači 25
{
int x = 3;
px = &x;
printf("Vrednost promenljive px je (tj. px) : %p\n", px);
printf("Vrednost promenljive na koju ukazuje px (tj. *px) je : %d\n", *px);
25
26 Milena Vujošević–Janičić
main()
{
void *pp;
int x=2;
char c=’a’;
pp = &x;
*(int *)pp = 17; /* x postaje 17*/
printf("\n adresa od x je %p", &x);
printf("\n%d i %p",*(int*)pp,(int * )pp);
pp = &c;
printf("\n adresa od c je %p", &c);
printf("\n%c i %p",*(char*)pp,(char * )pp);
/*
adresa od x je 0012FF78
17 i 0012FF78
adresa od c je 0012FF74
a i 0012FF74
*/
Posebna konstanta koja se koristi da se označi da pokazivač ne
pokazuje na neko mesto u memoriji je NULL.
26
1.5 Pokazivači i argumenti funkcija 27
main()
{
int div, mod;
printf("Adresa promenljive div je %p\n", &div);
printf("Adresa promenljive mod je %p\n", &mod);
27
28 Milena Vujošević–Janičić
#include <stdio.h>
28
1.6 Pokazivači i nizovi (polja) 29
main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int num_of_elements = sizeof(a)/sizeof(int);
int* pa;
29
30 Milena Vujošević–Janičić
/* 1 2 3 4 5 6 7 8 9 10 */
}
poruka je niz znakova koji sadrži dati tekst. Pojedine znake moguće
je promeniti ali se poruka uvek odnosi na isto mesto u memoriji.
pporuka je pokazivač, koji je inicijalizovan da pokazuje na kon-
stantnu nisku, on može biti preusmeren da pokazuje na nešto drugo,
ali rezultat neće biti definisan ako pokušate da modifikujete sadržaj
niske (jer je to konstantna niska).
Ako deklarišemo
30
1.6 Pokazivači i nizovi (polja) 31
#include <stdio.h>
main()
{
int a[]={1,2,3,4,5,6,7,8};
int* poz=nadjiint(a,sizeof(a)/sizeof(int),4);
if (poz!=NULL)
printf("Element pronadjen na poziciji %d\n",poz-a);
}
Primer 1.6.3
int strlen(char *s)
{
int n;
for(n=0; *s != ’\0’; s++) n++;
return n;
}
Primer 1.6.4
/* Funkcija kopira string t u string s */
void copy(char* s, char* t)
{
while (*s++=*t++)
;
}
31
32 Milena Vujošević–Janičić
s++;
t++;
}
*s = ’\0’;
*/
Primer 1.6.5
/* Vrsi leksikografsko poredjenje dva stringa.
Vraca :
0 - ukoliko su stringovi jednaki
<0 - ukoliko je s leksikografski ispred t
>0 - ukoliko je s leksikografski iza t
*/
int string_compare1(char *s, char *t)
{
/* Petlja tece sve dok ne naidjemo
na prvi razliciti karakter */
for (; *s == *t; s++, t++)
if (*s == ’\0’) /* Naisli smo na kraj
oba stringa, a nismo nasli razliku */
return 0;
return *s - *t;
}
32
1.6 Pokazivači i nizovi (polja) 33
/* Nije nadjeno */
return NULL;
}
/* Nije nadjeno */
return NULL;
}
Primer 1.6.8
#include <stdio.h>
33
34 Milena Vujošević–Janičić
return -1;
}
if (c==’\n’)
*s++ = c;
*s = ’\0’;
return s - line;
}
main()
{
char rec[]="zdravo";
char linija[100];
while (getline(linija, 100))
if (sadrzi_string_pok(linija, rec))
printf("%s",linija);
34
1.7 Alokacija memorije 35
main()
{
int n;
int i;
int *a;
35
36 Milena Vujošević–Janičić
/* Oslobadjamo memoriju*/
free(a);
}
#include <stdio.h>
#include <stdlib.h>
main()
{
int *m, *c, i, n;
free(m);
free(c);
}
36
1.8 Niz pokazivača 37
37
38 Milena Vujošević–Janičić
printf("%d", nizip[1][1]);
*(nizip[2]) = 2;
printf("%d", *(nizip[2]));
free(nizip[0]);
free(nizip[1]);
free(nizip[2]);
}
Primer 1.8.2
#include <stdio.h>
#include <stdlib.h>
main()
{
/* Niz karaktera*/
char nizc[5];
printf("%s", nizcp[0]);
printf("%s", nizcp[1]);
printf("%s", nizcp[2]);
}
38
1.9 Pokazivači na funkcije 39
#include <stdio.h>
int kvadrat(int n)
{
return n*n;
}
int kub(int n)
{
return n*n*n;
}
int parni_broj(int n)
{
return 2*n;
}
return suma;
}
main()
{
printf("Suma kvadrata brojeva od jedan do 3 je %d\n", sumiraj(kvadrat,3));
printf("Suma kubova brojeva od jedan do 3 je %d\n", sumiraj(kub,3));
printf("Suma prvih pet parnih brojeva je %d\n", sumiraj(parni_broj,5));
}
/*Izlaz:
Suma kvadrata brojeva od jedan do 3 je 14
Suma kubova brojeva od jedan do 3 je 36
Suma prvih pet parnih brojeva je 30
*/
39
40 Milena Vujošević–Janičić
1.10 Matrice
Primer 1.10.1 Statička alokacija prostora za matricu.
#include <stdio.h>
main()
{
int a[3][3] = {{0, 1, 2}, {10, 11, 12}, {20, 21, 22}};
int i, j;
printf("%d\n", a[1][1]); /* 22 */
40
1.10 Matrice 41
main()
{
/* Dimenzije matrice */
int m, n;
/* Matrica */
int *a;
int i,j;
/* Unos i alokacija */
printf("Unesi broj vrsta matrice : ");
scanf("%d",&m);
a=malloc(m*n*sizeof(int));
if (a == NULL) {
printf("Greska prilikom alokacije memorije!\n");
exit(1);
}
41
42 Milena Vujošević–Janičić
/* Oslobadjamo memoriju */
free(a);
}
Primer 1.10.3 Program ilustruje rad sa kvadratnim matricama i
relacijama. Elementi i je u relaciji sa elementom j ako je m[i][j] =
1, a nisu u relaciji ako je m[i][j] = 0.
#include <stdlib.h>
#include <stdio.h>
42
1.10 Matrice 43
free(m);
exit(1);
}
}
return m;
}
/* Ispis matrice /
void ispisi_matricu(int** m, int n)
{
int i, j;
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
printf("%d ",m[i][j]);
printf("\n");
}
}
return 1;
}
43
44 Milena Vujošević–Janičić
int i,j;
for (i=0; i<n; i++)
for (j=i+1; j<n; j++)
if (m[i][j]!=m[j][i])
return 0;
return 1;
}
main()
{
int **m;
int n;
int i,j;
44
1.10 Matrice 45
ispisi_matricu(m,n);
if (refleksivna(m,n))
printf("Relacija je refleksivna\n");
if (simetricna(m,n))
printf("Relacija je simetricna\n");
if (tranzitivna(m,n))
printf("Relacija je tranzitivna\n");
simetricno_zatvorenje(m,n);
ispisi_matricu(m,n);
obrisi(m,n);
}
Primer 1.10.4 Izračunati vrednost determinante matrice preko Laplasovog
razvoja.
#include <stdio.h>
#include <stdlib.h>
45
46 Milena Vujošević–Janičić
{
m[i]=malloc(n*sizeof(int));
if (m[i] == NULL)
{
int k;
for(k=0;k<i;k++)
free(m[k]);
printf("Greska prilikom alokacije memorije!\n");
free(m);
exit(1);
}
}
return m;
}
46
1.11 Strukture 47
det+= znak*matrica[0][i]*determinanta(podmatrica,n-1);
znak*=-1;
}
deallocate(podmatrica,n-1);
return det;
}
main()
{
int **matrica;
int n;
scanf("%d", &n);
matrica = allocate(n);
ucitaj_matricu(matrica, n);
printf("Determinanta je : %d\n",determinanta(matrica,n));
deallocate(matrica, n);
}
1.11 Strukture
Informacije kojima se opisuje realni svet retko se predstavljaju u
elementarnoj formi u vidu celih, realnih, znakovnih konstanti itd.
Mnogo češće imamo posla sa složenim objektima koji se sastoje od
elemenata raznih tipova. Na primer jednu osobu karakterišu ime,
prezime, datum i mesto ro enja.
Struktura predstavlja skup podataka kojim se opisuju neka bitna
svojstva objekta. Komponente koje obrazuju strukturu nazivaju se
47
48 Milena Vujošević–Janičić
elementi strukture.
Sintaksa strukture:
struct ime_strukture
{
tip ime_elementa1;
tip ime_elementa2;
...
};
struct licnost
{
char ime[31];
char adresa[41];
unsigned starost;
};
struct licnost
{
char ime[31];
char adresa[41];
unsigned starost;
} osoba1, osoba2;
struct
{
char ime[31];
char adresa[41];
unsigned starost;
} osoba1, osoba2;
48
1.11 Strukture 49
Primer 1.11.2
osoba1.starost=20;
osoba2.starost=21;
...
if (osoba1.starost == osoba2.starost)
printf(" Osobe su iste starosti");
struct licnost
{
char ime[30];
struct datum datumrodjenja;
};
49
50 Milena Vujošević–Janičić
50
1.11 Strukture 51
/* Koordinatni pocetak */
tacka kp={0.0,0.0};
/* Niz tacaka */
tacka niz[100];
void IspisiTacku(tacka A)
{
printf("(%f,%f)\n",A.x,A.y);
}
void IspisiVektor(vektor v)
{
printf("(%f,%f)\n",v.x,v.y);
}
51
52 Milena Vujošević–Janičić
float duzina(vektor v)
{
return sqrt(v.x*v.x+v.y*v.y);
}
/* Heronov obrazac */
float PovrsinaTrougla(tacka A, tacka B, tacka C)
{
float a=rastojanje(B,C);
float b=rastojanje(A,C);
float c=rastojanje(A,B);
float s=(a+b+c)/2.0;
return sqrt(s*(s-a)*(s-b)*(s-c));
}
return povrsina;
}
52
1.11 Strukture 53
{
int i;
float o=0;
o+=rastojanje(poligon[0], poligon[br_temena-1]);
return o;
}
main()
{
tacka poligon[]={{0.0,0.0},
{0.0,1.0},
{1.0,1.0},
{1.0,0.0}};
printf("Obim poligona je %f\n",Obim(poligon,4));
printf("Povrsina poligona je %f\n",
PovrsinaKonveksnogPoligona(poligon,4));
}
Primer 1.11.6 Program koji učitava niz studenata i sortira ih po
njihovim ocenama.
#include <stdio.h>
#include <ctype.h>
#define MAX_IME 20
while (isspace(c=getchar()))
53
54 Milena Vujošević–Janičić
word[i]=’\0’;
54
1.11 Strukture 55
main()
{
student studenti[100];
int br_studenata = UcitajPodatke(studenti,100);
SelectionSort(studenti, br_studenata);
IspisiPodatke(studenti, br_studenata);
}
Primer 1.11.7 Dinamički niz.
/* Program za svaku rec unetu sa standardnog
ulaza ispisuje broj pojavljivanja.
Verzija sa dinamickim nizom i realokacijom.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
55
56 Milena Vujošević–Janičić
while (isspace(c=getchar()))
;
word[i]=’\0’;
main()
{
char procitana_rec[80];
int i;
while (getword(procitana_rec,80)!=-1)
{
/* Proveravamo da li rec vec postoji u nizu */
for (i=0; i<duzina; i++)
/* Ako bismo uporedili procitana_rec == niz_reci[i].ime
bili bi uporedjeni pokazivaci a ne odgovarajuci sadrzaji!!!
Zato koristimo strcmp. */
if (strcmp(procitana_rec, niz_reci[i].ime)==0)
{
niz_reci[i].br_pojavljivanja++;
break;
}
56
1.11 Strukture 57
if (novi_niz == NULL)
{
free(niz_reci);
printf("Greska prilikom alokacije memorije");
exit(1);
}
57
58 Milena Vujošević–Janičić
duzina++;
}
}
free(niz_reci);
}
1.12 qsort
Primer 1.12.1 Implementacija funkcije qsort.
#include <stdio.h>
#include <string.h>
58
1.13 Sortiranje — generička funkcija 59
/* u v[left] */
swap(v, left, (left + right)/2);
last = left;
/* partition */
for (i = left + 1; i <= right; i++)
if (v[i] < v[left])
swap(v, ++last, i);
main()
{
int array[]={8, 3, 2, 6, 5, 7, 4, 9, 1};
int n=sizeof(array)/sizeof(int);
printarray(array, 0, n-1);
qsort(array, 0, n-1);
printarray(array, 0, n-1);
59
60 Milena Vujošević–Janičić
{
int i, j;
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(a[i]<a[j])
{
int pom=a[i];
a[i]=a[j];
a[j]=pom;
}
}
Razlike:
• prvi argument funkcije;
• pomoćna promenljiva;
• pore enje.
Sortiranje studenata po oceni ukoliko je data struktura student:
60
1.13 Sortiranje — generička funkcija 61
61
62 Milena Vujošević–Janičić
{
return st1.ocena - st2.ocena;
}
62
1.13 Sortiranje — generička funkcija 63
a[i]=a[j];
a[j]=pom;
}
}
Šta dalje? Kako da dobijemo jednu funkciju sortiranja bez obzira
na tip elemenata niza?
Teba da rešimo sledeće stvari:
• razmena mesta elemenata ne sme da zavisi od tipa elemenata
koji se razmenjuju.
• potpis funkcije pore enja ne sme da zavisi od tipa elemenata
koji se porede kako bi on bio jedinstven.
• prvi argument funkcije ne sme da zavisi od tipa elemenata niza.
Da bi smo razmenili dva elementa potrebna nam je pomoćna
promenljiva u kojoj privremeno čuvamo neku vrednost. Ako ne
znamo tip elementa onda ne možemo da napravimo pomoćnu promenljivu.
Ali zato mozemo da koristeći funkciju malloc odvojimo neko mesto
u memoriji za smestanje elementa koji nam u datoj situaciji treba.
Koliko je to mesto? Nekada 4 bajta, npr za int, a nekada dosta veće,
npr za studenta. Kako funkcija sortiranja zna koliko mesta treba da
odvoji? Znace tako sto ćemo joj tu veličinu proslediti kao argument.
Sada, dakle umesto pomoćne promenljive, imamo blok u memoriji,
a umesto naredbe dodele koristićemo funkciju memcpy koja kopira
deo memorije sa jednog mesta na drugo mesto.
Dakle, razmenu ćemo da radimo na sledeći način:
void* tmp = malloc(size);
if (tmp==NULL) {printf("Greska prilikom alokacije memorije!\n");exit(1);}
memcpy(tmp, adresa_itog, size);
memcpy(adresa_itog, adresa_jtog, size);
memcpy(adresa_jtog, tmp, size);
free(tmp);
Potpis funkcije pore enja ne sme da zavisi od tipa elemenata koji
se porede. To se može postići koristeći pokazivač na tip void.
Na primer, pore enje dva cela broja:
int poredi_br(void* a, void* b)
{
int br_a = *(int*)a;
int br_b = *(int*)b;
return br_a-br_b;
}
63
64 Milena Vujošević–Janičić
return student1.ocena-student2.ocena;
}
if (poredi(adresa_itog, adresa_jtog)<0)
{
void* tmp = malloc(size);
64
1.13 Sortiranje — generička funkcija 65
if (tmp==NULL) {
printf("Greska prilikom alokacije memorije!\n");
exit(1);
}
memcpy(tmp, adresa_itog, size);
memcpy(adresa_itog, adresa_jtog, size);
memcpy(adresa_jtog, tmp, size);
free(tmp);
}
}
}
return br_a-br_b;
}
main() {
int a[] = {8, 2, 1, 9, 3, 7, 6, 4, 5};
float b[] = {0.3, 2, 5, 5.8, 8}
int n = sizeof(a)/sizeof(int);
int nf = sizeof(b)/sizeof(float);
int i;
65
66 Milena Vujošević–Janičić
#include <stdlib.h>
#include <stdio.h>
return br_a-br_b;
*/
return *((int*)a)-*((int*)b);
}
main()
66
1.14 qSort funkcija iz standardne biblioteke 67
{
int i;
int niz[]={3,8,7,1,2,3,5,6,9};
float nizf[]={3.0,8.7,7.8,1.9,2.1,3.3,6.6,9.9};
int n=sizeof(niz)/sizeof(int);
qsort((void*)niz, n, sizeof(int), poredi);
for(i=0; i<n; i++)
printf("%d",niz[i]);
n=sizeof(nizf)/sizeof(float);
qsort((void*)nizf, n, sizeof(float), poredi_float);
for(i=0; i<n; i++)
printf("%f",nizf[i]);
}
Primer 1.14.2 Binarno pretraživanje - korišćenje ugra ene bsearch
funkcije.
main()
{
int x=-1;
int niz[]={1,2,3,4,5,6,7,8,9,10,11,12};
int* elem=(int*)bsearch((void*)&x,
(void*)niz,
sizeof(niz)/sizeof(int),
sizeof(int),
poredi);
if (elem==NULL)
printf("Element nije pronadjen\n");
else
printf("Element postoji na poziciji %d\n",elem-niz);
67
68 Milena Vujošević–Janičić
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
main()
{
int i;
char* nizreci[]={"Jabuka","Kruska","Sljiva","Dinja","Lubenica"};
68
1.15 Generičko sortiranje reči 69
69
70 Milena Vujošević–Janičić
return -1;
do
{
word[i++]=c;
} while(--lim>0 && isalpha(c=getchar()));
word[i]=’\0’;
return i;
}
main()
{
char word[80];
int i;
/* Citamo reci */
while (getword(word,80)!=-1)
{
/* Trazimo rec u spisku kljucnih reci binarnom pretragom */
keyword* k=(keyword*)bsearch((void*)word,
(void*)keywords,
num_of_keywords,
sizeof(keyword),
70
1.16 Argumenti komandne linije 71
cmp);
/* Ukoliko je pronadjena uvecavamo broj pojavljivanja */
if (k!=NULL)
(*k).num++;
}
/* Vrsimo ispis */
for (i=0; i<num_of_keywords; i++)
printf("%s %d\n", keywords[i].word, keywords[i].num);
}
#include <stdio.h>
71
72 Milena Vujošević–Janičić
1.17 Datoteke
Primer 1.17.1 Program demonstrira otvaranje datoteka ("r" - read
i "w" - write mod) i osnovne tehnike rada sa datotekama.
/* U datoteku se upisuje prvih 10 prirodnih
brojeva, a zatim se iz iste datoteke
citaju brojevi dok se ne stigne do kraja i
ispisuju se na standardni izlaz */
#include <stdio.h>
#include <stdlib.h>
main()
{
int i;
/* Zatvaramo datoteku */
fclose(f);
72
1.17 Datoteke 73
if (f == NULL) {
printf("Greska prilikom otvaranja datoteke podaci.txt za citanje\n");
exit(1);
}
/* Zatvaramo datoteku */
fclose(f);
}
main()
{
FILE* datoteka;
73
74 Milena Vujošević–Janičić
/* Zatvaramo datoteku */
fclose(datoteka);
}
Primer 1.17.3 Program ilustruje rad sa datotekama. Program kopira
datoteku čije se ime zadaje kao prvi argument komandne linije u da-
toteku čije se ime zadaje kao drugi argument komandne linije. Uz
svaku liniju se zapisuje i njen redni broj.
#include <stdio.h>
74
1.17 Datoteke 75
*/
char line[MAX_LINE];
FILE *in, *out;
int line_num;
if (argc != 3) {
fprintf(stderr,"Upotreba : %s ulazna_datoteka izlazna_datoteka\n",argv[0]);
return 1;
}
line_num = 1;
/* Zatvaramo datoteke */
75
76 Milena Vujošević–Janičić
fclose(in);
fclose(out);
}
Primer 1.17.4 Prodavnica - ilustruje čitanje niza struktura iz tek-
tsualne datoteke.
/* Datoteka, cije se ime zadaje kao argument komandne linije
ili ako se ne zada onda se ime unosi sa standardnog
ulaza, sadrzi podatke o proizvodima koji se prodaju
u okviru odredjene prodavnice. Svaki
proizvod se odlikuje sledecim podacima:
bar-kod - petocifreni pozitivan broj
ime - niska karaktera
cena - realan broj zaokruzen na dve decimale
pdv - stopa poreza - realan broj zaokruzen na dve decimale
Pretpostavljamo da su podaci u datoteci
korektno zadati.
Pretpostavljamo da se u prodavnici ne
prodaje vise od 1000 razlicitih artikala
Na standardni izlaz ispisati podatke o
svim proizvodima koji se prodaju u prodavnici.
Zadatak je moguce resiti i bez koriscenja nizova
(i takvo resenje je bolje). */
#include <stdio.h>
76
1.17 Datoteke 77
artikal artikli[MAX_ARTIKALA];
/* Prijavljujemo uspeh */
return 1;
}
77
78 Milena Vujošević–Janičić
od korisnika da ga unese */
if (argc<2) {
/* Ucitavamo ime datoteke */
char ime_datoteke[256];
printf("U kojoj datoteci se nalaze podaci o proizvodima: ");
scanf("%s", ime_datoteke);
/* Ucitavamo artikle */
while (ucitaj_artikal(f, &artikli[br_artikala]))
br_artikala++;
/* Zatvara se datoteka*/
fclose(f);
}
1.18 Liste
1.18.1 Red
78
1.18 Liste 79
A B ... X NULL
novi element
početak reda
novi kraj reda
A B ... X Y NULL
B ... X Y NULL
#include <stdio.h>
#include <stdlib.h>
79
80 Milena Vujošević–Janičić
while (broj) {
/*Alocira se prostor za novi clan liste*/
novi =(Elem*)malloc (sizeof (Elem));
if (novi == NULL)
{
fprintf(stderr, "Greska prilikom alokacije memorije\n");
exit(1);
}
/* Postavljanje vrednosti */
novi->broj = broj;
novi->sled = NULL;
/* Ispisivanje liste*/
void pisi (Elem *lista)
{
while (lista != NULL)
{
printf ("%d ", lista->broj),
lista = lista->sled;
}
putchar (’\n’);
}
80
1.18 Liste 81
if (preth != NULL )
preth->sled = tekuci;
/* Ovaj slucaj odnosi se na izbacivanje
elementa sa pocetka liste */
else lista = tekuci;
free (zaizbacivanje);
}
else
{
preth = tekuci;
tekuci = tekuci->sled;
}
return lista;
}
81
82 Milena Vujošević–Janičić
main ()
{
Elem *lista;
int k;
82
1.18 Liste 83
/* --------------------------------------------- */
/* Ispisivanje liste: iterativna verzija */
void ispisi_listu_i(CVOR* l) {
CVOR* t;
for (t = l; t != NULL; t=t->sl)
printf("%d ", t->br);
}
/* --------------------------------------------- */
/* Oslobadjanje liste : iterativna verzija */
void oslobodi_listu_i(CVOR* l) {
while (l!=NULL)
{
CVOR* tmp = l->sl;
free(l);
l = tmp;
}
}
83
84 Milena Vujošević–Janičić
/* --------------------------------------------- */
/* Ubacuje dati broj na pocetak date liste.
Funkcija pozivaocu eksplicitno vraca pocetak
rezultujuce liste.*/
CVOR* ubaci_na_pocetak(CVOR* l, int br) {
CVOR* novi = napravi_cvor(br);
novi->sl = l;
return novi;
}
if (l == NULL)
return novi;
else
{
CVOR* t;
/* Prodjemo do kraja liste */
for (t = l; t->sl!=NULL; t=t->sl)
;
t->sl = novi;
84
1.18 Liste 85
/* --------------------------------------------- */
/* Kljucna ideja u realizaciji ove funkcije je
pronalazenje poslednjeg elementa liste ciji
je kljuc manji od datog elementa br.
*/
CVOR* ubaci_sortirano(CVOR* pl, int br) {
CVOR* novi = napravi_cvor(br);
return pl;
}
main() {
CVOR* l = NULL;
CVOR* s = NULL;
85
86 Milena Vujošević–Janičić
int i;
for (i = 0; i<5; i++)
l = ubaci_na_kraj(l, i);
for (; i<10; i++)
l = ubaci_na_kraj_rekurzivno(l, i);
ispisi_listu_i(l);
putchar(’\n’);
ispisi_listu_r(l);
putchar(’\n’);
ispisi_listu_unazad(l);
putchar(’\n’);
oslobodi_listu_i(l);
s = ubaci_sortirano(s, 5);
s = ubaci_sortirano(s, 8);
s = ubaci_sortirano(s, 7);
s = ubaci_sortirano(s, 6);
s = ubaci_sortirano(s, 4);
ispisi_listu_r(s);
putchar(’\n’);
oslobodi_listu_r(s);
}
86
1.18 Liste 87
A B C ... Z
1.18.3 Stek
Primer 1.18.4 Program proverava da li su zagrade ( i ) dobro up-
arene.
#include <stdio.h>
#include <stdlib.h>
main()
{
int c;
int br_otv = 0;
while((c=getchar()) != EOF)
{
switch(c)
{
case ’(’:
br_otv++;
break;
case ’)’:
br_otv--;
if (br_otv<0)
{
printf("Visak zatvorenih zagrada\n");
exit(1);
}
87
88 Milena Vujošević–Janičić
}
}
if (br_otv == 0)
printf("Zagrade su u redu\n");
else
printf("Visak otvorenih zagrada\n");
}
Primer 1.18.5 Program proverava da li su zagrade (, [, {, }, ] i )
dobro uparene - statička implementacija steka.
#include <stdio.h>
#include <stdlib.h>
#define MAX_ZAGRADA 100
main()
{
int c;
char otv_zagrade[MAX_ZAGRADA];
int br_otv = 0;
while((c=getchar()) != EOF)
{
switch(c)
{
case ’(’:
case ’{’:
case ’[’:
{
otv_zagrade[br_otv] = c;
br_otv++;
break;
}
case ’]’:
case ’}’:
case ’)’:
if (br_otv>0 && odgovarajuce(otv_zagrade[br_otv-1], c))
88
1.18 Liste 89
{
br_otv--;
}
else
{
printf("Visak zatvorenih zagrada: %c u liniji %d\n", c, br_linija);
exit(1);
}
}
}
if (br_otv == 0)
printf("Zagrade su u redu\n");
else
printf("Visak otvorenih zagrada\n");
}
X Y ... A NULL
novi element
Y X V ... A NULL
X V ... A NULL
89
90 Milena Vujošević–Janičić
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define OTVORENA 1
#define ZATVORENA 2
#define GRESKA 0
s[i]=’\0’;
90
1.18 Liste 91
main()
{
char tag[MAX_TAG];
int zatvorenost;
while ((zatvorenost = gettag(tag, MAX_TAG))>0)
{
if (zatvorenost==OTVORENA)
{
/* Svaku otvorenu etiketu stavljamo na stek */
else
{
91
92 Milena Vujošević–Janičić
92
1.18 Liste 93
...
NULL A B C ... Z NULL
#include <stdlib.h>
#include <stdio.h>
if (lista==NULL)
{ novi->sledeci=novi;
novi->prethodni=novi;
return novi;
}
else
{ novi->prethodni=lista;
novi->sledeci=lista->sledeci;
lista->sledeci->prethodni=novi;
lista->sledeci=novi;
return novi;
93
94 Milena Vujošević–Janičić
}
}
/* Ispis liste */
void ispisi(cvor* lista)
{
if (lista!=NULL)
{ cvor* tekuci=lista;
do
{ printf("%d\n",tekuci->broj);
tekuci=tekuci->sledeci;
} while (tekuci!=lista);
}
}
printf("Ispada %d\n",lista->broj);
lista->sledeci->prethodni=lista->prethodni;
lista->prethodni->sledeci=lista->sledeci;
free(lista);
return sledeci;
}
else return NULL;
}
main() {
/* Umecemo petoro dece u listu */
cvor* lista = NULL;
lista=ubaci(1,lista);
lista=ubaci(2,lista);
lista=ubaci(3,lista);
lista=ubaci(4,lista);
94
1.18 Liste 95
lista=ubaci(5,lista);
lista=lista->sledeci;
int smer = 0;
/* Dok ima dece u listi */
while(lista!=NULL)
{ int i;
lista=izbaci(lista);
smer = smer ? 0 : 1;
}
}
Primer 1.18.8 Program ispisuje broj pojavljivanja za svaku od reči
koja se pojavila u tekstu unetom sa standardnog ulaza. Verzija sa
(sortiranom) listom.
#include <stdlib.h>
#include <stdio.h>
95
96 Milena Vujošević–Janičić
}
}
96
1.18 Liste 97
return pocetak;
}
/* Ukoliko je rec koju ubacujemo manja od tekuce reci, gradimo novi
cvor i ubacujemo ga ispred pocetka */
else
{ cvor* novi=malloc(sizeof(cvor));
if (novi == NULL)
{
printf("Greska prilikom alokacije memorije!\n");
exit(1);
}
strcpy(novi->ime,rec);
novi->br_pojavljivanja=1;
novi->sledeci=pocetak;
return novi;
}
}
if (c==EOF)
return -1;
do
{ word[i++]=c;
}while (i<lim-1 && isalpha(c=getchar()));
word[i]=’\0’;
return i;
}
97
98 Milena Vujošević–Janičić
if (strcmp(lista->ime,rec)==0)
return lista;
return nadji_rec(lista->sledeci,rec);
}
main()
{
cvor* lista=NULL;
char procitana_rec[80];
while(getword(procitana_rec,80)!=-1)
{ cvor* pronadjen=nadji_rec(lista,procitana_rec);
if (pronadjen!=NULL)
pronadjen->br_pojavljivanja++;
else
lista=ubaci_sortirano(lista,procitana_rec);
}
ispisi_listu(lista);
obrisi_listu(lista);
}
1.19 Drvo
Primer 1.19.1 Binarno pretrazivacko drvo - drvo sadrži cele bro-
jeve.
#include <stdlib.h>
#include <stdio.h>
98
1.19 Drvo 99
NULL NULL
NULL NULL
cvor* napravi_cvor(int b) {
cvor* novi = (cvor*)malloc(sizeof(cvor));
if (novi == NULL)
{
fprintf(stderr, "Greska prilikom
alokacije memorije");
exit(1);
}
novi->broj = b;
novi->l = NULL;
novi->d = NULL;
return novi;
}
99
100 Milena Vujošević–Janičić
12 21
NULL NULL
5 15
if (b < drvo->broj)
drvo->l = ubaci_u_drvo(drvo->l, b);
else
drvo->d = ubaci_u_drvo(drvo->d, b);
return drvo;
}
100
1.19 Drvo 101
if (drvo->broj == b)
return 1;
if (b < drvo->broj)
return pronadji(drvo->l, b);
else
return pronadji(drvo->d, b);
}
101
102 Milena Vujošević–Janičić
return suma_listova(drvo->l) +
suma_listova(drvo->d);
}
ispisi_listove(drvo->l);
102
1.19 Drvo 103
ispisi_listove(drvo->d);
}
if (drvo->d==NULL)
return drvo->broj;
return max_vrednost(drvo->d);
}
103
104 Milena Vujošević–Janičić
}
}
main()
{
cvor* drvo = NULL;
drvo = ubaci_u_drvo(drvo, 1);
drvo = ubaci_u_drvo(drvo, 8);
drvo = ubaci_u_drvo(drvo, 5);
drvo = ubaci_u_drvo(drvo, 3);
drvo = ubaci_u_drvo(drvo, 7);
drvo = ubaci_u_drvo(drvo, 6);
drvo = ubaci_u_drvo(drvo, 9);
if (pronadji(drvo, 3))
printf("Pronadjeno 3\n");
if (pronadji(drvo, 2))
printf("Pronadjeno 2\n");
if (pronadji(drvo, 7))
printf("Pronadjeno 7\n");
ispisi_drvo(drvo);
putchar(’\n’);
printf("Suma cvorova : %d\n", suma_cvorova(drvo));
printf("Broj cvorova : %d\n", broj_cvorova(drvo));
printf("Broj listova : %d\n", broj_listova(drvo));
printf("Suma listova : %d\n", suma_listova(drvo));
printf("Dubina drveta : %d\n", dubina(drvo));
printf("Maximalna vrednost : %d\n", max_vrednost(drvo));
ispisi_listove(drvo);
obrisi_drvo(drvo);
}
/*
Pronadjeno 3
Pronadjeno 7
1 3 5 6 7 8 9
Suma cvorova : 39
Broj cvorova : 7
Broj listova : 3
104
1.19 Drvo 105
Suma listova : 18
Dubina drveta : 5
Maximalna vrednost : 9
3 6 9
*/
Primer 1.19.2 Program sa ulaza čita tekst i ispisuje broj pojavlji-
vanja svake od reči koje su se javljale u tekstu. Radi poboljsanja
efikasnosti, prilikom brojanja reci koristi se struktura podataka pogodna
za leksikografsku pretragu - u ovom slucaju binarno pretrazivacko
drvo.
#include <stdlib.h>
#include <stdio.h>
105
106 Milena Vujošević–Janičić
106
1.19 Drvo 107
return drvo;
}
}
if (c==EOF)
return -1;
do
{
word[i++]=c;
} while (i<lim-1 && isalpha(c=getchar()));
word[i]=’\0’;
return i;
}
main() {
/* Drvo je na pocetku prazno */
cvor* drvo=NULL;
char procitana_rec[80];
/* Ispisujemo drvo */
ispisi_drvo(drvo);
/* Uklanjamo ga iz memorije */
obrisi_drvo(drvo);
}
107
108 Milena Vujošević–Janičić
#include <stdlib.h>
#include <stdio.h>
cvor* razlicite_reci[MAX_BROJ_RAZLICITIH_RECI];
108
1.19 Drvo 109
return novi_cvor;
}
int cmp = strcmp(rec, drvo->ime);
109
110 Milena Vujošević–Janičić
if (cmp>0)
{ drvo->desno=ubaci(drvo->desno, rec);
return drvo;
}
}
word[i]=’\0’;
return i;
}
110
1.19 Drvo 111
if (argc!=2)
{ fprintf(stderr,"Greska :
Ocekivano ime datoteke\n");
exit(1);
}
if ((ulaz=fopen(argv[1],"r"))==NULL)
{
fprintf(stderr,"Greska : nisam uspeo da otvorim datoteku %s\n");
exit(1);
}
fclose(ulaz);
}
111
112 Milena Vujošević–Janičić
1.20 Grafovi
Graf1 G=(V,E) sastoji se od skupa V čvorova i skupa E grana. Grane
predstavljaju relacije izme u čvorova i odgovara paru čvorova. Graf
može biti usmeren (orijentisan), ako su mu grane ure eni parovi i
neusmeren (neorjentisan) ako su grane neure eni parovi.
Uobičajena su dva načina predstavljanja grafova. To su matrica
povezanosti grafa i lista povezanosti.
Matrica povezanosti je kvadratna matrica dimenzije n, pri čemu
je n broj čvorova u grafu, takva da je element na preseku i-te vrste
i j-te kolone jednak jedinici ukoliko postoji grana u grafu od i-tog
do j-tog čvora, inače je nula.
Umesto da se i sve nepostojeće grane eksplicitno predstavljaju u
matrici povezanosti, mogu se formirati povezane liste od jedinica iz
i-te vrste za i=1,2,...,n. To je lista povezanosti. Svakom čvoru se
pridružuje povezana lista, koja sadrži sve grane susedne tom čvoru.
Graf je predstavljen vektorom lista. Svaki elemenat vektora sadrži
ime (indeks) čvora i pokazivač na njegovu listu čvorova.
Prvi problem na koji se nailazi pri konstrukciji bilo kog algo-
ritma za obradu grafa je kako pregledati ulaz. Postoje dva osnovna
algoritma za obilazak grafa: pretraga u dubinu (DFS, skraćenica od
depth-first-search) i pretraga u širinu (BFS, skraćenica od breadth-
first-search).
Kod DFS algoritma, obilazak započinje iz proizvoljnog zadatog
čvora r koji se naziva koren pretrage u dubinu. Koren se označava
kao posećen. Zatim se bira proizvoljan neoznačen čvor r1, susedan
sa r, pa se iz čvora r1 rekurzivno startuje pretraga u dubinu. Iz
nekog nivoa rekurzije izlazi se kad se nai e na čvor v kome su svi
susedi već označeni.
Primer 1.20.1 Primer reprezentovanja grafa preko matrice povezanosti.
U programu se unosi neorijentisan graf i DFS algoritmom se utvr uju
int** alociraj_matricu(int n)
{ int **matrica;
int i;
matrica=malloc(n*sizeof(int*));
if (matrica==NULL)
1 Tekst i primeri preuzeti od Jelene Tomašević, url: www.matf.bg.ac.yu/˜jtomasevic, zas-
112
1.20 Grafovi 113
{
printf("Greska prilikom alokacije memorije\n");
exit(1);
}
int* alociraj_niz(int n)
{ int* niz;
niz=calloc(n,sizeof(int));
if (niz==NULL)
{
printf("Greska prilikom alokacije memorije\n");
exit(1);
}
return niz;
}
113
114 Milena Vujošević–Janičić
114
1.20 Grafovi 115
main()
{
int i, j;
printf("Unesi broj cvorova : ");
scanf("%d",&n);
graf=alociraj_matricu(n);
unesi_graf(graf,n);
ispisi_graf(graf,n);
posecen=alociraj_niz(n);
poseti(0);
oslobodi_niz(posecen);
oslobodi_matricu(graf,n);
}
Primer 1.20.2 Primer predstavljanja grafa preko niza listi suseda
svakog od čvorova grafa U programu se unosi graf i DFS algoritmom
se utvrdjuje koji su čvorovi dostižni iz cvora 0.
#include <stdlib.h>
#include <stdio.h>
115
116 Milena Vujošević–Janičić
/* Ispis liste */
void ispisi_listu(cvor_liste* lista)
{ if (lista)
{ printf("%d ",lista->broj);
ispisi_listu(lista->sledeci);
}
}
main()
{
int i;
printf("Unesi broj cvorova grafa : ");
scanf("%d",&broj_cvorova);
for (i=0; i<broj_cvorova; i++)
{ int br_suseda,j;
graf[i]=NULL;
116
1.21 Razno 117
poseti(0);
}
1.21 Razno
k
Primer 1.21.1 Stepenovanje prirodnog broja efikasno: nk = (n 2 )2
k−1
ako je k parno ili nk = n(n 2 )2 ako je k neparno.
int stepen(int n, int k)
{
int p, s;
if (k==1) s=n;
else
{
p=stepen(n,k/2);
if(k%2==0) s=p*p;
else s=p*p*n;
}
return s;
}
Primer 1.21.2 MINESWEEPER - primer jednostavne igrice.
#include <stdlib.h>
117
118 Milena Vujošević–Janičić
#include <stdio.h>
#include <time.h>
/* Dimenzija table */
int n;
118
1.21 Razno 119
free(m);
}
/* Postavljamo bombu */
bombe[vrsta][kolona]=1;
}
}
119
120 Milena Vujošević–Janičić
printf("\n");
}
}
120
1.21 Razno 121
return br;
121
122 Milena Vujošević–Janičić
int gotova_partija()
{ int i,j;
for (i=0; i<n; i++)
for (j=0; j<n; j++)
{ /* Ukoliko postoji nepokrivena bomba,
partija nije zavrsena */
if (bombe[i][j]==1 && stanje[i][j]!=ZASTAVICA)
return 0;
}
main() {
122
1.21 Razno 123
/* Alociramo table */
bombe=alociraj(n);
stanje=alociraj(n);
/* Postavljamo bombe */
postavi_bombe();
/* Reagujemo na akciju */
123
124 Milena Vujošević–Janičić
switch(akcija)
{ case ’o’:
otvori_polje(v-1,k-1);
break;
case ’z’:
postavi_zastavicu(v-1,k-1);
}
}
/* Konstatujemo pobedu */
ispisi_stanje();
printf ("Cestitam! Pobedili ste\n");
obrisi(stanje,n);
obrisi(bombe,n);
}
124
Osnovi programiranja
Programski jezik C
— Zadaci sa vežbi —
2
Sadržaj
1 HTML 7
2 Konverzije 9
2.1 Pozicioni brojni sistemi . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Prevo enje iz dekadnog sistema u binarni . . . . . . . . . . . . . 10
2.3 Prevo enje iz dekadnog sistema u oktalni . . . . . . . . . . . . . 10
2.4 Prevo enje iz dekadnog sistema u heksadekadni . . . . . . . . . . 10
2.5 Prevo enje iz dekadnog sistema u sistem sa osnovom n . . . . . . 11
2.6 Prevo enje iz binarnog sistema u heksadekadni . . . . . . . . . . 11
2.7 Prevo enje iz binarnog sistema u oktalni . . . . . . . . . . . . . . 12
3 Algoritmi 13
3.1 Rešavanje problema uz pomoć računara . . . . . . . . . . . . . . 13
3.2 Formiranje algoritma . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3 Algebarski algoritmi . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3.1 NZD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3.2 Koren prirodnog broja . . . . . . . . . . . . . . . . . . . . 19
4 Programski jezik C 21
4.1 Zdravo svete! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.2 Imena promenljivih . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.3 Deklaracije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.4 Tipovi i veličina podataka . . . . . . . . . . . . . . . . . . . . . . 22
4.5 Funkcije printf i scanf . . . . . . . . . . . . . . . . . . . . . . . . 23
4.6 Aritmetički operatori . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.7 Operatori i izrazi dodeljivanja vrednosti . . . . . . . . . . . . . . 26
4.8 Inkrementacija i dekrementacija . . . . . . . . . . . . . . . . . . . 27
4.9 Relacioni i logički operatori . . . . . . . . . . . . . . . . . . . . . 28
4.10 Kontrola toka — if, while, do - while, for . . . . . . . . . . . . . . 30
4.10.1 if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.10.2 Else-if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.10.3 while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.10.4 do-while . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.10.5 for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.11 Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.12 Uslovni izraz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.13 Simboličke konstante . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.14 Enumeracija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3
4 SADRŽAJ
4.15 Funkcije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.16 Nizovi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.17 Konstante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.18 Konverzija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.18.1 Automatska konverzija . . . . . . . . . . . . . . . . . . . . 41
4.18.2 Eksplicitna konverzija . . . . . . . . . . . . . . . . . . . . 41
4.18.3 Funkcije koje vrše konverziju . . . . . . . . . . . . . . . . 42
4.19 Operator sizeof() . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.20 Znakovni ulaz i izlaz . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.21 Nizovi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.22 Dvostruka for petlja . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.23 Formiranje HTML dokumenta . . . . . . . . . . . . . . . . . . . . 51
4.24 Funkcije — prenos parametara po vrednosti . . . . . . . . . . . . 53
4.25 Break i continue . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.26 Rad sa niskama karaktera . . . . . . . . . . . . . . . . . . . . . . 56
4.27 Makroi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.28 Bitski operatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.29 Linearna i binarna pretraga . . . . . . . . . . . . . . . . . . . . . 69
4.30 Razni zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.31 Sortiranje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.32 Rekurzija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.33 Životni vek i oblast važenja promenjivih, statičke promenljive . . 89
4.34 Pokazivači . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
4.35 Pokazivači i argumenti funkcija . . . . . . . . . . . . . . . . . . . 93
4.36 Pokazivači i nizovi (polja) . . . . . . . . . . . . . . . . . . . . . . 94
4.37 Alokacija memorije . . . . . . . . . . . . . . . . . . . . . . . . . . 100
4.38 Niz pokazivača . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
4.39 Pokazivači na funkcije . . . . . . . . . . . . . . . . . . . . . . . . 104
4.40 Matrice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
4.41 Strukture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
4.41.1 Operator typedef . . . . . . . . . . . . . . . . . . . . . . . 113
4.42 qsort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
4.43 Sortiranje — generička funkcija . . . . . . . . . . . . . . . . . . . 121
4.44 qSort funkcija iz standardne biblioteke . . . . . . . . . . . . . . . 127
4.45 Generičko sortiranje reči . . . . . . . . . . . . . . . . . . . . . . . 129
4.46 Argumenti komandne linije . . . . . . . . . . . . . . . . . . . . . 131
4.47 Datoteke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
4.48 Liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
4.48.1 Red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
4.48.2 Kružna lista . . . . . . . . . . . . . . . . . . . . . . . . . . 145
4.48.3 Stek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
4.48.4 Dvostruko povezane liste . . . . . . . . . . . . . . . . . . 150
4.49 Drvo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
4.50 Grafovi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
4.51 Razni zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
4
Predgovor
Milena Vujošević-Janičić
www.matf.bg.ac.yu/~milena
5
6 SADRŽAJ
6
Glava 1
HTML
http://www.matf.bg.ac.yu/nastavno/dvitas/nastava/op/html/op-html.html
7
8 Milena Vujošević–Janičić
8
Glava 2
Konverzije
3. (1101)7 = 1 ∗ 70 + 0 ∗ 71 + 1 ∗ 72 + 1 ∗ 73 = (399)10
Zadatak 1
(110111100)2 = (?)10
(77)8 = (?)10
(F F F F )16 = (?)10
1 Deo teksta i primera preuzet sa sajta www.matf.bg.ac.yu/˜jelenagr
9
10 Milena Vujošević–Janičić
Primer 2.2.1
(26)10 = (?)2
kolicnik ostatak
26 / 2 = 13 0
13 / 2 = 6 1
6/2=30
3/2=11
1 / 2 = 0 1 kraj postupka konverzije
(26)10 = (11010)2
Zadatak 2
(54)10 = (?)2
(126)10 = (?)2
(332)10 = (?)2
Primer 2.3.1
(181)10 = (?)8
kolicnik ostatak
181 / 8 = 22 5
22 / 8 = 2 6
2 / 8 = 0 2 kraj postupka konverzije
(181)10 = (265)8
Zadatak 3
(67)10 = (?)8
(336)10 = (?)8
(442)10 = (?)8
Primer 2.4.1
(181)10 = (?)16
kolicnik ostatak
181 / 16 = 11 5
11 / 16 = 0 11 (heksadekadna cifra B) kraj postupka konverzije
(181)10 = (B5)16
Zadatak 4
(48)10 = (?)16
(1336)10 = (?)16
(332)10 = (?)16
10
2.5 Prevo enje iz dekadnog sistema u sistem sa osnovom n
11
osnovom n
Primer 2.5.1
(181)10 = (?)n
kolicnik ostatak
181 / n = k1 o1
k 1 / n = k 2 o2
...
kl / n = 0 ol+1 kraj postupka konverzije
Zadatak 5
(48)10 = (?)16
(1336)10 = (?)16
(332)10 = (?)16
primer:
4 0100 (0 ∗ 20 + 0 ∗ 21 + 1 ∗ 22 + 0 ∗ 23 )
F 1111 (1 ∗ 20 + 1 ∗ 21 + 1 ∗ 22 + 1 ∗ 23 )
11
12 Milena Vujošević–Janičić
od bitova najmanje težine. Ako ukupan broj bitova nije deljiv sa cetiri, onda se
dopisuje potreban broj vodecih nula (one su bez uticaja na promenu vrednosti
originalnog zapisa).
Primer 2.6.1
(1111011100001101010000)2 =
= (001111011100001101010000)2 =
= (3DC350)16
Zadatak 6
(1111110111001100011010100100)2 = (?)16
4 100 (0 ∗ 20 + 0 ∗ 21 + 1 ∗ 22 )
Primer 2.7.1
(11111010001010)2 =
= (011111010001010)2 =
= (37212)8
Zadatak 7
(1111110111010100100)2 = (?)8
12
Glava 3
Algoritmi
13
14 Milena Vujošević–Janičić
Tok rada algoritma se opisuju linijama koje povezuju grafičke simbole koji
reprezenuju obradu.
Algoritam Ispis
ulaz: nema podataka na ulazu
izlaz: poruka Zdravo, svete!!!
{
output " Zdravo, svete!!!"
}
Algoritam Sabiranje
ulaz: x,y
izlaz: zbir brojeva x,y
/* algoritam je formiran tako da funkcionise
za bilo koji realan broj sa ulaza. Zbog toga se
u algoritmu koristi promenljiva - ime koje
oznacava promenljivu vrednost.*/
{
input x,y;
zbir = x + y;
output zbir;
}
Algoritam Maksimum
ulaz: x, y;
izlaz: veci od brojeva x i y
{
input x,y;
if (x>y) max=x
else max=y;
output max;
}
Primer 3.3.4 Algoritam za izracunavanje sume brojeva koja se unosi pre unosa
nule.
Algoritam Zbir
ulaz: brojevi sve dok se ne unese nula
izlaz: zbir brojeva
{
zbir=0; /*Inicijalizujemo zbir na nulu*/
input x; /*Unosimo prvi u nizu brojeva*/
while x!=0 /*Proveravani da li je broj
14
3.3 Algebarski algoritmi 15
Algoritam Maksimum
ulaz: brojevi sve dok se ne unese nula
izlaz: maksimum unetih brojeva
{
input x;
max = x;
while (x!=0) /*Proveravani da li je broj
x razlicit od nule*/
{
input x; /*unosimo novi ulazni broj*/
if (x>max) max=x; /*proveravamo da li je uneti
broj veci od tekuceg
maksimuma i ako jeste
onda tekucem maksimumu
dodeljujemo njegovu
vrednost*/
}
output max; /*Na izlaz saljemo izracunati
maximum*/
}
Algoritam n!
ulaz: prirodan broj n;
izlaz: faktorijel prirodnog broja n;
{
input n;
f=1;
while (n>1)
{
f=f*n;
n=n-1;
}
output f;
}
15
16 Milena Vujošević–Janičić
Algoritam razmena
ulaz: dva broja
izlaz: razmena dva broja
{
input x,y;
pom=x;
x=y;
y=pom;
output x,y;
}
x = qy + r, 0 ≤ r < y, 0 ≤ q
.
Algoritam kolicnik
ulaz: prirodni brojevi x i y;
izlaz: kolicnik i ostatak pri deljenju
{
input x,y;
kolicnik=0;
ostatak=x;
while (ostatak>=y)
{
ostatak=ostatak-y;
kolicnik=kolicnik+1;
}
output kolicnik, ostatak;
}
a ∗ x2 + b ∗ x + c
16
3.3 Algebarski algoritmi 17
x2=(-b-sqrt(d))/2a;
output x1, x2;
}
else if (d=0)
{
x=-b/2a;
output x;
}
else
{
Re=-b/2a;
Im=sqrt(-d)/2a;
output Re+i*Im, Re-i*Im;
}
}
3.3.1 NZD
Zadatak 14 Naći najveći zajednički delitelj za dva broja.
Algoritam NZD1
ulaz prirodni brojevi a, b;
izlaz nzd(a,b);
{
input a,b;
nzd = 1;
br=2;
while (br<=a && br<=b)
17
18 Milena Vujošević–Janičić
{
if (a%br)==0 && (b%br)==0 nzd=br;
br=br+1;
}
output nzd;
}
18
3.3 Algebarski algoritmi 19
}
while (b!=0)
{
pom = b;
b = a % b;
a = pom;
}
output a;
}
Algoritam Koren1
ulaz prirodan broj n;
izlaz ceo deo korena prirodnog broja;
{
input n;
koren=1;
while (koren*koren<=n)
koren=koren+1;
koren=koren-1;
output koren;
}
Algoritam Koren2
ulaz prirodan broj n;
izlaz ceo deo korena prirodnog broja;
{
input n;
suma=0;
broj=0;
while (suma<=n)
{
suma=suma+broj+broj+1;
broj=broj+1;
}
broj=broj-1;
output broj;
}
19
20 Milena Vujošević–Janičić
20
Glava 4
Programski jezik C
main()
/*iskazi f-je main su zatvoreni u zagrade */
{
/*poziv f-je printf da odstampa poruku*/
printf("hello, world\n");
}
Primer 4.1.2 Program štampa poruku ”hello, world”
#include <stdio.h>
main()
{
printf("hello, ");
printf("world");
printf("\n");
}
Specijalni znaci:
\n novi red
\t tabulator
\\ kosa crta
\" navodnici
\a zvuk
\’ jednstruki navodnik
21
22 Milena Vujošević–Janičić
4.3 Deklaracije
Da bi se promenljiva mogla upotrebljavati ona se mora na početku programa
deklarisati. Prilikom deklaracije može se izvršiti i početna inicijalizacija.
Važi
22
4.5 Funkcije printf i scanf 23
#include <stdio.h>
main()
{
/*deklaracija vise promenljivih
istog tipa */
int rez,pom1,pom2;
pom1=20;
pom2=15;
rez=pom1-pom2;
/*ispisivanje rezultata*/
printf("Rezultat je %d-%d=%d\n",pom1,pom2,rez);
}
Izlaz iz programa:
Rezultat je 20-15=5
Iskaz dodele:
pom1=20;
pom2=15;
Individualni iskazi se zavrsavaju sa ;
Primer 4.5.1
#include <stdio.h>
main()
{
printf("Slova:\n%3c\n%5c\n", ’z’ , ’Z’);
}
Izlaz iz programa:
Slova:
z
Z
%c je za stampanje karaktera
%3c je za stampanje karaktera na tri pozicije
Isto tako smo mogli i %3d za stampanje broja na tri pozicije ili %6d za stampanje
broja na 6 pozicija.
Pravila:
%d stampaj kao ceo broj
23
24 Milena Vujošević–Janičić
#include <stdio.h>
main()
{
int x;
printf("Unesi ceo broj : ");
#include <stdio.h>
main()
{
int a, b, c;
printf("Unesi prvi broj : ");
scanf("%d", &a);
printf("Unesi drugi broj : ");
scanf("%d", &b);
c = a + b;
printf("%d + %d = %d\n", a, b, c);
}
Ulaz:
Unesi prvi broj : 2 <enter>
Unesi drugi broj : 3 <enter>
Izlaz:
2 + 3 = 5
24
4.6 Aritmetički operatori 25
#include <stdio.h>
main()
{
int a, b;
printf("Unesi prvi broj : ");
scanf("%d",&a);
Ulaz:
Unesi prvi broj : 2 <enter>
Unesi drugi broj : 3 <enter>
Izlaz:
Zbir a+b je : 5
Razlika a-b je : -1
Proizvod a*b je : 6
Celobrojni kolicnik a/b je : 0
Progresan pokusaj racunanja realnog kolicnika a/b je : 0.000000
Realni kolicnik a/b je : 0.666667
Ostatak pri deljenju a/b je : 2
25
26 Milena Vujošević–Janičić
#include <stdio.h>
main()
{
int a = 5;
int b = 2;
int d = 5/2; /* Celobrojno deljenje - rezultat je 2 */
float c = a/b; /* Iako je c float, vrsi se celobrojno
deljenje jer su i a i b celi */
Izlaz iz programa:
c = 2.000000
Uzrok problema : 5/2 = 2.000000
Popravljeno : 5.0/2.0 = 2.500000
Moze i : 5/2.0 = 2.500000 i 5.0/2 = 2.500000
Za promenljive mora kastovanje : 2.500000
Moze i za:
+ - * / % << >> ^ |
izraz1 op = izraz2
je ekvivalnetno sa
izraz1 = (izraz1) op (izraz2)
26
4.8 Inkrementacija i dekrementacija 27
y=(x++)*(++z);
#include <stdio.h>
main()
{
int x, y;
int a = 0, b = 0;
Izlaz iz programa:
Na pocetku:
a = 0
b = 0
Posle : a++; ++b;
a = 1
b = 1
Posle : x = ++a;
a = 2
27
28 Milena Vujošević–Janičić
x = 2
Posle : y = b++;
b = 2
y = 1
(3<5)
(a<=10)
a < 5 != 1 <=> (a < 5)!=1
Logicki operatori:
! unarna negacija (najvisi prioritet)
&& logicko i (visi prioritet od ili)
|| logicko ili izracunavaju se sleva na desno!
main()
{
int a = 3>5, /* manje */
b = 5>3, /* vece */
c = 3==5, /* jednako */
d = 3!=5; /* razlicito */
28
4.9 Relacioni i logički operatori 29
Izlaz iz programa:
3>5 - 0
5>3 - 1
3==5 - 0
3!=5 - 1
Konjunkcija : 3>5 && 5>3 - 0
Disjunkcija : 3>5 || 5>3 - 1
Negacija : !(3>5) - 1
Primer 4.9.2 Ilustracija lenjog izračunavanja logičkih operatora.
Prilikom izracunavanja izraza - A && B, ukoliko je A netačno, izraz B se
ne izračunava. Prilikom izračunavanja izraza - A k B, ukoliko je A tačno, izraz
B se ne izračunava.
#include <stdio.h>
main()
{
/* Funkcija izracunaj() ce biti pozvana
samo za parne vrednosti a */
int a;
for (a = 0; a < 10; a++)
if (a%2 == 0 && izracunaj())
printf("Uslov ispunjen : a = %d, b = %d\n", a, b);
else
printf("Uslov nije ispunjen : a = %d, b = %d\n", a, b);
printf("----------------------------\n");
29
30 Milena Vujošević–Janičić
za neparne vrednosti a */
b = 0;
for (a = 0; a < 10; a++)
if (a%2 == 0 || izracunaj())
printf("Uslov ispunjen : a = %d, b = %d\n", a, b);
else
printf("Uslov nije ispunjen : a = %d, b = %d\n", a, b);
}
Primer 4.10.1 Program ilustruje if i ispisuje ukoliko je uneti ceo broj negativan
#include <stdio.h>
main()
{
int b;
printf("Unesi ceo broj:");
scanf("%d", &b);
if (b < 0)
printf("Broj je negativan\n");
}
Else se odnosi na prvi neuparen if, voditi o tome računa, ako želimo drugačije
moramo da navedemo vitičaste zagrade.
if (izraz)
if (izraz1) iskaz 1
else iskaz
ovo else se odnosi na drugo if a ne na prvo if!
if (izraz)
{
if (izraz1) iskaz 1
}
else iskaz
tek sada se else odnosi na prvo if!!!
4.10.2 Else-if
if (izraz1)
iskaz1
30
4.10 Kontrola toka — if, while, do - while, for 31
else if (izraz2)
iskaz2
else if (izraz3)
iskaz3
else if (izraz4)
iskaz4
else iskaz
npr if (a<5)
printf("A je manje od 5\n");
else if (a=5)
printf("A je jednako 5\n");
else if (a>10)
printf("A je vece od 10\n");
else if (a=10)
printf("A je jednako 10\n");
else printf("A je vece od pet i manje od 10\n");
#include <stdio.h>
main()
{
int b;
printf("Unesi ceo broj : ");
scanf("%d", &b);
if (b < 0)
printf("Broj je negativan\n");
else if (b == 0)
printf("Broj je nula\n");
else
printf("Broj je pozitivan\n");
}
Ulaz:
Unesi ceo broj:-5
Izlaz:
Broj je negativan
Ulaz:
Unesi ceo broj:5
Izlaz:
Broj je pozitivan
#include <stdio.h>
main()
31
32 Milena Vujošević–Janičić
{
int b;
printf("Unesi ceo broj : ");
scanf("%d", &b);
Ulaz:
Unesi ceo broj:-5
Izlaz:
Broj je pozitivan
4.10.3 while
while(uslov) { ... }
Uslov u zagradi se testira i ako je ispunjen telo petlje se izvrsava. Zatim se uslov
ponovo testira i ako je ispunjen ponovo se izvrsava telo petlje. I tako sve dok
uslov ne bude ispunjen. Tada se izlazi iz petlje i nastavlja sa prvom sledecom
naredbom u programu.
Ukoliko iza while sledi samo jedna naredba nema potrebe za zagradama.
while (i<j)
i=2*i;
4.10.4 do-while
Ovo je slično paskalskom repeat-until izrazu.
#include <stdio.h>
main()
{
int x;
x = 1;
do
{
printf("x = %d\n",x);
x++; /* x++ je isto kao i x=x+1 */
32
4.11 Switch 33
} while (x<=10);
}
4.10.5 for
Primer 4.10.5 Program ilustruje petlju - for.
#include <stdio.h>
main()
{
int x;
}
Izlaz:
1
2
3
4
4.11 Switch
switch (iskaz) {
case konstantan_izraz1: iskazi1
case konstantan_izraz2: iskazi2
...
default: iskazi
}
#include <stdio.h> /*
Upotreba switch-a
*/
main() {
char x;
scanf("%c",&x);
switch (x)
{
case ’a’:
case ’e’:
case ’i’:
case ’o’:
case ’u’: printf(" x je samoglasnik");
33
34 Milena Vujošević–Janičić
break;
case ’r’: printf(" x je r");
break;
default: printf(" x je suglasnik");
}
}
#include<stdio.h>
main()
{
int n;
printf("Unesi paran broj manji od 10\n");
scanf("%d",&n);
switch(n) {
case 0:
printf("Uneli ste nulu\n");
break;
case 2:
printf("Uneli ste dvojku\n");
break;
case 4:
printf("Uneli ste cetvorku\n");
break;
case 6:
printf("Uneli ste sesticu\n");
break;
case 8:
printf("Uneli ste osmicu\n");
break;
defalut:
printf("Uneli ste nesto sto nije paran broj\n");
}
}
Ulaz:
Unesi paran broj manji od 10
2
Izlaz:
Uneli ste dvojku
z = (a<b)? a : b; /*z=min(a,b)*/
max = (a>b)? a : b;
34
4.13 Simboličke konstante 35
#include <stdio.h>
#define POCETAK 0
#define KRAJ 20
#define KORAK 10
main()
{
int a;
a = POCETAK;
while (a <= KRAJ)
{
printf("%d cm = %f in\n", a, a/2.54);
a += KORAK; /* isto sto i a = a + KORAK; */
}
}
Izlaz:
0 cm = 0.000000 in
10 cm = 3.937008 in
20 cm = 7.874016 in
#include <stdio.h>
#define POCETAK 0
#define KRAJ 20
#define KORAK 10
main()
{
int a;
for (a = POCETAK; a <= KRAJ; a += KORAK)
printf("%d cm = %f in\n", a, a/2.54);
}
Izlaz:
0 cm = 0.000000 in
10 cm = 3.937008 in
20 cm = 7.874016 in
35
36 Milena Vujošević–Janičić
#include <stdio.h>
#define EURO 85.90
main()
{
printf("4 eura ima vrednost %f dinara\n", 4*EURO);
printf("1 euro ima vrednost %.0f dinara\n",EURO);
}
4.14 Enumeracija
Izvesna alternativa za define
koriscenje:
int x=0;
boje b;
b=ZELENA;
x=b+CRNA; /* 5 + 12=17*/
4.15 Funkcije
Primer 4.15.1 sum - najjednostavnija funkcija koja sabira dva broja
/* Definicija funkcije */
int sum(int a, int b)
{
int c;
c = a + b;
return c;
/* Ovo je krace moglo da bude napisano
kao return a+b; */
}
main()
{
int c;
36
4.15 Funkcije 37
/* Poziv funkcije */
c = sum(3,5);
printf("%d\n", c);
main()
{
/* Poziv funkcije */
printf("%d\n", zbir(3,5));
}
/* Definicija funkcije */
int zbir(int a, int b)
{
return a+b;
}
Primer 4.15.3 power - funkcija koja stepenuje realan broj na celobrojni izlozi-
lac
#include <stdio.h>
return rezultat;
}
37
38 Milena Vujošević–Janičić
if (negativan)
k = -k;
main()
{
/* Poziv funkcije */
float s = power(2.0,8);
printf("%f\n", s);
}
4.16 Nizovi
Deklaracija niza:
int niz[5]; /* niz od 5 elemenata tipa int*/
Pristupanje elementima niza:
niz[0] = 4;
niz[1] = 2 * niz[0]; /*niz[1] = 8*/
niz[2] = niz[0] * niz[1]; /*niz[2] = 32*/
niz[3] = 5;
niz[4] = 7;
Unos vrednosti elemenata niza sa tastature:
for(i=0; i<5; i++)
scanf("%d", &a[i]);
Stampanje elemenata niza
for(i=0; i<5; i++)
printf("%d ", a[i]);
Brojanje elemenata niza je od nule!
Pristupanje elementu niza, indeks može da bude proizvoljan izraz celobrojne
vrednosti: niz[i*2]=5.
main()
{
int a[10];
38
4.16 Nizovi 39
int i;
for (i = 0; i<10; i++)
{
printf("a[%d]=",i);
scanf("%d",&a[i]);
}
printf("Unazad : \n");
/* Pronalazimo maksimum */
max = a[0];
for (i = 1; i < BR_ELEM; i++)
if (a[i]>max)
max = a[i];
/* Ispisujemo maksimum */
printf("Max = %d\n",max);
}
#include <stdio.h>
#define BR_ELEM 5
main()
{
int a, max, i;
scanf("%d",&a);
max = a;
for (i = 1; i < BR_ELEM; i++)
{
39
40 Milena Vujošević–Janičić
scanf("%d",&a);
if (a>max)
max = a;
}
4.17 Konstante
Koji su tipovi konstanti?
Celobrojna konstanta 1234 je tipa int.
Da bi konstanta bila long navodi se iza nje slovo L ili l, npr 123456789L.
Ako želimo da nam je konstanta unsigned onda na kraju pišemo U ili u.
Može i 1234567ul.
40
4.18 Konverzija 41
++i;
return i;
}
int main()
{
printf("Duzina ove niske
je: %d \n",strlen("Duzina ove niske je:"));
return 0;
}
4.18 Konverzija
4.18.1 Automatska konverzija
Ako je jedan od operanada razližličit vrši se konverzija, uvek u smeru manjeg
ka većem tipu
Naredba dodele:
int i=5;
float f=2.3;
f=i; /* f ce imati vrednost 5.0*/
obrnuto:
int i=5;
float f=2.3;
i=f; /* i ce imati vrednost 2*/
float x;
x=2.3+4.2; /* x ce imati vrednost 6.5 */
x=(int)2.3+(int)4.2; /* x ce imati vrednost 6 */
x=(int)2.3*4.5; /* x ce imati vrednost 9.0 jer zbog prioriteta
operatora konverzije prvo ce biti izvrsena
konverzija broja 2.3 u 2 pa tek onda izvrseno
mnozenje. */
x=(int)(2.3*4.5) /* x ce imati vrednost 10.0 */
41
42 Milena Vujošević–Janičić
#include<stdio.h>
main()
{
char c;
printf("Unesi neko veliko slovo:\n");
scanf("%c", &c);
printf("Odgovarajuce malo slovo je %c\n", lower(c));
}
42
4.19 Operator sizeof() 43
#include<stdio.h>
main()
{
int n;
n = atoi("234");
printf("\nN je : %d\n",n);
}
printf("sizeof(int)=%d\n", sizeof(int));
printf("sizeof(long)=%d\n", sizeof(long));
printf("sizeof(short)=%d\n", sizeof(short));
printf("sizeof(signed)=%d\n", sizeof(signed));
printf("sizeof(unsigned)=%d\n", sizeof(unsigned));
printf("sizeof(char)=%d\n", sizeof(char));
printf("sizeof(float)=%d\n", sizeof(float));
printf("sizeof(double)=%d\n", sizeof(double));
printf("sizeof(i)=%d\n", sizeof(i));
printf("sizeof(f)=%d\n", sizeof(f));
printf("sizeof(n)=%d\n", sizeof(n));
printf("Broj elemenata niza n : %d\n", sizeof(n)/sizeof(int));
43
44 Milena Vujošević–Janičić
sizeof(short)=2
sizeof(signed)=4
sizeof(unsigned)=4
sizeof(char)=1
sizeof(float)=4
sizeof(double)=8
sizeof(i)=4
sizeof(f)=4
sizeof(n)=40
Broj elemenata niza n : 10
#include <stdio.h>
main()
{
int c; /* Karakter - obratiti paznju na int */
c = getchar(); /* cita karakter sa standardnog ulaza */
putchar(c); /* pise karakter c na standardni izlaz */
44
4.20 Znakovni ulaz i izlaz 45
#include <stdio.h>
main()
{
/*Koristi se int a ne char zato sto zelimo
da razlikujemo kraj ulaza od vazecih znakova*/
int c;
main()
{
int c;
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
45
46 Milena Vujošević–Janičić
++nc;
/* %ld odnosi se na tip long. */
printf("%ld\n", nc);
}
main()
{
double nc;
46
4.20 Znakovni ulaz i izlaz 47
Primer 4.20.8 Program prepisuje ulaz na izlaz pri čemu više blanko znakova
zamenjuje jednim.
#include <stdio.h>
main()
{
int znak; /*tekuci znak sa ulaza*/
int preth; /*znak koji prethodi tekucem */
preth=’a’; /* inicijalizujemo vrednost prethodnog
da bi prvi prolazak kroz petlju bio ispravan*/
while ( (znak=getchar() ) !=EOF)
{
if (znak !=’ ’ || preth != ’ ’) putchar(znak);
preth=znak;
}
}
main()
{
int c;
int br_cifara = 0;
while ((c = getchar()) != EOF)
if (’0’<=c && c<=’9’)
br_cifara++;
main()
{
int c;
int br_0=0, br_1=0, br_2=0;
47
48 Milena Vujošević–Janičić
4.21 Nizovi
Primer 4.21.1 Program ilustruje inicijalizaciju nizova.
#include <stdio.h>
main()
{
/* Niz inicijalizujemo tako sto mu navodimo vrednosti
u viticasnim zagradama. Dimenzija niza se odredjuje
na osnovu broja inicijalizatora */
int a[] = {1, 2, 3, 4, 5, 6};
/* Ispisujemo nizove */
int i;
for (i = 0; i < a_br_elem; i++)
printf("a[%d]=%d\n",i, a[i]);
48
4.21 Nizovi 49
#include <stdio.h>
main()
{
/* Poslednji bajt niske karaktera se postavlja na ’\0’ tj. 0 */
char s[] = {’a’, ’b’, ’c’, ’\0’ };
#include <stdio.h>
main()
{
/* Niz brojaca za svaku od cifara */
int br_cifara[10];
int i, c;
/* Resetovanje brojaca */
49
50 Milena Vujošević–Janičić
/* Ispis rezultata */
for (i = 0; i < 10; i++)
printf("Cifra %d se pojavila %d put%s\n",
i, br_cifara[i], br_cifara[i] == 1 ? "" : "a");
}
#include <stdio.h>
main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == ’\n’)
++nl;
/*Operator || znaci OR*/
if (c == ’ ’ || c == ’\n’ || c == ’\t’)
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}
50
4.22 Dvostruka for petlja 51
#include<stdio.h>
int main()
{
int i,j;
#include<stdio.h>
int main()
{
int i,j;
51
52 Milena Vujošević–Janičić
Primer 4.23.2 Napisati program koji generiše html dokument sa engleskim al-
fabetom.
#include <stdio.h>
main()
{
int i;
printf("<HTML><head><title>Engleski alfabet</title><head>\n");
printf("<body><ul>");
for(i=0;i<=25;i++)
printf("<li> %c %c \n",’A’+i,’a’+i);
printf("</ul></body></HTML>\n"); }
Primer 4.23.3 Napisati program koji generise html dokument koji prikazuje
tablicu mnozenja za brojeve od 1 do 10.
#include<stdio.h>
main()
{
int i,j;
printf("<html><head><title>Mnozenje</title></head>");
printf("<body><h3 align=center> Rezultat </h3>");
printf("<table border=1>\n");
printf("</tr>");
}
printf("</table>");
printf("</body></html>");
}
52
4.24 Funkcije — prenos parametara po vrednosti 53
int prost(int p)
{
int i, koren, ind;
koren=sqrt(p);
ind=(p%2) || (p==2);
i=3;
while (ind && i<=koren)
{
ind=p%i;
i+=2;
}
return ind;
}
main()
{
int k;
for(k=2;k<=100;k++)
if (prost(k)) printf("%d ",k);
}
Primer 4.24.2
#include <stdio.h> /* Ilustruje vidljivost imena*/
int i=10;
void main() {
{
int i=3;
{
int i=1;
printf("%d\n", i);
}
printf("%d\n",i);
}
printf("%d\n",i);
}
53
54 Milena Vujošević–Janičić
void f(int x)
{
x++;
}
main()
{
int x=3;
f(x);
printf("%d\n", x);
}
main()
{
/* Obavezno je alocirati memoriju za niz karaktera */
char s[100];
get_word(s);
printf("%s\n", s);
}
Primer 4.24.5 Funkcija za ispis niza brojeva - demonstrira prenos nizova bro-
jeva u funkciju.
#include <stdio.h>
54
4.25 Break i continue 55
{
int i;
for (i = 0; i < n; i++)
printf("%d ",a[i]);
putchar(’\n’);
main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
#include <stdio.h>
main()
{
print_string("Zdravo\n");
}
55
56 Milena Vujošević–Janičić
s[n+1] = ’\0’;
return n;
}
Primer 4.25.2
for(i=0; i<n; i++)
{
if (a[i]==0) continue;
... /* obradi pozitivne elemente nekako*/
}
#include <stdio.h>
return i;
}
56
4.26 Rad sa niskama karaktera 57
main()
{
char s[] = "Zdravo svima";
string_reverse(s);
printf("%s\n", s);
}
/*
Izlaz:
amivs ovardZ
*/
#include <stdio.h>
57
58 Milena Vujošević–Janičić
58
4.26 Rad sa niskama karaktera 59
ukoliko s ne sadrzi c */
int string_last_char(char s[], char c)
{
/* Pronalazimo kraj stringa s */
int i;
for (i = 0; s[i]; i++)
;
/* Nije nadjeno */
return -1;
/*
Koristeci string_length :
return -1;
*/
}
main()
{
char s[100];
char t[] = "Zdravo";
59
60 Milena Vujošević–Janičić
string_copy(s, t);
printf("%s\n", s);
string_concatenate(s, u);
printf("%s\n", s);
printf("%d\n",string_char("racunari", ’n’));
printf("%d\n",string_last_char("racunari", ’a’));
printf("%d\n",string_string("racunari", "rac"));
printf("%d\n",string_string("racunari", "ari"));
printf("%d\n",string_string("racunari", "cun"));
printf("%d\n",string_string("racunari", "cna"));
}
/*
Izlaz:
Zdravo
Zdravo svima
4
5
0
5
2
-1*/
4.27 Makroi
#define ime tekst_zamene
#include<stdio.h>
60
4.27 Makroi 61
main()
{
printf("sum(3,5) = %d\n", sum(3,5));
printf("square_w(5) = %d\n", square_w(5));
printf("square_w(3+2) = %d\n", square_w(3+2));
printf("square(3+2) = %d\n", square(3+2));
printf("min(1,2,3) = %d\n", min(1,2,3));
printf("min(1,3,2) = %d\n", min(1,3,2));
printf("min(2,1,3) = %d\n", min(2,1,3));
printf("min(2,3,1) = %d\n", min(2,3,1));
printf("min(3,1,2) = %d\n", min(3,1,2));
printf("min(3,2,1) = %d\n", min(3,2,1));
}
Izlaz iz programa:
sum(3,5) = 8
square_w(5) = 25
square_w(3+2) = 11
square(3+2) = 25
min(1,2,3) = 1
min(1,3,2) = 1
min(2,1,3) = 1
min(2,3,1) = 1
min(3,1,2) = 1
min(3,2,1) = 1
Primer 4.27.2
#define max(A, B) ((A)>(B) ? (A) : (B))
x=max(p+q, r+s)
max(i++, j++)
61
62 Milena Vujošević–Janičić
Primer 4.27.4
#include <stdio.h>
#define max1(x,y) (x>y?x:y)
#define max2(x,y) ((x)>(y)?(x):(y))
#define swapint(x,y) { int z; z=x; x=y; y=z; }
#define swap(t,x,y) { \
t z; \
z=x; \
x=y; \
y=z; }
main()
{
int x=2,y=3;
swapint(x,y);
swap(int,x,y);
printf( "x = %d, y = %d\n", x, y );
/* x = 3, y = 5 */
}
Izlaz:
max1(x,y) = 3
max1(x=5,y) = 3
max1(x++,y++) = 4
x = 3, y = 5
x = 5, y = 3
x = 3, y = 5
62
4.28 Bitski operatori 63
#include <stdio.h>
main()
{ printf("%o %o\n",255,15);
printf( "255 & 15 = %d\n", 255 & 15 );
printf( "255 | 15 = %d\n", 255 | 15 );
printf( "255 ^ 15 = %d\n", 255 ^ 15 );
printf( "2 << 2 = %d\n", 2 << 2 );
printf( "16 >> 2 = %d\n", 16 >> 2 );
}
Primer 4.28.2 print bits - stampa bitove u zapisu datog celog broja x.
#include <stdio.h>
void print_bits(int x)
{
/* Broj bitova tipa unsigned */
63
64 Milena Vujošević–Janičić
int wl = sizeof(int)*8;
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
main()
{
print_bits(127);
print_bits(128);
print_bits(0x00FF00FF);
print_bits(0xFFFFFFFF);
}
Izlaz iz programa:
00000000000000000000000001111111
00000000000000000000000010000000
00000000111111110000000011111111
11111111111111111111111111111111
#include <stdio.h>
main()
{
int n,k;
printf("Unesite broj i poziciju tog broja koju zelite da proverite:\n");
scanf("%d%d",&n,&k);
if ((n & (1 << k))!=0)
printf("Bit je 1\n");
else
printf("Bit je 0\n");
}
void print_bits(int x)
{
/* Broj bitova tipa unsigned */
int wl = sizeof(int)*8;
64
4.28 Bitski operatori 65
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
main(){
int n,k;
printf("Unesite broj i poziciju tog broja koju zelite da promenite:\n");
scanf("%d%d",&n,&k);
printf("Binarno, une\v seni broj je\n");
print_bits(n);
printf("Novi broj je %d\n",(n |(1<<k)));
printf("Binarno, novi broj je\n");
print_bits((n |(1<<k)));
}
Primer 4.28.5 sum of bits - izračunava sumu bitova datog neoznačenog broja.
#include <stdio.h>
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
int sum_of_bits(unsigned x)
{
int br;
for (br = 0; x; x>>=1)
if (x&1)
br++;
return br;
}
65
66 Milena Vujošević–Janičić
main()
{
printf("Binarni zapis broja 127 je\n");
print_bits(127);
printf("Suma bitova broja 127 je %d\n",sum_of_bits(127));
printf("Binarni zapis broja 128 je\n");
print_bits(128);
printf("Suma bitova broja 128 je %d\n",sum_of_bits(128));
printf("Binarni zapis broja 0x00FF00FF je\n");
print_bits(0x00FF00FF);
printf("Suma bitova broja 0x00FF00FF je %d\n",sum_of_bits(0x00FF00FF));
printf("Binarni zapis broja 0xFFFFFFFF je\n");
print_bits(0xFFFFFFFF);
printf("Suma bitova broja 0xFFFFFFFF je %d\n",sum_of_bits(0xFFFFFFFF));
}
Izlaz iz programa:
Binarni zapis broja 127 je
00000000000000000000000001111111
Suma bitova broja 127 je 7
Binarni zapis broja 128 je
00000000000000000000000010000000
Suma bitova broja 128 je 1
Binarni zapis broja 0x00FF00FF je
00000000111111110000000011111111
Suma bitova broja 0x00FF00FF je 16
Binarni zapis broja 0xFFFFFFFF je
11111111111111111111111111111111
Suma bitova broja 0xFFFFFFFF je 32
Primer 4.28.6 get bits, set bits, invert bits - izdvajanje, postavljanje i inver-
tovanje pojedinacnih bitova
#include <stdio.h>
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
66
4.28 Bitski operatori 67
0000000...00011111
tako sto sve jedinice ~0 pomerimo u levo za n mesta
1111111...1100000
a zatim komplementiramo
*/
unsigned last_n_1 = ~(~0 << n);
main()
{
unsigned x = 0x0AA0AFA0;
print_bits(x);
67
68 Milena Vujošević–Janičić
Izlaz iz programa:
00001010101000001010111110100000
00000000000000000000000010101111
00001010101000001111111110100000
00001010101000000101000010100000
Primer 4.28.7 right rotate bits, mirror bits - rotiranje i simetrija bitova.
#include <stdio.h>
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
x |= last_bit<<wl-1;
}
return x;
}
68
4.29 Linearna i binarna pretraga 69
cita unatrag */
unsigned mirror(unsigned x)
{
int i;
int wl = sizeof(unsigned)*8;
main()
{
unsigned x = 0xFAF0FAF0;
print_bits(x);
print_bits(mirror(x));
print_bits(right_rotate(x, 2));
}
Izlaz iz programa:
11111010111100001111101011110000
00001111010111110000111101011111
00111110101111000011111010111100
69
70 Milena Vujošević–Janičić
{
int i;
for (i = 0; i<br_elem; i++)
if (niz[i] == x)
return i;
/* nikako else */
return -1;
}
main()
{
/* Inicijalizacija niza moguca je
i na ovaj nacin*/
int a[] = {4, 3, 2, 6, 7, 9, 11};
70
4.30 Razni zadaci 71
int d = n-1;
/* Element je nadjen */
return -1;
}
main()
{
int a[] = {3, 5, 7, 9, 11, 13, 15};
int x;
int i;
if (i==-1)
printf("Elementa %d nema\n", x);
else
printf("Pronadjen na poziciji %d\n", i);
}
71
72 Milena Vujošević–Janičić
main()
{
int n=-44;
char nst[100];
itoa(n,nst);
printf("%s\n",nst);
}
Primer 4.30.2 btoi - konverzija iz datog brojnog sistema u dekadni.
#include <stdio.h>
#include <ctype.h>
Npr.
cifra ’B’ u osnovi 16 ima vrednost 11
72
4.30 Razni zadaci 73
return -1;
}
return sum;
}
main()
{
char bin[] = "11110000";
char hex[] = "FF";
73
74 Milena Vujošević–Janičić
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
}
i = 0;
while ((to[i] = from[i]) != ’\0’)
++i;
}
74
4.30 Razni zadaci 75
#include <ctype.h>
#include <stdio.h>
#define MAXLINE 100
i = 0;
while (--lim > 0 && (c=getchar()) != EOF && c != ’\n’)
s[i++] = c;
if (c == ’\n’)
s[i++] = c;
s[i] = ’\0’;
return i;
}
if (s[i] == ’.’)
i++;
75
76 Milena Vujošević–Janičić
sum = 0;
while (getline(line, MAXLINE) > 0)
printf("\t%g\n", sum += atof(line));
}
Primer 4.30.5 Funkcija koja uklanja znak c kad god se pojavi u stringu s.
#include <stdio.h>
main()
{
char niz[20];
char c;
printf("Unesi karakter\n\n");
scanf("%c", &c);
scanf("%s", niz);
squeeze(niz, c);
printf("%s\n", niz);
}
4.31 Sortiranje
Primer 4.31.1 U prvom prolazu se razmenjuju vrednosti a[0] sa onim članovima
ostatka niza koji su veći od njega. Na taj način će se posle prvog prolaza kroz
niz a[0] postaviti na najveći element niza.
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Niz od maksimalno MAXDUZ elemenata*/
int a[MAXDUZ];
76
4.31 Sortiranje 77
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
exit(1);
}
/*Sortiranje*/
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(a[i]<a[j])
{
pom=a[i];
a[i]=a[j];
a[j]=pom;
}
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
putchar(’\n’);
return 0;
}
Primer 4.31.2 sort2
Modifikacija prethodnog rešenja radi dobijanja na efikasnosti. Ne vrše se zamene
svaki put već samo jednom, kada se prona e odgovarajući element u nizu sa
kojim treba izvršiti zamenu tako da u nizu bude postavljen trenutno najveći
element na odgovarajuće mesto.
#include<stdio.h>
#define MAXDUZ 100
int main()
{
77
78 Milena Vujošević–Janičić
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
exit(1);
}
return 0;
78
4.31 Sortiranje 79
}
Primer 4.31.3 bbsort1
Algoritam sortiranja buble sort poredi dva susedna elementa niza i ako su pogrešno
raspore eni zamenjuje im mesta. Posle pore enja svih susednih parova najmanji
od njih će isplivati na kraj niza. Zbog toga se ovaj metod naziva metod mehurića.
Da bi se najmanji broj nesortiranog dela niza doveo na svoje mesto treba ponoviti
postupak.
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Dimenzija niza, pomocna promenljiva
i brojacke promenljive */
int n,pom,i,j;
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
exit(1);
}
/*Sortiranje */
for(i=n-1; i>0; i--)
for(j=0; j<i; j++)
if(a[j]<a[j+1])
{
pom=a[j];
a[j]=a[j+1];
a[j+1]=pom;
}
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
79
80 Milena Vujošević–Janičić
}
Primer 4.31.4 bbsort2
Unapredjujemo prethodni algoritam kako bismo obezbedli da se ne vrše provere
onda kada je niz već sortiran nego da se u tom slučaju prekine rad.
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Dimenzija niza, pomocna promenljiva
i brojacke promenljive */
int n,pom,i,j;
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
exit(1);
}
/*Sortiranje */
for(zam=1,i=n-1; zam && i>0; i--)
for(zam=0,j=0; j<i; j++)
if(a[j]<a[j+1])
80
4.31 Sortiranje 81
{
/* Zamena odgovarajucih clanova niza */
pom=a[j];
a[j]=a[j+1];
a[j+1]=pom;
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
return 0;
}
Primer 4.31.5 isort
Insert sort, u svakom trenutku je početak niza sortiran a sortiranje se vrši tako
što se jedan po jedan element niza sa kraja ubacuje na odgovarajuće mesto.
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Dimenzija niza, pomocna
i brojacke promenljive */
int n,pom,i,j;
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n!\n");
exit(1);
}
81
82 Milena Vujošević–Janičić
scanf("%d",&a[i]);
}
/*Sortiranje*/
for(i=1; i<n; i++)
for(j=i; (j>0) && (a[j]>a[j-1]); j--)
{
pom=a[j];
a[j]=a[j-1];
a[j-1]=pom;
}
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
putchar(’\n’);
return 0;
}
Primer 4.31.6 Binarno pretrazivanje
#include<stdio.h>
#define MAXDUZ 100
int main()
{
/* Dimenzija niza,pomocna i brojacke
promenljive */
int n,pom,i,j;
82
4.31 Sortiranje 83
/*Sortiranje*/
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(a[i]>a[j])
{
pom=a[i];
a[i]=a[j];
a[j]=pom;
}
/* Unos elementa binarne pretrage */
printf("Unesite element koji se trazi\n");
scanf("%d",&x);
donji = 0;
gornji = n-1;
pozicija = -1;
while(donji<=gornji)
{
srednji = (donji + gornji)/2;
if(a[srednji] == x)
{
pozicija = srednji;
break;
}
else
if(a[srednji] < x)
donji = srednji + 1;
else
gornji = srednji -1;
}
/* Ispis rezultata */
if(pozicija == -1)
printf("Trazeni broj se ne nalazi u nizu!\n");
else
printf("Broj %d se nalazi na %d poziciji
sortiranog niza! \n",x,pozicija+1);
putchar(’\n’);
return 0;
}
Primer 4.31.7 Sabiranje dva velika broja, njihovo pore enje, unos i ispis, množenje
#include<stdio.h>
83
84 Milena Vujošević–Janičić
c=getchar();
while ( brcifara < maxduz && c >= ’0’ && c <= ’9’)
{
cifre[brcifara++]=c-’0’;
c=getchar();
}
return brcifara;
}
84
4.31 Sortiranje 85
return 0;
}
cifre[i] = pom%10;
pamtim = pom/10;
}
if (pamtim)
{
cifre[i]=pamtim;
brcifara=i+1;
}
else brcifara=i;
return brcifara;
}
85
86 Milena Vujošević–Janičić
return pbrcifara;
}
int main()
{
int d1,d2,d;
int broj1[MAXDUZ], broj2[MAXDUZ], zbir[MAXDUZ];
d1=unos_broja(broj1,MAXDUZ);
d2=unos_broja(broj2,MAXDUZ);
obrni(broj1,d1);
obrni(broj2,d2);
d=saberi(broj1,d1,broj2,d2,zbir);
ispisi(zbir,d);
return 0;
}
4.32 Rekurzija
C funkcije se mogu rekurzivno koristiti, što znači da funkcija može pozvati samu
sebe direktno ili indirektno.
86
4.32 Rekurzija 87
int main()
{
long int b=-1234;
printb(b);
putchar(’\n’);
return 0;
}
Kad funkcija rekurzivno pozove sebe, svakim pozivom pojavljuje se novi skup
svih automatskih promenljivih, koji je nezavisan od prethodonog skupa. Prva
funkcija printb kao argument dobija broj -12345, ona prenosi 1234 u drugu printb
funkciju, koja dalje prenosi 123 u treću, i tako redom do poslednje koja prima
1 kao argument. Ta funkcija štampa 1 i završava sa radom tako da se vraća na
prethodni nivo, na kome se štampa dva i tako redom.
#include<stdio.h>
int suma(int n)
{
if(n!=0)
return( n + suma(n-1) );
else return n;
}
main()
{
int S,n;
printf("Unesite n\n");
scanf("%d",&n);
S=suma(n);
printf("S=%d",S);
putchar(’\n’);
}
#include<stdio.h>
unsigned long fakt(int n)
{
if(n!=0)
return( n*fakt(n-1) );
else return 1;
}
main()
{
int n;
unsigned long f;
printf("Unesite n\n");
scanf("%d",&n);
87
88 Milena Vujošević–Janičić
f=fakt(n);
printf("f=%d",f);
putchar(’\n’);
}
int main()
{
int Fn,n;
printf("Unesite n\n");
scanf("%d",&n);
Fn=fibr(n);
printf("F[%d]=%d",n,Fn);
putchar(’\n’);
return 0;
}
88
4.33 Životni vek i oblast važenja promenjivih, statičke promenljive89
#include <stdio.h>
/* Globalna promenjiva */
int a = 0;
void nonstatic_var()
{
/* Nestaticke promenjive ne cuvaju vrednosti kroz pozive funkcije */
int s=0;
s++;
printf("nonstatic::s=%d\n",s);
}
void static_var()
{
/* Staticke promenjive cuvaju vrednosti kroz pozive funkcije.
Inicijalizacija se odvija samo u okviru prvog poziva. */
static int s=0;
s++;
printf("static::s=%d\n",s);
}
main()
89
90 Milena Vujošević–Janičić
{
/* Promenjive lokalne za funkciju main */
int i;
int x = 3;
increase();
decrease();
/* Globalna promenjiva a */
printf("main::a = %d\n", a);
Izlaz iz programa:
main::x = 3
for::x = 5
for::x = 5
for::x = 5
main::x = 3
increase::a = 1
decrease::a = -1
main::a = 1
nonstatic::s=1
nonstatic::s=1
nonstatic::s=1
static::s=1
static::s=2
static::s=3
90
4.34 Pokazivači 91
#include <stdio.h>
void f()
{
static int a;
a++;
printf("%d\n",a);
}
main()
{
int i;
for (i=0; i<=10; i++)
f();
}
4.34 Pokazivači
Pokazivač je promenljiva koja sadrži adresu promenljive.
#include <stdio.h>
main()
{
int x = 3;
91
92 Milena Vujošević–Janičić
px = &x;
printf("Vrednost promenljive px je (tj. px) : %p\n", px);
printf("Vrednost promenljive na koju ukazuje px (tj. *px) je : %d\n", *px);
void *pp;
Njemu može da se dodeli da pokazuje na int, ili na char ili na proizvoljan tip ali
je to neophodno eksplicitno naglasiti svaki put kada želimo da koristimo ono na
šta on pokazuje.
#include<stdio.h>
main()
{
void *pp;
int x=2;
char c=’a’;
pp = &x;
*(int *)pp = 17; /* x postaje 17*/
printf("\n adresa od x je %p", &x);
printf("\n%d i %p",*(int*)pp,(int * )pp);
pp = &c;
printf("\n adresa od c je %p", &c);
92
4.35 Pokazivači i argumenti funkcija 93
/*
adresa od x je 0012FF78
17 i 0012FF78
adresa od c je 0012FF74
a i 0012FF74
*/
swap(&a, &b);
93
94 Milena Vujošević–Janičić
main()
{
int div, mod;
printf("Adresa promenljive div je %p\n", &div);
printf("Adresa promenljive mod je %p\n", &mod);
94
4.36 Pokazivači i nizovi (polja) 95
Ako pa pokazuje na odre eni element polja, onda po definiciji pa+1 pokazuje
na sledeći element, pa+i pokazuje na i-ti element posle pa. Stoga, ako pa
pokazuje na a[0] tada
*(pa+1)
se odnosi na sadržaj od a[1].
pa+i je adresa od a[i], a
*(pa+i)
je sadržaj od a[i]. Dozvoljeno je upotrebljavati i sintaksu kao kod nizova:
*(pa+i) <==> pa[i]
Ovo sve važi bez obzira na tip ili veličinu elemenata u polju a.
Iskaz pa=&a[0] se može napisati kao pa=a jer je ime niza sinonim za
lokaciju početnog elementa.
#include <stdio.h>
main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int num_of_elements = sizeof(a)/sizeof(int);
int* pa;
95
96 Milena Vujošević–Janičić
/* sizeof(a) = 40
sizeof(pa) = 4 */
96
4.36 Pokazivači i nizovi (polja) 97
#include <stdio.h>
main()
{
int a[]={1,2,3,4,5,6,7,8};
int* poz=nadjiint(a,sizeof(a)/sizeof(int),4);
if (poz!=NULL)
printf("Element pronadjen na poziciji %d\n",poz-a);
}
Primer 4.36.3
int strlen(char *s)
{
int n;
for(n=0; *s != ’\0’; s++) n++;
return n;
}
Primer 4.36.4
/* Funkcija kopira string t u string s */
void copy(char* s, char* t)
{
while (*s++=*t++)
;
}
*/
97
98 Milena Vujošević–Janičić
Primer 4.36.5
/* Vrsi leksikografsko poredjenje dva stringa.
Vraca :
0 - ukoliko su stringovi jednaki
<0 - ukoliko je s leksikografski ispred t
>0 - ukoliko je s leksikografski iza t
*/
int string_compare1(char *s, char *t)
{
/* Petlja tece sve dok ne naidjemo
na prvi razliciti karakter */
for (; *s == *t; s++, t++)
if (*s == ’\0’) /* Naisli smo na kraj
oba stringa, a nismo nasli razliku */
return 0;
return *s - *t;
}
/* Nije nadjeno */
return NULL;
}
98
4.36 Pokazivači i nizovi (polja) 99
/* Nije nadjeno */
return NULL;
}
Primer 4.36.8
#include <stdio.h>
99
100 Milena Vujošević–Janičić
if (c==’\n’)
*s++ = c;
*s = ’\0’;
return s - line;
}
main()
{
char rec[]="zdravo";
char linija[100];
while (getline(linija, 100))
if (sadrzi_string_pok(linija, rec))
printf("%s",linija);
}
Primer 4.37.1
#include <stdio.h>
#include <stdlib.h>
main()
{
int n;
int i;
int *a;
100
4.37 Alokacija memorije 101
int a[n];
*/
a = (int*)malloc(n*sizeof(int));
/* Oslobadjamo memoriju*/
free(a);
}
Primer 4.37.2 Demonstracija funkcije calloc - funkcija inicijalizuje sadrzaj
memorije na 0.
#include <stdio.h>
#include <stdlib.h>
main()
{
int *m, *c, i, n;
101
102 Milena Vujošević–Janičić
free(m);
free(c);
}
102
4.38 Niz pokazivača 103
printf("%d", nizip[1][1]);
*(nizip[2]) = 2;
printf("%d", *(nizip[2]));
free(nizip[0]);
free(nizip[1]);
free(nizip[2]);
}
Primer 4.38.2
#include <stdio.h>
#include <stdlib.h>
main()
{
/* Niz karaktera*/
char nizc[5];
printf("%s", nizcp[0]);
printf("%s", nizcp[1]);
printf("%s", nizcp[2]);
}
103
104 Milena Vujošević–Janičić
#include <stdio.h>
int kvadrat(int n)
{
return n*n;
}
int kub(int n)
{
return n*n*n;
}
int parni_broj(int n)
{
return 2*n;
}
return suma;
}
main()
{
printf("Suma kvadrata brojeva od jedan do 3 je %d\n", sumiraj(kvadrat,3));
printf("Suma kubova brojeva od jedan do 3 je %d\n", sumiraj(kub,3));
printf("Suma prvih pet parnih brojeva je %d\n", sumiraj(parni_broj,5));
}
/*Izlaz:
Suma kvadrata brojeva od jedan do 3 je 14
Suma kubova brojeva od jedan do 3 je 36
Suma prvih pet parnih brojeva je 30
*/
4.40 Matrice
Primer 4.40.1 Statička alokacija prostora za matricu.
#include <stdio.h>
104
4.40 Matrice 105
main()
{
int a[3][3] = {{0, 1, 2}, {10, 11, 12}, {20, 21, 22}};
int i, j;
printf("%d\n", a[1][1]); /* 22 */
main()
{
/* Dimenzije matrice */
int m, n;
/* Matrica */
int *a;
int i,j;
105
106 Milena Vujošević–Janičić
/* Unos i alokacija */
printf("Unesi broj vrsta matrice : ");
scanf("%d",&m);
a=malloc(m*n*sizeof(int));
if (a == NULL) {
printf("Greska prilikom alokacije memorije!\n");
exit(1);
}
/* Oslobadjamo memoriju */
free(a);
}
Primer 4.40.3 Program ilustruje rad sa kvadratnim matricama i relacijama.
Elementi i je u relaciji sa elementom j ako je m[i][j] = 1, a nisu u relaciji ako
je m[i][j] = 0.
#include <stdlib.h>
#include <stdio.h>
106
4.40 Matrice 107
int** a;
int m,n;
*/
return m;
}
/* Ispis matrice /
void ispisi_matricu(int** m, int n)
{
int i, j;
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
printf("%d ",m[i][j]);
printf("\n");
107
108 Milena Vujošević–Janičić
}
}
return 1;
}
108
4.40 Matrice 109
a[i][j]=1;
}
}
main()
{
int **m;
int n;
int i,j;
ispisi_matricu(m,n);
if (refleksivna(m,n))
printf("Relacija je refleksivna\n");
if (simetricna(m,n))
printf("Relacija je simetricna\n");
if (tranzitivna(m,n))
printf("Relacija je tranzitivna\n");
simetricno_zatvorenje(m,n);
ispisi_matricu(m,n);
obrisi(m,n);
}
Primer 4.40.4 Izračunati vrednost determinante matrice preko Laplasovog razvoja.
#include <stdio.h>
#include <stdlib.h>
109
110 Milena Vujošević–Janičić
return m;
}
110
4.41 Strukture 111
{
int vrsta,kolona;
for (kolona=0; kolona<i; kolona++)
for(vrsta=1; vrsta<n; vrsta++)
podmatrica[vrsta-1][kolona] = matrica[vrsta][kolona];
for (kolona=i+1; kolona<n; kolona++)
for(vrsta=1; vrsta<n; vrsta++)
podmatrica[vrsta-1][kolona-1] = matrica[vrsta][kolona];
det+= znak*matrica[0][i]*determinanta(podmatrica,n-1);
znak*=-1;
}
deallocate(podmatrica,n-1);
return det;
}
main()
{
int **matrica;
int n;
scanf("%d", &n);
matrica = allocate(n);
ucitaj_matricu(matrica, n);
printf("Determinanta je : %d\n",determinanta(matrica,n));
deallocate(matrica, n);
}
4.41 Strukture
Informacije kojima se opisuje realni svet retko se predstavljaju u elementarnoj
formi u vidu celih, realnih, znakovnih konstanti itd. Mnogo češće imamo posla
sa složenim objektima koji se sastoje od elemenata raznih tipova. Na primer
jednu osobu karakterišu ime, prezime, datum i mesto ro enja.
Struktura predstavlja skup podataka kojim se opisuju neka bitna svojstva
objekta. Komponente koje obrazuju strukturu nazivaju se elementi strukture.
Sintaksa strukture:
struct ime_strukture
{
tip ime_elementa1;
tip ime_elementa2;
...
};
struct licnost
{
char ime[31];
111
112 Milena Vujošević–Janičić
char adresa[41];
unsigned starost;
};
struct
{
char ime[31];
char adresa[41];
unsigned starost;
} osoba1, osoba2;
Primer 4.41.2
osoba1.starost=20;
osoba2.starost=21;
...
if (osoba1.starost == osoba2.starost)
printf(" Osobe su iste starosti");
112
4.41 Strukture 113
posoba->ime
posoba->adresa
posoba->starost
struct datum
{
unsigned dan;
unsigned mesec;
unsigned godina;
};
struct licnost
{
char ime[30];
struct datum datumrodjenja;
};
osoba.datumrodjenja.dan = 10;
osoba.datumrodjenja.mesec = 5;
osoba.datumrodjenja.godina = 1986;
Nakon ovoga možemo u tekstu deklarista promenljivu x kao RealanBroj, ona će
zapravo biti tipa double.
113
114 Milena Vujošević–Janičić
struct _tacka {
float x;
float y;
}
može se koristiti:
#include <math.h>
#include <stdio.h>
/* Koordinatni pocetak */
tacka kp={0.0,0.0};
/* Niz tacaka */
tacka niz[100];
114
4.41 Strukture 115
void IspisiTacku(tacka A)
{
printf("(%f,%f)\n",A.x,A.y);
}
void IspisiVektor(vektor v)
{
printf("(%f,%f)\n",v.x,v.y);
}
float duzina(vektor v)
{
return sqrt(v.x*v.x+v.y*v.y);
}
/* Heronov obrazac */
float PovrsinaTrougla(tacka A, tacka B, tacka C)
{
float a=rastojanje(B,C);
float b=rastojanje(A,C);
float c=rastojanje(A,B);
float s=(a+b+c)/2.0;
return sqrt(s*(s-a)*(s-b)*(s-c));
}
return povrsina;
}
115
116 Milena Vujošević–Janičić
o+=rastojanje(poligon[0], poligon[br_temena-1]);
return o;
}
main()
{
tacka poligon[]={{0.0,0.0},
{0.0,1.0},
{1.0,1.0},
{1.0,0.0}};
printf("Obim poligona je %f\n",Obim(poligon,4));
printf("Povrsina poligona je %f\n",
PovrsinaKonveksnogPoligona(poligon,4));
}
Primer 4.41.6 Program koji učitava niz studenata i sortira ih po njihovim
ocenama.
#include <stdio.h>
#include <ctype.h>
#define MAX_IME 20
while (isspace(c=getchar()))
;
116
4.41 Strukture 117
c = getchar();
}
word[i]=’\0’;
main()
{
student studenti[100];
117
118 Milena Vujošević–Janičić
SelectionSort(studenti, br_studenata);
IspisiPodatke(studenti, br_studenata);
}
Primer 4.41.7 Dinamički niz.
/* Program za svaku rec unetu sa standardnog
ulaza ispisuje broj pojavljivanja.
Verzija sa dinamickim nizom i realokacijom.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
while (isspace(c=getchar()))
;
118
4.41 Strukture 119
word[i]=’\0’;
main()
{
char procitana_rec[80];
int i;
while (getword(procitana_rec,80)!=-1)
{
/* Proveravamo da li rec vec postoji u nizu */
for (i=0; i<duzina; i++)
/* Ako bismo uporedili procitana_rec == niz_reci[i].ime
bili bi uporedjeni pokazivaci a ne odgovarajuci sadrzaji!!!
Zato koristimo strcmp. */
if (strcmp(procitana_rec, niz_reci[i].ime)==0)
{
niz_reci[i].br_pojavljivanja++;
break;
}
if (novi_niz == NULL)
{
free(niz_reci);
119
120 Milena Vujošević–Janičić
free(niz_reci);
}
4.42 qsort
Primer 4.42.1 Implementacija funkcije qsort.
#include <stdio.h>
#include <string.h>
120
4.43 Sortiranje — generička funkcija 121
/* partition */
for (i = left + 1; i <= right; i++)
if (v[i] < v[left])
swap(v, ++last, i);
main()
{
int array[]={8, 3, 2, 6, 5, 7, 4, 9, 1};
int n=sizeof(array)/sizeof(int);
printarray(array, 0, n-1);
qsort(array, 0, n-1);
printarray(array, 0, n-1);
121
122 Milena Vujošević–Janičić
Razlike:
• pomoćna promenljiva;
• pore enje.
122
4.43 Sortiranje — generička funkcija 123
{
student pom=a[i];
a[i]=a[j];
a[j]=pom;
}
}
123
124 Milena Vujošević–Janičić
{
return strcmp(st1.ime, st2.ime);
}
Funkcija pore enja vraća 0 ukoliko su elementi jednaki, broj manji od nule
ukoliko je prvi manji od drugog i broj veći od nule ukolikoje prvi veći od drugog.
124
4.43 Sortiranje — generička funkcija 125
funkciju malloc odvojimo neko mesto u memoriji za smestanje elementa koji nam
u datoj situaciji treba. Koliko je to mesto? Nekada 4 bajta, npr za int, a nekada
dosta veće, npr za studenta. Kako funkcija sortiranja zna koliko mesta treba
da odvoji? Znace tako sto ćemo joj tu veličinu proslediti kao argument. Sada,
dakle umesto pomoćne promenljive, imamo blok u memoriji, a umesto naredbe
dodele koristićemo funkciju memcpy koja kopira deo memorije sa jednog mesta
na drugo mesto.
Dakle, razmenu ćemo da radimo na sledeći način:
Potpis funkcije pore enja ne sme da zavisi od tipa elemenata koji se porede.
To se može postići koristeći pokazivač na tip void.
Na primer, pore enje dva cela broja:
return br_a-br_b;
}
return student1.ocena-student2.ocena;
}
125
126 Milena Vujošević–Janičić
if (poredi(adresa_itog, adresa_jtog)<0)
{
void* tmp = malloc(size);
if (tmp==NULL) {
printf("Greska prilikom alokacije memorije!\n");
exit(1);
}
memcpy(tmp, adresa_itog, size);
memcpy(adresa_itog, adresa_jtog, size);
memcpy(adresa_jtog, tmp, size);
free(tmp);
}
}
}
return br_a-br_b;
}
126
4.44 qSort funkcija iz standardne biblioteke 127
main() {
int a[] = {8, 2, 1, 9, 3, 7, 6, 4, 5};
float b[] = {0.3, 2, 5, 5.8, 8}
int n = sizeof(a)/sizeof(int);
int nf = sizeof(b)/sizeof(float);
int i;
#include <stdlib.h>
#include <stdio.h>
return br_a-br_b;
*/
return *((int*)a)-*((int*)b);
}
127
128 Milena Vujošević–Janičić
main()
{
int i;
int niz[]={3,8,7,1,2,3,5,6,9};
float nizf[]={3.0,8.7,7.8,1.9,2.1,3.3,6.6,9.9};
int n=sizeof(niz)/sizeof(int);
qsort((void*)niz, n, sizeof(int), poredi);
for(i=0; i<n; i++)
printf("%d",niz[i]);
n=sizeof(nizf)/sizeof(float);
qsort((void*)nizf, n, sizeof(float), poredi_float);
for(i=0; i<n; i++)
printf("%f",nizf[i]);
}
Primer 4.44.2 Binarno pretraživanje - korišćenje ugra ene bsearch funkcije.
main()
{
int x=-1;
int niz[]={1,2,3,4,5,6,7,8,9,10,11,12};
int* elem=(int*)bsearch((void*)&x,
(void*)niz,
sizeof(niz)/sizeof(int),
sizeof(int),
poredi);
if (elem==NULL)
printf("Element nije pronadjen\n");
else
printf("Element postoji na poziciji %d\n",elem-niz);
}
128
4.45 Generičko sortiranje reči 129
podatke tipa char ** koji se konvertuju u svoj tip i derefenciraju radi dobijanja
podataka tipa char *.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
main()
{
int i;
char* nizreci[]={"Jabuka","Kruska","Sljiva","Dinja","Lubenica"};
129
130 Milena Vujošević–Janičić
}
Primer 4.45.2 Sa ulaza se unose reči. Program broji pojavljivanja svake od
ključnih reči programskog jezika C. Na kraju se reči ispisuju opadajuće po broju
pojavljivanja.
#include <stdio.h>
#include <stdlib.h>
word[i]=’\0’;
return i;
}
130
4.46 Argumenti komandne linije 131
main()
{
char word[80];
int i;
/* Citamo reci */
while (getword(word,80)!=-1)
{
/* Trazimo rec u spisku kljucnih reci binarnom pretragom */
keyword* k=(keyword*)bsearch((void*)word,
(void*)keywords,
num_of_keywords,
sizeof(keyword),
cmp);
/* Ukoliko je pronadjena uvecavamo broj pojavljivanja */
if (k!=NULL)
(*k).num++;
}
/* Vrsimo ispis */
for (i=0; i<num_of_keywords; i++)
printf("%s %d\n", keywords[i].word, keywords[i].num);
}
131
132 Milena Vujošević–Janičić
#include <stdio.h>
4.47 Datoteke
Primer 4.47.1 Program demonstrira otvaranje datoteka ("r" - read i "w" -
write mod) i osnovne tehnike rada sa datotekama.
/* U datoteku se upisuje prvih 10 prirodnih
brojeva, a zatim se iz iste datoteke
citaju brojevi dok se ne stigne do kraja i
ispisuju se na standardni izlaz */
#include <stdio.h>
#include <stdlib.h>
main()
{
int i;
132
4.47 Datoteke 133
/* Zatvaramo datoteku */
fclose(f);
/* Zatvaramo datoteku */
fclose(f);
}
133
134 Milena Vujošević–Janičić
#include <stdio.h>
main()
{
FILE* datoteka;
/* Zatvaramo datoteku */
fclose(datoteka);
}
Primer 4.47.3 Program ilustruje rad sa datotekama. Program kopira datoteku
čije se ime zadaje kao prvi argument komandne linije u datoteku čije se ime
zadaje kao drugi argument komandne linije. Uz svaku liniju se zapisuje i njen
redni broj.
#include <stdio.h>
134
4.47 Datoteke 135
char line[MAX_LINE];
FILE *in, *out;
int line_num;
if (argc != 3) {
fprintf(stderr,"Upotreba : %s ulazna_datoteka izlazna_datoteka\n",argv[0]);
return 1;
}
line_num = 1;
/* Zatvaramo datoteke */
fclose(in);
fclose(out);
}
Primer 4.47.4 Prodavnica - ilustruje čitanje niza struktura iz tektsualne da-
toteke.
/* Datoteka, cije se ime zadaje kao argument komandne linije
ili ako se ne zada onda se ime unosi sa standardnog
ulaza, sadrzi podatke o proizvodima koji se prodaju
135
136 Milena Vujošević–Janičić
Pretpostavljamo da se u prodavnici ne
prodaje vise od 1000 razlicitih artikala
Na standardni izlaz ispisati podatke o
svim proizvodima koji se prodaju u prodavnici.
Zadatak je moguce resiti i bez koriscenja nizova
(i takvo resenje je bolje). */
#include <stdio.h>
136
4.47 Datoteke 137
/* Prijavljujemo uspeh */
return 1;
}
137
138 Milena Vujošević–Janičić
/* Ucitavamo artikle */
while (ucitaj_artikal(f, &artikli[br_artikala]))
br_artikala++;
/* Zatvara se datoteka*/
fclose(f);
}
4.48 Liste
4.48.1 Red
A B ... X NULL
novi element
početak reda
novi kraj reda
A B ... X Y NULL
B ... X Y NULL
138
4.48 Liste 139
#include <stdlib.h>
while (broj) {
/*Alocira se prostor za novi clan liste*/
novi =(Elem*)malloc (sizeof (Elem));
if (novi == NULL)
{
fprintf(stderr, "Greska prilikom alokacije memorije\n");
exit(1);
}
/* Postavljanje vrednosti */
novi->broj = broj;
novi->sled = NULL;
/* Ispisivanje liste*/
139
140 Milena Vujošević–Janičić
if (preth != NULL )
preth->sled = tekuci;
/* Ovaj slucaj odnosi se na izbacivanje
elementa sa pocetka liste */
else lista = tekuci;
free (zaizbacivanje);
}
else
{
preth = tekuci;
tekuci = tekuci->sled;
}
140
4.48 Liste 141
return lista;
}
main ()
{
Elem *lista;
int k;
/* --------------------------------------------- */
/* Ispisivanje liste: iterativna verzija */
void ispisi_listu_i(CVOR* l) {
141
142 Milena Vujošević–Janičić
CVOR* t;
for (t = l; t != NULL; t=t->sl)
printf("%d ", t->br);
}
/* --------------------------------------------- */
/* Oslobadjanje liste : iterativna verzija */
void oslobodi_listu_i(CVOR* l) {
while (l!=NULL)
{
CVOR* tmp = l->sl;
free(l);
l = tmp;
}
}
/* --------------------------------------------- */
/* Ubacuje dati broj na pocetak date liste.
Funkcija pozivaocu eksplicitno vraca pocetak
rezultujuce liste.*/
CVOR* ubaci_na_pocetak(CVOR* l, int br) {
CVOR* novi = napravi_cvor(br);
142
4.48 Liste 143
novi->sl = l;
return novi;
}
if (l == NULL)
return novi;
else
{
CVOR* t;
/* Prodjemo do kraja liste */
for (t = l; t->sl!=NULL; t=t->sl)
;
t->sl = novi;
/* --------------------------------------------- */
/* Kljucna ideja u realizaciji ove funkcije je
pronalazenje poslednjeg elementa liste ciji
je kljuc manji od datog elementa br.
*/
CVOR* ubaci_sortirano(CVOR* pl, int br) {
CVOR* novi = napravi_cvor(br);
143
144 Milena Vujošević–Janičić
return pl;
}
main() {
CVOR* l = NULL;
CVOR* s = NULL;
int i;
for (i = 0; i<5; i++)
l = ubaci_na_kraj(l, i);
for (; i<10; i++)
l = ubaci_na_kraj_rekurzivno(l, i);
ispisi_listu_i(l);
putchar(’\n’);
ispisi_listu_r(l);
putchar(’\n’);
ispisi_listu_unazad(l);
putchar(’\n’);
oslobodi_listu_i(l);
s = ubaci_sortirano(s, 5);
s = ubaci_sortirano(s, 8);
s = ubaci_sortirano(s, 7);
s = ubaci_sortirano(s, 6);
144
4.48 Liste 145
s = ubaci_sortirano(s, 4);
ispisi_listu_r(s);
putchar(’\n’);
oslobodi_listu_r(s);
}
A B C ... Z
4.48.3 Stek
Primer 4.48.4 Program proverava da li su zagrade ( i ) dobro uparene.
#include <stdio.h>
#include <stdlib.h>
main()
{
int c;
int br_otv = 0;
while((c=getchar()) != EOF)
{
switch(c)
145
146 Milena Vujošević–Janičić
{
case ’(’:
br_otv++;
break;
case ’)’:
br_otv--;
if (br_otv<0)
{
printf("Visak zatvorenih zagrada\n");
exit(1);
}
}
}
if (br_otv == 0)
printf("Zagrade su u redu\n");
else
printf("Visak otvorenih zagrada\n");
}
#include <stdio.h>
#include <stdlib.h>
#define MAX_ZAGRADA 100
main()
{
int c;
char otv_zagrade[MAX_ZAGRADA];
int br_otv = 0;
while((c=getchar()) != EOF)
{
switch(c)
{
case ’(’:
case ’{’:
case ’[’:
{
otv_zagrade[br_otv] = c;
br_otv++;
break;
146
4.48 Liste 147
}
case ’]’:
case ’}’:
case ’)’:
if (br_otv>0 && odgovarajuce(otv_zagrade[br_otv-1], c))
{
br_otv--;
}
else
{
printf("Visak zatvorenih zagrada: %c u liniji %d\n", c, br_linija);
exit(1);
}
}
}
if (br_otv == 0)
printf("Zagrade su u redu\n");
else
printf("Visak otvorenih zagrada\n");
}
X Y ... A NULL
novi element
Y X V ... A NULL
X V ... A NULL
147
148 Milena Vujošević–Janičić
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define OTVORENA 1
#define ZATVORENA 2
#define GRESKA 0
s[i]=’\0’;
148
4.48 Liste 149
main()
{
char tag[MAX_TAG];
int zatvorenost;
while ((zatvorenost = gettag(tag, MAX_TAG))>0)
{
if (zatvorenost==OTVORENA)
{
/* Svaku otvorenu etiketu stavljamo na stek */
else
{
/* Za zatvorene etikete proveravamo da li je stek prazan
odnosno da li se na vrhu steka nalazi odgovarajuca
otvorena etiketa */
if (stek != NULL && strcmp(stek->tag, tag) == 0)
{
/* Uklanjamo etiketu sa steka */
CVOR* tmp = stek->sledeci;
free(stek);
stek = tmp;
}
else
{
/* Prijavljujemo gresku */
printf("Neodgovarajuci tag : </%s>!\n",tag);
149
150 Milena Vujošević–Janičić
exit(1);
}
}
}
...
NULL A B C ... Z NULL
#include <stdlib.h>
#include <stdio.h>
150
4.48 Liste 151
if (lista==NULL)
{ novi->sledeci=novi;
novi->prethodni=novi;
return novi;
}
else
{ novi->prethodni=lista;
novi->sledeci=lista->sledeci;
lista->sledeci->prethodni=novi;
lista->sledeci=novi;
return novi;
}
}
/* Ispis liste */
void ispisi(cvor* lista)
{
if (lista!=NULL)
{ cvor* tekuci=lista;
do
{ printf("%d\n",tekuci->broj);
tekuci=tekuci->sledeci;
} while (tekuci!=lista);
}
}
printf("Ispada %d\n",lista->broj);
151
152 Milena Vujošević–Janičić
lista->sledeci->prethodni=lista->prethodni;
lista->prethodni->sledeci=lista->sledeci;
free(lista);
return sledeci;
}
else return NULL;
}
main() {
/* Umecemo petoro dece u listu */
cvor* lista = NULL;
lista=ubaci(1,lista);
lista=ubaci(2,lista);
lista=ubaci(3,lista);
lista=ubaci(4,lista);
lista=ubaci(5,lista);
lista=lista->sledeci;
int smer = 0;
/* Dok ima dece u listi */
while(lista!=NULL)
{ int i;
lista=izbaci(lista);
smer = smer ? 0 : 1;
}
}
Primer 4.48.8 Program ispisuje broj pojavljivanja za svaku od reči koja se
pojavila u tekstu unetom sa standardnog ulaza. Verzija sa (sortiranom) listom.
#include <stdlib.h>
#include <stdio.h>
152
4.48 Liste 153
153
154 Milena Vujošević–Janičić
{ pocetak->sledeci=ubaci_sortirano(pocetak->sledeci,rec);
return pocetak;
}
/* Ukoliko je rec koju ubacujemo manja od tekuce reci, gradimo novi
cvor i ubacujemo ga ispred pocetka */
else
{ cvor* novi=malloc(sizeof(cvor));
if (novi == NULL)
{
printf("Greska prilikom alokacije memorije!\n");
exit(1);
}
strcpy(novi->ime,rec);
novi->br_pojavljivanja=1;
novi->sledeci=pocetak;
return novi;
}
}
if (c==EOF)
return -1;
do
{ word[i++]=c;
}while (i<lim-1 && isalpha(c=getchar()));
word[i]=’\0’;
return i;
}
return nadji_rec(lista->sledeci,rec);
}
154
4.49 Drvo 155
main()
{
cvor* lista=NULL;
char procitana_rec[80];
while(getword(procitana_rec,80)!=-1)
{ cvor* pronadjen=nadji_rec(lista,procitana_rec);
if (pronadjen!=NULL)
pronadjen->br_pojavljivanja++;
else
lista=ubaci_sortirano(lista,procitana_rec);
}
ispisi_listu(lista);
obrisi_listu(lista);
}
4.49 Drvo
NULL NULL
NULL NULL
155
156 Milena Vujošević–Janičić
12 21
NULL NULL
5 15
#include <stdlib.h>
#include <stdio.h>
156
4.49 Drvo 157
cvor* napravi_cvor(int b) {
cvor* novi = (cvor*)malloc(sizeof(cvor));
if (novi == NULL)
{
fprintf(stderr, "Greska prilikom
alokacije memorije");
exit(1);
}
novi->broj = b;
novi->l = NULL;
novi->d = NULL;
return novi;
}
if (b < drvo->broj)
drvo->l = ubaci_u_drvo(drvo->l, b);
else
drvo->d = ubaci_u_drvo(drvo->d, b);
return drvo;
}
if (drvo->broj == b)
return 1;
if (b < drvo->broj)
return pronadji(drvo->l, b);
else
return pronadji(drvo->d, b);
}
157
158 Milena Vujošević–Janičić
158
4.49 Drvo 159
return drvo->broj;
return suma_listova(drvo->l) +
suma_listova(drvo->d);
}
ispisi_listove(drvo->l);
ispisi_listove(drvo->d);
}
if (drvo->d==NULL)
return drvo->broj;
return max_vrednost(drvo->d);
}
159
160 Milena Vujošević–Janičić
main()
{
cvor* drvo = NULL;
drvo = ubaci_u_drvo(drvo, 1);
drvo = ubaci_u_drvo(drvo, 8);
drvo = ubaci_u_drvo(drvo, 5);
drvo = ubaci_u_drvo(drvo, 3);
drvo = ubaci_u_drvo(drvo, 7);
drvo = ubaci_u_drvo(drvo, 6);
drvo = ubaci_u_drvo(drvo, 9);
if (pronadji(drvo, 3))
printf("Pronadjeno 3\n");
if (pronadji(drvo, 2))
printf("Pronadjeno 2\n");
if (pronadji(drvo, 7))
printf("Pronadjeno 7\n");
ispisi_drvo(drvo);
putchar(’\n’);
printf("Suma cvorova : %d\n", suma_cvorova(drvo));
printf("Broj cvorova : %d\n", broj_cvorova(drvo));
printf("Broj listova : %d\n", broj_listova(drvo));
printf("Suma listova : %d\n", suma_listova(drvo));
printf("Dubina drveta : %d\n", dubina(drvo));
printf("Maximalna vrednost : %d\n", max_vrednost(drvo));
ispisi_listove(drvo);
obrisi_drvo(drvo);
}
/*
Pronadjeno 3
Pronadjeno 7
1 3 5 6 7 8 9
Suma cvorova : 39
160
4.49 Drvo 161
Broj cvorova : 7
Broj listova : 3
Suma listova : 18
Dubina drveta : 5
Maximalna vrednost : 9
3 6 9
*/
Primer 4.49.2 Program sa ulaza čita tekst i ispisuje broj pojavljivanja svake od
reči koje su se javljale u tekstu. Radi poboljsanja efikasnosti, prilikom brojanja
reci koristi se struktura podataka pogodna za leksikografsku pretragu - u ovom
slucaju binarno pretrazivacko drvo.
#include <stdlib.h>
#include <stdio.h>
161
162 Milena Vujošević–Janičić
{
cvor* novi_cvor=(cvor*)malloc(sizeof(cvor));
if (novi_cvor==NULL)
{
printf("Greska prilikom alokacije memorije\n");
exit(1);
}
strcpy(novi_cvor->ime, rec);
novi_cvor->br_pojavljivanja=1;
return novi_cvor;
}
162
4.49 Drvo 163
if (c==EOF)
return -1;
do
{
word[i++]=c;
} while (i<lim-1 && isalpha(c=getchar()));
word[i]=’\0’;
return i;
}
main() {
/* Drvo je na pocetku prazno */
cvor* drvo=NULL;
char procitana_rec[80];
/* Ispisujemo drvo */
ispisi_drvo(drvo);
/* Uklanjamo ga iz memorije */
obrisi_drvo(drvo);
}
#include <stdlib.h>
#include <stdio.h>
163
164 Milena Vujošević–Janičić
} cvor;
cvor* razlicite_reci[MAX_BROJ_RAZLICITIH_RECI];
return novi_cvor;
}
int cmp = strcmp(rec, drvo->ime);
164
4.49 Drvo 165
{ drvo->br_pojavljivanja++;
return drvo;
}
word[i]=’\0’;
return i;
}
165
166 Milena Vujošević–Janičić
-
(*(cvor**)a)->br_pojavljivanja;
}
if (argc!=2)
{ fprintf(stderr,"Greska :
Ocekivano ime datoteke\n");
exit(1);
}
if ((ulaz=fopen(argv[1],"r"))==NULL)
{
fprintf(stderr,"Greska : nisam uspeo da otvorim datoteku %s\n");
exit(1);
}
fclose(ulaz);
}
166
4.50 Grafovi 167
4.50 Grafovi
Graf1 G=(V,E) sastoji se od skupa V čvorova i skupa E grana. Grane predstavl-
jaju relacije izme u čvorova i odgovara paru čvorova. Graf može biti usmeren
(orijentisan), ako su mu grane ure eni parovi i neusmeren (neorjentisan) ako su
grane neure eni parovi.
Uobičajena su dva načina predstavljanja grafova. To su matrica povezanosti
grafa i lista povezanosti.
Matrica povezanosti je kvadratna matrica dimenzije n, pri čemu je n broj
čvorova u grafu, takva da je element na preseku i-te vrste i j-te kolone jednak
jedinici ukoliko postoji grana u grafu od i-tog do j-tog čvora, inače je nula.
Umesto da se i sve nepostojeće grane eksplicitno predstavljaju u matrici
povezanosti, mogu se formirati povezane liste od jedinica iz i-te vrste za i=1,2,...,n.
To je lista povezanosti. Svakom čvoru se pridružuje povezana lista, koja sadrži
sve grane susedne tom čvoru. Graf je predstavljen vektorom lista. Svaki eleme-
nat vektora sadrži ime (indeks) čvora i pokazivač na njegovu listu čvorova.
Prvi problem na koji se nailazi pri konstrukciji bilo kog algoritma za obradu
grafa je kako pregledati ulaz. Postoje dva osnovna algoritma za obilazak grafa:
pretraga u dubinu (DFS, skraćenica od depth-first-search) i pretraga u širinu
(BFS, skraćenica od breadth-first-search).
Kod DFS algoritma, obilazak započinje iz proizvoljnog zadatog čvora r koji
se naziva koren pretrage u dubinu. Koren se označava kao posećen. Zatim se
bira proizvoljan neoznačen čvor r1, susedan sa r, pa se iz čvora r1 rekurzivno
startuje pretraga u dubinu. Iz nekog nivoa rekurzije izlazi se kad se nai e na
čvor v kome su svi susedi već označeni.
su dostižni iz čvora 0.
#include <stdlib.h>
#include <stdio.h>
int** alociraj_matricu(int n)
{ int **matrica;
int i;
matrica=malloc(n*sizeof(int*));
if (matrica==NULL)
{
printf("Greska prilikom alokacije memorije\n");
exit(1);
}
167
168 Milena Vujošević–Janičić
if (matrica[i]==NULL)
{
printf("Greska prilikom alokacije memorije\n");
exit(1);
}
}
return matrica;
}
int* alociraj_niz(int n)
{ int* niz;
niz=calloc(n,sizeof(int));
if (niz==NULL)
{
printf("Greska prilikom alokacije memorije\n");
exit(1);
}
return niz;
}
168
4.50 Grafovi 169
printf("\n");
}
}
main()
{
int i, j;
printf("Unesi broj cvorova : ");
scanf("%d",&n);
graf=alociraj_matricu(n);
unesi_graf(graf,n);
ispisi_graf(graf,n);
posecen=alociraj_niz(n);
poseti(0);
oslobodi_niz(posecen);
oslobodi_matricu(graf,n);
}
Primer 4.50.2 Primer predstavljanja grafa preko niza listi suseda svakog od
čvorova grafa U programu se unosi graf i DFS algoritmom se utvrdjuje koji su
čvorovi dostižni iz cvora 0.
#include <stdlib.h>
#include <stdio.h>
169
170 Milena Vujošević–Janičić
/* Ispis liste */
void ispisi_listu(cvor_liste* lista)
{ if (lista)
{ printf("%d ",lista->broj);
ispisi_listu(lista->sledeci);
}
}
170
4.51 Razni zadaci 171
main()
{
int i;
printf("Unesi broj cvorova grafa : ");
scanf("%d",&broj_cvorova);
for (i=0; i<broj_cvorova; i++)
{ int br_suseda,j;
graf[i]=NULL;
poseti(0);
}
171
172 Milena Vujošević–Janičić
}
return s;
}
Primer 4.51.2 MINESWEEPER - primer jednostavne igrice.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/* Dimenzija table */
int n;
172
4.51 Razni zadaci 173
free(m);
}
/* Postavljamo bombu */
bombe[vrsta][kolona]=1;
}
}
173
174 Milena Vujošević–Janičić
return br;
174
4.51 Razni zadaci 175
175
176 Milena Vujošević–Janičić
pokriveno zastavicom
*/
int gotova_partija()
{ int i,j;
for (i=0; i<n; i++)
for (j=0; j<n; j++)
{ /* Ukoliko postoji nepokrivena bomba,
partija nije zavrsena */
if (bombe[i][j]==1 && stanje[i][j]!=ZASTAVICA)
return 0;
}
main() {
/* Alociramo table */
bombe=alociraj(n);
stanje=alociraj(n);
/* Postavljamo bombe */
postavi_bombe();
176
4.51 Razni zadaci 177
/* Reagujemo na akciju */
switch(akcija)
{ case ’o’:
otvori_polje(v-1,k-1);
break;
case ’z’:
postavi_zastavicu(v-1,k-1);
}
}
/* Konstatujemo pobedu */
ispisi_stanje();
printf ("Cestitam! Pobedili ste\n");
obrisi(stanje,n);
obrisi(bombe,n);
}
177
Programiranje 1
Programski jezik C
— Zadaci sa vežbi —
Milena Vujosevic-Janicic
www.matf.bg.ac.yu/~milena
1
Sadrzaj
1 Programski jezik C 4
1.1 Zdravo svete! . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Imena promenljivih . . . . . . . . . . . . . . . . . . . 5
1.3 Deklaracije . . . . . . . . . . . . . . . . . . . . . . . 5
1.4 Tipovi i velicina podataka . . . . . . . . . . . . . . . 5
1.5 Konstante . . . . . . . . . . . . . . . . . . . . . . . . 7
1.6 Funkcije printf i scanf . . . . . . . . . . . . . . . . . . 8
1.7 Aritmeticki operatori . . . . . . . . . . . . . . . . . . 10
1.8 Operatori i izrazi dodeljivanja vrednosti . . . . . . . 12
1.9 Inkrementacija i dekrementacija . . . . . . . . . . . . 12
1.10 Relacioni i logicki operatori . . . . . . . . . . . . . . 14
1.11 Kontrola toka — if, while, do - while, for . . . . . . . 15
1.11.1 if . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.11.2 Else-if . . . . . . . . . . . . . . . . . . . . . . 16
1.11.3 while . . . . . . . . . . . . . . . . . . . . . . . 18
1.11.4 do-while . . . . . . . . . . . . . . . . . . . . . 18
1.11.5 for . . . . . . . . . . . . . . . . . . . . . . . . 18
1.12 Switch . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.13 Uslovni izraz . . . . . . . . . . . . . . . . . . . . . . . 20
1.14 Konverzija . . . . . . . . . . . . . . . . . . . . . . . . 21
1.14.1 Automatska konverzija . . . . . . . . . . . . . 21
1.14.2 Eksplicitna konverzija . . . . . . . . . . . . . 21
1.15 Dvostruka for petlja . . . . . . . . . . . . . . . . . . 22
1.16 Simbolicke konstante . . . . . . . . . . . . . . . . . . 22
1.17 Enumeracija . . . . . . . . . . . . . . . . . . . . . . . 24
1.18 Operator sizeof() . . . . . . . . . . . . . . . . . . . 24
1.19 Znakovni ulaz i izlaz . . . . . . . . . . . . . . . . . . 25
1.20 Makroi . . . . . . . . . . . . . . . . . . . . . . . . . . 32
1.21 Pokazivaci . . . . . . . . . . . . . . . . . . . . . . . . 35
1.22 Nizovi . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.23 Pokazivaci i nizovi (polja) . . . . . . . . . . . . . . . 40
1.24 Break i continue . . . . . . . . . . . . . . . . . . . . . 42
2
SADRŽAJ SADRŽAJ
1.25 Funkcije . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.26 Zivotni vek i oblast vazenja promenjivih, staticke promenljive 46
1.27 Funkcije — prenos parametara po vrednosti . . . . . 49
1.28 Pokazivaci i argumenti funkcija . . . . . . . . . . . . 52
1.29 Povratne vrednosti funkcija . . . . . . . . . . . . . . 56
1.30 Rad sa niskama karaktera . . . . . . . . . . . . . . . 58
1.31 Linearna i binarna pretraga . . . . . . . . . . . . . . 69
1.32 Strukture . . . . . . . . . . . . . . . . . . . . . . . . 72
1.33 Operator typedef . . . . . . . . . . . . . . . . . . . . 74
1.34 Unije . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
1.35 Strukture — primeri . . . . . . . . . . . . . . . . . . 76
1.36 Datoteke . . . . . . . . . . . . . . . . . . . . . . . . . 86
3
Glava 1
Programski jezik C
main()
/*iskazi f-je main su zatvoreni u zagrade */
{
/*poziv f-je printf da odstampa poruku*/
printf("hello, world\n");
}
Primer 1.1.2 Program štampa poruku ”hello, world”
#include <stdio.h>
main()
{
printf("hello, ");
printf("world");
printf("\n");
}
Specijalni znaci:
\n novi red
\t tabulator
\\ kosa crta
\" navodnici
\a zvuk
\’ jednstruki navodnik
4
Milena Vujošević–Janičić 1.2 Imena promenljivih
1.3 Deklaracije
Da bi se promenljiva mogla upotrebljavati ona se mora na pocetku
programa deklarisati. Prilikom deklaracije moze se izvrsiti i pocetna
inicijalizacija.
Kvali kator const moze biti dodeljen deklaraciji bilo koje promenljive
da bi oznacio da se ona nece menjati
const double e=2.71828182845905
5
Milena Vujošević–Janičić 1.4 Tipovi i veličina podataka
Vazi
broj bajtova(short) <= broj bajtova(int) <= broj bajtova(long)
Tip char zauzima jedan bajt ali u zavisnosti od sistema ovaj
tip moze da se odnosi na oznacene ili na neoznacene brojeve. Zato
Postoje kvali katori signed i unsigned koji preciziraju da li se misli
na oznacene ili neoznacene cele brojeve. Npr.
signed char: -128 do 127
dok je
unsigned char: od 0 do 255.
Velicina za int je razlicita u zavisnosti od sistema i moze biti 2
ili 4 bajta. Med̄utim, ako je promenljiva tipa short int onda ona
sigurno zauzima samo dva bajta a to znaci da u nju mogu da stanu
celobrojne vrednosti iz intervala -32 768 do +32 767, odnosno mogu
se koristiti sledeci sinonimi
short <=> short int <=> signed short int <=> -32 768 do 32 767
Ukoliko se koristi unsigned short int onda je interval
unsigned short int <=> 0 do 65 535
Za realne tipove podataka koriste se float, double i long double.
Njihove velicine mogu da zavise od sistema. Na primer:
float (4 bajta)
float minimalna pozitivna vrednost 1.175494351e-38
float maximalna pozitivna vrednost 3.402823466e+38
double (8 bajta)
double minimalna pozitivna vrednost 2.2250738585072014e-308
double maximalna pozitivna vrednost 1.7976931348623158e+308
main()
{
/*deklaracija vise promenljivih
istog tipa */
int rez,pom1,pom2;
pom1=20;
6
Milena Vujošević–Janičić 1.5 Konstante
pom2=15;
rez=pom1-pom2;
/*ispisivanje rezultata*/
printf("Rezultat je %d-%d=%d\n",pom1,pom2,rez);
}
Izlaz iz programa:
Rezultat je 20-15=5
Iskaz dodele:
pom1=20;
pom2=15;
Individualni iskazi se zavrsavaju sa ;
1.5 Konstante
Koji su tipovi konstanti?
Celobrojna konstanta 1234 je tipa int.
Da bi konstanta bila long navodi se iza nje slovo L ili l, npr 123456789L.
Ako zelimo da nam je konstanta unsigned onda na kraju pisemo U
ili u.
Moze i 1234567ul.
7
Milena Vujošević–Janičić 1.6 Funkcije printf i scanf
8
Milena Vujošević–Janičić 1.6 Funkcije printf i scanf
#include <stdio.h>
main()
{
int vrednost;
vrednost=’A’;
printf("Veliko slovo\n karakter=%3c\nvrednost=%3d\n",vrednost,vrednost);
vrednost=’a’;
printf("Malo\n karakter=%3c\nvrednost=%3d\n",vrednost,vrednost);
}
main()
{
int x;
printf("Unesi ceo broj : ");
main()
{
9
Milena Vujošević–Janičić 1.7 Aritmetički operatori
int a, b, c;
printf("Unesi prvi broj : ");
scanf("%d", &a);
printf("Unesi drugi broj : ");
scanf("%d", &b);
c = a + b;
printf("%d + %d = %d\n", a, b, c);
}
Ulaz:
Unesi prvi broj : 2 <enter>
Unesi drugi broj : 3 <enter>
Izlaz:
2 + 3 = 5
10
Milena Vujošević–Janičić 1.7 Aritmetički operatori
Ulaz:
Unesi prvi broj : 2 <enter>
Unesi drugi broj : 3 <enter>
Izlaz:
Zbir a+b je : 5
Razlika a-b je : -1
Proizvod a*b je : 6
Celobrojni kolicnik a/b je : 0
Progresan pokusaj racunanja realnog kolicnika a/b je : 0.000000
Realni kolicnik a/b je : 0.666667
Ostatak pri deljenju a/b je : 2
Primer 1.7.2 Program ilustruje celobrojno i realno deljenje.
#include <stdio.h>
main()
{
int a = 5;
int b = 2;
int d = 5/2; /* Celobrojno deljenje - rezultat je 2 */
float c = a/b; /* Iako je c float, vrsi se celobrojno
deljenje jer su i a i b celi */
Izlaz iz programa:
c = 2.000000
Uzrok problema : 5/2 = 2.000000
11
Milena Vujošević–Janičić 1.8 Operatori i izrazi dodeljivanja vrednosti
Moze i za:
+ - * / % << >> ^ |
izraz1 op = izraz2
je ekvivalnetno sa
izraz1 = (izraz1) op (izraz2)
y=(x++)*(++z);
Primer 1.9.1 Ilustracija prefiksnog i postfiksnog operatora ++
12
Milena Vujošević–Janičić 1.9 Inkrementacija i dekrementacija
#include <stdio.h>
main()
{
int x, y;
int a = 0, b = 0;
Izlaz iz programa:
Na pocetku:
a = 0
b = 0
Posle : a++; ++b;
a = 1
b = 1
Posle : x = ++a;
a = 2
x = 2
Posle : y = b++;
b = 2
y = 1
13
Milena Vujošević–Janičić 1.10 Relacioni i logički operatori
(3<5)
(a<=10)
a < 5 != 1 <=> (a < 5)!=1
Logicki operatori:
! unarna negacija (najvisi prioritet)
&& logicko i (visi prioritet od ili)
|| logicko ili izracunavaju se sleva na desno!
main()
{
int a = 3>5, /* manje */
b = 5>3, /* vece */
c = 3==5, /* jednako */
d = 3!=5; /* razlicito */
14
Milena Vujošević–Janičić 1.11 Kontrola toka — if, while, do - while, for
Izlaz iz programa:
3>5 - 0
5>3 - 1
3==5 - 0
3!=5 - 1
Konjunkcija : 3>5 && 5>3 - 0
Disjunkcija : 3>5 || 5>3 - 1
Negacija : !(3>5) - 1
main()
{
int b;
printf("Unesi ceo broj:");
scanf("%d", &b);
if (b < 0)
printf("Broj je negativan\n");
}
15
Milena Vujošević–Janičić 1.11 Kontrola toka — if, while, do - while, for
if (izraz1) iskaz 1
else iskaz
ovo else se odnosi na drugo if a ne na prvo if!
if (izraz)
{
if (izraz1) iskaz 1
}
else iskaz
tek sada se else odnosi na prvo if!!!
1.11.2 Else-if
if (izraz1)
iskaz1
else if (izraz2)
iskaz2
else if (izraz3)
iskaz3
else if (izraz4)
iskaz4
else iskaz
npr if (a<5)
printf("A je manje od 5\n");
else if (a=5)
printf("A je jednako 5\n");
else if (a>10)
printf("A je vece od 10\n");
else if (a=10)
printf("A je jednako 10\n");
else printf("A je vece od pet i manje od 10\n");
Primer 1.11.2 Program ilustruje if-else konstrukciju i ispituje znak
broja.
#include <stdio.h>
main()
{
int b;
printf("Unesi ceo broj : ");
scanf("%d", &b);
16
Milena Vujošević–Janičić 1.11 Kontrola toka — if, while, do - while, for
if (b < 0)
printf("Broj je negativan\n");
else if (b == 0)
printf("Broj je nula\n");
else
printf("Broj je pozitivan\n");
}
Ulaz:
Unesi ceo broj:-5
Izlaz:
Broj je negativan
Ulaz:
Unesi ceo broj:5
Izlaz:
Broj je pozitivan
main()
{
int b;
printf("Unesi ceo broj : ");
scanf("%d", &b);
Ulaz:
Unesi ceo broj:-5
Izlaz:
Broj je pozitivan
17
Milena Vujošević–Janičić 1.11 Kontrola toka — if, while, do - while, for
1.11.3 while
while(uslov) { ... }
Uslov u zagradi se testira i ako je ispunjen telo petlje se izvrsava.
Zatim se uslov ponovo testira i ako je ispunjen ponovo se izvrsava
telo petlje. I tako sve dok uslov ne bude ispunjen. Tada se izlazi iz
petlje i nastavlja sa prvom sledecom naredbom u programu.
Ukoliko iza while sledi samo jedna naredba nema potrebe za
zagradama.
while (i<j)
i=2*i;
1.11.4 do-while
Ovo je slicno paskalskom repeat-until izrazu.
do iskaz while (izraz)
Primer 1.11.4 Program ilustruje petlju do-while.
#include <stdio.h>
main()
{
int x;
x = 1;
do
{
printf("x = %d\n",x);
x++; /* x++ je isto kao i x=x+1 */
} while (x<=10);
}
1.11.5 for
Primer 1.11.5 Program ilustruje petlju - for.
#include <stdio.h>
main()
{
int x;
18
Milena Vujošević–Janičić 1.12 Switch
}
Izlaz:
1
2
3
4
1.12 Switch
switch (iskaz) {
case konstantan_izraz1: iskazi1
case konstantan_izraz2: iskazi2
...
default: iskazi
}
Primer 1.12.1 Voditi računa o upotrebi break-a.
#include <stdio.h> /*
Upotreba switch-a
*/
main() {
char x;
scanf("%c",&x);
switch (x)
{
case ’a’:
case ’e’:
case ’i’:
case ’o’:
case ’u’: printf(" x je samoglasnik");
break;
case ’r’: printf(" x je r");
break;
default: printf(" x je suglasnik");
}
}
Primer 1.12.2 Ilustracija switch konstrukcije.
19
Milena Vujošević–Janičić 1.13 Uslovni izraz
#include<stdio.h>
main()
{
int n;
printf("Unesi paran broj manji od 10\n");
scanf("%d",&n);
switch(n) {
case 0:
printf("Uneli ste nulu\n");
break;
case 2:
printf("Uneli ste dvojku\n");
break;
case 4:
printf("Uneli ste cetvorku\n");
break;
case 6:
printf("Uneli ste sesticu\n");
break;
case 8:
printf("Uneli ste osmicu\n");
break;
defalut:
printf("Uneli ste nesto sto nije paran broj\n");
}
}
Ulaz:
Unesi paran broj manji od 10
2
Izlaz:
Uneli ste dvojku
z = (a<b)? a : b; /*z=min(a,b)*/
max = (a>b)? a : b;
20
Milena Vujošević–Janičić 1.14 Konverzija
1.14 Konverzija
1.14.1 Automatska konverzija
Ako je jedan od operanada razlizlicit vrsi se konverzija, uvek u smeru
manjeg ka vecem tipu
Naredba dodele:
int i=5;
float f=2.3;
f=i; /* f ce imati vrednost 5.0*/
obrnuto:
int i=5;
float f=2.3;
i=f; /* i ce imati vrednost 2*/
float x;
x=2.3+4.2; /* x ce imati vrednost 6.5 */
x=(int)2.3+(int)4.2; /* x ce imati vrednost 6 */
x=(int)2.3*4.5; /* x ce imati vrednost 9.0 jer zbog prioriteta
operatora konverzije prvo ce biti izvrsena
konverzija broja 2.3 u 2 pa tek onda izvrseno
mnozenje. */
x=(int)(2.3*4.5) /* x ce imati vrednost 10.0 */
Primer 1.14.1 Kako izbeći celobrojno deljenje
int a,b;
float f;
a = 5;
b = 2;
f = a/b; /* Celobrojno deljenje, f=2*/
f = (1.0*a)/b; /* Implicitna konverzija: 1.0*a je realan
broj pa priliko deljenja sa b dobija se
realan rezultat f=2.5*/
f = (0.0+a)/b; /* Implicitna konverzija: (0.0+a) je realan
broj pa priliko deljenja sa b dobija se
realan rezultat f=2.5*/
21
Milena Vujošević–Janičić 1.15 Dvostruka for petlja
22
Milena Vujošević–Janičić 1.16 Simboličke konstante
#define POCETAK 0
#define KRAJ 20
#define KORAK 10
main()
{
int a;
a = POCETAK;
while (a <= KRAJ)
{
printf("%d cm = %f in\n", a, a/2.54);
a += KORAK; /* isto sto i a = a + KORAK; */
}
}
Izlaz:
0 cm = 0.000000 in
10 cm = 3.937008 in
20 cm = 7.874016 in
main()
{
int a;
for (a = POCETAK; a <= KRAJ; a += KORAK)
printf("%d cm = %f in\n", a, a/2.54);
}
Izlaz:
0 cm = 0.000000 in
10 cm = 3.937008 in
20 cm = 7.874016 in
Zadatak 2 Šta će biti ispisano nakon izvršavanja sledećeg programa?
23
Milena Vujošević–Janičić 1.17 Enumeracija
#include <stdio.h>
#define EURO 85.90
main()
{
printf("4 eura ima vrednost %f dinara\n", 4*EURO);
printf("1 euro ima vrednost %.0f dinara\n",EURO);
}
1.17 Enumeracija
Izvesna alternativa za define
enum boolean {NO, YES};
enum meseci {JAN = 1, FEB, MAR, APR, MAJ, JUN,
JUL, AVG, SEP, OKT, NOV, DEC}
enum boje {CRVENA, ZELENA=5, PLAVA,
LJUBICASTA=10, ZUTA, CRNA}
koriscenje:
int x=0;
boje b;
b=ZELENA;
x=b+CRNA; /* x = 5 + 12*/
24
Milena Vujošević–Janičić 1.19 Znakovni ulaz i izlaz
printf("sizeof(int)=%d\n", sizeof(int));
printf("sizeof(long)=%d\n", sizeof(long));
printf("sizeof(short)=%d\n", sizeof(short));
printf("sizeof(signed)=%d\n", sizeof(signed));
printf("sizeof(unsigned)=%d\n", sizeof(unsigned));
printf("sizeof(char)=%d\n", sizeof(char));
printf("sizeof(float)=%d\n", sizeof(float));
printf("sizeof(double)=%d\n", sizeof(double));
printf("sizeof(i)=%d\n", sizeof(i));
printf("sizeof(f)=%d\n", sizeof(f));
}
25
Milena Vujošević–Janičić 1.19 Znakovni ulaz i izlaz
main()
{
int c; /* Karakter - obratiti paznju na int */
c = getchar(); /* cita karakter sa standardnog ulaza */
putchar(c); /* pise karakter c na standardni izlaz */
}
Ulaz:
s
Izlaz iz programa:
s
s
aa
K
d
main()
{
int c;
26
Milena Vujošević–Janičić 1.19 Znakovni ulaz i izlaz
#include <stdio.h>
main()
{
int c;
main()
{
27
Milena Vujošević–Janičić 1.19 Znakovni ulaz i izlaz
int c;
main()
{
long broj_znakova;
broj_znakova = 0;
while (getchar() != EOF)
++broj_znakova;
/* %ld odnosi se na tip long. */
printf("%ld\n", broj_znakova);
}
main()
{
long broj_znakova;
28
Milena Vujošević–Janičić 1.19 Znakovni ulaz i izlaz
main()
{
int c;
int br_cifara = 0;
while ((c = getchar()) != EOF)
29
Milena Vujošević–Janičić 1.19 Znakovni ulaz i izlaz
main()
{
int c;
int br_0=0, br_1=0, br_2=0;
main()
{
30
Milena Vujošević–Janičić 1.19 Znakovni ulaz i izlaz
main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == ’\n’)
++nl;
if (c == ’ ’ || c == ’\n’ || c == ’\t’)
state = OUT;
31
Milena Vujošević–Janičić 1.20 Makroi
1.20 Makroi
#define ime tekst_zamene
main()
{
printf("sum(3,5) = %d\n", sum(3,5));
printf("square_w(5) = %d\n", square_w(5));
printf("square_w(3+2) = %d\n", square_w(3+2));
printf("square(3+2) = %d\n", square(3+2));
printf("min(1,2,3) = %d\n", min(1,2,3));
printf("min(1,3,2) = %d\n", min(1,3,2));
printf("min(2,1,3) = %d\n", min(2,1,3));
printf("min(2,3,1) = %d\n", min(2,3,1));
32
Milena Vujošević–Janičić 1.20 Makroi
Izlaz iz programa:
sum(3,5) = 8
square_w(5) = 25
square_w(3+2) = 11
square(3+2) = 25
min(1,2,3) = 1
min(1,3,2) = 1
min(2,1,3) = 1
min(2,3,1) = 1
min(3,1,2) = 1
min(3,2,1) = 1
Primer 1.20.2
#define max(A, B) ((A)>(B) ? (A) : (B))
max(i++, j++)
Primer 1.20.4
#include <stdio.h>
#define max1(x,y) (x>y?x:y)
#define max2(x,y) ((x)>(y)?(x):(y))
#define swapint(x,y) { int z; z=x; x=y; y=z; }
#define swap(t,x,y) { \
33
Milena Vujošević–Janičić 1.20 Makroi
t z; \
z=x; \
x=y; \
y=z; }
main()
{
int x=2,y=3;
swapint(x,y);
swap(int,x,y);
printf( "x = %d, y = %d\n", x, y );
/* x = 3, y = 5 */
}
Izlaz:
max1(x,y) = 3
max1(x=5,y) = 3
max1(x++,y++) = 4
x = 3, y = 5
x = 5, y = 3
x = 3, y = 5
34
Milena Vujošević–Janičić 1.21 Pokazivači
1.21 Pokazivači
Pokazivac je promenljiva koja sadrzi adresu promenljive.
int x=1, y=1;
int *ip; /* ip je pokazivac na int,
odnosno *ip je tipa int*/
px = &x;
printf("Vrednost promenljive px je (tj. px) : %p\n", px);
printf("Vrednost promenljive na koju
ukazuje px (tj. *px) je : %d\n", *px);
35
Milena Vujošević–Janičić 1.22 Nizovi
1.22 Nizovi
Deklaracija niza:
int niz[5]; /* niz od 5 elemenata tipa int*/
Pristupanje elementima niza:
niz[0] = 4;
niz[1] = 2 * niz[0]; /*niz[1] = 8*/
niz[2] = niz[0] * niz[1]; /*niz[2] = 32*/
niz[3] = 5;
niz[4] = 7;
Unos vrednosti elemenata niza sa tastature:
for(i=0; i<5; i++)
scanf("%d", &a[i]);
Stampanje elemenata niza
for(i=0; i<5; i++)
printf("%d ", a[i]);
Brojanje elemenata niza je od nule!
Pristupanje elementu niza, indeks moze da bude proizvoljan izraz
celobrojne vrednosti: niz[i*2]=5.
Primer 1.22.1 Program ilustruje korišćenje nizova. Ispisuje 10
unetih brojeva unazad.
#include <stdio.h>
#define BR_ELEM 10
36
Milena Vujošević–Janičić 1.22 Nizovi
main()
{
int a[BR_ELEM];
int i;
for (i = 0; i<BR_ELEM; i++)
{
printf("a[%d]=",i);
scanf("%d",&a[i]);
}
printf("Unazad : \n");
/* Pronalazimo maksimum */
max = a[0];
for (i = 1; i < BR_ELEM; i++)
if (a[i]>max)
max = a[i];
/* Ispisujemo maksimum */
printf("Max = %d\n",max);
}
Primer 1.22.3 Program pronalazi maksimum brojeva sa ulaza -
verzija bez niza. (Ovo rešenje je efikasnije jer je brže i koristi manje
memorije.)
37
Milena Vujošević–Janičić 1.22 Nizovi
#include <stdio.h>
#define BR_ELEM 5
main()
{
int a, max, i;
scanf("%d",&a);
max = a;
for (i = 1; i < BR_ELEM; i++)
{
scanf("%d",&a);
if (a>max)
max = a;
}
main()
{
/* Niz inicijalizujemo tako sto mu navodimo vrednosti
u viticasnim zagradama. Dimenzija niza se odredjuje
na osnovu broja inicijalizatora */
int a[] = {1, 2, 3, 4, 5, 6};
/* Ispisujemo nizove */
int i;
for (i = 0; i < a_br_elem; i++)
38
Milena Vujošević–Janičić 1.22 Nizovi
printf("a[%d]=%d\n",i, a[i]);
}
Primer 1.22.5 Brojanje pojavljivanja svake od cifara. Korišćenje
niza brojača.
#include <stdio.h>
main()
{
/* Niz brojaca za svaku od cifara */
int br_cifara[10];
int i, c;
/* Resetovanje brojaca */
for (i = 0; i < 10; i++)
br_cifara[i] = 0;
/* Ispis rezultata */
for (i = 0; i < 10; i++)
printf("Cifra %d se pojavila %d put%s\n",
i, br_cifara[i], br_cifara[i] == 1 ? "" : "a");
}
Konstantne niske
Konstantna niska: ”Ja sam niska”
ili
”” /*prazna niska*/
Navodnici nisu deo niske vec se koriste da bi je ogranicili. Ako ih
zelimo unutar niske, oni se navode sa \".
39
Milena Vujošević–Janičić 1.23 Pokazivači i nizovi (polja)
main()
{
/* Poslednji bajt niske karaktera se postavlja na ’\0’ tj. 0 */
char s[] = {’a’, ’b’, ’c’, ’\0’ };
40
Milena Vujošević–Janičić 1.23 Pokazivači i nizovi (polja)
Deklaracija
int a[10];
de nise niz a velicine 10 koji predstavlja blok od 10 uzastopnih
objekata nazvanih a[0], a[1], ..., a[9]. Notacija a[i] odgo-
vara i-tom elementu niza.
Ako je pa pokazivac na ceo broj
int *pa;
tada iskaz pa = &a[0];
podesava da pa pokaze na nulti element niza a, odnosno pa sadrzi
adresu od a[0].
Ako pa pokazuje na odred̄eni element polja, onda po de niciji
pa+1 pokazuje na sledeci element, pa+i pokazuje na i-ti element
posle pa. Stoga, ako pa pokazuje na a[0] tada
*(pa+1)
se odnosi na sadrzaj od a[1].
pa+i je adresa od a[i], a
*(pa+i)
je sadrzaj od a[i]. Dozvoljeno je upotrebljavati i sintaksu kao
kod nizova:
*(pa+i) <==> pa[i]
Ovo sve vazi bez obzira na tip ili velicinu elemenata u polju a.
Iskaz pa=&a[0] se moze napisati kao pa=a jer je ime niza
sinonim za lokaciju početnog elementa.
main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int num_of_elements = sizeof(a)/sizeof(int);
int* pa;
41
Milena Vujošević–Janičić 1.24 Break i continue
42
Milena Vujošević–Janičić 1.25 Funkcije
1.25 Funkcije
Primer 1.25.1 sum - najjednostavnija funkcija koja sabira dva broja
/* Definicija funkcije */
int sum(int a, int b)
{
int c;
c = a + b;
return c;
/* Ovo je krace moglo da bude napisano
kao return a+b; */
}
main()
{
int c;
/* Poziv funkcije */
c = sum(3,5);
printf("%d\n", c);
43
Milena Vujošević–Janičić 1.25 Funkcije
main()
{
/* Poziv funkcije */
printf("%d\n", zbir(3,5));
}
/* Definicija funkcije */
int zbir(int a, int b)
{
return a+b;
}
return rezultat;
}
if (negativan)
k = -k;
44
Milena Vujošević–Janičić 1.25 Funkcije
return rezultat;
}
main()
{
/* Poziv funkcije */
float s = power(2.0,8);
printf("%f\n", s);
}
main()
{
char c;
printf("Unesi neko veliko slovo:\n");
scanf("%c", &c);
printf("Odgovarajuce malo slovo je %c\n", lower(c));
}
int prost(int p)
{
int i, koren, ind;
koren=sqrt(p);
ind=(p%2) || (p==2);
i=3;
while (ind && i<=koren)
45
Milena Vujošević–Janičić
1.26 Životni vek i oblast važenja promenjivih, statičke promenljive
{
ind=p%i;
i+=2;
}
return ind;
}
main()
{
int k;
for(k=2;k<=100;k++)
if (prost(k)) printf("%d ",k);
}
int i=10;
void main() {
{
int i=3;
{
int i=1;
printf("%d\n", i);
}
printf("%d\n",i);
}
printf("%d\n",i);
}
Primer 1.26.2 Demonstracija životnog veka i oblasti važenja promen-
jivih.
#include <stdio.h>
/* Globalna promenjiva */
int a = 0;
46
Milena Vujošević–Janičić
1.26 Životni vek i oblast važenja promenjivih, statičke promenljive
void nonstatic_var()
{
/* Nestaticke promenjive ne cuvaju vrednosti kroz pozive funkcije */
int s=0;
s++;
printf("nonstatic::s=%d\n",s);
}
void static_var()
{
/* Staticke promenjive cuvaju vrednosti kroz pozive funkcije.
Inicijalizacija se odvija samo u okviru prvog poziva. */
static int s=0;
s++;
printf("static::s=%d\n",s);
}
main()
{
/* Promenjive lokalne za funkciju main */
int i;
int x = 3;
47
Milena Vujošević–Janičić
1.26 Životni vek i oblast važenja promenjivih, statičke promenljive
increase();
decrease();
/* Globalna promenjiva a */
printf("main::a = %d\n", a);
Izlaz iz programa:
main::x = 3
for::x = 5
for::x = 5
for::x = 5
main::x = 3
increase::a = 1
decrease::a = -1
main::a = 1
nonstatic::s=1
nonstatic::s=1
nonstatic::s=1
static::s=1
static::s=2
static::s=3
48
Milena Vujošević–Janičić 1.27 Funkcije — prenos parametara po vrednosti
main()
{
int x=3;
f(x);
printf("%d\n", x);
}
main()
{
49
Milena Vujošević–Janičić 1.27 Funkcije — prenos parametara po vrednosti
main()
{
string str[] = "Zdravo\n"
print_string(str);
}
main()
{
int n;
50
Milena Vujošević–Janičić 1.27 Funkcije — prenos parametara po vrednosti
char broj[]="234"
n = atoi(broj);
printf("\nN je : %d\n",n);
}
Primer 1.27.5 Demonstrira prenos nizova u funkciju - preneti niz
se moze menjati.
#include <stdio.h>
#include <ctype.h>
main()
{
/* Obavezno je alocirati memoriju za niz karaktera */
char s[100];
get_word(s);
printf("%s\n", s);
}
Primer 1.27.6 Veza izmed̄u pokazivača i nizova u funkcijama.
#include <stdio.h>
main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int num_of_elements = sizeof(a)/sizeof(int);
51
Milena Vujošević–Janičić 1.28 Pokazivači i argumenti funkcija
int* pa;
pa = a;
52
Milena Vujošević–Janičić 1.28 Pokazivači i argumenti funkcija
53
Milena Vujošević–Janičić 1.28 Pokazivači i argumenti funkcija
main()
{
int x = 3, y = 5;
printf("Adresa promenljive x je %p\n", &x);
printf("Vrednost promenljive x je %d\n", x);
printf("Adresa promenljive y je %p\n", &y);
printf("Vrednost promenljive y je %d\n", y);
54
Milena Vujošević–Janičić 1.28 Pokazivači i argumenti funkcija
main()
{
int div, mod;
printf("Adresa promenljive div je %p\n", &div);
printf("Adresa promenljive mod je %p\n", &mod);
55
Milena Vujošević–Janičić 1.29 Povratne vrednosti funkcija
main()
{
/* Funkcija izracunaj() ce biti pozvana
samo za parne vrednosti a */
int a;
for (a = 0; a < 10; a++)
if (a%2 == 0 && izracunaj())
printf("Uslov ispunjen : a = %d, b = %d\n", a, b);
else
printf("Uslov nije ispunjen : a = %d, b = %d\n", a, b);
printf("----------------------------\n");
56
Milena Vujošević–Janičić 1.29 Povratne vrednosti funkcija
57
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
main()
{
58
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
return i;
}
59
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
main()
{
char s[] = "Zdravo svima";
string_reverse(s);
printf("%s\n", s);
}
/*
Izlaz:
amivs ovardZ
*/
Primer 1.30.4 strlen, strcpy, strcat, strcmp, strchr, strstr
- manipulacija niskama karaktera. Vezbe radi, implementirane su
funkcije biblioteke string.h
#include <stdio.h>
60
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
61
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
/* Nije nadjeno */
return -1;
/*
Koristeci string_length :
return -1;
62
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
*/
}
main()
{
char s[100];
char t[] = "Zdravo";
char u[] = " svima";
string_copy(s, t);
printf("%s\n", s);
string_concatenate(s, u);
printf("%s\n", s);
printf("%d\n",string_char("racunari", ’n’));
printf("%d\n",string_last_char("racunari", ’a’));
printf("%d\n",string_string("racunari", "rac"));
printf("%d\n",string_string("racunari", "ari"));
printf("%d\n",string_string("racunari", "cun"));
printf("%d\n",string_string("racunari", "cna"));
}
63
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
/*
Izlaz:
Zdravo
Zdravo svima
4
5
0
5
2
-1*/
main()
{
char niz[20];
char c;
printf("Unesi karakter\n\n");
scanf("%c", &c);
scanf("%s", niz);
squeeze(niz, c);
printf("%s\n", niz);
}
Primer 1.30.6 Obrtanje stringa i pretvaranje broja u string
#include <stdio.h>
#include <string.h>
64
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
{
int c, i, j;
main()
{
int n=-44;
char nst[100];
itoa(n,nst);
printf("%s\n",nst);
}
Primer 1.30.7 Konvertovanje stringa u broj u pokretnom zarezu.
#include <ctype.h>
#include <stdio.h>
#define MAXLINE 100
65
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
i = 0;
while (--lim > 0 && (c=getchar()) != EOF && c != ’\n’)
s[i++] = c;
if (c == ’\n’)
s[i++] = c;
s[i] = ’\0’;
return i;
}
if (s[i] == ’.’)
i++;
66
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
sum = 0;
while (getline(line, MAXLINE) > 0)
printf("\t%g\n", sum += atof(line));
}
Primer 1.30.8 Program učitava linije sa ulaza i pamti najdužu lin-
iju.
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
}
67
Milena Vujošević–Janičić 1.30 Rad sa niskama karaktera
int c, i;
i = 0;
while ((to[i] = from[i]) != ’\0’)
++i;
}
Npr.
cifra ’B’ u osnovi 16 ima vrednost 11
cifra ’8’ nije validna u osnovi 6
*/
68
Milena Vujošević–Janičić 1.31 Linearna i binarna pretraga
return -1;
}
return sum;
}
main()
{
char bin[] = "11110000";
char hex[] = "FF";
69
Milena Vujošević–Janičić 1.31 Linearna i binarna pretraga
main()
{
/* Inicijalizacija niza */
int a[] = {4, 3, 2, 6, 7, 9, 11};
70
Milena Vujošević–Janičić 1.31 Linearna i binarna pretraga
main()
{
int a[] = {3, 5, 7, 9, 11, 13, 15};
int x;
int i;
71
Milena Vujošević–Janičić 1.32 Strukture
scanf("%d",&x);
i = binarna_pretraga(a, sizeof(a)/sizeof(int), x);
if (i==-1)
printf("Elementa %d nema u nizu!\n", x);
else
printf("Element %d je pronadjen na poziciji %d\n", x, i);
}
1.32 Strukture
Informacije kojima se opisuje realni svet retko se predstavljaju u
elementarnoj formi u vidu celih, realnih, znakovnih konstanti itd.
Mnogo cesce imamo posla sa slozenim objektima koji se sastoje od
elemenata raznih tipova. Na primer jednu osobu karakterisu ime,
prezime, datum i mesto rod̄enja.
Struktura predstavlja skup podataka kojim se opisuju neka bitna
svojstva objekta. Komponente koje obrazuju strukturu nazivaju se
elementi strukture.
Sintaksa strukture:
struct ime_strukture
{
tip ime_elementa1;
tip ime_elementa2;
...
};
Za svaki element strukture odvaja se odgovarajuci blok memorije.
72
Milena Vujošević–Janičić 1.32 Strukture
Primer 1.32.2
osoba1.starost=20;
osoba2.starost=21;
...
if (osoba1.starost == osoba2.starost)
printf("Osobe su iste starosti\n");
73
Milena Vujošević–Janičić 1.33 Operator typedef
struct datum
{
unsigned dan;
unsigned mesec;
unsigned godina;
};
struct licnost
{
char ime[30];
struct datum datumrodjenja;
};
Sada se danu, mesecu i godini datuma rodjenja pristupa na sledeći
način:
osoba.datumrodjenja.dan = 10;
osoba.datumrodjenja.mesec = 5;
osoba.datumrodjenja.godina = 1986;
74
Milena Vujošević–Janičić 1.34 Unije
1.34 Unije
Unije se kreiraju koristeci kljucnu rec union a elementima unija se
pristupa uz pomoc operatora . (tacka). Osnovna razlika izmed̄u
unija i struktura je u tome sto unije koriste manju koicinu memorije
u odnosu na odgovarajuce strukture. Na primer, struktura koja ima
dva elementa, jedan tipa double i jedan tipa int zauzima 8+4=12
bajtova u memoriji dok odgovarajuca unija zauzima samo 8 bajtova.
To je zato sto se za uniju odvaja onoliko prostora koliko je potrebno
za najveci element unije, dok se u strukturi odvaja memorija za
svaki element pojedinacno. Usteda u memoriji se placa time sto
programer mora da vodi racuna na koji nacin u kom trenutku moze
da koristi uniju.
Primer 1.34.1
#include<stdio.h>
75
Milena Vujošević–Janičić 1.35 Strukture — primeri
main()
{
NUM n;
/* Nakon naredne dodele n.d ima vrednost 3.14*/
n.d = 3.14;
main()
{
/* Deklarisemo neinicijalizovanu tacku */
point a;
76
Milena Vujošević–Janičić 1.35 Strukture — primeri
Izlaz:
sizeof(point) = 8
x koordinata tacke a je 0
y koordinata tacke a je 0
x koordinata tacke b je 1
y koordinata tacke b je 2
main()
{
tacka Tacke[MAXDUZ];
77
Milena Vujošević–Janičić 1.35 Strukture — primeri
pozicija = 0;
maxRastojanje = 0;
zbir = 0;
78
Milena Vujošević–Janičić 1.35 Strukture — primeri
/* Izlaz iz programa:
Unesite broj tacaka (manji od 100):
4
Unesi x koordinatu 1. tacke
1
Unesi y koordinatu 1. tacke
1
Unesi x koordinatu 2. tacke
0
Unesi y koordinatu 3. tacke
1
Unesi x koordinatu 3. tacke
2
Unesi y koordinatu 3. tacke
2
Unesi x koordinatu 4. tacke
1
Unesi y koordinatu 4. tacke
0
Kvadrat rastojanja 1. tacke je 2
Kvadrat rastojanja 2. tacke je 1
Kvadrat rastojanja 3. tacke je 8
Kvadrat rastojanja 4. tacke je 1
Zbir kvadrata rastojanja je 12
Najdalja tacka od koordinatnog pocetka
je tacka (2,2)
*/
Primer 1.35.3 Napisati funkcije koje izračunavaju površinu i obim
proizvoljnog poligona čija su temena zadatak kao nizovi tačaka i pro-
gram koji testira te funkcije i izračunava obim i povrvšinu trougla i
kvadrata.
#include <stdio.h>
79
Milena Vujošević–Janičić 1.35 Strukture — primeri
/* Poluobim */
float s = (a+b+c)/2;
return sqrt(s*(s-a)*(s-b)*(s-c));
}
80
Milena Vujošević–Janičić 1.35 Strukture — primeri
return obim;
}
return a;
}
main()
{
/* Definisemo dva poligona: trougao i kvadrat. */
81
Milena Vujošević–Janičić 1.35 Strukture — primeri
/* Velicina reci. */
#define SIZE 100
82
Milena Vujošević–Janičić 1.35 Strukture — primeri
int c, i = 0;
main()
{
ime niz[] = { {"Jelena", 0}, {"Ivana", 0}, {"Milena", 0},
{"Ruzica", 0}, {"Ana", 0}, {"Milos", 0},
{"Petar", 0}, {"Janko", 0}, {"Pedja", 0}
};
83
Milena Vujošević–Janičić 1.35 Strukture — primeri
max = 0;
pozicija = 0;
/* Izracunava se maksimalan broj pojavljivanja. */
for (i=0; i < sizeof(niz)/sizeof(ime); i++)
if (niz[i].broj_pojavljivanja > max)
{
max = niz[i].broj_pojavljivanja;
pozicija = i;
}
if (c==EOF) return c;
s[i++]=c;
84
Milena Vujošević–Janičić 1.35 Strukture — primeri
s[i++]=c;
s[i]=’\0’;
return c;
}
main()
{
char s[30];
rec r[500];
int i,c,max, pozicija;
int n=0; /*Broj elemenata u nizu reci*/
85
Milena Vujošević–Janičić 1.36 Datoteke
{
max=r[i].brpoj;
pozicija = i;
}
printf("rec: %s se pojavila %d puta\n",r[i].ime,r[i].brpoj);
}
printf("Max broj pojavljivanja je %d za rec %s",max.r[pozicija].ime);
}
1.36 Datoteke
Primer 1.36.1 Program demonstrira otvaranje datoteka ("r" - read
i "w" - write mod) i osnovne tehnike rada sa datotekama.
/* U datoteku se upisuje prvih 10 prirodnih
brojeva, a zatim se iz iste datoteke
citaju brojevi dok se ne stigne do kraja i
ispisuju se na standardni izlaz */
#include <stdio.h>
#include <stdlib.h>
main()
{
int i;
/* Zatvaramo datoteku */
86
Milena Vujošević–Janičić 1.36 Datoteke
fclose(f);
/* Zatvaramo datoteku */
fclose(f);
}
Pokazivaci stdin, stdout i stderr su de nisani u okviru stdio.h
i mogu se koristiti za pisanje na standardni ulaz, izlaz i izlaz za
gresku.
FILE* stdin;
FILE* stdout;
FILE* stderr;
87
Milena Vujošević–Janičić 1.36 Datoteke
main()
{
FILE* datoteka;
/* Zatvaramo datoteku */
fclose(datoteka);
}
main()
{
int c;
FILE *in, *out;
88
Milena Vujošević–Janičić 1.36 Datoteke
/* Zatvaramo datoteke */
fclose(in);
fclose(out);
}
89
Programiranje 2
Programski jezik C
— Zadaci sa vezbi —
Milena Vujosevic-Janicic
www.matf.bg.ac.yu/~milena
1
Sadrzaj
2 Datoteke 7
3 Bitski operatori 19
4 Vežbanje 30
4.1 Polinomi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.2 Veliki brojevi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5 Sortiranje 40
5.1 Vremenska slozenost . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.2 Selection sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.3 Bubble sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.4 Insertion sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.5 Razni zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
6 Pokazivači 58
6.1 Pokazivacka aritmetika — primeri . . . . . . . . . . . . . . . . . . . . 59
6.2 Niska karaktera i pokazivac na konstantnu nisku . . . . . . . . . . . . 64
6.3 Pokazivaci na pokazivace . . . . . . . . . . . . . . . . . . . . . . . . . 65
6.4 Nizovi pokazivaca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
7 Rekurzija 69
7.1 Osnovni primeri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
7.2 Binarna pretraga . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.3 MergeSort algoritam . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.4 QuickSort algoritam . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
8 Pokazivači na funkcije 86
8.1 Funkcija qsort iz standardne biblioteke . . . . . . . . . . . . . . . . . 89
8.2 Funkcija bsearch iz standardne biblioteke . . . . . . . . . . . . . . . 93
8.3 Funkcije lsearch i lfind . . . . . . . . . . . . . . . . . . . . . . . . 97
8.4 Pokazivaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
2
SADRŽAJ SADRŽAJ
10 Liste 118
10.1 Implementacija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
10.2 Kruzna (ciklicna) lista . . . . . . . . . . . . . . . . . . . . . . . . . . 143
10.3 Red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
10.4 Stek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
10.5 Dvostruko povezane liste . . . . . . . . . . . . . . . . . . . . . . . . . 160
11 Stabla 166
11.1 Binarno pretrazivacko stablo . . . . . . . . . . . . . . . . . . . . . . . 167
12 Grafovi 209
3
Glava 1
#include <stdio.h>
4
Milena Vujošević–Janičić Argumenti komandne linije
#include <stdio.h>
main(int argc, char** argv)
{
/* Za svaki argument komande linije, pocevsi od argv[1]
(preskacemo ime programa) */
int i;
for (i = 1; i < argc; i++)
{
/* Ukoliko i-ti argument pocinje crticom */
if (argv[i][0] == ’-’)
{
/* Ispisujemo sva njegova slova pocevsi od pozicije 1 */
int j;
for (j = 1; argv[i][j] != ’\0’; j++)
printf("Prisutna je opcija : %c\n", argv[i][j]);
}
/* Ukoliko ne pocinje crticom, prekidamo */
else
break;
}
}
Izlaz:
Prisutna opcija : a
Prisutna opcija : b
Prisutna opcija : c
Prisutna opcija : d
Prisutna opcija : f
Prisutna opcija : g
Primer 1.3 Program ispisuje opcije navedene u komandnoj liniji. K&R rešenje.
#include <stdio.h>
5
Milena Vujošević–Janičić Argumenti komandne linije
6
Glava 2
Datoteke
Primer 2.1 Program demonstrira otvaranje datoteka ("r" - read i "w" - write mod)
i osnovne tehnike rada sa datotekama.
/* U datoteku se upisuje prvih 10 prirodnih
brojeva, a zatim se iz iste datoteke
citaju brojevi dok se ne stigne do kraja i
ispisuju se na standardni izlaz */
#include <stdio.h>
#include <stdlib.h>
main()
{
int i;
/* Zatvaramo datoteku */
7
Milena Vujošević–Janičić Datoteke
fclose(f);
/* Zatvaramo datoteku */
fclose(f);
}
Pokazivaci stdin, stdout i stderr su de nisani u okviru stdio.h i mogu se
koristiti za pisanje na standardni ulaz, izlaz i izlaz za gresku.
FILE* stdin;
FILE* stdout;
FILE* stderr;
Primer 2.2 Program demonstrira ”a” - append mod datoteka - nadovezivanje.
#include <stdio.h>
8
Milena Vujošević–Janičić Datoteke
#include <stdlib.h>
main()
{
FILE* datoteka;
/* Zatvaramo datoteku */
fclose(datoteka);
}
Primer 2.3 Program kopira sadrzaj datoteke ulaz.txt u datoteku izlaz.txt.
#include <stdio.h>
#include <stdlib.h>
main()
{
int c;
FILE *in, *out;
9
Milena Vujošević–Janičić Datoteke
exit(1);
}
/* Zatvaramo datoteke */
fclose(in);
fclose(out);
}
Primer 2.4 Program kopira n puta sadrzaj datoteke ulaz.txt u datoteku izlaz.txt.
#include <stdio.h>
#include <stdlib.h>
main()
{
int c, n;
FILE *in, *out;
10
Milena Vujošević–Janičić Datoteke
}
/* Zatvaramo datoteke */
fclose(in);
fclose(out);
}
Primer 2.5 Program ilustruje rad sa datotekama. Program kopira datoteku čije se
ime zadaje kao prvi argument komandne linije u datoteku čije se ime zadaje kao
drugi argument komandne linije. Uz svaku liniju se zapisuje i njen redni broj.
#include <stdio.h>
#include <stdlib.h>
char line[MAX_LINE];
FILE *in, *out;
int line_num;
if (argc != 3) {
fprintf(stderr,"Neispravna upotreba programa!\n
Pravilna upotreba:
%s ulazna_datoteka izlazna_datoteka\n",argv[0]);
11
Milena Vujošević–Janičić Datoteke
exit(1);
}
line_num = 1;
/* Zatvaramo datoteke */
fclose(in);
fclose(out);
}
Primer 2.6 Prodavnica - ilustruje čitanje niza struktura iz tektsualne datoteke.
/* Datoteka, cije se ime zadaje kao argument komandne linije
ili ako se ne zada onda se ime unosi sa standardnog
ulaza, sadrzi podatke o proizvodima koji se prodaju
u okviru odredjene prodavnice. Svaki
proizvod se odlikuje sledecim podacima:
bar-kod - petocifreni pozitivan broj
ime - niska karaktera
cena - realan broj zaokruzen na dve decimale
pdv - stopa poreza - realan broj zaokruzen na dve decimale
Pretpostavljamo da su podaci u datoteci
korektno zadati.
Pretpostavljamo da se u prodavnici ne
prodaje vise od 1000 razlicitih artikala
Na standardni izlaz ispisujemo podatke o
12
Milena Vujošević–Janičić Datoteke
#include <stdio.h>
#include <stdlib.h>
/* Prijavljujemo uspeh */
return 1;
}
13
Milena Vujošević–Janičić Datoteke
14
Milena Vujošević–Janičić Datoteke
br_artikala=0;
/* Ucitavamo artikle */
while (ucitaj_artikal(f, &artikli[br_artikala]))
br_artikala++;
/* Zatvara se datoteka*/
fclose(f);
}
Primer 2.7 Program u datoteku čije se ime zadaje kao prvi argument komandne
linije upisuje prvih N prirodnih brojeva (N se zadaje sa standardnog ulaza) i zatim
izračunava dužinu datoteke u bajtovima.
#include <stdio.h>
#include <stdlib.h>
void main()
{
FILE *f;
int i, n;
15
Milena Vujošević–Janičić Datoteke
Primer 2.8 Napisati program koji u datoteci čije se ime zadaje kao prvi argument
16
Milena Vujošević–Janičić Datoteke
komandne linije zamenjuje sva pojavljivanja niske koja se zadaje kao drugi argument
komandne linije niskom koja se zadaje kao treći argument komandne linije (pret-
postaviti da ce obe niske iste dužine i da nisu duze od 20 karaktera). Na primer, ako
se program pokrene sa
a.out datoteka.txt ana Ana
tada se svako pojavljivanje reči ana u datoteci datoteka.txt zamenjuje sa Ana.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
17
Milena Vujošević–Janičić Datoteke
18
Glava 3
Bitski operatori
main()
{ printf("%o %o\n",255,15);
printf( "255 & 15 = %d\n", 255 & 15 );
printf( "255 | 15 = %d\n", 255 | 15 );
printf( "255 ^ 15 = %d\n", 255 ^ 15 );
printf( "2 << 2 = %d\n", 2 << 2 );
printf( "16 >> 2 = %d\n", 16 >> 2 );
}
19
Milena Vujošević–Janičić Bitski operatori
void print_bits(int x)
{
/* Broj bitova tipa unsigned */
int wl = sizeof(int)*8;
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
main()
{
print_bits(127);
print_bits(128);
print_bits(0x00FF00FF);
print_bits(0xFFFFFFFF);
}
Izlaz iz programa:
00000000000000000000000001111111
00000000000000000000000010000000
00000000111111110000000011111111
11111111111111111111111111111111
Primer 3.3 Program proverava da li se na k-tom mestu broja n nalazi bit koji ima
vrednost 1.
#include <stdio.h>
20
Milena Vujošević–Janičić Bitski operatori
bit: ... 0 0 0 1 1 1 0 0 1 1 0 */
main()
{
int n,k;
printf("Unesite broj i poziciju tog broja koju zelite da proverite:\n");
scanf("%d%d",&n,&k);
if ((n & (1 << k))!=0)
printf("Bit je 1\n");
else
printf("Bit je 0\n");
}
Primer 3.4 Program postavlja na k-to mesto broja n bit 1.
#include <stdio.h>
void print_bits(int x)
{
/* Broj bitova tipa unsigned */
int wl = sizeof(int)*8;
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
main(){
int n,k;
printf("Unesite broj i poziciju tog broja koju zelite da postavite na 1:\n");
scanf("%d%d",&n,&k);
printf("Binarno, uneseni broj je\n");
print_bits(n);
printf("Novi broj je %d\n",(n |(1<<k)));
printf("Binarno, novi broj je\n");
print_bits((n |(1<<k)));
}
Izrazom a>>b vrsi se pomeranje sadrzaja operanda a predstavljenog u binarnom
obliku za b mesta u desno. Popunjavanje upraznjenih mesta na levoj strani zavisi od
tipa podataka i vrste racunara. Ako se pomeranje primenjuje nad operandom tipa
unsigned popunjavanje je nulama. Ako se radi o oznacenom operandu popunjavanje
je jedinicama kada je u krajnjem levom bitu jedinica, a nulama kada je u krajnjem
levom bitu nula.
21
Milena Vujošević–Janičić Bitski operatori
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
int sum_of_bits(unsigned x)
{
int br;
for (br = 0; x; x>>=1)
if (x&1)
br++;
/* Drugo resenje:
int wl = sizeof(unsigned)*8;
int br = 0;
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
if(x&mask) br++ ;
*/
return br;
}
22
Milena Vujošević–Janičić Bitski operatori
main()
{
printf("Binarni zapis broja 127 je\n");
print_bits(127);
printf("Suma bitova broja 127 je %d\n",sum_of_bits(127));
printf("Binarni zapis broja 128 je\n");
print_bits(128);
printf("Suma bitova broja 128 je %d\n",sum_of_bits(128));
printf("Binarni zapis broja 0x00FF00FF je\n");
print_bits(0x00FF00FF);
printf("Suma bitova broja 0x00FF00FF je %d\n",sum_of_bits(0x00FF00FF));
printf("Binarni zapis broja 0xFFFFFFFF je\n");
print_bits(0xFFFFFFFF);
printf("Suma bitova broja 0xFFFFFFFF je %d\n",sum_of_bits(0xFFFFFFFF));
}
Izlaz iz programa:
Binarni zapis broja 127 je
00000000000000000000000001111111
Suma bitova broja 127 je 7
Binarni zapis broja 128 je
00000000000000000000000010000000
Suma bitova broja 128 je 1
Binarni zapis broja 0x00FF00FF je
00000000111111110000000011111111
Suma bitova broja 0x00FF00FF je 16
Binarni zapis broja 0xFFFFFFFF je
11111111111111111111111111111111
Suma bitova broja 0xFFFFFFFF je 32
Primer 3.6 get_bits, set_bits, invert_bits - izdvajanje, postavljanje i inver-
tovanje pojedinačnih bitova.
#include <stdio.h>
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
23
Milena Vujošević–Janičić Bitski operatori
24
Milena Vujošević–Janičić Bitski operatori
main()
{
unsigned x = 0x0AA0AFA0;
print_bits(x);
Izlaz iz programa:
00001010101000001010111110100000
00000000000000000000000010101111
00001010101000001111111110100000
00001010101000000101000010100000
Primer 3.7 right_rotate_bits, mirror_bits - rotiranje i simetrija bitova.
#include <stdio.h>
unsigned mask;
for (mask = 1<<wl-1; mask; mask >>= 1)
putchar(x&mask ? ’1’ : ’0’);
putchar(’\n’);
}
25
Milena Vujošević–Janičić Bitski operatori
{
/* Poslednji bit broja x */
unsigned last_bit = x & 1;
x |= last_bit<<wl-1;
}
return x;
}
main()
{
unsigned x = 0xFAF0FAF0;
print_bits(x);
26
Milena Vujošević–Janičić Bitski operatori
print_bits(mirror(x));
print_bits(right_rotate(x, 2));
}
Izlaz iz programa:
11111010111100001111101011110000
00001111010111110000111101011111
00111110101111000011111010111100
Primer 3.8 Promeljiva c je tipa char. Šta ce biti vrednost promenljive c posle izraza
dodele
c=(15|3)>>1;?
c=(15 & 3)<<1; ?
Primer 3.9 Napisati program koji sa standardnog ulaza učcitava pozitivan ceo broj,
a na standardni izlaz ispisuje vrednost tog broja sa razmenjenim vrednostima bitova
na pozicijama i, j. Pozicije i, j se učitavaju kao parametri komandne linije. Sma-
trati da je krajnji desni bit binarne reprezentacije 0-ti bit. Pri rešavanju nije dozvol-
jeno koristiti pomoćni niz niti aritmeticke operatore +,-,/,*,%.
#include <stdio.h>
#include <stdlib.h>
27
Milena Vujošević–Janičić Bitski operatori
rezultat |= mask_i;
/* Ako je na j-tom mestu 0, upisujemo
to na i-to mesto*/
else
rezultat &= ~mask_i;
return rezultat;
}
printf("Unesi broj\n");
scanf("%u", &n);
m = razmeni(n, i, j);
int par_nepar(int n)
{
28
Milena Vujošević–Janičić Bitski operatori
29
Glava 4
Vezbanje
4.1 Polinomi
Primer 4.1 Program ilustruje rad sa polinomima.
#include <stdio.h>
#include <math.h>
#define max(a, b) ((a) > (b) ? (a) : (b))
/*
* Polinom 3*x^3 + 2*x + 1.5 se predstavlja kao:
* stepen -> 3
* koeficijenti -> 1.5 2 0 3 x x x x x ... x
*/
typedef struct polinom
{
float koeficijenti[21];
int stepen;
} Polinom;
/*
* Funkcija vraca koeficijent uz x^i u polinomu p
* Zbog efikasnosti ne prenosimo celu strukturu vec
* samo pokazivac na strukturu.
*/
float vratiKoeficijent(Polinom* p, int i)
{
return i <= p->stepen ? p->koeficijenti[i] : 0.0f;
}
/*
* Funkcija postavlja koeficijent uz x^i u polinomu p na
* dati koeficijent k
30
Milena Vujošević–Janičić 4.1 Polinomi
*/
void postaviKoeficijent(Polinom* p, int i, float k)
{
int j;
/*
Ukoliko je stepen polinoma bio manji, postavljamo
sve koeficijente izmedju na 0.0 i uvecavamo stepen
*/
if (i > p->stepen)
{
for (j = p->stepen+1; j < i; j++)
p->koeficijenti[j] = 0.0f;
p->stepen = i;
}
p->koeficijenti[i] = k;
}
/*
* Funkcija kreira polinom datog stepena sa datim nizom
* koeficijenata. Pretpostavlja se da su koeficijenti
* u datom nizu koeficijenti[] uredjeni opadajuce po stepenima
* polinoma.
*/
Polinom napraviPolinom(int stepen, float koeficijenti[])
{
int i;
Polinom p;
p.stepen = stepen;
for (i = 0; i <= stepen; i++)
{
postaviKoeficijent(&p, i, koeficijenti[stepen - i]);
}
return p;
}
/*
* Funkcija ispisuje polinom u citljivijem obliku.
* Na primer: 3.0*x^3 + 0.0*x^2 + 2.0*x^1 + 1.5*x^0
*/
void ispisiPolinom(Polinom* p)
{
int i;
for (i = p->stepen; i >= 0; i--)
31
Milena Vujošević–Janičić 4.1 Polinomi
{
printf("%.2f*x^%d", vratiKoeficijent(p, i), i);
if (i > 0)
printf(" + ");
}
printf("\n");
}
/*
* Funkcija izracunava vrednost polinoma u tacki x
* Hornerovom shemom. Na primer,
* 3*x^3 + 2*x + 1.5 =
* (((0*x + 3)*x + 0)*x + 2)*x + 1.5
* Postupak izracunavanja p(10):
* 0.0
* 10 * 0.0 + 3 = 3.0
* 10 * 3.0 + 0 = 30.0
* 10 * 30.0 + 2 = 302.0
* 10 * 302.0 + 1.5 = 3021.5
*/
float vrednost(Polinom* p, float x)
{
int i;
float suma = 0.0f;
for (i = p->stepen; i >= 0; i--)
{
suma = suma*x + vratiKoeficijent(p, i);
}
return suma;
}
/*
* Funkcija sabira dva polinoma
*/
Polinom saberi(Polinom* p, Polinom* q)
{
int i;
Polinom zbir;
zbir.stepen = max(p->stepen, q->stepen);
for (i = 0; i <= zbir.stepen; i++)
postaviKoeficijent(&zbir, i,
vratiKoeficijent(p, i)
+ vratiKoeficijent(q, i));
return zbir;
32
Milena Vujošević–Janičić 4.1 Polinomi
/*
* Funkcija mnozi dva polinoma. Na primer,
*
* 1*x^2 + 2*x + 3
* 4*x + 7
*
* 0.0*x^3 + 0.0*x^2 + 0.0*x + 0.0
* 0.0*x^3 + 0.0*x^2 + 0.0*x + 21.0 i=0 j=0
* 0.0*x^3 + 0.0*x^2 + 12.0*x + 21.0 i=0 j=1
* 0.0*x^3 + 0.0*x^2 + 26.0*x + 21.0 i=1 j=0
* 0.0*x^3 + 8.0*x^2 + 26.0*x + 21.0 i=1 j=1
* 0.0*x^3 + 15.0*x^2 + 26.0*x + 21.0 i=2 j=0
* 4.0*x^3 + 15.0*x^2 + 26.0*x + 21.0 i=2 j=1
*/
Polinom pomnozi(Polinom* p, Polinom* q)
{
int i, j;
Polinom proizvod;
proizvod.stepen = p->stepen + q->stepen;
for (i = 0; i <= proizvod.stepen; i++)
{
postaviKoeficijent(&proizvod, i, 0.0f);
}
for (i = 0; i <= p->stepen; i++)
{
for (j = 0; j <= q->stepen; j++)
{
/* r[i+j] = r[i+j] + p[i]*q[j] */
postaviKoeficijent(&proizvod, i+j,
vratiKoeficijent(&proizvod, i+j) +
vratiKoeficijent(p, i) * vratiKoeficijent(q, j));
}
}
return proizvod;
}
main()
{
float pkoeficijenti[] = {1.0f, 2.0f, 1.0f};
Polinom p = napraviPolinom(2, pkoeficijenti);
float qkoeficijenti[] = {1.0f, 1.0f};
Polinom q = napraviPolinom(1, qkoeficijenti);
Polinom r = pomnozi(&p, &q);
33
Milena Vujošević–Janičić 4.2 Veliki brojevi
ispisiPolinom(&r);
}
34
Milena Vujošević–Janičić 4.2 Veliki brojevi
{
int i;
for (i=duzina-1; i>=0; i--)
printf("%d",cifre[i]);
putchar(’\n’);
}
return 1;
}
35
Milena Vujošević–Janičić 4.2 Veliki brojevi
return 1;
if (a[i] < b[i])
return -1;
}
return 0;
}
36
Milena Vujošević–Janičić 4.2 Veliki brojevi
rezultat[i] = prenos;
*duzina_rezultata = i+1;
}
}
else
*duzina_rezultata=i;
return;
}
/* Funkcija mnozi broj, dat svojim nizom cifara i duzinom, datom cifrom c */
void pomnozi_cifrom (int a[], int duzina_a, int cifra,
int rezultat[],
int* duzina_rezultata)
{
int i, prenos = 0;
37
Milena Vujošević–Janičić 4.2 Veliki brojevi
*duzina_rezultata = duzina_a;
}
*duzina_rezultata = 0;
/*
b=351 * a=123
---------------
1 korak ===> rez: 351 * 3 = 1053
2 korak ===> 351 * 2 = 702
------------------
rez: 8073
3 korak ===> 351 * 1 = 351
------------------
rez: 43173
*/
/* Za svaku cifru broja a */
for (i=0; i<duzina_a; i++)
{
/* vrsimo mnozenje broja b i-tom cifrom broja a */
pomnozi_cifrom(b, duzina_b, a[i], pom, &duzina_pom);
38
Milena Vujošević–Janičić 4.2 Veliki brojevi
}
if (prenos)
{
rezultat[i+k] = prenos;
*duzina_rezultata = i+k+1;
}
else
*duzina_rezultata = i+k;
}
}
/* Ucitavaju se brojevi */
printf("Unesite prvi broj : ");
duzina_a = uzmi_broj(a,MAX_CIFRE);
39
Glava 5
Sortiranje
rastucem poretku:
niz[0] < niz[1] < ... < niz[i] < niz[i + 1] < ... < niz[n 1]
neopadajucem poretku:
niz[0] niz[1] ... niz[i] niz[i + 1] ... niz[n 1]
nerastucem poretku:
niz[0] ≥ niz[1] ≥ ... ≥ niz[i] ≥ niz[i + 1] ≥ ... ≥ niz[n 1]
40
Milena Vujošević–Janičić 5.2 Selection sort
/*Sortiranje*/
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(a[i]<a[j])
{
pom=a[i];
a[i]=a[j];
a[j]=pom;
}
}
main()
{
/* Niz od maksimalno MAXDUZ elemenata*/
41
Milena Vujošević–Janičić 5.2 Selection sort
int a[MAXDUZ];
if (n>MAXDUZ)
{
printf("Nedozvoljena vrednost za n\n");
exit(1);
}
selection(a,n);
/* Ispis niza */
printf("Sortirani niz:\n");
for(i=0; i<n; i++)
printf("%d\t",a[i]);
putchar(’\n’);
}
Primer 5.2 (Selection sort2) Modifikacija prethodnog rešenja radi dobijanja na
efikasnosti. Ne vrše se zamene svaki put već samo jednom, kada se pronad̄e odgo-
varajući element u nizu sa kojim treba izvršiti zamenu tako da u nizu bude postavljen
trenutno najveći element na odgovarajuće mesto.
Primer sortiranja:
n = 6 a: 1 3 5 2 6 8
-------------
i = 0 => a: 8 1 5 2 6 3
-------------
i = 1 => a: 8 6 5 2 1 3
-------------
i = 2 => a: 8 6 5 2 1 3
-------------
42
Milena Vujošević–Janičić 5.3 Bubble sort
...
void selection2(int a[], int n)
{
int i, j, max;
43
Milena Vujošević–Janičić 5.3 Bubble sort
i = 4 j = 0 => a: 5 3 2 6 8 1
...
zam=1;
for(i=n-1; zam && i>0; i--)
for(zam=0,j=0; j<i; j++)
if(a[j]<a[j+1])
{
/* Zamena odgovarajucih clanova niza */
pom=a[j];
a[j]=a[j+1];
a[j+1]=pom;
44
Milena Vujošević–Janičić 5.4 Insertion sort
Primer 5.6 (Insertion sort 2) Broj dodela se moze redukovati tako sto se umesto
stalnih zamena koristi dodela privremenoj promenljivoj — elemente niza pomeramo
za jedno mesto sve dok ne nad̄emo poziciju na koju treba da postavimo dati element
(koji je sačuvan u privremenoj promenljivoj).
void insertion2(int a[], int n)
{
int i, j, tmp;
for (i = 1; i < n; i++)
{
int tmp = a[i];
45
Milena Vujošević–Janičić 5.5 Razni zadaci
return k;
}
46
Milena Vujošević–Janičić 5.5 Razni zadaci
main() {
int a[] = {1, 5, 6, 9, 13};
int b[] = {2, 3, 7, 11, 12, 15};
int c[30];
int na = sizeof(a)/sizeof(int);
int nb = sizeof(b)/sizeof(int);
int nc = merge(a, na, b, nb, c);
int i;
#define MAX_IME 20
while (isspace(c=getchar()))
;
word[i]=’\0’;
47
Milena Vujošević–Janičić 5.5 Razni zadaci
else return i;
main()
{
student studenti[100];
48
Milena Vujošević–Janičić 5.5 Razni zadaci
SelectionSort(studenti, br_studenata);
IspisiPodatke(studenti, br_studenata);
}
Primer 5.9 Program učitava informacije o studentima iz datoteke čije se ime zadaje
iz komandne linije, i koja je u formatu:
n
prezime1 ime1 smer1 prosek1
prezime2 ime2 smer2 prosek2
...
prezimen imen smern prosekn
Studenti se sortiraju leksikografski po prezimenima i imenima, a zatim se njihovi
podaci tako sortirani ispisuju na izlaz, ili u izlazni fajl, ako je njegovo ime zadato u
komandnoj liniji.
#include <stdio.h>
#include <string.h>
#define MAX_IME 20
#define MAX_PREZIME 30
#define MAX_SMER 10
char ime[MAX_IME];
char prezime[MAX_PREZIME];
char smer[MAX_SMER];
double prosek;
} Student;
49
Milena Vujošević–Janičić 5.5 Razni zadaci
if (min != i)
{
pom = studenti[i];
studenti[i] = studenti[min];
studenti[min] = pom;
}
}
}
50
Milena Vujošević–Janičić 5.5 Razni zadaci
/* Funkcija main */
int main (int argc, char ** argv)
{
int n, i;
FILE *in = stdin, *out = stdout;
Student studenti[MAX_STUDENATA];
51
Milena Vujošević–Janičić 5.5 Razni zadaci
fclose(in);
fclose(out);
return 0;
}
Primer 5.10 Program utvrd̄uje da li su dve niske karaktera anagrami. Dve niske
su anagrami ako se sastoje od istog broja istih karaktera. Na primer, niske ”trave”
i ”vetar” jesu anagrami, dok ”vetar” i ”vatra” nisu.
#include <stdio.h>
#include <string.h>
if (min != i)
{
pom = s[i];
s[i] = s[min];
s[min] = pom;
}
}
52
Milena Vujošević–Janičić 5.5 Razni zadaci
/* Test program */
int main ()
{
53
Milena Vujošević–Janičić 5.5 Razni zadaci
return 0;
}
Primer 5.11 Interpolaciona pretraga se može porediti sa pretragom rečnika:
ako neko traži reč na slovo B, sigurno neće da otvori rečnik na polovini, već verovatno
negde bliže početku.
/* Funkcija trazi u SORTIRANOM nizu a[] duzine n
broj x. Vraca indeks pozicije nadjenog elementa
ili -1, ako element nije pronadjen */
int interpolaciona_pretraga (int a[], int n, int x)
{
int l = 0;
int d = n - 1;
int s;
54
Milena Vujošević–Janičić 5.5 Razni zadaci
55
Milena Vujošević–Janičić 5.5 Razni zadaci
i++;
/* Ako je element niza b manji, tada u tom nizu prelazimo
na sledeci element */
else
j++;
}
/* Vracamo broj elemenata preseka */
return k;
56
Milena Vujošević–Janičić 5.5 Razni zadaci
c[k++] = a[i++];
57
Glava 6
Pokazivaci
main()
{
void *pp; /* Ovaj pokazivac moze da pokazuje na adrese
na kojima se nalaze razliciti tipovi
podataka. */
int x=2;
58
Milena Vujošević–Janičić 6.1 Pokazivačka aritmetika — primeri
char c=’a’;
/*
Adresa od x je 0012FF78
17 i 0012FF78
Adresa od c je 0012FF74
a i 0012FF74
*/
#include <stdio.h>
59
Milena Vujošević–Janičić 6.1 Pokazivačka aritmetika — primeri
main()
{
int a[]={1,2,3,4,5,6,7,8};
int* poz=nadjiint(a,sizeof(a)/sizeof(int),4);
if (poz!=NULL)
printf("Element pronadjen na poziciji %d\n",poz-a);
}
60
Milena Vujošević–Janičić 6.1 Pokazivačka aritmetika — primeri
}
*dest = ’\0’;
*/
Primer 6.5 Nadovezuje string t na kraj stringa s. Pretpostavlja da u s ima do-
voljno prostora.
void string_concatenate(char *s, char *t)
{
/* Pronalazimo kraj stringa s */
while (*s) /* while (*s != 0)*/
s++;
/* Nakon prethodne petlje, s pokazuje na ’\0’, kopiranje
pocinje od tog mesta, tako da ce znak ’\0’ biti prepisan. */
/* Kopiranje se vrisi slicno funkciji string_copy */
while (*s++ = *t++)
;
}
Primer 6.6 Funkcija strcmp vrši leksikografsko pored̄enje dva stringa. Vraća:
0 — ukoliko su stringovi jednaki
<0 — ukoliko je s leksikografski ispred t
>0 — ukoliko je s leksikografski iza t
return *s - *t;
}
Primer 6.7 Pronalazi prvu poziciju karaktera c u stringu s, i vraća pokazivač na
nju, odnosno NULL ukoliko s ne sadrži c.
char* string_char(char *s, char c)
{
61
Milena Vujošević–Janičić 6.1 Pokazivačka aritmetika — primeri
int i;
for (; *s; s++)
if (*s == c)
return s;
/* Nije nadjeno */
return NULL;
}
/* Nije nadjeno */
return NULL;
}
Primer 6.9 Za svaku liniju ucitanu sa ulaza proverava se da li sadrži reč zdravo.
#include <stdio.h>
62
Milena Vujošević–Janičić 6.1 Pokazivačka aritmetika — primeri
/* Nije nadjeno */
return NULL;
}
if (c==’\n’)
*s++ = c;
*s = ’\0’;
return s - line;
}
main()
{
char rec[]="zdravo";
char linija[100];
while (getline(linija, 100))
if (sadrzi_string_pok(linija, rec))
63
Milena Vujošević–Janičić 6.2 Niska karaktera i pokazivač na konstantnu nisku
printf("%s",linija);
}
64
Milena Vujošević–Janičić 6.3 Pokazivači na pokazivače
65
Milena Vujošević–Janičić 6.4 Nizovi pokazivača
Primer 6.11 Program ucitava linije iz fajla ulaz.txt i zatim ih ispisuje na stan-
dardnom izlazu sortirane po dužini, počev od najkraće linije.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
char redovi[MAX_REDOVA][MAX_RED];
char *p_redovi[MAX_REDOVA];
int i, n;
FILE * in;
/* Otvaramo fajl */
in = fopen("ulaz.txt", "r");
n = i;
66
Milena Vujošević–Janičić 6.4 Nizovi pokazivača
/* Zatavaramo fajl */
fclose(in);
return 0;
}
p = *s;
*s = *t;
*t = p;
}
67
Milena Vujošević–Janičić 6.4 Nizovi pokazivača
if(min != i)
{
razmeni(&redovi[min], &redovi[i]);
}
}
}
68
Glava 7
Rekurzija
Funkcija1 moze da poziva samu sebe, neposredno ili posredno. Ova pojava se zove
rekurzija. Ovakav pristup se cesto koristi prilikom resavanja problema koji imaju
prirodnu rekurzivnu de niciju, tj. kod kojih se problem dimenzije n moze jednos-
tavno svesti na problem dimenzije n-1 ili neke druge manje dimenzije. Rekurzija je
analogna matematickoj indukciji.
Ono sto je potencijalni problem kod razumevanja rekurzije je to sto se u jednom
trenutku mogu izvrsavati vise poziva jedne iste funkcije. Na primer, ako funkcija
f() prilikom svog izvrsavanja pozove samu sebe, tada se zapocinje novi poziv iste
funkcije. Prethodni poziv ceka da se zavrsi tekuci, a zatim nastavlja sa radom. Poziv
rekurzivne funkcije koji je zapocet, a cije izvrsavanje jos nije zavrseno nazivamo
aktivni poziv. Svaki poziv funkcije izvrsava se nezavisno od svih ostalih aktivnih
poziva u tom trenutku, zahvaljujuci cinjenici da svaki od aktivnih poziva ima svoje
sopostvene kopije formalnih parametara i lokalnih podataka. Kada se neki od poziva
zavrsi, njegove kopije nestaju iz memorije, ali kopije ostalih poziva i dalje postoje u
memoriji. Posledica ovog pristupa je da kada rekurzivna funkcija promeni vrednosti
svojih lokalnih podataka, ove promene ne uticu na ostale aktivne pozive, zato sto
oni imaju svoje lokalne kopije istih podataka.
Kreiranje i odrzavanje lokalnih kopija se jednostavno i e kasno ostvaruje zah-
valjujuci tome sto su parametri funkcije i lokalne nestaticke promenljive smestene
na sistemskom steku — u pitanju je struktura podataka u kojoj se novi podaci uvek
smestaju na vrh a prilikom uklanjanja podataka takodje se uklanja podatak sa vrha,
tj. podatak koji je poslednji dodat (LIFO struktura — last in, rst out). Prilikom
pozivanja bilo koje funkcije najpre se na stek smeste njeni argumenti (one vrednosti
koje su predate prilikom poziva) a zatim se na vrh steka smeste i lokalne promenljive.
Nakon toga se zapocne izvrsavanje tela funkcije. Ako se tom prilikom pozove neka
druga funkcija (ili ta ista, ako je rekurzija u pitanju) tada se na vrh steka dodaju
argumenti ovog poziva, kao i lokalne promenljive te funkcije, itd. Kada se funkci-
jski poziv zavrsi, tada se sa vrha steka skidaju njegove lokalne promenljive, kao i
parametri poziva, nakon cega na vrhu steka ostaju lokalne promenljive prethodnog
poziva itd.
1 Tekst preuzet sa www.matf.bg.ac.rs/m̃ilan
69
Milena Vujošević–Janičić 7.1 Osnovni primeri
/* Alternativni zapis:
return n == 0 ? 1 : n*faktorijel(n-1); */
main()
{
int n;
unsigned long f;
printf("Unesite n\n");
scanf("%d", &n);
f = faktorijel(n);
70
Milena Vujošević–Janičić 7.1 Osnovni primeri
printf("f = %d\n",f);
}
main()
{
int s,n;
printf("Unesite n\n");
scanf("%d", &n);
s = suma(n);
printf("s = %d\n",s);
}
71
Milena Vujošević–Janičić 7.1 Osnovni primeri
int main()
{
long int b=-1234;
printb(b);
putchar(’\n’);
return 0;
}
Kad funkcija rekurzivno pozove sebe, svakim pozivom pojavljuje se novi skup svih
automatskih promenljivih, koji je nezavisan od prethodonog skupa. Prva funkcija
printb kao argument dobija broj -12345, ona prenosi 1234 u drugu printb funkciju,
koja dalje prenosi 123 u treću, i tako redom do poslednje koja prima 1 kao argument.
Ta funkcija štampa 1 i završava sa radom tako da se vraća na prethodni nivo, na
kome se štampa dva i tako redom.
Primer 7.5 Stepenovanje prirodnog broja
iterativno
rekurzivno, koristeći činjenicu da je xk = x · xk−1 i x0 = 1
k k 1
rekurzivno, koristeći činjenicu da je xk = (x2 ) 2 ako je k parno ili xk = x(x2 ) 2
ako je k neparno, i x0 = 1 i x1 = x.
#include <stdio.h>
72
Milena Vujošević–Janičić 7.1 Osnovni primeri
int s = 1;
for (i = 0; i<k; i++)
s*=x;
return s;
}
if (k == 0)
return 1;
else
return x*stepen(x, k-1);
73
Milena Vujošević–Janičić 7.1 Osnovni primeri
{
p = stepen(n, k/2);
if(k%2 == 0) s = p*p;
else s = p*p*n;
}
return s;
}
*/
main()
{
printf("Stepen je: %d\n", stepen(2, 8));
printf("------------------\n");
printf("Stepen je: %d\n", stepen2(2, 8));
}
/* Izlaz iz programa:
Racunam stepen(2, 8)
Racunam stepen(2, 7)
Racunam stepen(2, 6)
Racunam stepen(2, 5)
Racunam stepen(2, 4)
Racunam stepen(2, 3)
Racunam stepen(2, 2)
Racunam stepen(2, 1)
Racunam stepen(2, 0)
Stepen je: 256
------------------
Racunam stepen2(2, 8)
Racunam stepen2(4, 4)
Racunam stepen2(16, 2)
Racunam stepen2(256, 1)
Stepen je: 256
*/
Primer 7.6 Fibonačijevi brojevi se definišu rekurentno na sledeći način:
f(0) = 1, f(1) = 1, f(n) = f(n-1) + f(n-2)
Napisati funkciju koja izračunava n-ti Fibonačijev broj.
#include <stdio.h>
#include <stdlib.h>
74
Milena Vujošević–Janičić 7.1 Osnovni primeri
if((n==0)||(n==1))
return 1;
else
return(Fib(n-1)+Fib(n-2));
/* Alternativni zapis:
return (n == 0 || n == 1) ? 1 : Fib(n-1) + Fib(n-2); */
}
75
Milena Vujošević–Janičić 7.1 Osnovni primeri
Racunam Fib(1)
Fib(5) = 8
Fib(5)?
=> 8 = 5+3
/ \
/ \
/ \
Fib(4)? Fib(3)?
=> 5=3+2 => 3=2+1
/ \ / \
Fib(3)? Fib(2)? Fib(2)? Fib(1)?
=> 3=2+1 => 2=1+1 => 2=1+1 |
/ \ / \ / \ 1
Fib(2)? Fib(1) Fib(1) Fib(0) Fib(1) Fib(0)
=> 2=1+1 | | | | |
/ \ 1 1 1 1 1
Fib(1) Fib(0)
| |
1 1
_______________________________________________________________
*/
Primer 7.7 U slučaju da se rekurzijom problem svodi na više manjih podproblema
koji se mogu preklapati, postoji opasnost da se pojedini podproblemi manjih dimenz-
ija rešavaju veći broj puta. Na primer,
fibonacci(20) = fibonacci(19) + fibonacci(18)
fibonacci(19) = fibonacci(18) + fibonacci(17)
tj. problem fibonacci(18) se resava dva puta. Problemi manjih dimenzija će se
rešavati još veći broj puta. Rešenje za ovaj problem je kombinacija rekurzije sa tzv.
”dinamičkim programiranjem” – podproblemi se rešavaju samo jednom, a njihova
rešenja se pamte u memoriji (obično u nizovima ili matricama), odakle se koriste
ako tokom rešavanja ponovo budu potrebni.
#include <stdio.h>
#include <stdlib.h>
#define MAX 50
76
Milena Vujošević–Janičić 7.1 Osnovni primeri
/* Izlaz iz rekurzije */
if(n < 2)
return f[n] = 1;
else
/* Rekurzivni pozivi */
return f[n] = fibonacci(n - 1) + fibonacci(n - 2);
}
/* Test program */
int main()
{
int n, i;
/*Inicijalizuje se niz*/
for(i=0; i<MAX; i++)
f[i] = 0;
scanf("%d", &n);
printf("%d\n", fibonacci(n));
return 0;
}
Primer 7.8 Program rešava problem tzv. ”hanojskih kula”: data su tri vertikalna
štapa, na jednom se nalazi n diskova poluprečnika 1,2,3,... do n, tako da se najveći
nalazi na dnu, a najmanji na vrhu. Ostala dva štapa su prazna. Potrebno je pre-
mestiti diskove na drugi štap tako da budu u istom redosledu, premeštajući jedan po
jedan disk, pri čemu se ni u jednom trenutku ne sme staviti veći disk preko manjeg.
77
Milena Vujošević–Janičić 7.1 Osnovni primeri
/*
| | |
=== | |
===== | |
======= | |
========= | |
----------- ----------- -----------
X Y Z
===>
...
| | |
| | |
| | ===
| | =====
========= | =======
----------- ----------- -----------
X Y Z
...
===>
| | |
| === |
| ===== |
| ======= |
| ========= |
----------- ----------- -----------
X Y Z
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
78
Milena Vujošević–Janičić 7.1 Osnovni primeri
/* Funkcija premesta jedan disk sa vrha prve kule na vrh druge kule */
void move(Tower *from, Tower * to)
{
/* Proveravamo da li je potez ispravan */
if(from->n == 0 || (to->n > 0 && from->s[from->n - 1] >= to->s[to->n - 1]))
{
/* Premestanje diska */
to->s[to->n++] = from->s[--from->n];
79
Milena Vujošević–Janičić 7.1 Osnovni primeri
}
}
/* Test program */
int main()
{
Tower x, y, z;
int n;
80
Milena Vujošević–Janičić 7.2 Binarna pretraga
print_tower(&z);
return 0;
}
main()
81
Milena Vujošević–Janičić 7.3 MergeSort algoritam
{
int a[] = {3, 5, 7, 9, 11, 13, 15};
int x;
int i;
if (i==-1)
printf("Elementa %d nema\n", x);
else
printf("Pronadjen na poziciji %d\n", i);
}
/* sortiranje ucesljavanjem */
void merge_sort (int a[], int l, int d)
{
int s;
int b[MAX]; /* pomocni niz */
int i, j, k;
/* Izlaz iz rekurzije */
if (l >= d)
return;
/* rekurzivni pozivi */
merge_sort (a, l, s);
merge_sort (a, s + 1, d);
82
Milena Vujošević–Janičić 7.3 MergeSort algoritam
while(i <= s)
b[k++] = a[i++];
while(j <= d)
b[k++] = a[j++];
/* Test program */
int main(int argc, char ** argv)
{
int a[MAX];
int n, i;
int x;
/* Poziv funkcije */
merge_sort(a, 0, n - 1);
/* Prikaz niza */
for(i = 0; i < n; i++)
printf("%d ", a[i]);
83
Milena Vujošević–Janičić 7.4 QuickSort algoritam
putchar(’\n’);
return 0;
}
84
Milena Vujošević–Janičić 7.4 QuickSort algoritam
/* Zahtevanu konfiguraciju < < < < pivot > > > > dobijamo tako
sto zamenimo mesto pivotu i poslednjem elementu manjem od njega */
swap(a, l, last);
main()
{
int a[] = {5, 8, 2, 4, 1, 9, 3, 7, 6};
int n = sizeof(a)/sizeof(int);
int i;
quick_sort(a, 0, n-1);
85
Glava 8
Pokazivaci na funkcije
Binarne instrukcije koje cine funkciju su takod̄e negde u memoriji, i imaju svoju
adresu. Zato je moguce je de nisati pokazivac na funkciju. Na primer, deklaracija:
int (*fp)(int);
de nise promenljivu f, koja je tipa ”pokazivac na funkciju koja prihvata argument
tipa int, i vraca vrednost tipa int”. Ova promenljiva sadrzi adresu neke funkcije
tog tipa. Na primer, ako je deklarisana funkcija:
int f(int a);
Tada je moguce dodeliti:
fp = &f; /* Operator adrese nije neophodan. */
Promenljiva fp sadrzi adresu funkcije f. Funkcija f se sada moze pozivati derefer-
enciranjem pokazivaca fp:
(*fp)(3);
Zagrade oko izraza *fp su neophodne zbog prioriteta operatora. Dereferenciranjem
pokazivaca na funkciju dobija se funkcija, koja se onda poziva na uobicajen nacin.
int kvadrat(int n)
{
return n*n;
}
int kub(int n)
{
return n*n*n;
}
86
Milena Vujošević–Janičić Pokazivači na funkcije
int parni_broj(int n)
{
return 2*n;
}
return suma;
}
main()
{
/* Ili:
printf("Suma kvadrata brojeva od jedan do 3 je %d\n", sumiraj(&kvadrat,3));
printf("Suma kubova brojeva od jedan do 3 je %d\n", sumiraj(&kub,3));
printf("Suma prvih pet parnih brojeva je %d\n", sumiraj(&parni_broj,5));
*/
}
/*Izlaz:
Suma kvadrata brojeva od jedan do 3 je 14
Suma kubova brojeva od jedan do 3 je 36
Suma prvih pet parnih brojeva je 30
*/
87
Milena Vujošević–Janičić Pokazivači na funkcije
/*
Zaglavlje math.h sadrzi deklaracije razih matematickih funkcija. Izmedju
ostalog, to su sledece funkcije:
double sin(double x);
double cos(double x);
double tan(double x);
double asin(double x);
double acos(double x);
double atan(double x);
double atan2(double y, double x);
double sinh(double x);
double cosh(double x);
double tanh(double x);
double exp(double x);
double log(double x);
double log10(double x);
double pow(double x, double y);
double sqrt(double x);
double ceil(double x);
double floor(double x);
double fabs(double x);
*/
printf("-----------------------\n");
for(x = a; x <= b; x+=h)
printf("| %8.3f | %8.3f |\n", x, (*f)(x));
printf("-----------------------\n");
88
Milena Vujošević–Janičić 8.1 Funkcija qsort iz standardne biblioteke
/* Funkcija main */
int main()
{
double a, b, h;
/* Unosimo korak */
printf("Uneti korak: ");
scanf("%lf", &h);
return 0;
}
89
Milena Vujošević–Janičić 8.1 Funkcija qsort iz standardne biblioteke
vraca pozitivnu vrednost ako je prvi manji, 0 ako su jednaki i negativnu vrednost
ako je prvi veci).
Kvalifikator const
Kljucna rec const u programskom jeziku C sluzi za de nisanje konstanti. Ako
napisemo:
const int a = 2;
tada se u daljem toku programa promenljivoj a ne moze dodeljivati vrednost. Za
razliku od konstanti de nisanih de ne direktivom ova konstanta ima jasno de nisan
tip koji prevodilac proverava prilikom upotrebe.
Treba naglasiti, medjutim, da ako se napise:
const int * p = &a;
tada se const ne odnosi na promenljivu p, vec na podatak tipa int na koji p
pokazuje. Dakle, nije pokazivac konstantan, vec on pokazuje na konstantan podatak.
Na primer:
int b;
p = &b;
je dozvoljeno, ali:
*p = 4;
nije dozvoljeno, zato sto je p pokazivac na konstantan int (odnosno, kroz pokazivac
p nije moguce menjati vrednost koja se nalazi na adresi na koju on ukazuje). Ovo
se moze razumeti tako sto se deklaracija procita sa desna u levo:
const int * p; /* p je pokazivac na int koji je konstantan*/
Slicno bi bilo i ako napisemo:
int const * p; /* p je pokazivac na konstantan int. */
Med̄utim, ako napisemo:
int * const p; /* p je konstantan pokazivac na int. */
Kombinacija ovoga je:
const int * const p; /* p je konstantan pokazivac na int
koji je konstantan.*/
Dakle, u ovom poslednjem slucaju konstantni su i pokazivac i ono na sta on pokazuje.
90
Milena Vujošević–Janičić 8.1 Funkcija qsort iz standardne biblioteke
Upotreba qsort
Primer 8.3 Upotrebom qsort funkcije iz standardne biblioteke izvršiti sortiranje
niza celih i niza realnih brojeva.
/* Ilustracija upotrebe funkcije qsort iz stdlib.h
Sortira se niz celih brojeva.
*/
#include <stdlib.h>
#include <stdio.h>
return br_a-br_b;
*/
return *((int*)a)-*((int*)b);
}
main()
{
int i;
int niz[]={3,8,7,1,2,3,5,6,9};
float nizf[]={3.0,8.7,7.8,1.9,2.1,3.3,6.6,9.9};
int n=sizeof(niz)/sizeof(int);
qsort((void*)niz, n, sizeof(int), poredi);
for(i=0; i<n; i++)
printf("%d",niz[i]);
91
Milena Vujošević–Janičić 8.1 Funkcija qsort iz standardne biblioteke
n=sizeof(nizf)/sizeof(float);
qsort((void*)nizf, n, sizeof(float), poredi_float);
for(i=0; i<n; i++)
printf("%f",nizf[i]);
}
Primer 8.4 Sortiranje reči. Ako se sortira niz stringova, onda svaki element je
sam po sebi pokazivač tipa char *, te funkcija pored̄enja tada prima podatke tipa
char ** koji se konvertuju u svoj tip i derefenciraju radi dobijanja podataka tipa
char *.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
main()
{
int i;
char* nizreci[]={"Jabuka","Kruska","Sljiva","Dinja","Lubenica"};
92
Milena Vujošević–Janičić 8.2 Funkcija bsearch iz standardne biblioteke
qsort((void*)nizreci, sizeof(nizreci),
sizeof(char*), poredi_leksikografski);
printf("Sortirano:\n");
for (i=0; i<sizeof(nizreci); i++)
printf("%s\n",nizreci[i]);
}
/*
Izlaz:
Dinja Jabuka Kruska Lubenica Sljiva
Sortirano:
Lubenica Kruska Jabuka Sljiva Dinja
*/
93
Milena Vujošević–Janičić 8.2 Funkcija bsearch iz standardne biblioteke
main()
{
int x=-1;
int niz[]={1,2,3,4,5,6,7,8,9,10,11,12};
int* elem=(int*)bsearch((void*)&x,
(void*)niz,
sizeof(niz)/sizeof(int),
sizeof(int),
poredi);
if (elem==NULL)
printf("Element nije pronadjen\n");
else
printf("Element postoji na poziciji %d\n",elem-niz);
}
Primer 8.6 Sa ulaza se unose reči. Program broji pojavljivanja svake od ključnih
reči programskog jezika C. Na kraju se reči ispisuju opadajuće po broju pojavljivanja.
#include <stdio.h>
#include <stdlib.h>
94
Milena Vujošević–Janičić 8.2 Funkcija bsearch iz standardne biblioteke
word[i]=’\0’;
return i;
}
95
Milena Vujošević–Janičić 8.2 Funkcija bsearch iz standardne biblioteke
main()
{
char word[80];
int i;
/* Citamo reci */
while (getword(word,80)!=-1)
{
/* Trazimo rec u spisku kljucnih reci binarnom pretragom */
/* Prvi argument funkcije bsearch treba da bude pokazivac
na rec koju trazimo. Posto je word tipa niza karaktera, tada
uzimanjem adrese od word dobijamo istu vrednost kao i word,
tj nema razlike izmedju word i &word. Zbog toga se u funkciji
poredjenja koristi dreferenciranje na sledeci nacin
strcmp((char*)a, (*(keyword*)b).word); }
Da je word tipa char*, tada bi poziv funkcije bsearch
sa argumentom &word povlacilo da funkcija poredjenja
koristi dereferenciranje na sledeci nacin
strcmp(*(char**)a, (*(keyword*)b).word); }
*/
keyword* k=(keyword*)bsearch((void*)word,
(void*)keywords,
num_of_keywords,
sizeof(keyword),
cmp);
/* Ukoliko je pronadjena uvecavamo broj pojavljivanja */
if (k!=NULL)
(*k).num++;
}
/* Vrsimo ispis */
for (i=0; i<num_of_keywords; i++)
96
Milena Vujošević–Janičić 8.3 Funkcije lsearch i lfind
8.4 Pokazivači
Primer 8.7 Različite deklaracije:
int *p; pokazivac na int
int **p; pokazivac na pokazivac na tip int
97
Milena Vujošević–Janičić 8.4 Pokazivači
98
Glava 9
99
Milena Vujošević–Janičić Dinamička alokacija memorije
main()
{
int n;
int i;
int *a;
100
Milena Vujošević–Janičić Dinamička alokacija memorije
/* Oslobadjamo memoriju*/
free(a);
}
Primer 9.2 Demonstracija funkcije calloc - funkcija inicijalizuje sadrzaj memo-
rije na 0.
#include <stdio.h>
#include <stdlib.h>
main()
{
int *m, *c, i, n;
101
Milena Vujošević–Janičić Dinamička alokacija memorije
/*Odstampace se nule*/
for (i = 0; i<n; i++)
printf("c[%d] = %d\n", i, c[i]);
102
Milena Vujošević–Janičić Dinamička alokacija memorije
/* Vracamo p */
return p;
}
int main()
{
char * p = NULL;
char s[MAX], t[MAX];
/* Ucitavamo stringove */
scanf("%s", s);
scanf("%s", t);
/* Nadovezujemo stringove */
p = nadovezi_stringove(s,t);
/* Prikazujemo rezultat */
printf("%s\n", p);
/* Oslobadjamo memoriju*/
free(p);
return 0;
}
Primer 9.4 Niz pokazivača na nizove različitih dužina.
#include <stdio.h>
#include <stdlib.h>
main()
{
/* Niz od tri elemenata tipa int*/
int nizi[3];
103
Milena Vujošević–Janičić Dinamička alokacija memorije
printf("%d", nizip[1][1]);
104
Milena Vujošević–Janičić 9.1 Matrice
*(nizip[2]) = 2;
printf("%d", *(nizip[2]));
/* Oslobadjamo memoriju. */
free(nizip[0]);
free(nizip[1]);
free(nizip[2]);
}
9.1 Matrice
Primer 9.5 Statička alokacija prostora za matricu.
#include <stdio.h>
main()
{
int i, j;
printf("%d\n", a[1][1]); /* 22 */
105
Milena Vujošević–Janičić 9.1 Matrice
}
}
Ukoliko je potrebna veca eksibilnost, tj. da se dimenzije matrice mogu uneti kao
parametri programa, tada je neophodno koristiti dinamicku alokaciju memorije.
Primer 9.6 Implementacija matrice preko niza.
#include <stdlib.h>
#include <stdio.h>
main()
{
/* Dimenzije matrice */
int m, n;
/* Matrica */
int *a;
int i,j;
/* Unos i alokacija */
printf("Unesi broj vrsta matrice : ");
scanf("%d",&m);
106
Milena Vujošević–Janičić 9.1 Matrice
scanf("%d",&a(i,j));
}
/* Oslobadjamo memoriju */
free(a);
}
Primer 9.7 Druga opcija za implementaciju matrice je koristći pokazivač na pokazivač.
1. Definišemo pokazivač na pokazivač na int:
int **p;
Ovaj pokazivač će čuvati adresu prvog u nizu dinamički alociranih pokazivača
na int-ove.
2. Dinamički alociramo niz od m pokazivača na int-ove, i adresu prvog u nizu
smeštamo u promenljivu p:
p = (int**) malloc(sizeof(int*) * m));
Ovi pokazivači služe da pokazuju na prve elemente nizova int-ova koji pred-
stavljaju dinamički alocirane vrste.
3. Svaku vrstu alociramo posebnim malloc-om, i povratnu adresu smeštamo u i-ti
pokazivač u malopre alociranom nizu pokazivača.
for(i = 0; i < m; i++)
p[i] = malloc(sizeof(int) * n);
Primetimo da nizovi int-ova koji se alociraju nisu morali biti jednakih dimen-
zija (ne moraju svi biti duzine n, kao što je ovde rečeno). Ovo može da bude
korisno, ako znamo da će u nekoj vrsti biti korišćeno samo nekoliko prvih ele-
menata, tada možemo alocirati manje za tu vrstu, i tako uštedeti prostor.
107
Milena Vujošević–Janičić 9.1 Matrice
#include <stdio.h>
#include <stdlib.h>
int main()
{
int **p;
int m, n;
int i, j;
108
Milena Vujošević–Janičić 9.1 Matrice
/* Ispis matrice */
for(i = 0; i < m ; i++)
{
for(j = 0; j < n; j++)
printf("%3d ", p[i][j]);
putchar(’\n’);
}
return 0;
}
Primer 9.8 Program ilustruje rad sa kvadratnim matricama i relacijama. Kôd za
alokaciju i dealokaciju memorije je izdvojen u funkcije. Element i je u relaciji sa
elementom j ako je m[i][j] = 1, a nisu u relaciji ako je m[i][j] = 0.
#include <stdlib.h>
#include <stdio.h>
109
Milena Vujošević–Janičić 9.1 Matrice
{
int k;
printf("Greska prilikom alokacije memorije!\n");
for(k=0;k<i;k++)
free(m[k]);
free(m);
exit(1);
}
}
return m;
}
/* Ispis matrice /
void ispisi_matricu(int** m, int n)
{
int i, j;
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
printf("%d ",m[i][j]);
printf("\n");
}
}
return 1;
}
110
Milena Vujošević–Janičić 9.1 Matrice
main()
{
int **m;
111
Milena Vujošević–Janičić 9.1 Matrice
int n;
int i,j;
ispisi_matricu(m,n);
if (refleksivna(m,n))
printf("Relacija je refleksivna\n");
if (simetricna(m,n))
printf("Relacija je simetricna\n");
if (tranzitivna(m,n))
printf("Relacija je tranzitivna\n");
simetricno_zatvorenje(m,n);
ispisi_matricu(m,n);
obrisi(m,n);
}
Primer 9.9 Izračunati vrednost determinante matrice preko Laplasovog razvoja.
#include <stdio.h>
#include <stdlib.h>
112
Milena Vujošević–Janičić 9.1 Matrice
{
m[i]=malloc(n*sizeof(int));
if (m[i] == NULL)
{
int k;
for(k=0;k<i;k++)
free(m[k]);
printf("Greska prilikom alokacije memorije!\n");
free(m);
exit(1);
}
}
return m;
}
113
Milena Vujošević–Janičić 9.2 Realokacija memorije
det+= znak*matrica[0][i]*determinanta(podmatrica,n-1);
znak*=-1;
}
deallocate(podmatrica,n-1);
return det;
}
main()
{
int **matrica;
int n;
scanf("%d", &n);
matrica = allocate(n);
ucitaj_matricu(matrica, n);
printf("Determinanta je : %d\n",determinanta(matrica,n));
deallocate(matrica, n);
}
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
114
Milena Vujošević–Janičić 9.2 Realokacija memorije
while (isspace(c=getchar()))
;
word[i]=’\0’;
main()
{
char procitana_rec[80];
int i;
115
Milena Vujošević–Janičić 9.2 Realokacija memorije
while (getword(procitana_rec,80)!=-1)
{
/* Proveravamo da li rec vec postoji u nizu */
for (i=0; i<duzina; i++)
/* Ako bismo uporedili procitana_rec == niz_reci[i].ime
bili bi uporedjeni pokazivaci a ne odgovarajuci sadrzaji.
Zato koristimo strcmp. */
if (strcmp(procitana_rec, niz_reci[i].ime)==0)
{
niz_reci[i].br_pojavljivanja++;
break;
}
if (novi_niz == NULL)
{
free(niz_reci);
printf("Greska prilikom alokacije memorije");
exit(1);
}
116
Milena Vujošević–Janičić 9.2 Realokacija memorije
free(niz_reci);
}
117
Glava 10
Liste
10.1 Implementacija
Prilikom promene liste (dodavanje novog elementa, brisanje elementa, premestanje
elemenata, itd.) postoji mogucnost da glava liste bude promenjena, tj. da to postane
neki drugi cvor (sa drugom adresom). U tom slucaju se pokazivac na glavu liste mora
azurirati. Kada promenu liste obavljamo u posebnoj funkciji (kao sto je bio slucaj u
prethodnom primeru, gde smo za dodavanje i brisanje imali posebne funkcije) onda
je potrebno da se pozivajucoj funkciji vrati informacija o promeni adrese glave,
kako bi pozivajuca funkcija mogla da azurira svoju pokazivacku promenljivu. Ovo
se moze uraditi na dva nacina:
1. Pozvana funkcija koja vrsi promenu na listi vraca kao povratnu vrednost adresu
glave nakon promene. Ova adresa moze biti ista kao i pre promene (ako glava
nije dirana) a moze se i razlikovati. U svakom slucaju, ta adresa treba da se
dodeli pokazivackoj promenljivoj koja cuva adresu glave u pozivajucoj funkciji.
1 Tekst preuzet sa sajta www.matf.bg.ac.rs/ milan
118
Milena Vujošević–Janičić 10.1 Implementacija
novi->vrednost = broj;
novi->sledeci = NULL;
119
Milena Vujošević–Janičić 10.1 Implementacija
return novi;
}
/* Ako lista nije prazna, tada se krecemo duz liste sve dok
ne dodjemo do poslednjeg cvora (tj. do cvora ciji pokazivac
na sledeci pokazuje na NULL) */
while(tekuci->sledeci != NULL)
tekuci = tekuci->sledeci;
120
Milena Vujošević–Janičić 10.1 Implementacija
/* Ako lista nije prazna, tada se krecemo duz liste sve dok
ne dodjemo do poslednjeg cvora (tj. do cvora ciji pokazivac
na sledeci pokazuje na NULL) */
while(tekuci->sledeci != NULL)
tekuci = tekuci->sledeci;
return NULL;
}
121
Milena Vujošević–Janičić 10.1 Implementacija
{
putchar(’[’);
for(;glava != NULL; glava = glava->sledeci)
printf("%d ", glava->vrednost);
putchar(’]’);
putchar(’\n’);
}
while(glava != NULL)
{
/* moramo najpre zapamtiti adresu sledeceg
elementa, a tek onda osloboditi glavu */
pomocni = glava->sledeci;
free(glava);
glava = pomocni;
}
return NULL;
}
while(*glava != NULL)
{
/* moramo najpre zapamtiti adresu sledeceg
elementa, a tek onda osloboditi glavu */
pomocni = (*glava)->sledeci;
free(*glava);
*glava = pomocni;
}
}
*/
122
Milena Vujošević–Janičić 10.1 Implementacija
123
Milena Vujošević–Janičić 10.1 Implementacija
*glava = novi;
return;
}
124
Milena Vujošević–Janičić 10.1 Implementacija
NULL */
if(glava == NULL) return NULL;
125
Milena Vujošević–Janičić 10.1 Implementacija
return;
}
*/
/* test program */
int main()
{
126
Milena Vujošević–Janičić 10.1 Implementacija
printf("-------------------------------------------------------\n");
printf("---------------- Testiranje pretrage ------------------\n");
printf("-------------------------------------------------------\n");
printf("Prikaz trenutnog sadrzaja liste:\n");
prikazi_listu(glava);
printf("-------------------------------------------------------\n");
printf("Uneti broj koji se trazi: ");
scanf("%d",&broj);
glava = oslobodi_listu(glava);
/*oslobodi_listu(&glava);*/
127
Milena Vujošević–Janičić 10.1 Implementacija
glava = oslobodi_listu(glava);
/*oslobodi_listu(&glava);*/
glava = oslobodi_listu(glava);
/*oslobodi_listu(&glava);*/
return 0;
}
Primer 10.2 Sve funkcije iz prethodnih primera, za koje to ima smisla, definisane
su rekurzivno. Primetno je da su ove rekurzivne varijante mnogo jednostavnije.
Razlog je to što su liste po svojoj prirodi rekurzivne strukture. Naime, liste se mogu
rekurzivno definisati na sledeći način:
objekat označen sa [] je lista (prazna lista)
ako je L lista, i G neki element, tada je ured̄eni par (G,L) takod̄e lista. Element
G nazivamo glavom liste, a listu L repom liste.
Na primer, uredjeni par (2, []) je lista, i po dogovoru cemo je zapisivati kao [2].
Takodje par (3,[2]) je lista koju možemo zapisati kao [3 2], itd.
U opstem slucaju, ako je L=[a1 a2 a3 ... an] lista, i ako je b neki element,
tada je uredjeni par (b,L) takod̄e lista, koju možemo zapisati kao [b a1 a2 ... an].
128
Milena Vujošević–Janičić 10.1 Implementacija
Glava liste je b, a rep liste je lista L. Sada se obrada liste može razdvojiti na dva
dela:
Izvršiti operaciju nad glavom liste
Izvršiti rekurzivni postupak nad repom liste (koji je takod̄e lista).
Za testiranje narednog programa može se koristiti main funkcija iz primera 10.1.
#include <stdio.h>
#include <stdlib.h>
novi->vrednost = broj;
novi->sledeci = NULL;
return novi;
}
129
Milena Vujošević–Janičić 10.1 Implementacija
}
/*
void dodaj_na_pocetak_liste(Cvor **glava, int broj)
{
Cvor * novi = napravi_cvor(broj);
novi->sledeci = *glava;
*glava = novi;
}
*/
/*
void dodaj_na_kraj_liste(Cvor **glava, int broj)
{
/* Izlaz iz rekurzije: slucaj prazne liste.
U tom slucaju je glava nove liste upravo novi cvor. */
if(*glava == NULL)
*glava = napravi_cvor(broj);
else
/* U slucaju da je lista neprazna, tada ona ima glavu i rep,
pri cemu je rep opet lista. Tada je dodavanje na kraj
liste ekvivalentno dodavanju na kraj repa liste, sto
130
Milena Vujošević–Janičić 10.1 Implementacija
*/
/*
void dodaj_sortirano(Cvor **glava, int broj)
{
131
Milena Vujošević–Janičić 10.1 Implementacija
132
Milena Vujošević–Janičić 10.1 Implementacija
/*
void obrisi_element(Cvor **glava, int broj)
{
133
Milena Vujošević–Janičić 10.1 Implementacija
if(*glava->vrednost == broj)
{
Cvor *pomocni = *glava;
*glava = *glava->sledeci;
free(pomocni);
}
}
*/
/* Izlaz iz rekurzije */
if(glava == NULL) return;
/* Prikaz glave */
printf("%d ", glava->vrednost);
prikazi_listu_r(glava);
putchar(’]’);
putchar(’\n’);
}
134
Milena Vujošević–Janičić 10.1 Implementacija
return NULL;
}
/*
void oslobodi_listu(Cvor **glava)
{
/* Izlaz iz rekurzije */
if(*glava == NULL) return;
*glava = NULL;
}
*/
Primer 10.3 Program ispisuje broj pojavljivanja za svaku od reči koja se pojavila u
tekstu unetom sa standardnog ulaza. Verzija sa (sortiranom) listom.
#include <stdlib.h>
#include <stdio.h>
135
Milena Vujošević–Janičić 10.1 Implementacija
strcpy(novi->ime, rec);
novi->br_pojavljivanja = 1;
novi->sledeci = NULL;
return novi;
}
136
Milena Vujošević–Janičić 10.1 Implementacija
return napravi_cvor(rec);
if (c==EOF)
return -1;
do
{ word[i++]=c;
}while (i<lim-1 && isalpha(c=getchar()));
word[i]=’\0’;
return i;
}
137
Milena Vujošević–Janičić 10.1 Implementacija
main()
{
cvor* lista=NULL;
char procitana_rec[80];
cvor* pronadjen;
while(getword(procitana_rec,80)!=-1)
lista=ubaci_sortirano(lista,procitana_rec);
pronadjen=nadji_rec(lista,"programiranje");
if (pronadjen!=NULL)
printf("Rec programiranje se javlja u listi!\n");
else
printf("Rec programiranje se ne javlja u listi!\n");
ispisi_listu(lista);
obrisi_listu(lista);
}
Primer 10.4 Primer ilustruje sortiranje liste. Lista moze biti sortirana na dva
načina. Prvi način je da se premeštaju čvorovi u listi (što zahteva prevezivanje
pokazivača), a drugi je da se premeštaju vrednosti koje čvorovi sadrže. Prvi način
je komplikovaniji, ali je često efikasniji, naročito ako su objekti koji se čuvaju kao
podaci u čvorovima veliki.
U oba slučaja se može koristiti rekurzija, a može se realizovati i iterativno. U
ovom primeru ilustrujemo oba načina sortiranja lista (prvi rekurzivno, a drugi iter-
ativno).
#include <stdio.h>
#include <stdlib.h>
138
Milena Vujošević–Janičić 10.1 Implementacija
#include <time.h>
novi->vrednost = broj;
novi->sledeci = NULL;
return novi;
}
139
Milena Vujošević–Janičić 10.1 Implementacija
/* Izlaz iz rekurzije */
if(glava == NULL) return;
/* Prikaz glave */
printf("%d ", glava->vrednost);
prikazi_listu_r(glava);
putchar(’]’);
putchar(’\n’);
}
return NULL;
}
140
Milena Vujošević–Janičić 10.1 Implementacija
{
/* u slucaju da je lista prazna, ili da je vrednost
glave veca ili jednaka od vrednosti broja koji
umecemo, tada se novi cvor umece na pocetak liste. */
if(glava == NULL || glava->vrednost >= novi->vrednost)
{
novi->sledeci = glava;
return novi;
}
/* vracamo glavu */
return glava;
}
/* Izlaz iz rekurzije */
if(glava == NULL)
return NULL;
141
Milena Vujošević–Janičić 10.1 Implementacija
/* Vracamo glavu */
return glava;
}
/* test program */
int main()
{
Cvor *glava = NULL;
int n = 10;
142
Milena Vujošević–Janičić 10.2 Kružna (ciklična) lista
srand(time(NULL));
/* Sortiramo listu */
glava = sortiraj_listu(glava);
/* glava = sortiraj_listu2(glava); */
/* Oslobadjamo listu */
glava = oslobodi_listu(glava);
return 0;
}
A B C ... Z
Primer 10.5 (februar 2006.) Grupa od n plesača (na čijim kostimima su u smeru
kazaljke na satu redom brojevi od 1 do n) izvodi svoju plesnu tačku tako što formiraju
krug iz kog najpre izlazi k-ti plesač (odbrojava se počev od plesača označenog brojem
1 u smeru kretanja kazaljke na satu). Preostali plesači obrazuju manji krug iz kog
opet izlazi k-ti plesač (odbrojava se pocev od sledećeg suseda prethodno izbačenog,
opet u smeru kazaljke na satu). Izlasci iz kruga se nastavljaju sve dok svi plesači
143
Milena Vujošević–Janičić 10.3 Red
10.3 Red
A B ... X NULL
novi element
pocetak reda
novi kraj reda
A B ... X Y NULL
B ... X Y NULL
Red (eng. queue) je struktura podataka nad kojom su de nisane sledece operacije:
Dodavanje elementa – kazemo da je element dodat na kraj reda (eng. enqueue()
operacija)
Uklanjanje elementa koji je prvi dodat – kazemo da je element skinut sa pocetka
reda (eng. dequeue() operacija)
Ocitavanje vrednosti elementa koji je na pocetku reda (eng. front() operacija)
Red spada u FIFO strukture (eng. First In First Out). Moze se implementirati
na vise nacina. Najjednostavniji nacin je da se de nise kao niz. Medjutim, tada
je ogranicen max. broj elemenata u redu dimenzijom niza. Zbog toga se obicno
pribegava koriscenju lista za implementaciju reda, gde se enqueue() operacija svodi
na dodavanje na kraj liste, a dequeue() operacija se svodi na uklanjanje glave liste.
144
Milena Vujošević–Janičić 10.3 Red
strcpy(novi->ime_fajla, ime_fajla);
novi->sledeci = NULL;
return novi;
}
145
Milena Vujošević–Janičić 10.3 Red
if(*kraj != NULL)
{
(*kraj)->sledeci = novi;
*kraj = novi;
}
else /* ako je red prazan */
{
*pocetak = novi;
*kraj = novi;
}
}
if(*pocetak == NULL)
return 0;
if(ime_fajla != NULL)
strcpy(ime_fajla, (*pocetak)->ime_fajla);
pomocni = *pocetak;
*pocetak = (*pocetak)->sledeci;
free(pomocni);
if(*pocetak == NULL)
*kraj = NULL;
return 1;
}
146
Milena Vujošević–Janičić 10.3 Red
while(*pocetak != NULL)
{
pomocni = *pocetak;
*pocetak = (*pocetak)->sledeci;
free(pomocni);
}
*kraj = NULL;
}
/* Glavni program */
int main(int argc, char ** argv)
{
Cvor * pocetak = NULL, * kraj = NULL;
FILE *in = NULL;
char ime_fajla[MAX];
int x, y;
int pronadjen = 0;
147
Milena Vujošević–Janičić 10.3 Red
/* Trazeni broj x */
x = atoi(argv[2]);
}
/* Zatvaramo fajl */
fclose(in);
}
148
Milena Vujošević–Janičić 10.3 Red
/* Oslobadjamo red */
oslobodi_red(&pocetak, &kraj);
return 0;
}
Primer 10.7 Program formira celobrojni red i ispisuje sadržaj reda na standardni
izlaz.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
if(*kraj != NULL)
{
149
Milena Vujošević–Janičić 10.3 Red
(*kraj)->sledeci = novi;
*kraj = novi;
}
else /* ako je red prazan */
{
*pocetak = novi;
*kraj = novi;
}
}
if(*pocetak == NULL)
return 0;
if(broj != NULL)
*broj = (*pocetak)->broj);
pomocni = *pocetak;
*pocetak = (*pocetak)->sledeci;
free(pomocni);
if(*pocetak == NULL)
*kraj = NULL;
return 1;
}
main()
{
Cvor * pocetak = NULL, * kraj = NULL;
int i, broj;
/*Formiranje jednostavnog reda*/
for(i=0; i<100; i++)
dodaj_u_red(&pocetak, &kraj, i);
150
Milena Vujošević–Janičić 10.4 Stek
10.4 Stek
Stek (eng. stack) je struktura podataka nad kojom su de nisane sledece operacije:
Dodavanje elementa – kazemo da je element potisnut na vrh steka (eng. push()
operacija).
Uklanjanje elementa koji je poslednji dodat – kazemo da je element skinut sa
vrha steka (eng. pop() operacija).
Ocitavanje vrednosti elementa koji je poslednji dodat (eng. top() operacija).
Stek spada u LIFO strukture (eng. Last In First Out). Moze se implementirati
na vise nacina. Najjednostavniji nacin je da se de nise kao niz. Medjutim, tada
je ogranicen max. broj elemenata na steku dimenzijom niza. Zbog toga se obicno
pribegava koriscenju lista za implementaciju steka, gde se push() operacija svodi
na dodavanje na pocetak, a pop() operacija se svodi na uklanjanje glave liste. Obe
operacije se izvode u konstantnom vremenu.
Primer 10.8 Program proverava da li su zagrade (, [, {, }, ] i ) dobro uparene —
statička implementacija steka (pretpostavka da se na ulazu neće naći više od 100
otvorenih zagrada za redom).
#include <stdio.h>
#include <stdlib.h>
#define MAX_ZAGRADA 100
main()
{
int c;
char otv_zagrade[MAX_ZAGRADA];
int br_otv = 0;
while((c=getchar()) != EOF)
{
switch(c)
151
Milena Vujošević–Janičić 10.4 Stek
{
case ’(’:
case ’{’:
case ’[’:
{
otv_zagrade[br_otv] = c;
br_otv++;
break;
}
case ’]’:
case ’}’:
case ’)’:
if (br_otv>0 && odgovarajuce(otv_zagrade[br_otv-1], c))
{
br_otv--;
}
else
{
printf("Visak zatvorenih zagrada: %c u liniji %d\n", c, br_linija);
exit(1);
}
}
}
if (br_otv == 0)
printf("Zagrade su u redu\n");
else
printf("Visak otvorenih zagrada\n");
}
Primer 10.9 Program proverava da li su etikete u datom HTML fajlu dobro up-
arene.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define OTVORENA 1
#define ZATVORENA 2
#define VAN_ETIKETE 0
#define PROCITANO_MANJE 1
152
Milena Vujošević–Janičić 10.4 Stek
X Y ... A NULL
novi element
Y X V ... A NULL
X V ... A NULL
#define U_ETIKETI 2
strcpy(novi->etiketa, etiketa);
novi->sledeci = NULL;
153
Milena Vujošević–Janičić 10.4 Stek
return novi;
}
if(*vrh == NULL)
return 0;
if(etiketa != NULL)
strcpy(etiketa, (*vrh)->etiketa);
pomocni = *vrh;
*vrh = (*vrh)->sledeci;
free(pomocni);
return 1;
}
154
Milena Vujošević–Janičić 10.4 Stek
while(*vrh != NULL)
{
pomocni = *vrh;
*vrh = (*vrh)->sledeci;
free(pomocni);
}
}
155
Milena Vujošević–Janičić 10.4 Stek
{
tip = OTVORENA;
etiketa[i++] = tolower(c);
}
stanje = U_ETIKETI;
break;
case U_ETIKETI:
if(isalpha(c) && i < MAX - 1)
etiketa[i++] = tolower(c);
else {
stanje = VAN_ETIKETE;
etiketa[i]=’\0’;
return tip;
}
break;
}
}
return EOF;
}
/* Test program */
int main(int argc, char **argv)
{
/* Otvaramo datoteku */
if((f = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "fopen() greska!\n");
exit(1);
}
156
Milena Vujošević–Janičić 10.4 Stek
/* Zatvaramo fajl */
fclose(f);
157
Milena Vujošević–Janičić 10.4 Stek
/* Oslobadjamo stek */
oslobodi_stek(&vrh);
return 0;
}
Primer 10.10 Program formira celobrojni stek i ispisuje sadržaj steks na standardni
izlaz.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
158
Milena Vujošević–Janičić 10.4 Stek
if(*vrh == NULL)
return 0;
if(broj != NULL)
*broj = (*vrh)->broj);
pomocni = *vrh;
*vrh = (*vrh)->sledeci;
free(pomocni);
return 1;
}
main()
{
Cvor * vrh = NULL;
int i, broj;
/*Formiranje steka*/
for(i=0; i<100; i++)
potisni_na_stek(&vrh, i);
159
Milena Vujošević–Janičić 10.5 Dvostruko povezane liste
...
NULL A B C ... Z NULL
160
Milena Vujošević–Janičić 10.5 Dvostruko povezane liste
novi->vrednost = broj;
novi->prethodni = NULL;
novi->sledeci = NULL;
return novi;
}
return novi;
}
/* Ako lista nije prazna, tada se krecemo duz liste sve dok
ne dodjemo do poslednjeg cvora (tj. do cvora ciji pokazivac
161
Milena Vujošević–Janičić 10.5 Dvostruko povezane liste
162
Milena Vujošević–Janičić 10.5 Dvostruko povezane liste
if(tekuci->sledeci != NULL)
tekuci->sledeci->prethodni = novi;
tekuci->sledeci = novi;
return NULL;
}
163
Milena Vujošević–Janičić 10.5 Dvostruko povezane liste
putchar(’\n’);
}
164
Milena Vujošević–Janičić 10.5 Dvostruko povezane liste
{
printf("[]\n");
return;
}
putchar(’\n’);
}
while(glava != NULL)
{
/* moramo najpre zapamtiti adresu sledeceg
elementa, a tek onda osloboditi glavu */
pomocni = glava->sledeci;
free(glava);
glava = pomocni;
}
return NULL;
}
165
Glava 11
Stabla
166
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
NULL NULL
NULL NULL
U programiranju se stabla obicno koriste kao strukture podataka, tako sto svaki
cvor sadrzi po jedan podatak odred̄enog tipa. Nacin raspored̄ivanja podataka u
stablu zavisi od konkretne primene stabla. S obzirom na rekurzivnu prirodu stabla,
uobicajeno je da se u programiranju stabla obrad̄uju rekurzivno.
167
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
12 21
NULL NULL
5 15
#include <stdio.h>
168
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
novi->broj = b;
novi->l = NULL;
novi->d = NULL;
return novi;
}
if (b < koren->broj)
koren->l = ubaci_u_drvo(koren->l, b);
else
koren->d = ubaci_u_drvo(koren->d, b);
return koren;
}
if (koren->broj == b)
return 1;
if (b < koren->broj)
return pronadji(koren->l, b);
else
return pronadji(koren->d, b);
}
169
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
}
}
170
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
broj_listova(koren->d);
}
return suma_listova(koren->l) +
suma_listova(koren->d);
}
ispisi_listove(koren->l);
ispisi_listove(koren->d);
}
if (koren->d==NULL)
return koren->broj;
return max_vrednost(koren->d);
}
171
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
if (pronadji(koren, 3))
printf("Pronadjeno 3\n");
if (pronadji(koren, 2))
172
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
printf("Pronadjeno 2\n");
if (pronadji(koren, 7))
printf("Pronadjeno 7\n");
ispisi_drvo(koren);
putchar(’\n’);
printf("Suma cvorova : %d\n", suma_cvorova(koren));
printf("Broj cvorova : %d\n", broj_cvorova(koren));
printf("Broj listova : %d\n", broj_listova(koren));
printf("Suma listova : %d\n", suma_listova(koren));
printf("Dubina drveta : %d\n", dubina(koren));
printf("Maximalna vrednost : %d\n", max_vrednost(koren));
ispisi_listove(koren);
obrisi_drvo(koren);
}
/*
Pronadjeno 3
Pronadjeno 7
1 3 5 6 7 8 9
Suma cvorova : 39
Broj cvorova : 7
Broj listova : 3
Suma listova : 18
Dubina drveta : 5
Maximalna vrednost : 9
3 6 9
*/
Primer 11.2 Binarno pretraživačko drvo - funkcije za izračunavanje kopije, unije,
preseka i razlike dva drveta, funkcija za izbacivanje čvora iz drveta.
/* Struktura koja predstavlja cvor drveta */
typedef struct cvor {
} Cvor;
173
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
/* inicijalizacija */
novi->vrednost = broj;
novi->levi = NULL;
novi->desni = NULL;
174
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
175
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
176
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
Cvor * pomocni=NULL;
177
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
178
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
if(koren == NULL)
return;
prikazi_stablo (koren->levi);
printf("%d ", koren->vrednost);
prikazi_stablo (koren->desni);
}
/* Izlaz iz rekurzije */
if(koren == NULL)
return NULL;
return NULL;
}
179
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
180
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
181
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
/* test program */
int main()
{
printf("-------------------------------------------------------\n");
putchar(’\n’);
182
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
183
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
printf("-------------------------------------------------------\n");
putchar(’\n’);
pomocni = kopiraj_stablo(koren);
pomocni = kreiraj_uniju(pomocni, koren_2);
printf("-------------------------------------------------------\n");
printf("Prikaz 1. stabla:\n");
prikazi_stablo (koren);
putchar(’\n’);
printf("-------------------------------------------------------\n");
printf("Prikaz 2. stabla:\n");
prikazi_stablo (koren_2);
putchar(’\n’);
printf("-------------------------------------------------------\n");
printf("Unija ova dva stabla:\n");
prikazi_stablo (pomocni);
putchar(’\n’);
printf("-------------------------------------------------------\n");
pomocni = oslobodi_stablo(pomocni);
pomocni = kopiraj_stablo(koren);
pomocni = kreiraj_presek(pomocni, koren_2);
pomocni = oslobodi_stablo(pomocni);
pomocni = kopiraj_stablo(koren);
pomocni = kreiraj_razliku(pomocni, koren_2);
184
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
return 0;
}
Primer 11.3 Primer demonstrira sortiranje niza pomoću binarnog stabla. Elementi
niza se redom prvo smeste u binarno stablo pretrage, a zatim se elementi ”pokupe”
iz stabla obilazeći ga sa leva u desno (tj. u rastućem poretku). Vremenska složenost
ovakvog algoritma je u ekvivalentna quick_sort()-u. Prostorna slozenost je nesto
veća, jer sortiranje nije ”u mestu”, već se koristi pomoćna struktura – binarno
stablo.
#include <stdio.h>
#include <stdlib.h>
int vrednost;
struct cvor * levi;
struct cvor * desni;
} Cvor;
if (novi == NULL)
{
fprintf (stderr,"malloc() greska\n");
exit (1);
}
novi->vrednost = broj;
novi->levi = NULL;
novi->desni = NULL;
return novi;
185
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
if (koren == NULL)
return napravi_cvor (broj);
return koren;
if(koren == NULL)
return;
oslobodi_stablo (koren->levi);
oslobodi_stablo (koren->desni);
free(koren);
if(koren == NULL)
return 0;
r = kreiraj_niz(koren->levi, a);
186
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
a[r] = koren->vrednost;
s = kreiraj_niz(koren->desni, a + r + 1);
return r + s + 1;
kreiraj_niz(koren, a);
oslobodi_stablo(koren);
/* Test program */
int main()
{
int a[MAX];
int n, i;
187
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
sortiraj(a, n);
return 0;
}
Primer 11.4 Program sa ulaza čita tekst i ispisuje broj pojavljivanja svake od reči
koje su se javljale u tekstu. Radi poboljšanja efikasnosti, prilikom brojanja reči koristi
se struktura podataka pogodna za leksikografsku pretragu — u ovom slučaju binarno
pretraživačko drvo.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* inicijalizacija */
188
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
strcpy(novi->rec, rec);
novi->brojac = 1;
novi->levi = NULL;
novi->desni = NULL;
189
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
/* Izlaz iz rekurzije */
if (koren == NULL)
return NULL;
prikazi_stablo(koren->levi);
printf("%s: %d\n", koren->rec, koren->brojac);
prikazi_stablo(koren->desni);
190
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
if(koren == NULL)
return;
oslobodi_stablo (koren->levi);
oslobodi_stablo (koren->desni);
free(koren);
/* Zatvaramo string */
rec[i] = ’\0’;
/* test program */
int main(int argc, char **argv)
{
191
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
/* Otvaramo datoteku */
if((f = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "fopen() greska\n");
exit(1);
}
/* Oslobadjamo stablo */
oslobodi_stablo(koren);
return 0;
}
Primer 11.5 Mapa je apstraktna struktura podataka koja u sebi sadrzi parove oblika
(kljuc, vrednost). Pri tom su i ključ i vrednost unapred odred̄enog (ne obavezno
istog) tipa (na primer, ključ nam može biti string koji predstavlja ime studenta, a
vrednost je npr. broj koji predstavlja njegov prosek). Operacije koje mapa mora
192
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
193
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
/* inicijalizacija */
strcpy(novi->naziv, naziv);
novi->cena = cena;
novi->levi = NULL;
novi->desni = NULL;
194
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
/* cvor liste */
typedef struct cvor_liste {
char naziv[MAX];
int cena;
struct cvor_liste * sledeci;
} Cvor_liste;
195
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
strcpy(novi->naziv, naziv);
novi->cena = cena;
novi->sledeci = NULL;
return novi;
}
/* Funkcija pronalazi sve nazive cija je cena manja ili jednaka od date,
i formira listu koja sadrzi nadjene parove (naziv, cena) u leksikogra-
fskom poretku po nazivima. Prilikom pocetnog poziva, treci argument
treba da bude NULL. Funkcija obilazi stablo sa desna u levo, kako bi
se prilikom dodavanja na pocetak liste poslednji dodao onaj koji je
leksikografski najmanji (tj. on ce biti na pocetku). */
Cvor_liste * pronadji_manje (Cvor * koren, int cena, Cvor_liste * glava)
{
if(koren == NULL)
return glava;
196
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
return;
glava->sledeci = oslobodi_listu(glava->sledeci);
free(glava);
return NULL;
}
if(koren == NULL)
return NULL;
return NULL;
/* test program */
int main(int argc, char ** argv)
{
Cvor * koren = NULL, * pomocni;
Cvor_liste * glava = NULL;
FILE *f;
char naziv[MAX];
int cena;
197
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
if(argc < 2)
{
fprintf(stderr, "Morate navesti ime datoteke!\n");
exit(0);
}
/* Otvaramo datoteku */
if((f = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "fopen() greska\n");
exit(1);
}
/* Oslobadjanje memorije */
glava = oslobodi_listu(glava);
koren = oslobodi_stablo(koren);
return 0;
}
Primer 11.6 Program broji pojavljivanje svake etikete u tekstu i ispisuje etikete i
njihove frekvencije u opadajućem poretku po frekvencijama.
Radi poboljšanja efikasnosti, prilikom brojanja pojavljivanja etiketa koristi se
198
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
/* Izlaz iz rekurzije */
if(koren == NULL)
{
if((koren = malloc(sizeof(Cvor))) == NULL)
{
fprintf(stderr,"malloc() greska\n");
exit(1);
}
199
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
strcpy(koren->etiketa, etiketa);
koren->brojac = 1;
koren->levi = NULL;
koren->desni = NULL;
return koren;
}
/* Rekurzivni pozivi */
if((cmp = strcmp(koren->etiketa,etiketa)) < 0)
koren->desni = dodaj_leksikografski(koren->desni, etiketa);
else if(cmp > 0)
koren->levi = dodaj_leksikografski(koren->levi, etiketa);
else
koren->brojac++; /* uvecanje brojaca za vec prisutne etikete */
return koren;
}
200
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
{
/* u ovom stanju trazimo prvu sledecu pojavu znaka ’<’ */
case VAN_ETIKETE:
if(c == ’<’)
{
stanje = U_ETIKETI; /* sada smo u etiketi */
i = 0;
}
break;
/* u ovom stanju citamo slova koja slede, i nakon toga
ubacujemo procitanu etiketu u stablo */
case U_ETIKETI:
/* Ako je slovo, i nismo prekoracili duzinu niza
dodajemo slovo u niz */
if(isalpha(c) && i < MAX_ETIKETA - 1)
etiketa[i++] = c;
/* u suprotnom se vracamo u stanje VAN_ETIKETE */
else {
stanje = VAN_ETIKETE;
/* Ako je niz slova nakon ’<’ bio neprazan... */
if(i > 0)
{
etiketa[i]=’\0’;
/* ubacujemo procitanu etiketu u stablo */
koren = dodaj_leksikografski(koren, etiketa);
}
}
break;
}
return koren;
/* Izlaz iz rekurzije */
if(koren == NULL)
201
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
{
if((koren = malloc(sizeof(Cvor))) == NULL)
{
fprintf(stderr,"malloc() greska\n");
exit(1);
}
/* NAPOMENA: s obzirom da dve ili vise etiketa mogu imati isti broj
pojavljivanja, etiketa se mora dodavati u stablo, cak i ako ima
isti broj pojavljivanja sa korenom. Zato cemo u levo podstablo
dodavati etikete koje imaju veci broj pojavljivanja od korena,
dok cemo u desno podstablo dodavati etikete koje imaju manji
ili jednak broj pojavljivanja od korena. */
/* Rekurzivni pozivi */
if(koren->brojac >= broj)
koren->desni = dodaj_po_broju(koren->desni, etiketa, broj);
else if(koren->brojac < broj)
koren->levi = dodaj_po_broju(koren->levi, etiketa, broj);
return koren;
202
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
return novo;
}
ispisi_stablo(koren->levi);
printf("%s: %d\n", koren->etiketa, koren->brojac);
ispisi_stablo(koren->desni);
oslobodi_stablo(koren->levi);
oslobodi_stablo(koren->desni);
free(koren);
}
/* glavni program */
int main(int argc, char **argv)
{
203
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
/* Otvaramo fajl */
if((in = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "fopen() greska\n");
exit(1);
}
/* Oslobadjamo stabla */
oslobodi_stablo(koren);
oslobodi_stablo(resortirano);
return 0;
}
Primer 11.7 Efikasnije sortiranje čorova stabla — formira se niz pokazivača na
čvorove stabla koji se u skladu sa funkcijom pored̄enja sortiraju pomoću bibliotečke
qsort funkcije.
#include <stdlib.h>
#include <stdio.h>
204
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
cvor* razlicite_reci[MAX_BROJ_RAZLICITIH_RECI];
return novi_cvor;
}
205
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
return novi_cvor;
}
206
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
word[i]=’\0’;
return i;
}
if (argc!=2)
{ fprintf(stderr,"Greska :
Ocekivano ime datoteke\n");
207
Milena Vujošević–Janičić 11.1 Binarno pretraživačko stablo
exit(1);
}
if ((ulaz=fopen(argv[1],"r"))==NULL)
{
fprintf(stderr,"Greska : nisam uspeo da otvorim datoteku %s\n");
exit(1);
}
fclose(ulaz);
}
208
Glava 12
Grafovi
209
Milena Vujošević–Janičić Grafovi
sadrzi ime (indeks) cvora i pokazivac na njegovu listu cvorova. Ovakav pristup stedi
memoriju, a omogucava i e kasno dodavanje novih cvorova i grana.
Osnovni problem koji se javlja kod grafova jeste kako polazeci od nekog cvora, kre-
tanjem kroz puteva grafa posetiti sve cvorove. Ovakav postupak se naziva obilazak
grafa. Postoje dva osnovna algoritma za obilazak grafa: pretraga u dubinu (DFS,
skracenica od depth- rst-search) i pretraga u sirinu (BFS, skracenica od breadth-
rst-search).
Kod DFS algoritma, obilazak zapocinje iz proizvoljnog zadatog cvora r koji se
naziva koren pretrage u dubinu. Koren se oznacava kao posecen. Zatim se bira
proizvoljan neoznacen cvor r1, susedan sa r, pa se iz cvora r1 rekurzivno startuje
pretraga u dubinu. Iz nekog nivoa rekurzije izlazi se kad se naid̄e na cvor v kome su
svi susedi vec oznaceni.
Primer 12.1 Primer reprezentovanja grafa preko matrice povezanosti. U programu
se unosi neorijentisan graf i DFS algoritmom se utvrd̄uju čvrovi koji su dostižni iz
čvora 0.
#include <stdlib.h>
#include <stdio.h>
int** alociraj_matricu(int n)
{ int **matrica;
int i;
matrica=malloc(n*sizeof(int*));
if (matrica==NULL)
{
printf("Greska prilikom alokacije memorije\n");
exit(1);
}
210
Milena Vujošević–Janičić Grafovi
int* alociraj_niz(int n)
{ int* niz;
niz=calloc(n,sizeof(int));
if (niz==NULL)
{
printf("Greska prilikom alokacije memorije\n");
exit(1);
}
return niz;
}
211
Milena Vujošević–Janičić Grafovi
main()
{
int i, j;
printf("Unesi broj cvorova : ");
scanf("%d",&n);
graf=alociraj_matricu(n);
unesi_graf(graf,n);
ispisi_graf(graf,n);
posecen=alociraj_niz(n);
poseti(0, graf, n);
oslobodi_niz(posecen);
oslobodi_matricu(graf,n);
}
Primer 12.2 Primer demonstrira osnovne algoritme nad grafovima. U ovom primer
grafovi se predstavljaju matricama povezanosti. Zbog jednostavnosti, pretpostavlja se
da je broj cvorova ogranicen nekom fiksiranom konstantom, tako da se odgovarajuce
matrice alociraju staticki. Takod̄e, da bi se pojednostavile liste argumenata pojedinih
funkcija, većina promenljivih u ovom primeru se deklarišu kao globalne, kako bi kao
takve bile dostupne svim funkcijama.
#include <stdio.h>
#include <stdlib.h>
212
Milena Vujošević–Janičić Grafovi
return -1;
213
Milena Vujošević–Janičić Grafovi
int odlazna_numeracija[MAX_CVOROVA];
/* Obelezavanje */
posecen[polazni_cvor] = 1;
/* Ulazna obrada */
dolazna_numeracija[polazni_cvor] = ++brojac_dolazna;
/* Izlazna obrada */
odlazna_numeracija[polazni_cvor] = ++brojac_odlazna;
}
214
Milena Vujošević–Janičić Grafovi
int red[MAX_CVOROVA];
int sledeci_na_redu = 0;
int poslednji_na_redu = -1;
int i;
/* Test program */
int main()
{
int i,j;
int aciklican;
215
Milena Vujošević–Janičić Grafovi
scanf("%d", &graf[i][j]);
}
brojac_dolazna = 0;
brojac_odlazna = 0;
putchar(’\n’);
printf("Odlazna DFS numeracija: ");
for(i = 0; i < broj_cvorova; i++)
printf("%d ", odlazna_numeracija[i]);
putchar(’\n’);
return 0;
}
Primer 12.3 Primer predstavljanja grafa preko niza listi suseda svakog od čvorova
grafa. U programu se unosi graf i DFS algoritmom se utvrdjuje koji su čvorovi
dostižni iz cvora 0.
#include <stdlib.h>
#include <stdio.h>
216
Milena Vujošević–Janičić Grafovi
/* Ispis liste */
void ispisi_listu(cvor_liste* lista)
{ if (lista)
{ printf("%d ",lista->broj);
ispisi_listu(lista->sledeci);
}
}
int posecen[MAX_BROJ_CVOROVA];
217
Milena Vujošević–Janičić Grafovi
{ cvor_liste* sused;
printf("Posecujem cvor %d\n",i);
posecen[i]=1;
for( sused=graf[i]; sused!=NULL; sused=sused->sledeci)
if (!posecen[sused->broj])
poseti(sused->broj);
}
main()
{
int i;
printf("Unesi broj cvorova grafa : ");
scanf("%d",&broj_cvorova);
/*Unos grafa*/
for (i=0; i<broj_cvorova; i++)
{ int br_suseda,j;
graf[i]=NULL;
/*Ispis grafa*/
for (i=0; i<broj_cvorova; i++)
{ printf("%d - ",i);
ispisi_listu(graf[i]);
printf("\n");
218
Milena Vujošević–Janičić Grafovi
}
/*Koji su sve cvorovi dostupni iz cvora 0*/
poseti(0);
/*Oslobadjanje memorije*/
oslobodi_graf(graf, broj_cvorova);
}
Primer 12.4 MINESWEEPER - primer jednostavne igrice.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/* Dimenzija table */
int n;
219
Milena Vujošević–Janičić Grafovi
int** alociraj(int n)
{
int i;
int** m=(int**)malloc(n*sizeof(int*));
if(m==NULL) {printf("Greska prilikom alokacije memorije\n"); exit(1);}
for (i=0; i<n; i++)
{
m[i]=(int *)calloc(n,sizeof(int));
if(m[i]==NULL)
{printf("Greska prilikom alokacije memorije\n"); exit(1);}
}
return m;
}
free(m);
}
220
Milena Vujošević–Janičić Grafovi
/* Postavljamo bombu */
bombe[vrsta][kolona]=1;
}
}
221
Milena Vujošević–Janičić Grafovi
}
else if (stanje[i][j]==ZASTAVICA)
{ stanje[i][j]=ZATVORENO;
broj_zastavica--;
}
}
return br;
}
222
Milena Vujošević–Janičić Grafovi
223
Milena Vujošević–Janičić Grafovi
main() {
/* Alociramo table */
bombe=alociraj(n);
stanje=alociraj(n);
/* Postavljamo bombe */
postavi_bombe();
224
Milena Vujošević–Janičić Grafovi
scanf("%d",&k);
} while(v<1 || v>n || k<1 || k>n);
/* Reagujemo na akciju */
switch(akcija)
{ case ’o’:
otvori_polje(v-1,k-1);
break;
case ’z’:
postavi_zastavicu(v-1,k-1);
}
}
/* Konstatujemo pobedu */
ispisi_stanje();
printf ("Cestitam! Pobedili ste\n");
obrisi(stanje,n);
obrisi(bombe,n);
}
225
Ivan P. Stanimirović Uvod u programiranje
2. TIPOVI PODATAKA............................................................................................. 18
Statička i dinamička tipizacija ..................................................................................................................... 20
1
Ivan P. Stanimirović Uvod u programiranje
5. POTPROGRAMI ................................................................................................. 76
2
Ivan P. Stanimirović Uvod u programiranje
3
Ivan P. Stanimirović Uvod u programiranje
Literatura........................................................................................................................................................... 183
4
Ivan P. Stanimirović Uvod u programiranje
5
Ivan P. Stanimirović Uvod u programiranje
primenljivosti (ulaz).
0. 2. OSOBINE ALGORITAMA
Intuitivna definicija algoritma je nestroga definicija. Zato navodimo neke osobine koje
karakterišu svaki algoritam. Na taj način dodatno preciziramo ovaj pojam tako da je ekvivalentan sa
strogim matematičkim definicijama algoritma.
6
Ivan P. Stanimirović Uvod u programiranje
7
Ivan P. Stanimirović Uvod u programiranje
a an1 , n>0
2) stepen : an =
1, n=0
f(n1)+f(n2) , n >1
3) Fibonačijev niz : f(n) =
1 ,n=0
8
Ivan P. Stanimirović Uvod u programiranje
pravila može se uvesti ime algoritma. Pored toga algoritamska pravila se najčešće označavaju rednim
brojevima (0,1,2,. . . ), sa dodatnom simboličkom oznakom u vidu slova ili reči. Izvršenje algoritma
počinje od pravila sa rednim brojem 0 ili 1. Zatim se pravila algoritma izvršavaju prirodnim
redosledom (redno) dok se ne dođe do pravila za grananje,prelaz ili pravila za cikličko izvršavanje
algoritamskih koraka.
Navodimo neka najčešće upotrebljavana pravila za zapis algoritma :
1. Pravilo dodeljivanja : <promenljiva> := <izraz>
Izračunata vrednost izraza dodeljuje se promenljivoj sa leve strane simbola dodeljivanja := .
Alternativni simboli mogu biti = , , .
2. Pravilo uslovnog grananja : if <uslov> then <pravilo>
Ako je <uslov> ispunjen tada se izvršava <pravilo>,a u suprotnom prelazi se na sledeće pravilo.
3. Pravilo grananja : if <uslov> then <pravilo1>
else <pravilo2>
Ako je <uslov> ispunjen izvršava se <pravilo1>,a u suprotnom <pravilo2>.
4. Pravilo bezuslovnog grananja (skoka) : go to <oznaka pravila>
Ovo pravilo ukazuje da se prekida prirodni redosled izvršenja pravila algoritma i zahteva prelaz na
pravilo označeno sa <oznaka pravila>.
5. Pravilo za prekid izvršenja algoritma : Kraj (Stop)
Posle izvršenja ovog pravila prekida se izvršenje algoritma.
6. Pravilo za ulaz podataka : Ulaz (<lista ulaznih veličina>)
7. Pravilo za izlaz podataka : Izlaz (<lista izlaznih veličina>)
8. Pravilo ciklusa : Ponavljaj
<pravilo 1>
<pravilo 2>
. . .
<pravilo n>
Sve dok se <uslov> ne ispuni
Ovo pravilo definiše ponovljeno izvršavanje niza pravila <pravilo 1>,. . . ,<pravilo n> sve dok
<uslov> nije ispunjen. Kada se <uslov> ispuni prelazi se na sledeće pravilo.
Navedimo primer Euklidovog algoritma za nalaženje najvećeg zajedničkog delioca.
E0. Euklid
E1. Ulaz (m,n)
E2. r:= m MOD n ostatak deljenja
E3. Ako r=0 tada pređi na E7
E4. m:=n
E5. n:=r
E6. Pređi na E2
E7. nzd:=n
E8. Izlaz (nzd)
E9. Kraj
Slična algoritamska pravila imamo kod opisa algoritama pomoću pseudo koda. Pseudo kod koristi
pravila bliska naredbama programskog jezika. Pravila su jednostavna, čitljiva i nedvosmislena.
9
Ivan P. Stanimirović Uvod u programiranje
Svaki algoritamski korak predstavljen je grafičkim simbolom (blokom). Svi blokovi su povezani
linijama sa mogućim strelicama. Na taj način se zadaje struktura algoritma i redosled izvršavanja
algoritamskih koraka. Oblik grafičkog simbola ukazuje na vrstu algoritamskog koraka,odnosno
njegovu funkciju u algoritmu. U tabeli su dati najčešće korišćeni grafički simboli i njihova funkcija.
Grafički simbol algoritamskog koraka Funkcija algoritamskog koraka
(Definiše) početak algoritma
Proizvoljna algoritamska šema se u opštem slučaju može razložiti na elementarne šeme (ili
elementarne algoritamske strukture). Postoje tri vrste elementarnih šema:
1) linijska (sekvenca)
2) razgranata (grananje)
3) ciklička (ciklus)
Pokazuje se da je dovoljno imati na raspolaganju jednu linijsku,jednu razgranatu i jednu cikličku
elementarnu šemu da bi se realizovala proizvoljna algoritamska struktura. U praksi se često koriste
različiti oblici razgranatih i cikličkih elementarnih šema.
Može se primetiti da svaka od ovih elementarnih šema ima jedinstven ulaz u šemu i jedinstven
izlaz iz nje. To omogućuje lako komponovanje složenih algoritamskih šema pomoću elementarnih.
Takve šeme zovemo dobro strukturiranim. Ukoliko se na izlaz jedne elementarne šeme poveže ulaz
druge elementarne šeme i tako postupak nastavi dobijamo linijsku kompoziciju elementarnih šema.
Međutim,ako na izlaz nekog algoritamskog koraka u okviru cikličke šeme nadovežemo ulaz
elementarne cikličke šeme dobijamo koncentričnu kompoziciju cikličkih šema.
Višestruko grananje možemo realizovati kada (na izlaz nekog algoritamskog koraka) u okviru
jedne od grana umetnemo novu razgranatu šemu.
10
Ivan P. Stanimirović Uvod u programiranje
11
Ivan P. Stanimirović Uvod u programiranje
želimo da promenimo ovaj prioritet tada možemo upotrebiti male zagrade kao u aritmetičkom izrazu.
Tako izraz ( ) znači izbor ili , ( za razliku od zapisa ). Na taj način možemo reći da
je operacija spajanja distributivna u odnosu na operaciju razdvajanja. Obrnuto ne važi jer je () =
zbog uvedenog prioriteta.
Male zagrade možemo upotrebiti kao metasimbole u cilju skraćivanja zapisa (faktorizacije) u
sledećem slučaju.
Metaformulu
::= xy xz . . . xt
možemo zapisati u obliku
::= x ( y z . . . t )
što je mnogo preglednije. I ovo je primena distribucije prema razdvajanju.
Zagrade se mogu i dalje umetati,na sličan način kao kod aritmetičkih izraza. Na primer, ako je y
= f y1, z = f z1 , tada možemo zapisati
::= x ( f ( y1 z1 ) . . . t ).
2. Srednje zagrade
Srednje zagrade koristimo kada želimo da ukažemo na opcionu (fakultativnu) nisku (konstrukciju). To
znači da se takva niska može ali ne mora upotrebiti. Tako u opisu celog broja znak broja je opciona
konstrukcija pa možemo pisati:
< ceo broj > ::= < znak > < ceo broj bez znaka > .
U opštem slučaju možemo pisati :
= .
3. Velike zagrade
Pomoću rekurzije (rekurzivnih pravila) u Bekusovoj normalnoj formi možemo definisati (opisati) listu
(spisak,niz) proizvoljno mnogo elemenata. Tako možemo pisati
( 1 ) < ceo broj bez znaka > ::= < cifra > < ceo broj bez znaka > < cifra >
( 2 ) <spisak imena> ::= < ime > < ime > , < spisak imena > .
Velike zagrade možemo upotrebiti kao metasimbole da bi ukazali da se niska uokvirena velikim
zagradama može ponoviti proizvoljan broj puta i da se može izostaviti. U tom slučaju gornja pravila
možemo napisati na sledeći način:
( 1’ ) < ceo broj bez znaka > ::= < cifra > < cifra >
( 2’ ) < spisak imena > ::= < ime > , < ime > .
Za proizvoljnu konstrukciju (nisku) možemo pisati
= . . .
To znači da zapis predstavlja drugi način zapisa za iteraciju *= A* jednoelementnog skupa
A=, i pišemo
*= . . .
= . . . .
Zato umesto možemo pisati i *. Takođe zapis za proizvoljnu iteraciju možemo upotrebiti
umesto . . . .
Pomoću gornjuh i donjih indeksa možemo zadati maksimalni i minimalni broj ponavljanja neke
konstrukcije.
Sreću se i sledeći zapisi za konačne liste elemenata koji se ponavljaju pomoću tri tačke:
e1 , e2 , . . . , en
12
Ivan P. Stanimirović Uvod u programiranje
0. 4. 1. SINTAKSNI DIJAGRAMI
Sintaksni dijagrami su jedna vrsta grafičkog metajezika jer koriste grafičke simbole za opis
sintakse jezika. Zato su oni pregledniji i čitljiviji od Bekusove notacije. Ovaj jedinstven metajezik je
ekvivalentan sa Bekusovom normalnom formom. I proširene Bekusove normalne forme se lako
realizuju pomoću sintaksnih dijagrama.
Sintaksni dijagram je imenovani orijentisani graf sa jednim ulazom i jednim izlazom sa
čvorovima grafa koji predstavljaju terminalne ili neterminalne simbole. Svaki prolaz kroz sintaksni
dijagram od ulaza prema izlazu generiše jednu sintaksno pravilnu konstrukciju jezika. Linije (sa
strelicama) koje spajaju čvorove grafa realizuju metaoperacije nadovezivanja i razdvajanja (izbora) na
prirodan način.
Za terminalni simbol t koristimo grafički simbol kružnog ili elipsoidnog oblika. Za neterminalne
simbole predviđen je pravougaoni simbol..
Metaoperacija iz Bekusove notacije i proširenja (upotreba zagrada) se realizuju na jedostavan
način. U nastavku navodimo ekvivalentne realizacije operacija u oba metajezika.
1. Spajanje (nadovezivanje) :
12. . . n 12. . . n
1 2 n
2. Razdvajanje (izbor) :
1 2 . . . n 1
2
n
3. Iteracija (pozitivna iteracija) :
* = . . .
. . .
4. Opciona konstrukcija :
=
5. Ograničeno ponavljanje :
= . . . . . .
= . . . . . .
13
Ivan P. Stanimirović Uvod u programiranje
14
Ivan P. Stanimirović Uvod u programiranje
osnovu ulaznih podataka dobijaju izlazni podaci. U ovu grupu spadaju nerekurzivne i rekurzivne
funkcije i procedure.
Prilikom definicije jezika polazi se od osnovnog skupa znakova, azbuke jezika koja sadrži sve
završne simbole (terminalne simbole) jezika. Nad azbukom jezika definišu se ostali elementi jezika,
konstante, rezervisane reči, identifikatori od kojih se dalje grade druge složene sintaksne kategorije
kao što su na primer opisi, upravljačke naredbe i slično.
Danas se obično skup specijalnih znakova azbuke programskog jezika standardizuje i svodi na skup
znakova međunarodnog standardnog koda ISO7 (ASCII kod).
b | ! | " | $ | % | & | ' | ( | ) | * | + | , | - | . | / | : | ; | < | = | > | ? | @ | [ | ] | \ | ^ ili _ | ` | { | } | ~
Češto se pored osnovnog skupa specijalnih znakova koriste i složeni simboli, obično dvoznaci,
kao na primer:
| ** | >= | <= | => | =< | << | <> | >< | := | -> | /* | */ |
U nekim programskim jezicima (FORTRAN), zbog nedovoljnog broja odgovarajućih znakova
umesto specijalnih znakova koriste se posebne simboličke oznake .EQ., .NE., .GT., .GE., .LT., .LE.,
kojima se označavaju relacije jednako, različiti, veće, veće ili jednako, manje i manje ili jednako,
redom.
15
Ivan P. Stanimirović Uvod u programiranje
1.4. Konstante
Bilo koji niz znakova u programu, posmatran nezavisno od njegovog logičkog značenja, nad
kojim se mogu izvršavati određena dejstva (operacije) naziva se podatak. Deo podatka nad kojim se
mogu izvršavati elementarne operacije naziva se element podatka. Elementu podatka u matematici
približno odgovara pojam skalarne veličine. Podatak je uređeni niz znakova kojim se izražava
vrednost određene veličine.
Veličina koja u toku izvršavanja programa uvek ima samo jednu vrednost, koja se ne može
menjati, naziva se konstanta. Kao oznaka konstante koristi se ona sama.
U nekim programskim jezicima (Pascal, Ada, C) postoji mogućnost imenovanja konstante.
Konstantama se dodeljuju imena koja se u programu koriste umesto njih. Na taj način nastaju
simboličke konstante.
Tipovi konstanti koje se mogu koristiti u određenom programskom jeziku određeni su tipovima
podataka koje taj jezik predviđa.
U jeziku C se koristi više vrsta konstanti i to su:
- celobrojne konstante; 2, 3, +5, -123
- karakteri: 'a', 'b', ... ;
- stringovi: sekvence karaktera između navodnika.
Slede neki primeri različitih vrsta konstanti:
Celobrojne dekadne konstante: 1; 50; 153; +55; -55
Realne konstante u fiksnom zarezu: 3.14; 3.0; -0.314; -.314; +.314
Realne konstante u pokretnom zarezu:
3.14E0; -0.314E1; -.314E+0; +.314E-2 (FORTRAN, Pascal, Ada, C)
Realne konstante dvostruke tačnosti:
16
Ivan P. Stanimirović Uvod u programiranje
1.5. Promenljive
Veličine čije se vrednosti menjaju u toku izvršavanja programa nazivaju se promenljive.
Promenljivoj se u programu dodeljuje ime, i u svakom trenutku ona je definisana svojom vrednošću.
Kažemo da je svaka promenljiva u programu povezana sa tri pojma:
imenom - identifikatorom promenljive.
referencom - pokazivačem koji određuje mesto promenljive u memoriji i
vrednošću - podatkom nad kojim se izvršavaju operacije.
Veza između imena, reference i vrednosti promenljive može se predstaviti sledećim dijagramom:
ime vrednost
Na primer naredbu dodeljivanja X:=3.141592 čitamo: X dobija vrednost 3.141592, pri čemu
imamo u vidu da je X simboličko ime memorijske lokacije gde se u toku izvršavanja programa pamti
vrednost 3.141592. Pri tome je potrebno imati na umu sledeće pojmove:
• vrednost 3.141592, koja predstavlja vrednost promenljive X,
• adresu memorijske lokacije u kojoj se pamti vrednost 3.141592,
• ime promenljive X, identifikator koji se u datom programu koristi kao ime promenljive koja
ima datu brojnu vrednost.
1.6. Komentari
U svim programskim jezicima postoji mogućnost proširenja izvršnog koda programa komentarima
kojima se kod dodatno pojašnjava. Ovi komentari se u toku prevođenja programa ignoršu od strane
kompilatora i ne ulaze u sastav izvršnog koda koji se generiše prevođenjem programa. Međutim
komentari su veoma važan deo programa kojim se podešava njegova dokumentarnost, i bitno utiču na
efikasnost analize programa. Konvencija za zapisivanje komentara se razlikuje od jezika od jezika.
Slede primeri komentara u nekim programskim jezicima:
/* Ovo je primer komentara u jeziku C */
// Kratak C++ komentar u okviru jednog reda
17
Ivan P. Stanimirović Uvod u programiranje
2. TIPOVI PODATAKA
Jedan od najznačajnijih pojmova u okviru programskih jezika je pojam tipa podataka. Atribut tipa
određuje skup vrednosti koje se mogu dodeljivati promenljivima, format predstavljanja ovih vrednosti
u memoriji računara, skup osnovnih operacija koje se nad njima mogu izvršavati i veze sa drugim
tipovima podataka. Na primer, promenljivoj koja pripada celobrojnom tipu mogu se kao vrednosti
dodeljivati samo celi brojevi iz određenog skupa. Nad tako definisanim podacima mogu se izvršavati
osnovne aritmetičke operacije sabiranja, oduzimanja, mnozenja, deljenja, stepenovanja, kao i neke
specifične operacije kao što je određivanje vrednosti jednog broja po modulu drugog.
Koncept tipova podataka prisutan je, na neki način, već kod simboličkih asemblerskih jezika gde se
za definiciju tipa koriste implicitne definicije preko skupa specijalnih znakova kojima se određuju
podaci različitog tipa.
Neka je zadat skup T sačinjen od n proizvoljnih apstraktnih objekata: T:={v1,...,vn}, n>1. Ukoliko
su svi objekti istorodni, u smislu da se u okviru nekog programskog jezika na njih može primenjivati
jedan određeni skup operatora, onda se T naziva tip podataka, Ako za promenljive x i y uvek važi xT
i yT onda su one tipa T. To u okviru programa formalno definišemo iskazom
18
Ivan P. Stanimirović Uvod u programiranje
DEFINE x, y : T.
Vrednost je bilo koji entitet kojim se može manipulisati u programu. Vrednosti se mogu
evaluirati, zapamtiti u memoriji, uzimati kao argumenti, vraćati kao rezultati funkcija, i tako dalje.
Različiti programski jezici podržavaju različite tipove vrednosti.
Jedna od klasifikacija osnovnih tipova podataka prikazana je na slici.
Tipovi podataka su podeljeni u dve osnovne grupe: statički tipovi i dinamički tipovi. Pod
statičkim tipovima (ili tipovima sa statičkom strukturom podrazumevamo tipove podataka kod kojih je
unapred i fiksno definisana unutrašnja struktura svakog podataka, a veličina (t.j. memorijska
zapremina) fiksno se definiše pre (ili u vreme) izvršavanja programa koji koristi podatke statičkog
tipa.
Statički tipovi podataka obuhvataju skalarne i strukturirane podatke. Pod skalarnim tipovima
podrazumevamo najprostije tipove podataka čije su vrednosti skalari, odnosno takve veličine koje se
tretiraju kao elementarne celine i za koje nema potrebe da se dalje razlažu na komponente. U tom
smislu realne i kompleksne brojeve tretiramo kao skalare u svim programskim jezicima koji ih
tretiraju kao elementarne celine (neki jezici nemaju tu mogućnost pa se tada kompleksni brojevi
tretiraju kao struktura koja se razlaže na realni i imaginarni deo; na sličan način mogao bi se realni
broj razložiti na normalizovanu mantisu i eksponent). Pod strukturiranim tipovima podataka
podrazumevamo sve složene tipove podataka koji se realizuju povezivanjem nekih elementarnih
podataka u precizno definisanu strukturu. U ulozi elementarnih podataka obično se pojavljuju skalari
ili neke jednostavnije strukture. Kompozitna vrednost ili struktura podataka (data structure) jeste
vrednost koja je komponovana iz jednostavnijih vrednosti. Kompozitni tip jeste tip čije su vrednosti
kompozitne. Programski jezici podržavaju mnoštvo kompozitnih vrednosti: strukture, slogove, nizove,
algebarske tipove, objekte, unije, stringove, liste, stabla, sekvuencijalni fajlovi, direktni fajlovi,
relacije, itd.
Skalarni tipovi podataka mogu biti linearno uređeni ili linearno neuređeni. Linearno uređeni
tipovi podataka su tipovi kod kojih se vrednosti osnovnog skupa T preslikavaju na jedan interval iz
niza celih brojeva, t.j. za svaki podatak xT zna se redni broj podatka. Stoga svaki podatak izuzev
početnog ima svog prethodnika u nizu, i slično tome, svaki podatak izuzev krajnjeg ima svog
sledbenika u nizu.
19
Ivan P. Stanimirović Uvod u programiranje
Pod dinamičkim tipovima podataka podrazumevamo tipove podataka kod kojih se veličina i/ili
struktura podataka slobodno menja u toku obrade. Kod dinamičkih tipova sa promenljivom veličinom
podrazumevamo da je struktura podataka fiksna, ali se njihova veličina dinamićki menja tokom obrade
tako da se saglasno tome dinamički menjaju i memorijski zahtevi. Na primer, dopisivanjem novih
zapisa u sekvencijalnu datoteku veličina datoteke raste uz neizmenjenu strukturu. Kod dinamičkih
tipova sa promenljivom strukturom unapred je fiksno definisan jedino princip po kome se formira
struktura podataka dok se sama konkretna struktura i količina podataka u memoriji slobodno
dinamički menjaju.
Statička i dinamička tipizacija
Pre izvršenja bilo koje operacije, moraju se proveriti tipovi operanada da bi se sprečila greška u tipu
podataka. Na primer, pre izvršenja operacije množenja dva cela broja, oba operanda moraju biti
proverena da bi se osiguralo da oni budu celi brojevi. Slično, pre izvršenja neke and ili or operacije,
oba operanda moraju biti proverena da bi se osiguralo da oni budu tipa boolean. Pre izvršenja neke
operacije indeksiranja niza, tip operanda mora da bude array (a ne neka prosta vrednost ili slog).
Ovakva provera se naziva proverom tipa (type checks). Provera tipa mora da bude izvršena pre
izvršenja operacije.
Međutim, postoji izvestan stepen slobode u vremenu provere: provera tipa se može izvršiti ili u
vremenu kompilacije (compile-time) ili u vremenu izvršenja programa (at run-time). Ova mogućnost
leži u osnovi važne klasifikacije programskih jezika na statički tipizirane (statically typed) i
dinamički tipizirane (dynamically typed). U nekom statički tipiziranom jeziku, svaka varijabla i
svaki izraz imaju fiksni tip (koji je ili eksplicitno postavljen od strane programera ili izveden od strane
kompajlera). Svi operandi moraju biti proverenog tipa (type-checked) u vremenu kompilovanja
programa (at compile-time). U dinamički tipiziranim jezicima, vrednosti imaju fiksne tipove, ali
varijable i izrazi nemaju fiksne tipove. Svaki put kada se neki operand izračunava, on može da
proizvede vrednost različitog tipa. Prema tome, operandi moraju imati proveren tip posle njihovog
izračunavanja, ali pre izvršenja neke operacije, u vremenu izvršenja programa (at run-time). Mnogi
jezici visokog nivoa su statički tipizirani. SMALLTALK, LISP, PROLOG, PERL, i PYTHON jesu
primeri dinamički tipiziranih jezika.
S druge strane, moderni funkcionalni jezici (kao ML, HASKELL, MATHEMATICA)
omogućavaju da sve vrednosti, uključujući i funkcije, imaju sličnu obradu.
Izbor između statičke i dinamičke tipizacije je pragmatičan:
• Statička tipizacija je efikasnija. Dinamička tipizacija zahteva (verovatno ponovljenu) proveru tipova
u vremenu izvršenja programa (run-time type checks), što usporava izvršenje programa. Statička
tipizacija zahteva jedino proveru tipa u vremenu kompilacije programa (compile-time type checks),
čija je cena minimalna (i izvršava se jedanput). Osim toga, dinamička tipizacija primorava sve
vrednosti da budu etiketirane (tagged) (da bi se omogućila provera u vreme izvršenja), a ovakvo
označavanje povećava upotrebu memorijskog prostora. Statička tipizacija ne zahteva ovakvo
označavanje.
• Statička tipizacija je sigurnija: kompajler može da proveri kada program sadrži greške u tipovima.
Dinamička tipizacija ne omogućava ovakvu sigurnost.
• Dinamička tipizacija obezbeđuje veliku fleksibilnost, što je neophodno za neke aplikacije u kojima
tipovi podataka nisu unapred poznati.
U praksi veća sigurnost i efikasnost statičke tipizacije imaju prevagu nad većom fleksibilnošću
dinamičke tipizacije u velikoj većini aplikacija. Većina programskih jezika je statički tipizirana.
Na osnovu toga kako je postavljen koncept tipova podataka, programski jezici mogu da se svrstaju
u dve grupe: na programske jezike sa slabim tipovima podataka i na jezike sa jakim tipovima
podataka.
20
Ivan P. Stanimirović Uvod u programiranje
21
Ivan P. Stanimirović Uvod u programiranje
potrebno je tačno poznavati mehanizme transformacije tipova. U drugoj naredbi iz primera (k = x-j;)
od broja x koji je tipa float treba oduzeti broj j, tipa int i rezultat operacije dodeliti promenljivoj tipa
int. Da bi smo bili sigurni u korektnost rezultata potrebno je da znamo redosled transformacija koje se
pri tome izvršavaju, odnosno da li se prvo x prevodi u int i onda izvršava oduzimanje u skupu celih
brojeva i vrednost rezultata dodeljuje promenljivoj tipa int ili se j prevodi u tip float, izvršava
oduzimanje u skupu realnih brojeva, a zatim rezultat prevođi u tip int i dodeljuje promenljivoj k.
Koncept slabih tipova podataka dopušta puno slobode kod zapisivanja izraza u naredbama
dodeljivanja; međutim cena te slobode je nejasan program sa skrivenim transformacijama, bez
mogućnosti kontrole i korišćenja informacije o tipu u fazi kompilovanja programa.
22
Ivan P. Stanimirović Uvod u programiranje
Bit najstarijeg razreda označen sa S (sign) predstavlja predznak broja. Ako je S=0 onda je je broj
nenegativan, a ako je S=1 onda je broj negativan. Nula se označava sa nulama u svim bitovima:
0000 0000 0000 0000
Obično postoji osnovni (standardni) tip INTEGER ili int, koji se zavisno od realizacije odnosi na
određeni opseg celih brojeva. Nekad je to opseg koji odgovara formatu jedne polureči ili formatu
jedne reči. U odnosu na ovaj osnovni celobrojni tip češto postoji mogućnost definisanja i drugih
celobrojnih tipova koji se odnose na neki kraći ili prošireni format.
23
Ivan P. Stanimirović Uvod u programiranje
znakova iz određene azbuke koja redovno obuhvata abecedno poređana velika i mala slova, cifre,
specijalne znake i kontrolne znake. Pod specijalnim znacima se podrazumevaju svi oni znaci koji se
javljaju na tastaturama i mogu odštampati, ali nisu ni slova ni cifre (na tastaturi sa kojom je pisan ovaj
tekst specijalni znaci su ! # S % & *()_-+=:"; '<>?,/.). Pod kontrolnim znacima podrazumevaju se
znaci koji se ne mogu odštampati (ili prikazati na ekranu terminala), već služe za upravljanje radom
ulazno/izlaznog uređaja (na primer štampača). U ovu grupu spadaju specijalni znaci za pomeranje
papira, znak koji izaziva zvučni signal na terminalu i drugi).
Da bi se znaci razlikovali od simboličkih naziva promenljivih obično se umeću između apostrofa
(na nekim programskim jezicima umesto apostrofa se koriste znaci navoda). Tako se, na primer,
podrazumeva da A predstavlja simbolički naziv promenljive, dok 'A' predstavlja binarno kodirano prvo
slovo abecede.
U praksi se primenjuje nekoliko metoda za binarno kodiranje znakova. Najpoznatiji metod je
američki standard ASCII (American Standard Code for Information Interchange). Ovim smenama su
neki manje važni znaci iz skupa ASCII znakova zamenjeni sa specifičnim jugoslovenskim znacima
(na pr., umesto ASCII znakova \ | { } [ ] ~ @ i ^ u srpskoj varijanti se pojavljuju znaci Đ đ š ć š Ć č ž
Ž i Č). Neki terminali imaju mogućnost podesivog izbora skupa znakova tako da korisnik može po
potrebi izabratl američku ili jugoslovensku varijantu skupa ASCII znakova.
Prva 32 znaka u ASCII skupu su kontrolni znaci. Nekl od njlh imaju jedinstvenu interpretaciju kod
svih uređaja, a kod nekih interpretacija se razlikuje od uređaja do uređaja. Ovde pominjemo sledeće:
BEL (Bell) = zvučni signal
LF (Line Feed) = prelazak u naredni red
FF (Form Feed) = prelazak na narednu stranu
CR (Carriage /Return) = povratak na početak reda
ESC (Escape) = prelazak u komandni režim
Skup ASCII znakova je baziran na sedmobitnim znacima, pa prema tome obuhvata ukupno 128
znakova. Kako se radi o linearno uređenom skupu svaki znak ima svoj redni broj i ti brojevi su u
opsegu od 0 do 127. Funkcija koja za svaki znak daje njegov redni broj (ordinal number) označava se
sa ord. Argument ove funkcije je tipa CHARACTER, a vrednost funkcije je tipa CARDINAL. Za
slučaj ASCII skupa imamo da važi sledeće:
ord('0') = 48, ord('A') = 65. ord('a')=97.
Inverzna funkcija funkciji ord, koja od rednog broja znaka formira znak, (character) je funkcija chr:
chr(48) = '0', chr(65) = 'A', chr(97) = 'a' .
Ako je c promenljiva tipa CHARACTER, a n promenljiva tipa CARDINAL onda važi
chr(ord(c) ) = c , ord(chr(n) ) = n .
24
Ivan P. Stanimirović Uvod u programiranje
signed char 1 -128 do 127 ASCII skup znakova i veoma mali brojevi
enum 2 -32.768 do 32.767 Uređeni skup vrednosti
int 4 -2.147.483.648 do 2.147.483.647 Mali brojevi, kontrola petlji
unsigned int 4 0 do 4.294.967.295 Veliki brojevi i petlje
short int 2 -32.768 do 32.767 Mali brojevi, kontrola petlji
long 4 -2.147.483.648 do 2.147.483.647 Veliki brojevi
unsigned long 4 0 do 4.294.967.295 Astronomska rastojanja
-38 38
float 4 3,4*10 do 3,4*10 Naučne aplikačije (tačnost na 6 decimala)
-308 308
double 8 1,7*10 do 1,7*10 Naučne aplikačije (tačnost na 16 decimala)
-4932 4932
long double 10 3,4*10 do 3,4*10 Naučne aplikačije (tačnost na 19 decimala)
U C-u postoji skup operatora za rad sa binarnim sadržajima koji su prikazani u tabeli koja sledi.
Operator Značenje
&& Logička I operacija (AND)
|| Logička ILI operacija (OR)
^ Isključivo ILI (XOR)
>> Pomeranje udesno
<< Pomeranje ulevo
~ Komplement
U slučaju mešovitih izraza u kojima se pojavljuju različiti operatori takođe važe implicitna
pravila kojima je definisan prioritet operacija. Nabrojaćemo osnovna:
• Unarni operatori (na pr. ++) su uvek višeg prioriteta u odnosu na sve binarne.
• Aritmetičke operacije su višeg prioriteta u odnosu na relacije poređenja.
• Operatori poredenja <= i >= (manje ili jednako i veće ili jednako) su višeg prioriteta u odnosu
na jednako i nejednako.
• Poređenja su uvek višeg prioriteta u odnosu na operatore kojima se manipuliše bitovima.
• Operatori za manipulisanje bitovima su višeg prioriteta u odnosu na sve logičke operatore.
• Logičko I (&&) je višeg prioriteta u odnosu na logičko ILI ( | | ).
Celobrojni tipovi u C
Celobrojni tipovi su brojački tipovi i javljaju se kao označeni ili neoznačeni.
Celobrojne vrednosti obuhvataju celobrojne konstante, celobrojne promenljive, izraze i funkcije.
Celobrojne konstante predstavljaju podskup skupa celih brojeva čiji opseg zavisi od deklaracije ali i
od konkretne implementacije. U C jeziku celobrojne konstante se predstavljaju kao niske cifara. Ispred
koje može da stoji znak '+' za pozitivne, a obavezan je znak '-' za negativne vrednosti.
Promenljivoj osnovnog celobrojnog tipa int obično se dodeljuje memorijski prostor koji odgovara
"osnovnoj" jedinici memorije. Na taj način, opseg vrednosti tipa int u TURBO C na 16-bitnim
računarima je [-32768, +32767] = [-215,215-1], a na 32-bitnim računarima je
[-2147483648, +2147483647] = [-231,231-1].
Bitno je napomenuti da se mogu koristiti 3 brojna sistema, i to: dekadni (baza 10), oktalni (baza 8);
heksadekadni (baza 16). Heksadecimalni brojevi počinju sa 0x ili 0X. Dozvoljene cifre su 0, 1,.., 9 i
slova a, b, c, d, e, f (ili A, B, C, D, E, F). Oktalni brojevi počinju sa 0 a ostale cifre mogu biti 0, 1, ..7.
Na primer, 012 je dekadno 10, 076 je dekadno 62. Takođe, 0x12 je dekadni broj 18, 0x2f je dekadno
47, 0XA3 je dekadno 163. Celobrojne konstante koje ne počinju sa 0 su oktalne.
Opseg celih brojeva se može menjati primenom kvalifikatora long i short. Kvalifikator long može
da poveća opseg vrednosti celobrojnih promenljivih tipa int. Opseg vrednosti tipa long int (ili
skraćeno long) je [-2147483648, +2147483647] = [-231,+231-1].
25
Ivan P. Stanimirović Uvod u programiranje
Tip long int (ili long) garantuje da promenljive tog tipa neće zauzimati manje memorijskog
prostora od promenljivih tipa int.
Celobrojne konstante koje su prevelike da bi bile smeštene u prostor predviđen za konstante tipa int
tretiraju se kao long konstante. Ove konstante se dobijaju dodavanjem znaka L (ili l) na kraj konstante,
kao na primer 1265378L. Ako program ne koristi velike cele brojeve ne preporučuje se deklarisanje
promenljivih sa long, jer se time usporava izvršenje programa.
Kvalifikator short int (ili skraćeno short) smanjuje opseg celobrojnih promenljivih. Opseg
promenljivih tipa short uvek je [-215,215-1], tj. one se uvek smeštaju u 2 bajta. Upotrebom promenljivih
ovog tipa ponekad se postiže ušteda memorijskog prostora. Međutim, upotreba ovih promenljivih
može da uspori izvršavanje programa, jer se pre korišćenja u aritmetičkim izrazima ove promenljive
transformišu u tip int.
Ako smo sigurni da su vrednosti celobronih promenljivih nenegativne, one se mogu deklarisati na
jedan od sledećih načina:
unsigned int (skraćeno unsigned),
unsigned short int (skraćeno unsigned short),
unsigned long int (skraćeno unsigned long).
Time se interval pozitivnih vrednosti proširuje, jer bit za registrovanje znaka gubi to značenje.
Promenljive tipa unsigned int (skraćeno unsigned) mogu uzimati samo pozitivne celobrojne
vrednosti. Promenljive tipa unsigned imaju rang [0, 2širina_reči-1]. Prema tome, na 16-bitnim računarima
opseg promenljivih tipa unsigned int je [0,65535]=[0,216-1], dok je na 32-bitnim računarima
odgovarajući opseg jednak [0,232-1]=[0,+4294967295].
Konstante tipa long se mogu cpecificirati eksplicitno dodajući sufiks L ili l posle broja. Na primer,
777L je konstanta tipa long. Slično U ili u se može koristiti za konstante tipa unsigned. Na primer, 3U
je tipa unsigned, a 3UL je tipa unsigned long.
U slučaju greške integer overflov, program nastavlja da radi, ali sa nekorektnim rezultatom.
Promenljive celobrojnog tipa se deklarišu navođenjem imena promenljivih iza imena nekog
celobrojnog tipa. Imena promenljivih se međusobno razdvajaju zarezima, a iza spiska se navodi ';'. U
operatorima opisa je dozvoljeno izvršiti inicijalizaciju deklarisanih promenljivih.
Primer. Navedeno je nekoliko deklaracija promenljivih celobrojnih tipova.
long int x;
short int y;
unsigned int z,v,w;
26
Ivan P. Stanimirović Uvod u programiranje
Tip char
Tip char je jedan od fundamentalnih tipova podataka u jeziku C. Konstante i promenljive ovog tipa
se koriste za reprezentaciju karaktera. Znakovni tip (tip char) definiše uređen skup osnovnih znakova
jezika C. Takav skup obrazuje skup ASCII znakova. To znači da znakovnom tipu pripadaju i znaci
koji nemaju grafičku interpretaciju.
Svaki karakter se smešta u računaru u jednom bajtu memorije. Ako je bajt izgrađen od 8 bitova, on
može da pamti 28=256 različitih vrednosti. Promenlijve i konstante tipa char uzimaju za svoje
vrednosti karaktere odnosno cele brojeve dužine jednog bajta. To znači da se znak u memoriji
registruje u jednom bajtu. Promenljive ovog tipa se deklarišu pomoću ključne reči char.
Ako ispred deklaracije char stoji rezervisana reč signed, tada se specificira interval kodnih
vrednosti [-128,127]; ako je ispred char navedeno unsigned, tada se specificira kodni interval [0,255].
Primer. Iskazom
char ca, cb, cc;
promenljive ca, cb, cc deklarišu se kao promenljive tipa char. Karakter konstanta se piše između
apostrofa, kao: 'a', 'b', 'c'... U Turbo C se koriste ASCII kodovi karaktera, i oni predstavljaju njihovu
numeričku vrednost.
Promenljive tipa char se mogu inicijalizovati na mestu deklarisanja. Na primer, možemo pisati
char c='A', s='A', x;
int i=1;
Primer.
printf("%c", 'a');
printf("%c %c %c", 'A', 'B', 'C'); /* ABC */
Takođe, konstante i promenljive tipa char se mogu tretirati kao mali integeri.
Primer.
printf("%d", 'a'); /* 97 */
printf("%c",97); /* a */
Neke znakovne konstante se moraju specificirati kao ''escape'' sekvence, tj. moraju se navesti zajedno
sa znakom \ (backslash). Escape sekvence se koriste pri kreiranju izlaznih izveštaja u cilju
specificiranja upravljačkih znakova.
'\n' prelazak na novu liniju u ispisu;
'\t' horizontalni tab (pomera kursor za 5 ili 8 pozicija);
'\b' vraća kursor za jednu poziciju (povratnik, backspace);
'\f' form feed (pomera hartiju štampača na početak sledeće strane);
'\a' alarm;
27
Ivan P. Stanimirović Uvod u programiranje
'\'' apostrof;
'\\' backslash.
Primer.
printf("\"ABC\""); /* "ABC" */
Karakter konstante se takođe mogu prikazati pomoću jednocifrene, dvocifrene ili trocifrene
sekvence. Na primer '\007', ' \07' ili '\7' predstavlja bell (alarm).
Za ulaz i izlaz karaktera se mogu koristiti funkcije getchar() i putchar(). Ovi makroi su definisani
u fajlu stdio.h. Za učitavanje karaktera sa tastature koristi se getchar(), dok se putchar() koristi za
prikazivanje karaktera na ekran.
C obezbeđuje standardni fajl ctype.h koji sadrži skup makroa za testiranje karaktera i skup
prototipova funkcija za konverziju karaktera. Oni postaju dostupni pomoću preprocesorske direktive
#include <ctype.h>
Makroi u sledećoj tabeli testiraju karaktere, i vraćaju vrednosti true (0) i false (=0).
28
Ivan P. Stanimirović Uvod u programiranje
Primer. Ako je promenljiva i tipa int, tada se izrazom (double)i njena vrednost prevodi u
odgovarajuću vrednost tipa double.
Operator kast je istog prioriteta i asocijativnosti kao i ostali unarni operatori. Kast se može
primenjivati na izraze.
Primer.
(float)i+3 je ekvivalentno sa ((float)i)+3
(double)x=77 je ekvivalentno sa ((double)x)=77
29
Ivan P. Stanimirović Uvod u programiranje
Sizeof operator
Unarni operator sizeof() daje za rezultat broj bajtova potrebnih za smeštanje svog argumenta.
Vrednost izraza sizeof(obj) se izračunava za vreme kompilovanja. Argument može biti ime
promenljive, ime tipa ili izraz. Ako je obj ime promenljive, tada je vrednost izraza sizeof(obj) broj
bajtova potrebnih za registrovanje te promenljive u memoriji. Ako je operand obj ime tipa, tada je
vrednost izraza sizeof(obj) dužina tog tipa, odnosno broj bajtova potrebnih za registrovanje
elemenata tog tipa. Ako je argument neki tip, ime tog tipa se mora navesti između zagrada. Naredba
sizeof se koristi kada se generiše kôd koji zavisi od veličine tipa.
Osnovne aritmetičke operacije
Osnovne aritmetčke operacije su:
+ sabiranje,
- oduzimanje,
* množenje,
/ deljenje,
Ako su oba operanda operacije deljenja / celi brojevi tada se iz realnog broja koji predstavlja njihov
količnik odbacuje decimalna tačka i razlomljeni deo.
Na primer, 15/2=7, 2/4=0, -7/2=-3, 15%2=1, 7./4=1.74.
Operacija - može biti i unarna, i tada se koristi za promenu znaka svog argumenta (unarni minus).
Sve operacije poseduju prioritet i asocijativnost (redosled), kojima se determiniše postupak
evaluacije izraza. Ako u izrazu postoje operacije različitog nivoa prioriteta, operacije se izvršavaju po
opadajućem nivou prioriteta. Prioritet se može promeniti upotrebom zagrada. Asocijativnost odlučuje
o redosledu izvršavanja operacija istog prioriteta.
Levoasocijativne operacije se izvršavaju s leva na desno a desnoasocijativne s desna na levo.
Najviši priorirtet ima operacija promene znaka, zatim levoasocijativni multiplikativni operatori *, /
i %, dok su najnižeg nivoa prioriteta levoasocijativni aditivni operatori + i -.
Operacija inkrementiranja (uvećanja) ++ i operacija dekrementiranja (umanjenja) -- su unarne
operacije sa asocijativnošću s desna na levo. U tabeli prioriteta operatori zauzimaju sledeće mesto:
najvišeg prioriteta su unarni operatori - (promena znaka); ++, --;
nižeg prioriteta su multiplikativni *, /, %; dok su najmanjeg prioriteta aditivni operatori +, -.
Operacije ++ i -- se mogu pisati ispred argumenta (prefiksno) ili iza argumenta (postfiksno). Mogu
se primenjivati nad promenljivima a ne mogu na konstantama ili izrazima.
Primer. Može se pisati ++i, i++, --cnt, cnt-- a ne može 777++, ++(a*b-1).
Svaki od izraza ++i, i++, --i, i-- ima određenu vrednost. Izrazi ++i, i++ uzrokuju inkrementiranje
vrednosti promenljive i u memoriji za 1, dok izrazi --i, i-- uzrokuju dekrementiranje njene vrednosti za
1. Izrazom ++i vrednost za i se inkrementira pre nego što se upotrebi, dok se sa i++ vrednost za i
inkrementira posle upotrebe te vrednosti. Slična pravila važe za izraze --i, i--, samo što se radi o
dekrementiranju te vrednosti.
Operatori ++ i -- razlikuju se od operatora +, -, *, /, % po tome što menjaju vrednosti varijable u
memoriji, tj. operatori ++ i -- poseduju bočni efekat.
Primer. Kompajler koristi tipove operanada kako bi odredio rezultat izračunavanja.
30
Ivan P. Stanimirović Uvod u programiranje
31
Ivan P. Stanimirović Uvod u programiranje
atol(s) ova funkcija vrši konverziju celog broja iz niza ASCII cifara (karaktera) oblika “cc...” u
binarni ekvivalent tipa long. Argument s je string a rezultat je tipa long. Početne praznine se ignorišu.
Konverzija se završava kod prvog znaka koji ne može da bude deo broja.
Operacija dodeljivanja u C
U C jeziku se operator = tretira kao operator dodeljivanja. Njegov prioritet je manji od prioriteta do
sada razmatranih operacija, a njegova asocijativnost je ``s desna na levo''. Izraz dodeljivanja vrednosti
je oblika
<promenljiva> = <izraz>;
na čijoj je desnoj strani proizvoljan izraz. Kompletan izraz je završen sa ; (semicolon). Vrednost izraza
na desnoj strani se dodeljuje promenljivoj sa leve strane. Ako su tipovi promenljive i izraza različiti,
vrši se konverzija vrednosti izraza u odgovarajuću vrednost saglasno tipu promenljive. Vrednost izraza
dodeljivanja jednaka je vrednosti izraza sa njegove desne strane.
Primer. Sledeća sekvenca izraza
y=2; z=3; x=y+z;
može se efikasnije zapisati u obliku
x=(y=2)+(z=3);
Primer. Zbog desne asocijativnosti operatora = je izraz x=y=z=0 ekvivalentan izrazu
x=(y=(z=0)).
Primer. Operator y=x++; je ekvivalentan sledećoj sekvenci operatora: y=x; x=x+1;
Operator y=--x je ekvivalentan sledećim operatorima x=x-1; y=x;
Na primer,
x+=2; je ekvivalentno sa x=x+2;
x%=2; je ekvivalentno sa x=x%2;
Primer. Šta se ispisuje posle izvršenja sledećeg programa?
#include<stdio.h>
32
Ivan P. Stanimirović Uvod u programiranje
void main()
{ int x,y,z;
x=y=1;
z=(x+y++)*(y==1);
printf("%d, %d, %d\n",x,y,z);
int i=1,j;
i=i++*++i;
printf("%d\n",i);
i=j=2;
printf("%d\n",++j+i++);
printf("%d, %d\n",i,j);
}
Primer. Šta se ispisuje posle izvršenja sledećeg programa?
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
void main()
{ int i,j=6;
if(j=0) i=5;
else i=1;
printf("%d\n%d\n",i,j);
}
Logičke operacije
Postoje tri logičke operacije:
! je operacija negacije,
&& je konjunkcija, i
|| predstavlja opreaciju disjunkcije.
Rezultat primene ovih operacija je 0 ili 1.
Operacija negacije ! je unarna, i daje rezultat 1 ako je vrednost operanda 0, a vrednost 0 ako je
vrednost operanda 1.
Operacija konjunkcije && je binarna, i daje 1 ako su oba operanda različita od 0, a 0 u suprotnom.
Ako je levi operand jednak 0 pri izvršenju operacije konjunkcije desni operand se ignoriše.
Operacija disjunkcije || je binarna, i daje 1 ako je bar jedan operand različit od 0, a 0 inače. Ako je
vrednost levog operanda jednaka 1 pri izvršenju operacije disjunkcije desni operand se ignoriše.
Najviši prioritet ima operacija negacije; sledećeg nivoa prioriteta je operator konjunkcije, dok je
najnižeg nivoa prioriteta operator disjunkcije.
Prema tome,
33
Ivan P. Stanimirović Uvod u programiranje
34
Ivan P. Stanimirović Uvod u programiranje
U programskim jezicima postoji veći broj funkcija za unošenje i izdavanje podataka. Pomoću
naredbi ulaza i izlaza program dobija neophodne podatke i prikazuje dobijene rezultate. Ove funkcije
se koriste za standardni ulaz i izlaz podataka preko tastature i monitora. Postoje varijante ovih
funkcija koje se mogu koristiti za pristup datotekama.
35
Ivan P. Stanimirović Uvod u programiranje
36
Ivan P. Stanimirović Uvod u programiranje
- sirina zadaje maksimalnu širinu polja. Ako je širina polja veća od navedene u konverzionoj
specifikaciji, koristi se onoliko znakova koliko je zadato maksimalnom širinom.
- konverzioni_karakter je jedan od konverzionih znakova iz sledeće tabele:
konverzioni karakter tip argumenta
c pokazivač na char
h pokazivač na short
d pokazivač na int
ld, D pokazivač na long
o pokazivač na int
lo, O pokazivač na long
x pokazivač na int
lx, X pokazivač na long
f pokazivač na float
lf, F pokazivač na double
e pokazivač na float
le, E pokazivač na double
s pokazivač na string
37
Ivan P. Stanimirović Uvod u programiranje
#include <stdio.h>
#include <float.h>
int main(void)
{ double f = 3.1416, g = 1.2e-5, h = 5000000000.0;
printf("f=%lf\tg=%lf\th=%lf\n", f, g, h);
printf("f=%le\tg=%le\th=%le\n", f, g, h);
printf("f=%lg\tg=%lg\th=%lg\n", f, g, h);
printf("f=%7.2lf\tg=%.2le\th=%.4lg\n", f, g, h);
return 0;
}
f=3.141600 g=0.000012 h=5000000000.000000
f=3.141600e+00 g=1.200000e-05 h=5.000000e+09
f=3.1416 g=1.2e-05 h=5e+09
f= 3.14 g=1.20e-05 h=5e+09
38
Ivan P. Stanimirović Uvod u programiranje
se radi o smeni u ''vreme izvršavanja'', za razliku od pretprocesorske direktive kojom se vrši smena ''u
toku kompilacije''.
Primeri u jeziku C
Primer. Zbir dva broja u jeziku C.
#include <stdio.h>
main()
{ int x, y;
printf("Unesi dva cela broja");
scanf("%d %d", &x, &y);
printf("Njihov zbir je %5d\n",x+y);
}
39
Ivan P. Stanimirović Uvod u programiranje
Primer.
#include <stdio.h>
#define MAX 23
#define Ako if
#define Onda
#define Inace else
void main()
{ int n=24;
Ako (MAX > n) Onda printf("veci\n");
Inace printf("manji\n");
}
Svaki program sadrži naredbe dodeljivanja kojima se izračunavaju vrednosti određenih izraza i
pamte (dodeljuju) kao vrednosti odgovarajućih promenljivih. Ipak, veoma retko se bilo koji program
sastoji samo od jedne sekvence naredbi dodeljivanja kao i naredbi ulaza/izlaza. Mnogo se češće
zahteva postojanje više različitih tokova u zavisnosti od određenih uslova ili mogućnost višestrukog
izvršavanja dela programa. Naredbe koje omogućavaju definisanje toka programa nazivaju se
upravlajčke naredbe.
Upravlajčke naredbe u prvom imperativnom programskom jeziku FORTRAN bile su izvedene iz
osnovnih mašinskih naredbi. To je period kada metodologija programiranja tek počinje da se razvija
tako da još nije definisan neki osnovni skup upravljačkih naredbi. Početkom sedamdesetih Wirt
definiše metodologiju strukturnog programiranja i programski jezik Pascal sa skupom upravljačkih
struktura kojima se implementiraju osnovne algoritamske strukture. Ovaj koncept je široko prihvaćen,
tako da danas viši programski jezici iz grupe proceduralnih jezika obično raspolažu skupom
upravljačkih struktura kojima se upravlja tokom izvršenja programa u skladu sa konceptima
strukturnog programiranja. Iako se od jezika do jezika ovaj skup upravljačkih struktura donekle
razlikuje, može se reći da su ipak među njima u ovom domenu male suštinske razlike. Smatra se da je
skup naredbi kojima se upravlja tokom programa dovoljan ako obezbeđuje sledeće tri osnovne
upravlajčke strukture:
(1) Strukturu selekcije, koja omogućava izbor jedne od dve mogućnosti. U Pascal-u se obično
implementira izrazom oblika:
If B then St else Sf ;
Struktura selekcije određena je if-then i if-then-else izrazima.
(2) Strukturu višestruke selekcije, koja omogućava izbor jedne između više ponuđenih grana. U
Pascal-u se koristi case izraz oblika:
case X of
xa : Sa;
xb : Sb;
end;
(3) Strukturu iteracije, koja omogućava višestruko izvršavanje nekog bloka naredbi. U jeziku
Pascal se koristi while do petlja oblika:
while B do S;
Upravljačke strukture jednog proceduralnog jezika bi trebalo da ispunjavaju sledeće osobine:
• smisao naredbi mora da bude jasan i jednoznačan;
40
Ivan P. Stanimirović Uvod u programiranje
• sintaksa naredbe treba da bude tako postavljena da dozvoljava hijerarhijsko ugrađivanje drugih
naredbi, što mora da bude jednoznačno definisano i jasno iz samog teksta programa;
• potrebno je da postoji mogućnost lake modifikacije naredbi.
A B
1 3
Primer 2
Ciklički pomeriti u levo sadržaje lokacija A, B i C
P A B C
iz A u P
iz B u A
iz C u B
iz P u C
kraj
Primer 3. Ciklički pomeriti u levo sadržaje lokacija a1, a2, ..., an.
1 2 3 n
41
Ivan P. Stanimirović Uvod u programiranje
P a1 a2 a3 an-1 an
n+1
• iz a1 u P
• iz ai u ai-1, za i=2,...,n kako izvršiti pomeranje
• iz P u an za k mesta?
• kraj
Krajnji čvor u grafu koji predstavlja algoritam nema izlaznih potega, a ima samo jedan dolazni
poteg
kraj
ulaz: izlaz:
Blok odluke
da ne
uslov
42
Ivan P. Stanimirović Uvod u programiranje
A3
•oblik naredbe:
promenljiva:=vrednost
a:=b
n:=n+1
An
Alternacija (selekcija)
Omogućava uslovno izvršenje niza algoritamskih koraka
da
da ne uslov
uslov
S2 S2 S S1
S S1 1
1
43
Ivan P. Stanimirović Uvod u programiranje
Primer 1. Nacrtati dijagram toka algoritama kojim se odredjuje veći od dva zadata broja korišćenjem
formule
a, a b
max{ a, b}
b, a b
Petlja (ciklus)
Omogćava da se algoritamski koraci ponavljaju više puta.
Pravila
Ako petlja počne unutar then bloka ili else bloka, u tom bloku se mora i završiti!
Dozvoljene su paralelne (ugnježdjene) petlje.
su dozvoljene petlje koje se seku!
Paralelne petlje
44
Ivan P. Stanimirović Uvod u programiranje
m, m,n
n
r:=“ostatak od m/n”
r:=“ostatak od m/n”
m:=n
ne
do-while n:=r
r ≠0
repeat-until
da
nzd:=m
nzd:=n
nzd
nzd
kraj
kraj
45
Ivan P. Stanimirović Uvod u programiranje
max(a,b,c)
if (a>b) then
if (a>c) then
max:=a
else
max:=c
endif;
else
if (b>c) then
max:=b
else
max:=c
endif;
endif;
Petlje – pseudo kod
while (uslov) do repeat
niz_ naredbi niz_naredbi
enddo; until (uslov);
Primer: Primer:
r:=“ostatak od m/n”
while (r≠0) do repeat
m:=n; r:=“ostatak od m/n”;
n:=r; m=n;
r:=“ostatak od m/n”; n:=r;
enddo; until (r=0);
nzd:=n; nzd:=m;
Strukturogrami
Kombinacija grafičkog i pseudo koda;
Koriste se kao prikladna dokumentacija za već završene programe.
Program se piše tako da se popunjavaju određene geometrijske slike
if uslov
while uslov for i:=n1,n2,n3
else
sekvenca then telo
petlje
telo telo
S1 S2 petlje petlje
until uslov
Strukturogrami – primer
if a>b if a>b
then else else
then
47
Ivan P. Stanimirović Uvod u programiranje
end;
U ovom primeru postoji sedam blokova (označeni oznakama A:, B:, C:, D:, E:, F: i G:) i u svakom
od ovih blokova opisana je po jedna promenljiva. Sledeća tabela daje podatke o svim blokovima u
programu. Slovo L označava da je promenljiva lokalna, a G da je globalna.
Blok
Promenljiva A B C D E F G
a L G G G G G G
b L
c L G G
d L
e L
f L G
g L
U sledećem primeru dat je ilustrovan pojam bloka kao i pojam lokalnih i globalnih promenljivih.
Primer. Doseg i sakrivanje u C++.
int x=0; // globalno x
void f () {
int y=x, // lokalno y, globalno x;
x=y; // lokalno x, sakriva globalno x
x=1; // pristup lokalnom x
::x=5; // pristup globalnom x
{ int x; // lokalno x, sakriva prethodno x
x=2; // pristup drugom lokalnom x
}
x=3; // pristup prvom lokalnom x
}
int *p=&x; // uzimanje adrese globalnog x
#include<stdio.h>
int x=0; // globalno x
void main ()
{ int y=x, // lokalno y, globalno x;
x=y; // lokalno x, sakriva globalno x
printf("x = %d\n",x);
x=1; // pristup lokalnom x
printf("x = %d\n",x);
::x=5; // pristup globalnom x
printf("x = %d\n",x);
{ int x; // lokalno x, sakriva prethodno x
x=2; // pristup drugom lokalnom x
printf("x = %d\n",x);
}
// x=3; // pristup prvom lokalnom x
printf("x = %d\n",x);
int *p=&x;
printf("x = %d\n",*p);
}
Primer. Blok u jeziku C.
#include<stdio.h>
void main()
{ float a,b,c,d;
a=1.0; b=2.0; c=3.0; d=4.0;
printf("Spoljasnji blok a=%f b=%f c=%f d=%f\n",a,b,c,d);
{ float c,d,e,f;
c=a+10; d=b+20; e=c+30; f=d+40;
48
Ivan P. Stanimirović Uvod u programiranje
If-then struktura se obično implementira kao poseban, jednostavniji slučaj if-then-else strukture.
Jedino kod nekih starijih jezika (BASIC, FOTRAN) ona postoji kao zasebna upravljačka struktura.
U FORTRAN-u se if-then struktura naziva logičkom IF naredbom i ima sledeću formu:
IF (Iogički izraz) naredba
49
Ivan P. Stanimirović Uvod u programiranje
Naredba koja sledi iza logičkog izraza izvršava se samo ako je vrednost logičkog izraza jednaka
TRUE, inače se tok programa prenosi na sledeću naredbu.
Jedan od problema u primeni if naredbe jeste implementacija slučaja kada se izvršava veći broj
naredbi u jednoj ili then ili else grani. U programskim jezicima koji ne podržavaju koncept sekvence
naredbi, ova struktura se implementira koristeći GOTO naredbu.
Uobičajeni način korišćenja ove naredbe u FORTRAN-u IV ilustruje sledeći primer.
Primer. Logička IF naredba u FORTRAN-u. U naredbi je sa Uslov označena logička promenljiva.
IF (.NOT. Uslov) GO TO 20
I=1
J=2
K=3
20 CONTINUE
U ovom primeru, ako je vrednost promenljive Uslov jednaka FALSE program se nastavlja od
naredbe sa oznakom 20. Za vrednost TRUE iste promenljive program se nastavlja naredbom I=1 koja
sledi neposredno iza naredbe IF. Upotreba GO TO naredbe je bila neophodna s obzirom na
nepostojanje sekvence naredbi u FORTRANu IV.
Uvođenjem koncepta sekvence naredbi, if-then naredba u Algol-u dobija drugačiju sintaksu,
onakvu kakvu poznajemo u savremenim proceduralnim jezicima. U opštem slučaju njena struktura je
definisana na sledeći način:
if (logički izraz) then
begin
naredba_1;
...
naredba_n
end;
Sekvenca naredbi, obuhvaćena zagradama zagradama ili između begin i end, sastavni je deo if
naredbe. Ta sekvenca naredbi se izvršava za vrednost true logičkog izraza. Za vrednost false sekvenca
naredbi se preskače i program nastavlja sa prvom naredbom koja sledi iza zagrade end.
Primer. If-then naredba u Algol-u 60.
if (uslov) then
begin
i:=1;
j:=2;
k:=3
end;
If-then struktura se javlja u različitim oblicima u mnogim jezicima čiji su koreni u Algol-u 60,
uključujući i FORTRAN 77 i FORTRAN 90.
U FORTRAN-u se može koristiti IF-THEN struktura, prema sledećoj sintaksi:
IF(uslov)
naredba
END IF
Uočimo da se u ovom jeziku koriste ključne reči kojima se otvaraju i zatvaraju pojedini delovi
strukture.
U jeziku Pascal je if-then struktura preuzeta iz Algol-a. U jeziku C se umesto reči begin i end
koriste zagrade { i }, redom.
50
Ivan P. Stanimirović Uvod u programiranje
false true
uslov
else-grana then-grana
51
Ivan P. Stanimirović Uvod u programiranje
end
else res := 1;
Napomena: Jedna od najčešćih grešaka je da se test za jednakost “==” zameni sa dodeljivanjem “=”.
Primeri u C.
Primer. Napisati program kojim se dati brojevi x, y, z udvostručuju ako je x>= y>= z, a u protivnom
menjaju znak.
main()
{ float x,y,z;
printf("Zadati x,y,z:\n"); scanf("%f%f%f",&x,&y,&z);
if((x>=y) && (y>=z)) { x*=2; y*=2; z*=2; }
else { x=-x; y=-y; z=-z; }
printf("x=%f y=%f z=%f", x,y,z);
}
Kod else-if iskaza je važno da rezervisana reč else odgovara prethodnom slobodnom if, ukoliko to nije
drugačije određeno velikim zagradama.
Primer. Izračunati
-5, x<0,
y= x+2, 0<=x<1,
3x-1, 1<=x<5,
2x, x>=5.
void main()
{ float x,y;
scanf("%f",&x);
52
Ivan P. Stanimirović Uvod u programiranje
if(x<0) y=-5;
else if(x<1) y=x+2;
else if(x<5) y=3*x-1;
else y=2*x;
printf("y= %f\n", y);
}
Primer. Data su tri realna broja u poretku x < y < z. Umetnuti realni broj t tako da među njima bude
odnos x < y < z < t.
void main()
{ float x,y,z,t,p;
scanf("%f%f%f%f",&x,&y,&z,&t);
if(t<x) { p=t; t=z; z=y; y=x; x=p; }
if(t<y) { p=t; t=z; z=y; y=p; }
if(t<z) { p=t; t=z; z=p; }
printf("x= %f y= %f z= %f t= %f\n",x,y,z,t);
}
var a,b,c,D,x1,x2,x,Re,Im:real;
begin
readln(a,b,c);
if a<>0 then begin
D:=sqr(b)-4*a*c;
if(D>0) then begin
x1:=(-b+sqrt(D))/(2*a); x2:=(-b-sqrt(D))/(2*a);
writeln('x1= ',x1:0:3,' x2= ',x2:0:3);
end
else if D=0 then begin
53
Ivan P. Stanimirović Uvod u programiranje
#include<stdio.h>
#include<math.h>
void main()
{ float a,b,c,D,x1,x2,Re,Im;
scanf("%f%f%f",&a,&b,&c);
if(a)
{ D=b*b-4*a*c;
if(D>0)
{ x1=(-b+sqrt(D))/(2*a); x2=(-b-sqrt(D))/(2*a);
printf("x1= %f x2= %f\n",x1,x2);
}
else if(D==0)
{ x1=-b/(2*a); printf("x1= %f x2= %f\n",x1,x1); }
else
{ Re=-b/(2*a); Im=sqrt(-D)/(2*a);
printf("%f+i*%f, %f-i*%f\n",Re,Im,Re,Im);
}
}
else if(b)
{ x1=-c/b; printf("%f\n",x1); }
else if(c) printf("Jednacina nema resenja\n");
else printf("Identitet\n");
}
Primer. U gradu A se nalazi zaliha goriva od V (0 < V < 2000000000) litara, od koje kamion-cisterna
treba da dostavi što je moguće veću količinu u grad B. Od grada А do gada B ima tačno d (0 < d
2000) kilometara. Cisterna troši litar na jedan kilometar, a može da primi ukupno C (0 < C 5000)
litara za prevoz i potrošnju.
Napisati program koji za date V, d, C, ispisuje koliko najviše goriva može da se dostavi iz A u B, i
koliko PRI TOME najviše može ostati u A. Cisterna može ostati u gradu koji daje povoljniji ishod.
Test primer:
2000 100 1000 1700 0
#include <stdio.h>
void main ()
{ long V, d, C, A, B;
printf("Unesi kolicinu u gradu A: "); scanf ("%ld",&V);
printf("Unesi rastojanje između gradova: "); scanf ("%ld",&d);
printf("Unesi kapacitet cisterne: "); scanf ("%ld",&C);
A=V; B=0;
if((C>d) &&(V>=C))
{ if(C>2*d)
{ A=V%C; B=(C-2*d)*(V/C);
if(A<=d) B=B+d;
54
Ivan P. Stanimirović Uvod u programiranje
else
{ if(A-d>d){B=B+A-d; A=0;}
else B=B+d;
}
}
else {A=V-C; B=C-d;}
} y
printf ("A= %ld B= %ld\n", A, B);
5
16 15 14 13 12
17 4 3 2 11
-5 18 5 0 1 10 5 x
19 6 7 8 9
20 21 22 23 24 25
55
Ivan P. Stanimirović Uvod u programiranje
Primeri.
1. Vrednost izraza
s= -1, x < 0,
x * x, x>=0
može se izračunati pomoću
s=(x < 0) ? -1 : x*x;
56
Ivan P. Stanimirović Uvod u programiranje
Kako se svaka višestruka selekcija može simulirati običnim if-then-else grananjem, na sledećoj slici
prikazan je dijagram toka koji odgovara višestrukom grananju.
Ova struktura koja je u svom razvoju pretrpela mnogo izmena do jednog modernog oblika koji se
danas u manje-više sličnim varijantama javlja u svim programskim jezicima.
57
Ivan P. Stanimirović Uvod u programiranje
Semantika ove naredbe je sledeća: izračunava se vrednost izraza izraz, koji se naziva selektor.
Vrednost izraza izraz mora da bude celobrojna (ili znakovna, koja se automatski konvertuje u
odgovarajuću celobrojnu vrednost). Dobijena vrednost se upoređuje sa vrednostima vrednost11,
vrednost12, ..., koji moraju da budu celobrojne konstante ili celobrojni konstantni izrazi. Ove
vrednosti se mogu posmatrati kao obeležja za određenu grupu operatora. Ako je pronađeno obeležje
čija je vrednost jednaka vrednosti izraza izraz, izračunavaju se operatori koji odgovaraju toj vrednosti.
Ključna reč break predstavlja kraj jedne case grane, odnosno kraj grupe operatora sadržanih u nekoj
case grani. Ako nije pronađena vrednost u case granama jednaka vrednosti izraza izraz, izračunavaju
se iskazi u default grani; ako je izostavljena alternativa default, neće se izvršiti ni jedna od alternativa
operatora switch.
Izraz prema kome se vrši selekcija i konstante u pojedinim granama treba da budu integer tipa.
Naredbe u granama mogu da budu obične ili složene naredbe i blokovi.
Iako na prvi pogled ova naredba liči na ono što imamo u Pascal-u, radi se o nestrukturnoj naredbi
koja se izvršava tako što se izborom grane određuje samo mesto odakle naredba počinje, a iza toga se
nastavlja njen sekvencijalni tok. To konkretno znači da se naredba u default grani izvršava uvek kao i
to da se naredba u k-toj grani izvršava uvek kada je selektovana neka od prethodnih grana. Da bi se
prekinulo upravljanje pod dejstvom ove naredbe kada se izvrši selektovana grana, odnosno da bi se
postigla semantika case strukture u Pascal-u, potrebno je da se na kraju svake grane upravljanje
eksplicitno prenese na kraj cele switch naredbe. U te svrhe u C-u se koristi naredba break koja
predstavlja izlazak iz switch naredbe. Kôdom iz primera u C-u je realizovano višestruko grananje iz
prethodnog primera gde je korišćena case struktura iz Pascal-a.
Primer. Program kojim se simulira digitron. Učitavaju se dva operanda i aritmetički operator.
Izračunati vrednost unetog izraza.
void main()
{ float op1, op2;
char op;
printf("Unesite izraz \n");
scanf("%f %c %f", &op1, &op, &op2);
switch(op)
{ case '+': printf("%f\n", op1+op2); break;
case '-': printf("%f\n", op1-op2); break;
case '*': printf("%f\n", op1*op2); break;
case '/': printf("%f\n", op1/op2); break;
default: printf("Nepoznat operator\n");
}
}
Operator break se koristi u okviru switch operatora (kasnije i u while, do, for operatorima) da bi se
obezbedio izlaz neposredno na naredbu iza switch strukture. Ukoliko se iza neke grupe operatora u
switch operatoru ispusti break operator, tada se u slučaju izbora te grupe operatora izvršavaju i sve
preostale alternative do pojave break operatora ili do kraja switch operatora.
58
Ivan P. Stanimirović Uvod u programiranje
Operator switch se može realizovati pomoću većeg broja if operatora. Međutim, programi napisani
pomoću switch operatora su pregledniji.
Primer. Za zadati redni broj meseca ispisati broj dana u tom mesecu.
void main()
{ int mesec;
char ch; /* Da li je godina prestupna */
printf("Unesi redni broj meseca: ");
scanf("%d", &mesec);
switch(mesec)
{ case 1:case 3:case 5:case 7:case 8:case 10:case 12:
printf("31 dan\n");
break;
case 4: case 6: case 9: case 11:
printf("30 dana\n);
break;
case 2: printf("Da li je godina prestupna? ");
scanf("%c%c",&ch,&ch);
/* prvo ucitavanje je fiktivno, uzima enter */
if((ch=='D') || (ch=='d')) printf("29 dana\n);
else printf("28 dana\n");
break;
default: printf("Nekorektan redni broj\n");
}
}
59
Ivan P. Stanimirović Uvod u programiranje
niz naredbi
U ovoj petlji se naredbe u telu petlje izvršavaju za sve vrednosti brojačke promenljive I između
vrednosti izraza pocetni i vrednosti izraza krajnji.
60
Ivan P. Stanimirović Uvod u programiranje
ne
uslov
da
niz naredbi
Strukturnim programiranjem definisana je i until struktura (do-while struktura) koja predviđa post-
test uslova, odnosno ispitivanje uslova posle izvršenja tela petlje. Repeat-until struktura je prikazana
na sledećoj slici.
niz naredbi
uslov
ne
da
Poseban oblik petlji sa postuslovom je do-while naredba u C. Ovakva struktura sa postuslovom se
završava kada uslov nije ispunjen.
61
Ivan P. Stanimirović Uvod u programiranje
Primeri u jeziku C
Primer. Izračunati aritmetičku sredinu niza brojeva različitih od nule. Broj elemenata u nizu nije
unpred poznat.
void main()
{ int brojac=0;
float suma=0, stopcode=0, broj;
printf("Daj niz znakova zavrsen sa %d\n",stopcode);
scanf("%f",&broj);
while(broj != stopcode)
{ suma+=broj; brojac++; scanf("%f",&broj); }
printf("Srednja vrednost= %f\n",suma/brojac);
}
62
Ivan P. Stanimirović Uvod u programiranje
#include <stdio.h>
void main() {
int t, p = 0;
scanf("%d", &t);
while (t > 1) {
if (t % 3 == 1)
{ printf("3^%d ide na desnu\n", p); t--; }
else if (t % 3 == 2)
{ printf("3^%d ide na levu\n", p); t++; }
else { p++; t /= 3; }
}
printf("3^%d ide na desnu\n", p);
}
Primer. Izračunati
x 2k
k 0
(1) k
(2k )!
, x /2
.
Sumiranje prekinuti kada je apsolutna vrednost poslednjeg dodatog člana manja od zadate tačnosti e.
Koristi se
x2
ak ak 1
2k (2k 1)
void main()
{ double c,a,e,x;
int k=0;
scanf("%lf%lf",&x, &e);
while(fabs(a)>=e)
{ k++; a=-(x*x/(2*k*(2*k-1)))*a; c+=a; }
printf("cos(%.2lf)=%.7lf",x,c);
}
Primer. Heksadekadni broj prevesti u dekadni. Unošenje heksadekadnog broja prekinuti kada se
unese karakter koji ne pripada skupu karaktera '0', ... , '9', 'A', ... , 'F'.
63
Ivan P. Stanimirović Uvod u programiranje
#include <stdio.h>
void main()
{int broj,u,k;
char cif;
broj=0;u=1;
printf("unesi heksadekadni broj\n"); scanf("%c",&cif);
u=((cif<='F')&&(cif>='0'));
while (u)
{ if ((cif>='A')&&(cif<='F')) k=cif-55; else k=cif-48;
broj=broj*16+k; scanf("%c",&cif); u=((cif<='F')&&(cif>='0'));
}
printf("%d\n",broj);
}
Primer. Napisati program koji simulira rad džepnog kalkulatora. Program učitava niz brojnih
vrednosti razdvojenih znakovima aritmetičkih operacija +, -, *, / kao i izračunavanje vrednosti izraza
koji je definisan na ovaj način. Aritmetičke operacije se izvršavaju s leva na desno, bez poštovanja
njihovog prioriteta.
#include <stdio.h>
void main()
{ double result, num;
char op;
printf("\n\n"); scanf("%lf" , &num); scanf("%c" , &op);
result = num ;
while (op != '=')
{ scanf("%lf" , &num) ;
switch (op)
{ case '+' : result += num ; break;
case '-' : result -= num ; break;
case '*' : result *= num ; break;
case '/' : result /= num ; break;
}
scanf("%c" , &op);
}
printf("Rezultat je %.10lf." , result) ;
}
4. Dati su tegovi mase 3k kg, k = 0,1,2,... i to iz svake vrste po jedan. Napisati program koji određuje
koje tegove bi trebalo postaviti levo a koje desno da bi se izmerio predmet težine A kg koji se nalazi na
levom tasu.
#include <stdio.h>
void main()
{
int dteg,lteg,s,a;
printf("Unesite tezinu\n");
scanf("%d",&a);
s=1;
while (a>0)
{ dteg=a%3;
if (dteg==2)
{
dteg=0;
lteg=1;
}
else lteg=0;
printf("Teg od %dkg staviti levo: %d, desno:
%d\n",s,lteg,dteg);
s*=3;
a=(a+lteg)/3;
64
Ivan P. Stanimirović Uvod u programiranje
}
}
printf("\n%9s%5d\n%9s%5d\n%9s%5d\n%9s%5d\n%9s%5d\n",
"a_count:", a_count, "b_count:", b_count,
"cC_count:", cC_count, "other:", other_count,
"Total:", a_count+b_count+cC_count+other_count);
}
Primer. Unos teksta je završen prelazom u novi red. Prebrojati koliko je u unetom tekstu znakova
uzvika, znakova pitanja a koliko tačaka.
#include <stdio.h>
void main()
{ char c;
int uzv,upt,izj;
uzv=upt=izj=0;
while((c=getch())!='\n')
switch(c)
{ case '!':++uzv; break;
case '?':++upt; break;
case '.':++izj; break;
}
printf("\n"); printf("Uzvicnih ima %d\n",uzv);
printf("Upitnih ima %d\n",upt); printf("Izjavnih ima %d\n",izj);
}
Kod organizacije while ciklusa mora se voditi računa o tome da telo ciklusa menja parametre koji
se koriste kao preduslov za ciklus, tako da posle određenog broja iteracija postane “netačan”. U
protivnom, ciklus će biti beskonačan.
Do-while naredba u C
Do-while naredba je varijanta while naredbe. Razlikuje se od while naredbe po tome što je uslov na
kraju ciklusa:
do
operator
while(izraz);
65
Ivan P. Stanimirović Uvod u programiranje
sledeća naredba;
Telo ciklusa je označeno sa operator, i izvršava se jedanput ili više puta, sve dok izraz ne dobije
vrednost 0 (false). Tada se kontrola prenosi na sledeću naredbu.
Primeri
Primer. Ispis celog broja s desna na levo.
void main()
{ long broj;
printf("Unesite ceo broj"); scanf("%ld",&broj);
printf("Permutovani broj");
do { printf("%d",broj%10); broj /= 10; } while(broj);
printf("\n");
}
pocetak
66
netačno
uslov <> 0
Ivan P. Stanimirović Uvod u programiranje
Izrazi u zaglavlju petlje mogu da budu i izostavljeni. Na primer, petlja bez drugog izraza izvršava
se kao da je njegova vrednost true, što znači kao beskonačna petlja. Ako su izostavljeni prvi i treći
izraz, telo ciklusa je prazno.
U jeziku C se za definisanje petlje sa unapred definisanim brojem izvršenja tela petlje može
koristiti for naredba. Međutim, for naredba u C je mnogo fleksibilnija od odgovarajućih naredbi u
drugim jezicima. Naime, izrazi u zaglavlju petlje mogu da objedine više naredbi. To znači da se u
okviru petlje može istovremeno definisati više uslova upravljanja vezanih za različite promenljive koje
čak mogu da budu i različitih tipova. Razmotrimo sledeći primer.
Primeri
Primer. Suma prvih n prirodnih brojeva se može izračunati na više različitih načina.
1. sum=0; for(i=1; i<=n; ++i) sum += i;
2. sum=0; i=1; for(; i<=n;) sum += i++;
3. for(sum=0, i=1; i<=n; sum += i, i++);
Primer. Faktorijel prirodnog broja urađen na dva slična načina.
void main()
{ int i,n;
long fak=1;
printf("\n Unesite broj"); scanf("%d",&n);
for(i=1; i<=n; ++i) fak *=i;
printf("%d! = %ld \n",n,fak);
}
void main()
{ int i,n;
long fak=1;
printf("\n Unesite broj"); scanf(" %d",&n);
for(fak=1,i=1; i<=n; fak*=i,++i);
printf("%d! = %ld \n",n,fak);
}
67
Ivan P. Stanimirović Uvod u programiranje
scanf("%d",&n);
for(s=0; n>0; s=s*n+n--);
printf("Suma=%ld\n",s);
}
Primer. Program za određivanje savršenih brojeva do zadatog prirodnog broja. Savršen broj je jednak
sumi svojih delitelja.
void main()
{ int i,m,n,del,s;
scanf("%d",&m)
for(i=2;i<=m;i++)
{ n=i; s=1;
for(del=2; del<=i/2; del++) if(n%del==0) s+=del;
if(i==s) printf("%d\",i);
}
}
Primer. U ravni je dato N tačaka svojim koordinatama (x, y). Napisati program na programskom
jeziku C, koji na svom izlazu daje ukupan broj tačaka koje pripadaju oblastima I, II, III odnosno IV, i
broj tačaka koje ne pripadju ni jednoj od naznačenih oblasti. Oblasti su definisane kružnicom i
pravama kao na slici, a njihove jednačine glase:
K: x2 + (y-1)2 = 1
AB: y = x, BC: y = -x + 2, CD: y = x + 2, DA: y = -x.
68
Ivan P. Stanimirović Uvod u programiranje
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void main()
{ int n, i;
float x, y;
// Brojaci tacaka u odgovarajucim oblastima.
int br1 = 0, br2 = 0, br3 = 0, br4 = 0, brOstalo = 0 ;
// Promenljie koje definisu polozaje tacaka
int unutarK, ispodAB, iznadBC, iznadCD, ispodDA;
printf("Unesite broj tacaka\n"); scanf("%d", &n);
for (i = 0; i < n; i++)
{ printf("Unesite kordinate tacke %d\n", i + 1); scanf("%f %f", &x, &y);
unutarK = (x*x + (y-1)*(y-1)) < 1;
ispodAB = y < x;
iznadBC = y > -x + 2;
iznadCD = y > x + 2;
ispodDA = y < -x;
if (unutarK)
{ // Tacka je unutar kruznice
if (ispodAB) br1++;
else if (iznadBC) br2++;
else if (iznadCD) br3++;
else if (ispodDA) br4++;
}
}
brOstalo = n - br1 - br2 - br3 - br4;
printf("Brojevi tacaka u oblsatima I, II, III, IV respektivno iznose:
%d %d %d %d\n", br1, br2, br3, br4);
printf("Broj tacaka koje ne pripadaju ni jednoj oblasti iznosi: %d\n",
brOstalo);
}
(2)
69
Ivan P. Stanimirović Uvod u programiranje
Efekat iskaza while B do S može se rigorozno definisati tako što se kaže da je on ekvivalentan
efektu iskaza:
if B then
begin
S;
while B do S (3)
end.
(4)
Ovakva definicija znači da dijagrami (2) i (4) opisuju ekvivalentne procese izvršenja (radnje).
Primer while B do S iskaza dat je u programu (5), koji izračunava sumu h(n) = 1+1/2+ . . . +1/n.
var n : integer; h : real;
h :=0;
while n>0 do (5)
begin
h := h+1/n; n := n—1
end.
Drugi oblik repetitivnog iskaza je:
repeat S until B, (6)
gde je S niz iskaza a B logički izraz. Iskaz (6) definiše sledeću radnju: izvršava se iskaz S, a zatim se
izračunava izraz B. Ako je rezultat izračunavanja izraza B jednak false, ponovo se izvršava iskaz S, i
tako dalje. Proces ponavljanja radnje definisane sa S završava se kada izračunavanje izraza B da true.
Struktura ovako definisanog repetitivnog iskaza predstavlja se sledećim dijagramom:
(7)
Poređenjem (2) i (7) zaključujemo da se u (7) iskaz S mora izvršiti bar jednom, dok se u (2) on ne
mora uopšte izvršiti. Kako se u prvom slučaju B izračunava pre svakog izvršenja iskaza S, a u drugom
nakon svakog izvršenja iskaza S, razlozi efikasnosti nalažu da B bude u što je moguće prostijoj formi.
Rigorozna definicija radnje određene iskazom repeat S until B daje se na taj način što se
kaže da je ona ekvivalentna radnji koju određuje iskaz:
begin
S;
if B then
repeat S until B
70
Ivan P. Stanimirović Uvod u programiranje
end. (8)
(9)
Ovo znači da dijagrami (7) i (9) opisuju ekvivalentne radnje. Kako se u (2) i (7) pojavljuju
zatvorene putanje ili petlje, oba ova iskaza se često i nazivaju petljama. U njima se S se naziva telom
petlje.
Primer repeat iskaza dat je u programu (10), koji izračunava sumu h(n)=1+1/2+ . . .+ 1/n:
var n: integer; h: real;
h:=0;
repeat
h:= h+1/n; n:=n-1 (10)
until not(n>0).
Fundamentalni problem vezan za repetitivnu kompoziciju iskaza ilustrovaćemo primerima (5) i
(10). Proces izvršenja iskaza (10) je konačan samo ako u početku važi n>0. Za n<0 (10) predstavlja
beskonačnu petlju. S druge strane, program (5) se ponaša korektno, čak i ako je n<0, tj. proces
njegovog izvršavanja je konačan. Vidimo, dakle, da pogrešno koncipiran repetitivni iskaz može
opisivati radnju beskonačnog vremenskog trajanja.
71
Ivan P. Stanimirović Uvod u programiranje
U jeziku C postoji i naredba continue koja se takođe koristi za upravljanje tokom izvršenja petlje.
Ovom naredbom se samo preskače ostatak petlje i program nastavlja novim prolazom kroz petlju
počevši od prve naredbe petlje. Efekat te naredbe opisan je u narednom primeru.
Primer. Efekat naredbe continue u C.
sum=0;
while (sum < 2000)
{ scanf(“%d”, &podatak);
if (podatak < 0) continue;
sum = sum + podatak;
}
U ovom slučaju, kada se učita negativni podatak preskače se naredba za modifikovanje sume i
program nastavlja ponovnim prolaskom kroz petlju. To znači da će u ovom slučaju petlja uvek da se
završi kada se dostigne vrednost sum >= 2000, što u prethodnom primeru nije uvek bio slučaj.
72
Ivan P. Stanimirović Uvod u programiranje
Neograničeni skokovi omogućavaju komande koje imaju višestruke ulaze i višestruke izlaze. Oni
imaju tendenciju da produkuju ‘‘špagetti’’ kôd, tako nazvan zato što je njihov dijagram toka zamršen.
‘‘Špagetti’’ kôd ima tendenciju da bude teško razumljiv. Većina glavnih programskih jezika
podržava skokove, ali su realno zastareli u modenim jezicima. Čak i u jezicima koji podržavaju
skokove, njihova upotreba je ograničena restrikcijom dometa svakog obeležja: skok ‘‘goto L;’’ je
legalan samo unutar dosega L. U C, na primer, doseg svakog obeležja je najmanje obuhvaćen blok
komandom (‘‘{ . . . }’’). Prema tome, mogući su skokovi unutar blok komande, ili iz jedne blok
komande izvan neke ograđene blok komande; međutim, nemoguć je skok unutar neke blok komande
od spolja, niti iz jednog tela funkcije u drugo.
C skokovi nisu ograničeni da spreče ‘‘špagetti’’ kodovanje.
Skok unutar blok komande je relativno jednostavan, dok je skok izvan blok naredbe
komplikovaniji. Takav skok mora da uništi lokalne promenljive bloka pre nego što se transfer prenese
na destinaciju skoka.
Primer. Skok izvan blok naredbe. Uočimo sledeći (veštački) C kod:
#include<stdio.h>
void main()
{ char stop = '.',ch='!';
do { char ch;
73
Ivan P. Stanimirović Uvod u programiranje
ch = getchar();
if (ch == EOF) goto X;
putchar(ch);
} while (ch != stop);
printf("done");
X: printf("%c\n",ch);
}
Skok ‘‘goto X;’’ prenosi kontrolu izvan blok komande {. . .}. Prema tome, on takođe uništava lokalnu
promenljivu ch iz bloka. Po izlasku iz ciklusa, prikazuje se vrednost ‘!’ kao vrednost promenljive ch.
Skok izvan tela procedure je još komplikovaniji. Takav skok mora da uništi lokalne promenljive i
da terminira aktivaciju procedure pre prenosa kontrole na takvu destinaciju. Velike komplikacije
nastaju kada je destinacija skoka unutar tela rekurzivne procedure: koje rekurzivne aktivacije se
terminiraju kada se skok izvrši?
Prema tome, površno su skokovi veoma jednostavni, dok u suštini oni uvode neželjenu
kompleksnost u semantiku jezika visokog nivoa.
Za označavanje naredbi, na koje se pod dejstvom GOTO naredbe prenosi upravljanje, u
programskim jezicima se koristi koncept oznaka (labela). Iskaz Goto je prost iskaz koji ukazuje na to
da dalju obradu treba nastaviti u drugom delu programskog teksta, to jest sa mesta na kome je labela.
U nekim jezicima (C-u, Algol-u 60 na primer) koriste se identifikatori kao oznake. U drugim
(FORTRAN i Pascal na primer) to su neoznačene celobrojne konstante. U Adi su oznake takođe
identifikatori, ali obuhvaćeni zagradama << i >>, dok se za razdvajanje oznaka od naredbi na koje se
odnose u mnogim jezicima koristi dvotačka (:). Evo nekih primera:
Primer naredbe GOTO za skok na označenu naredbu u Adi.
goto KRAJ;
…
<<KRAJ>> SUM := SUM + PODATAK;
Isti primer napisan u C-u bio bi sledećeg oblika:
goto kraj;
…
kraj: sum := sum + podatak;
U svim programskim jezicima obično su definisana određena pravila koja ograničavaju korišćenje
naredbe GOTO. Na primer, u Pascal-u oznake moraju eksplicitno da budu opisane u odeljku
deklaracije naredbi. One se ne mogu prenositi kao argumenti potprograma niti modifikovati. Kao deo
GOTO naredbe može da bude samo neoznačena konstanta, ali ne i izraz ili promenljiva koja dobija
vrednost oznake.
74
Ivan P. Stanimirović Uvod u programiranje
goto 1;
end.
Primer. Primeri upotrebe Goto naredbe (programski deo):
label 1; { blok A }
...
procedure B; { blok B }
label 3, 5;
begin
goto 3 ;
3 : Writeln(‘Dobar dan');
5 : if P then
begin S; goto 5 end ; { while P do S }
goto 1 ;
{ ovo uzrokuje prevremen zavrsetak aktivacije procedure B}
Writeln('Doviđenja')
end; { blok B }
begin
B;
1: Writeln(‘program')
{ "goto 3" nije dozvoljen u bloku A )
end { blok A }
Skokovi izvana u strukturirani iskaz nisu dozvoljeni. Stoga su sledeći primeri nepravilni.
Primeri sintaksno nepravilnih programa:
a) for I := 1 to 10 do
begin
S1;
3: S2
end ;
goto 3
b) if B then goto 3;
...
if B1 then 3 : S
c) procedure P;
procedure Q;
begin ...
3 :S
end ;
begin ...
goto 3
end.
Iskaz Goto treba sačuvati za neuobičajene ill retke situacije gde je potrebno razbiti prirodnu
strukturu algoritma. Dobro je pravilo da bi trebalo izbegavati upotrebu skokova pri izražavanju
pravilnih ponavljanja i uslovnih izvršavanja iskaza, jer takvi skokovi uništavaju odraz strukture obrade
u tekstualnim (statičkim) strukturama programa. Štaviše, nedostatak slaganja između tekstualne i
obradne (tj. statičke i dinamičke) strukture poguban je po jasnoću progama i čini proveru ispravnosti
programa mnogo težom. Postojanje iskaza Goto u Pascal programu često ukazuje na to da programer
još nije naučio "misliti" u Pascalu (jer je u nekim drugim programskim jezicima Goto neophodna
konstrukcija).
75
Ivan P. Stanimirović Uvod u programiranje
5. POTPROGRAMI
U programiranju se često javlja potreba da se neki deo programa više puta ponovi u jednom
programu. Takođe, često puta se ista programska celina javlja u više različitih programa. Ovakva
nepotrebna ponavljanja se izbegavaju pomoću potprograma.
Potprogrami se uvek koriste sa idejom da se izbegne ponavljanje istih sekvenci naredbi u slučaju
kada u programu za to postoji potreba. Međutim, potprogrami su mnogo značajniji kao sredstvo za
struktuiranje programa. Pri razradi programa metodom dekompozicije odozgo naniže, svaka
pojedinačna aktivnost visokog nivoa može da se zameni pozivom potprograma. U svakoj sledećoj
etapi ide se sve niže i niže u tom procesu dekompozicije sve dok se rešenje kompleksnog programa ne
razbije na jednostavne procedure koje se konačno implementiraju. Kako napredujemo u veštini
računarskog programiranja, tako programe pišemo u nizu koraka preciziranja. Pri svakom koraku
razbijamo naš zadatak u više podzadataka, definišući tako više parcijalnih programa. Koncepti
procedure i funkcije omogućavaju da izložimo podzadatke kao konkretne potprograme.
Može se reći da su potprogrami osnovno sredstvo apstrakcije u programiranju. Potprogramom se
definiše skup izlaznih veličina u funkciji ulaznih veličina. Realizacija tih zavisnosti definisana je u
potprogramu.
Potprogrami se definišu kao programske celine koje se zatim po potrebi pozivaju i realizuju, bilo u
okviru istog programa u kome su i definisani, bilo u drugim programima.
Istaknimo neke opšte karakteristike potprograma kakvi se najčešće sreću u savremenim
programskim jezicima.
(1) Svaki potprogram ima jednu ulaznu tačku. Izuzetak od ovog pravila postoji jedino u
FORTRAN-u, gde je moguće definisati više različitih ulaza u potprogram.
(2) Program koji poziva potprogram prekida svoju aktivnost sve dok se ne završi pozvani
potprogram. To znači da se u jednom trenutku izvršava samo jedan potprogram.
(3) Po završetku pozvanog potprograma upravljanje se vraća programu koji ga je pozvao, i to na
naredbu koja sledi neposredno iza poziva potprograma.
Potprogram karakterišu sledeći osnovni elementi:
• ime potprograma,
• lista imena i tipova argumenata (fiktivni argumenti),
• lokalni parametri potprograma,
• telo potprograma,
• sredina (okruženje) u kojoj potprogram definisan.
Ime potprograma je uvedena reč, odnosno identifikator, kojom se potprogram imenuje i kojim se
vrši njegovo pozivanje.
Lista fiktivnih parametara: u nekim programskim jezicima ova lista može da sadrži samo imena
fiktivnih argumenata, čime je određen njihov broj i redosled navođenja, Kod novijih programskih
jezika u listi argumenata se navode i atributi o tipu argumenata kao i o načinu prenošenja u
potprogram. Fiktivnim argumentima definiše se skup ulazno-izlaznih veličina potprograma. Kod
poziva potprograma se fiktivni argumenti (parametri) zamenjuju stvarnim argumentima. Fiktivni i
stvarni argumenti moraju da se slažu po tipu, dimenzijama i redosledu navođenja u listi argumenata.
Lokalni parametri. U samoj proceduri mogu da budu definisani lokalni elementi procedure i to
promenljive, konstante, oznake, a u nekim jezicima i drugi potprogrami.
76
Ivan P. Stanimirović Uvod u programiranje
Telo potprograma čini sekvenca naredbi koja se izvršava nakon poziva potprograma. U telu
potprograma se realizuje kôd potprograma.
Okolinu (okruženje) potprograma predstavljaju vrednosti globalnih promenljivih okruženja u
kome je potprogram definisan i koje se po mehanizmu globalnih promenljivih mogu koristiti u
potprogramu.
U programskim jezicima se obično sreću dva tipa potprograma:
• funkcijski potprogrami (funkcije),
• potprogrami opšteg tipa (procedure).
5.1. Funkcije
Funkcijski potprogrami po konceptu odgovaraju matematičkim funkcijama. Lista argumenata u
deklaraciji ovih potprograma se obično sastoji se samo od ulaznih argumenata, na osnovu kojih se u
telu potprograma izračunava vrednost koja se prenosi u pozivajuću programsku jedinicu. Ulazne
vrednosti se u funkciji ne menjaju.
U jezicima Pascal i FORTRAN se za prenošenje vrednosti iz potprograma u pozivajuću jedinicu
koristi promenljiva koja se identifikuje sa imenom funkcije. U telu takvih funkcija mora da postoji bar
jedna naredba dodele kojom se rezultat dodeljuje imenu funkcije. Kaže se da funkcija prenosi vrednost
u glavni program preko svog imena.
U novijim programskim jezicima obično postoji naredba return kojom se eksplicitno navodi
vrednost koja se iz potprograma prenosi u glavni program. Naredba return se koristi u jeziku C. U
jeziku C se ne koristi reč function, jer su svi potprogrami funkcije. Ako funkcija vraća jedan rezultat
naredbom return ispred njenog imena se piše tip rezultata, inače se piše službena reč void.
Funkcijski potprogrami se pozivaju slično matematičkim funkcijama, tako što se u okviru izraza
navede ime funkcije sa imenima stvarnih parametara umesto fiktivnih. Koristeći gore navedene
primere, suma prvih 999 celih brojeva se može izračunati pozivom funkcije SUM na sledeći način:
SUMA := SUM(999) (Pascal)
ili
SUMA = SUM(999) (C, FORTRAN).
Funkcija se koristi u slučaju kada se vraća jedna veličina u rezultujuću programsku jedinicu.
77
Ivan P. Stanimirović Uvod u programiranje
…
operatorN
}
Deo definicije koji se nalazi pre prve zagrade '{' naziva se zaglavlje funkcijske definicije, a sve
između velikih zagrada se naziva telo funkcijske definicije.
Tip funkcije zavisi od tipa vrednosti koja se vraća. Takođe, koristi se službena reč void ako funkcija
ne vraća vrednost. Ako je tip rezultata izostavljen podrazumeva se int.
Parametri su po sintaksi identifikatori, i mogu se koristiti u telu funkcije (formalni parametri).
Navođenje formalnih parametara nije obavezno, što znači da funkcija može da bude bez formalnih
parametara.
Poziv funkcije koja daje rezultat realizuje se izrazom
ime(spisak_stvarnih_parametara)
koji predstavlja element drugih izraza. U slučaju da funkcija ne vraća rezultat, dopisuje znak `;', čime
poziv funkcije postaje operator:
ime(spisak_stvarnih_parametara);
Između formalnih i stvarnih parametara mora da se uspostavi određena korespodencija po broju,
tipu i redosledu.
Kada se formalni parametri definišu u zaglavlju funkcije, tada se za svaki parametar posebno
navodi tip. Tada je zaglavlje funkcije sledećeg oblika:
tip ime(tip param1,...,tip paramn)
U programskom jeziku C, formalni parametri se mogu deklaristati ispod zaglavlja funkcije. Tada se
svi parametri istog tipa mogu deklarisati odjednom, koristeći jedinstveno ime tipa.
Return naredba
Među operatorima u telu funkcije može se nalaziti operator return, koji predstavlja operator
povratka u pozivajuću funkciju. Ako se operator return ne navede, funkcija se završava izvršenjem
poslednjeg operatora u svom telu, i ne vraća rezultat.
Naredba return se koristi iz dva razloga:
- Kada se izvrši naredba return, kontrola toka programa se vraća u pozivajuću jedinicu.
- Osim toga, ako neki izraz sledi iza ključne reči return, tj. ako se naredba return koristi u obliku
return izraz ili return(izraz), tada se vrednost izraza izraz vraća u pozivajuću programsku
jedinicu. Ova vrednost mora da bude u skladu sa tipom funkcije u zaglavlju funkcijske definicije.
Naredba return u jeziku C ima jednu od sledeće dve forme:
return;
ili
return(izraz); odnosno return izraz;
78
Ivan P. Stanimirović Uvod u programiranje
Primer. Uzmimo kao primer funkciju za izračunavanje sume prvih n prirodnih brojeva. Radi
poređenja isti potprogram napisan je u različitim programskim jezicima:
Pascal
function SUM (n: integer) : integer;
var i, POM : integer; { Opis lokalnih promenljivih }
begin { Telo funkcije }
POM := 0:
for i := 1 to n do POM := POM + i;
SUM := POM {Vrednost koja se prenosi u glavni program}
end;
FORTRAN
INTEGER FUNCTION SUM(N)
INTEGER N
DO 10 I = 1, N
10 SUM = SUM + I
END
PROGRAM SUMA
INTEGER S,N
READ(*,10)N
10 FORMAT(I2)
S=SUM(N)
WRITE(*,20)S
20 FORMAT(I4)
C
#include<stdio.h>
int SUM (int n)
{ int POM = 0;
for(int i = 1; i <= n; i++)POM = POM + i ;
return POM;
}
void main()
{ int n;
scanf("%d",&n); printf("%d\n",SUM(n));
}
Prototip funkcije
U tradicionalnom stilu C jezika, funkcija se može koristiti pre nego što je definisana. Definicija
funkcije može da sledi u istom ili u nekom drugom fajlu ili iz biblioteke. Nepoznavanje broja
argumenata odnosno tipa funkcije može da uzrokuje greške. Ovo se može sprečiti prototipom funkcije,
kojim se eksplicitno ukazuje tip i broj parametara koje funkcija zahteva i tip rezultujućeg izraza. Opšta
forma prototipa funkcije je sledeća:
tip ime (lista_tipova_parametara);
U ovom izrazu je lista_tipova_parametara lista tipova odvojenih zarezima. Kada je funkcija pozvana,
argumenti se konvertuju, ako je moguće, u navedene tipove.
Na primer, sintaksno su ispravni sledeći prototipovi:
void poruka1(int);
int min(int, int);
Takođe, prototip funkcije može da uključi i imena parametara, čime se može obezbediti dodatna
dokumentacija za čitaoca.
Na primer, možemo pisati
double max(duble x, double y);
Primeri
79
Ivan P. Stanimirović Uvod u programiranje
Primer. Izračunati minimum dva cela broja. Funkcija min(x,y) vraća rezultat tipa int, te se eksplicitno
navođenje tipa rezultata može izostaviti. U pozivajućoj funkciji (u ovom slučaju je to funkcija main())
naveden je prototip funkcije min.
#include<stdio.h>
void main()
{ int min(int,int);
int j,k,m;
printf("Unesi dva cela broja: ");scanf("%d%d",&j,&k);
m=min(j,k); printf("\n%d je minimum za %d i %d\n\n", m,j,k);
}
min(int x,int y)
{ if (x<y) return(x); else return(y); }
void slucajni(int k)
{ int i,r,mini,maxi;
int min(int, int), max(int, int);
srand(10);
r=mini=maxi=rand(); printf("%d\n",r);
for(i=1;i<k;++i)
{ r=rand();printf("%d\n",r);
mini=min(r,mini);maxi=max(r, maxi);
}
printf("Minimum: %7d\n Maximum:%7d\n", mini,maxi);
}
int min(int i, int j)
{ if(i<j) return(i); else return(j); }
int max(int i, int j)
{ if(i>j) return(i); else return(j); }
Primer. Izračunavanje broja kombinacija m-te klase od n elemenata po formuli
n n!
m
m!(n m)!
Pascal
program fakt1;
var m,n:integer;
bk:longint;
function fakt(k:integer):longint;
var i:integer; p:longint;
begin
p:=1;
for i:=2 to k do p:=p*i;
fakt:=p;
end;
begin
readln(n,m);
bk:=fakt(n) div fakt(m) div fakt(n-m);
writeln('Broj kombinacija je ',bk);
80
Ivan P. Stanimirović Uvod u programiranje
end.
C
#include<stdio.h>
void main()
{ int m,n; long bk;
long fakt(int);
scanf("%d%d",&n,&m);
bk=fakt(n)/fakt(m)/fakt(n-m);
printf("Broj kombinacija je %ld\n",bk);
}
long fakt(int k)
{ int i; long p=1;
for(i=2; i<=k; i++) p*=i;
return(p);
}
Izračunavanje vrednosti n! se može izdvojiti u posebnom potprogramu. Tada se prethodno napisani
potprogrami mogu napisati na sledeći način.
Pascal (II način)
program fakt2;
var m,n:integer;
bk:longint;
function komb(p,q:integer):longint;
function fakt(k:integer):longint;
var i:integer;
p:longint;
begin {fakt}
p:=1;
for i:=2 to k do p:=p*i;
fakt:=p;
end;
begin {komb}
komb:= fakt(p) div fakt(q) div fakt(p-q)
end;
begin
readln(n,m);
bk:=komb(n,m); writeln('Broj kombinacija je ',bk);
end.
C (II način)
#include<stdio.h>
void main()
{ int m,n; long bk;
long komb(int, int);
scanf("%d%d",&n,&m);
bk=komb(n,m); printf("Broj kombinacija je %ld\n",bk);
}
long fakt(int k)
{ int i; long p=1;
for(i=2; i<=k; i++) p*=i;
return(p);
}
81
Ivan P. Stanimirović Uvod u programiranje
Primer. Izračunati
x3 x5 x 2 n1
sin( x) x ... (1) n1 ...
3! 5! (2n 1)!
Sumiranje prekinuti kada se ispuni uslov |a/S| <= , gde je zadata tačnost, S predstavlja tekuću
vrednost sume, dok a predstavlja vrednost člana koji se dodaje.
#include<stdio.h>
void main()
{ double x,eps;
double sinus(); scanf("%lf%lf",&x,&eps);
printf("Sinus je %lf\n", sinus(x,eps));
}
/* apsolutna vrednost */
double abs(x) { return (x>0)?x:-x; }
/* sinus */
double sinus(double x, double eps)
{ double sum, clan; int k; clan=x; k=0; sum=clan;
while(abs(clan)>eps*abs(sum))
{ k+=1; clan*=-(x*x)/(2*k*(2*k+1)); sum+=clan; }
return(sum);
}
void main()
{ int i,n; int prost(int);
printf("Dokle? "); scanf("%d", &n);
for(i=3; i<=n; i++) if(prost(i)==1) printf("%d\n",i);
}
void main()
{ long i; unsigned a,b,c;
for(i=100;i<=999;i++)
{ a=i%10; b=i%100/10; c=i/100;
if(fakt(a)+fakt(b)+fakt(c)==i) printf("%d\n",i);
}
}
Primer. Unositi prirodne brojeve dok se ne unese vrednost <=0. Izračunati NZS unetih brojeva.
void main()
{int k,ns,nzs=0; scanf("%d", &k);
if(k<=0) printf("%d\n",nzs);
82
Ivan P. Stanimirović Uvod u programiranje
else
{ ns=nzs=k; scanf("%d", &k);
while(k>0)
{nzs=funnzs(ns,k); ns=nzs; scanf("%d",&k); };
printf("nzs = %d\n",nzs);
} }
int funnzs(int a, int b)
{ int nz;
if(a>b)nz=a;
else nz=b;
while( ((nz % a) !=0) || ((nz % b)!=0) ) nz++;
return(nz);
}
Primer. Dekadni broj iz intervala [0, 3000] prevesti u rimski brojni sistem.
#define hi 'M'
#define ps 'D'
#define st 'C'
#define pd 'L'
#define ds 'X'
#define pe 'V'
#define je 'I'
void rim(int);
void main()
{ int n;
printf("Unesi prirodan broj -> "); scanf("%d", &n);
printf("\nOdgovarajuci rimski broj je: ");
rim(n); printf("\n");
}
void rim(int n)
{ while(n>= 1000) { printf("%c",hi); n-=1000; }
if(n>=900) {printf("%c",st); printf("%c",hi); n-=900;}
if(n>= 500) { printf("%c",ps); n-=500; }
if(n>=400)
{ printf("%c",st); printf("%c",ps); n-=400; }
while(n>=100) { printf("%c",st); n-=100; }
if(n>=90)
{ printf("%c",ds); printf("%c",st); n-=90; }
if(n>= 50) { printf("%c",pd); n-=50; }
if(n>=40)
{ printf("%c",ds); printf("%c",ps); n-=40; }
while(n>= 10) { printf("%c",ds); n-=10; }
if(n==9)
{ printf("%c",je); printf("%c",ds); n-=9; }
if(n>= 5) {printf("%c",pe); n-=5; }
if(n==4) {printf("%c",je); printf("%c",pe); n-=4; }
while(n>=1) { printf("%c",je); n--; } }
void main()
{int m,n,i=1,prosti=1; int prost(int n);
printf("Broj za koji se racuna najblizi prost broj");
scanf("%d",&m);
83
Ivan P. Stanimirović Uvod u programiranje
5.2. Procedure
Procedurama se definišu potprogrami opšteg tipa, kojima se može realizovati svaki algoritam koji
sǎm za sebe ima određeni smisao. Procedurama se obično u glavni program prenosi jedan ili skup
rezultata.
Opis potprograma opšteg tipa obično ima sledeću strukturu:
procedure IME_PROCEDURE (Lista argumenata)
Opisi lokalnih promenljivlh;
Telo procedure
end;
Opis počinje nekom ključnom reči kojom se eksplicitno navodi da definišemo proceduru. U
mnogim programskim jezicima koristi se reč procedure, mada ima i izuzetaka, na primer u
FORTRAN-u se koristi SUBROUTINE. Identifikator IME_PROCEDURE je uvedena reč kojom se
imenuje potprogram. Ime potprograma se koristi za poziv potprograma. Za razliku od funkcija, lista
84
Ivan P. Stanimirović Uvod u programiranje
argumenata kod procedura može da sadrži ulazne, izlazne i ulazno-izlazne argumente. Obično se
zahteva da se u listi argumenata navede njihov tip i način prenošenja vrednosti između glavnog
programa i potprograma. U Adi na primer, argumenti mogu da budu ulazni, izlazni i ulazno-izlazni što
se eksplicitno navodi rečima in, out i inout uz odgovarajuće argumente.
Deklaracija procedure služi da definiše programski deo i da ga pridruži identifikatoru, tako da se
moze aktivirati procedurnim iskazom. Deklaracija ima isti oblik kao i program, osim što započinje
zaglavljem procedure umesto zaglavljem programa.
85
Ivan P. Stanimirović Uvod u programiranje
Primer. Pronaći sve brojeve-blizance do zadatog broja n. Dva broja su blizanci ako su prosti i
razlikuju se za 2.
#include<stdio.h>
#include<math.h>
void main()
{ int n,i;
int prost(int);
scanf("%d",&n);
for (i=3;i<=n;i++)
if ((prost(i)) && (prost(i-2))) printf("%d %d\n",i-2,i);
86
Ivan P. Stanimirović Uvod u programiranje
int prost(int k)
{ int i=2,prosti=1;
while((i<=sqrt(k)) && (prosti)) { prosti=((k%i)!=0); i++; }
return(prosti);
}
U nekim drugim programskim jezicima (FORTRAN), takav poziv funkcije može da promeni
vrednost za v. Mehanizam izvršen u tom slučaju se naziva poziv po adresi (call by Reference). Da bi
se u C postigao efekat poziva po adresi moraju se koristiti pointeri promenljivih u listi parametara
prilikom definisanja funkcije, kao i adrese promenljivih koje su argumenti u pozivu funkcije.
87
Ivan P. Stanimirović Uvod u programiranje
(Algol, FORTRAN). U Pascal-u se koristi uvek kada uz argumente stoji var. U jeziku C se za prenos
po referenci koriste pokazivači.
Glavni program Funkcija
Prednosti prenosa po referenci su u njegovoj efikasnosti kako u pogledu vremena tako i u pogledu
memorijskog prostora. Nema potrebe za dupliranja memorijskog prostora niti se gubi vreme u
kopiranju vrednosti argumenata iz jednih memorijskih lokacija u druge. Međutim, treba imati u vidu
da se ovaj prenos implementira indirektnim adresiranjem pa se tu ipak nešto gubi na efikasnosti.
Takođe, mogući su i određeni bočni efekti u određenim posebnim slučajevima poziva potprograma.
Razmotrićemo neke od njih.
Kao u slučaju prenosa po rezultatu i ovde je moguća kolizija između stvarnih argumenata. Uzmimo
na primer potprogram PP u Pascal-u sa dva argumenta koji se prenose po vrednosti, čija je deklaracija
oblika
procedure PP(var x,y: integer);
Ako se ovaj potprogram pozove tako da se oba fiktivna argumenta zamene istim stvarnim
parametrom, na primer sa PP(m, m); , dolazi do kolizije jer se oba fiktivna argumenta referenciraju na
istu memorijsku lokaciju stvarnog argumenta m.
Kod prenosa po referenci kolizija može da nastane između elemenata programa koji se prenose kao
stvarni argumenti potprograma i onih koji se prenose kao globalni parametri. Razmotrimo sledeći
primer u Pascal-u:
program LocalGlobal;
var global: integer;
procedure PPG(var local: integer);
begin
local := local+1; writeln('global = ',global);local := local+global;
end;
begin
global := 2; PPG(global); writeln(global);
end.
Odgovarajući primer u jeziku C je predstavljen sledećim kôdom:
#include<stdio.h>
int global;
void PPG(int *local)
{ (*local)++;
printf("global = %d\n",global);
*local = *local+global;
}
void main()
{ global = 2;
PPG(&global);
printf("%d\n",global);
}
88
Ivan P. Stanimirović Uvod u programiranje
Posle poziva potprograma PPG biće odštampana vrednost je 6. Zaista, vrednost 2 dodeljena
promenljivoj global u potprogramu najpre koriguje naredbom local:=local+1; (posle čega je
global=3), a zatim i naredbom local:=local+global; (posle čega je local=global=3).
Promenljiva global se u potprogramu koristi i kao globalna promenljiva i kao stvarni argument, pa se i
promene argumenta potprograma i promene same promenljive global registruju u istoj memorijskoj
lokaciji. Napomenimo da bi u ovom primeru prenos sa kopiranjem (call by value-result) dao drugačiji
rezultat. U tom slučaju, vrednost stvarnog argumenta global kopira se u memorijsku lokaciju fiktivnog
argumenta local i u potprogramu se sve promene argumenta registruju u toj lokaciji. U prvoj naredbi
dodeljivanja promenljiva local dobija vrednost 3, a u drugoj se ova vrednost inkrementira za 2, što je
vrednost globalne promenljive global (dodeljena pre ulaska u potprogram). Time argument local
dobija vrednost 5, i to je vrednost koja se po završetku potprograma kopira natrag u memorijsku
lokaciju stvarnog argumenta global. To znači da se u ovom slučaju štampa vrednost 5. Slična analiza
istog programa moguća je i za slučaj prenosa argumenta potprograma po vrednosti. U tom slučaju
vrednost stvarnog argumenta global se kopira u potprogram ali su sve promene u potprogramu
nevidljive za glavni program, pa se po završetku potprograma štampa vrednost 2 koja je dodeljena
promenljivoj global pre poziva potprograma.
Poziv po adresi pomoću pokazivača u C
Deklaracije pointera i dodeljivanje
Pointeri se koriste za pristup memoriji i manipulaciju adresama. Vrednosti pokazivača jesu adrese
promenljivih. Do sada smo već videli upotrebu adresa kao argumenata u naredbi scanf(). Ako je v
promenljiva, tada je &v adresa (lokacija) u memoriji u kojoj je smeštena vrednost za v. Operator & je
unarni, ima asocijativnost sdesna na levo, a prioritet kao i ostali unarni operatori. Pointerske
promenljive se mogu deklarisati u programu, a onda koristiti tako da uzimaju adrese za svoje
vrednosti.
Na primer, deklaracija
int *p;
deklariše promenljivu p tipa ''pointer na int''. Rang vrednosti svakog pointera uključuje posebnu
adresu 0, definisanu kao NULL u <stdio.h>, kao i skup pozitivnih celih brojeva koji se
interpretiraju kao mašinske adrese.
Primer. Pointeru p se vrednosti mogu dodeljivati na sledeći način:.
p=&i;
p=0;
p=NULL; /* isto što i p=0; */
p=(int*)1507 /* apsolutna adresa u memoriji */ }
U prvom primeru p je ''pointer na i'', odnosno ''sadrži adresu od i''. Treći i drugi primer
predstavljaju dodelu specijalne vrednosti 0 pointeru p. U četvrtom primeru kast je nužan da bi se
izbeglo upozorenje kompajlera, a koristi se aktuelna memorijska lokacija kao vrednost promenljive p.
Ovakve naredbe se ne koriste u korisničkim programima, već samo u sistemskim.
Adresiranje i operator indirekcije
Neka su date deklaracije
int i, *p;
Tada naredbe
p=&i; scanf("%d",p);
uzrokuju da se sledeća uneta vrednost smešta u adresu zadatu pointerom p. Ali, s obzirom da p
ukazuje na i, to znači da se vrednost smešta u adresu od i.
Operator indirekcije * je unarni i ima isti prioritet i asocijativnost sa desna ulevo kao i ostali unarni
operatori. Ako je p pointer, tada *p predstavlja vrednost promenljive na koju ukazuje p. Direktna
vrednost za p je memorijska lokacija, dok je *p indirektna vrednost od p, tj. vrednost memorijske
lokacije sadržane u p. U suštini, * je inverzni operator u odnosu na operator &.
89
Ivan P. Stanimirović Uvod u programiranje
Na taj način, pointeri se mogu koristiti za dodelu vrednosti nekoj promenljivoj. Na primer, neka su
date deklaracije
int *p,x;
Tada se izrazima
p=&x; *p=6;
promenljivoj x dodeljuje vrednost 6.
Primer. Uočimo deklaracije
float x,y, *p;
i naredbe
p = &x; y=*p;
Prvom naredbom se adresa od x pridružuje pointeru p, a drugom se vrednost na koju ukazuje p
dodeljuje y. Ove dve naredbe su ekvivalentne sa
y=*&x;
odnosno
y=x.
Primer. Ilustracija pokazivača.
Primer.
void main()
{ int i=777,*p;
p=&i; printf("Vrednost za i:%d\n",*p);
printf("Adrese za i: %u ili %p\n",p,p);
}
90
Ivan P. Stanimirović Uvod u programiranje
void main()
{ int i=5, *pi=&i; printf("i= %d ili = %d\n", i, *pi); }
91
Ivan P. Stanimirović Uvod u programiranje
Primer. Primer u jeziku C kojim se ilustruju globalna promenljiva i prenos po adresi. Rezultat je kao
u slučaju prenosa po adresi.
#include<stdio.h>
int global;
void PPG(int *local)
{ (*local)++; printf("global = %d\n",global); *local = *local+global;}
void main()
{ global = 2; PPG(&global); printf("%d\n",global); }
Tehnika predaje parametara po adresi (Call by reference) se sastoji iz sledećih baznih pravila:
1. deklarisati formalne parametre funkcije kao pointere;
2. koristiti operatore indirekcije u telu funkcije;
3. pri pozivu funkcije koristiti adrese kao argumente.
Kako sredi() radi sa pokazivačima? Kada predajete pokazivač, predajete adresu objekta i tako
funkcija može manipulisati vrednošću na toj adresi. Da bi sredi() promenila stvarne vrednosti,
92
Ivan P. Stanimirović Uvod u programiranje
korišćenjem pokazivača, funkcija sredi(), trebalo bi da bude deklarisana da prihvata dva int
pokazivača. Zatim, dereferenciranjem pokazivača, vrednosti x i y će, u stvari, biti promenjene.
Primer. Predavanje po referenci korišcenjem pokazivača.
1: // Prenos parametara po referenci
2:
3: #include <iostream.h>
4:
5: void swap(int *x, int *y);
6:
7: int main()
8: {
9: int x = 5, y = 10;
10:
11: cout << "Main. Pre swap, x:”<<x<<" y: "<<y<<"\n";
12: swap(&x,&y);
13: cout<<"Main. Posle swap., x: "<<x<<" y: "<<y<<"\n";
14: return 0;
15: }
16:
17: void swap(int *px, int *py)
18: {
19: int temp;
20:
21: cout<<"Swap. Pre swap, *px: "<<*px<<" *py:"<<*py<<"\n";
22:
23: temp = *px;
24: *px = *py;
25: *py = temp;
26:
27: cout<<"Swap. Posle swap, *px: "<<*px<<" *py: "<<*py<<"\n";
28:
29: }
Izlaz:
Main. Pre swap, x:5 y: 10
Swap. Pre swap, *px: 5 *py:10
Swap. Posle swap, *px: 10 *py:5
Main. Posle swap, x:10 y: 5
U liniji 5 prototip funkcije swap() pokazuje da će njegova dva parametra biti pokazivači na int, a ne
int promenljive, Kada se pozove swap() u liniji 12, kao argumenti se predaju adrese od x i y. U liniji
19 lokalna promenljiva, temp, deklarisana je u funkciji swap() - nije potrebno da temp bude pokazivač;
ona će čuvati samo vrednost od *px (to jest, vrednost promenljive x u pozivajućoj funkciji), tokom
života funkcije. Posle povratka iz funkcije, promenljiva temp više neće biti potrebna.
U liniji 23 promenljivoj temp se dodeljuje vrednost memorijske lokacije koja je jednaka vrednosti
pokazivača px. U liniji 24 vrednost na adresi px se dodeljuje vrednosti na adresi py. U liniji 25
vrednost čuvana u temp (to jest, originalna vrednost na adresi px) stavlja se u adresu py.
Efekat ovoga je da će vrednosti u pozivajućoj funkciji, čije su adrese predate funkciji swap(), biti
zamenjene.
Prenos po referenci koristeći reference u C++
Prethodni program radi, ali sintaksa funkcije swap() je problematična zbog dve stvari. Prvo,
ponavljajuća potreba za dereferenciranjem pokazivača unutar funkcije swap() čini je podložnom
greškama i teškom za čitanje. Drugo, potreba da se preda adresa promenljivih u pozivajućoj funkciji
čini unutrašnji rad funkcije swap() više nego očiglednim za korisnike.
93
Ivan P. Stanimirović Uvod u programiranje
Cilj C++ je da spreči korisnika funkcije da se brine o tome kako ona radi. Zbog toga se prenos po
adresi u C++ može uraditi pomoću referenci.
Primer.
#include<iostream.h>
void f(int i, int &j){ // i je poziv po vrednosti, j po referenci
i++; // stvarni argument si se neće promeniti
j++; // stvarni argument sj će se promeniti
}
void main () {
int si=0,sj=0;
f(si,sj);
cout<<"si="<<si<<", sj="<<sj<<endl;
}
Izlaz: si=0, sj=1
94
Ivan P. Stanimirović Uvod u programiranje
U linijama 24-26 vrednosti se zamenjuju, a onda se štampaju u liniji 28, Izvršenje programa
"skače" u pozivajuću funkcuju i u liniji 14 vrednosti se štampaju u main(). Zato što su parametri za
swap() deklarisani kao reference, vrednosti iz main() se predaju po referenci i time se, takođe, menjaju
i u main().
Reference obezbeđuju pogodnost i lakoću upotrebe normalnih promenljivih, sa snagom i
sposobnošću predavanja po referenci koju imaju pokazivači.
Primer. Prenos parametra na dva načina.
#include<iostream.h>
int* f(int* x) {
(*x)++;
return x; // Vrednost za x se prenosi u stvarni parametar
}
int& g(int& x) {
x++; // Isti efekat kao u f()
return x; // Vrednost za x se prenosi u stvarni parametar
}
int main() {
int a = 0;
f(&a); // Ružno, ali eksplicitno
cout << "a = " << a << "\n";
g(a); // Jasno, ali sakriveno
cout << "a = " << a << "\n";
return 0;
}
Primer. Modifikacija prethodnog primera, koja se sastoji u upotrebi pokazivača p. Naredbom
p=f(&a); identifikovani su p i &a.
#include<iostream.h>
int* f(int* x) {
(*x)++;
return x; // Vrednost za x se prenosi u stvarni parametar
}
int& g(int& x) {
x++; // Isti efekat kao u f()
return x; // Vrednost za x se prenosi u stvarni parametar
}
void main() {
int a = 0,*p;
p=f(&a); // Ružno, ali eksplicitno
cout << "a = " << a << "\n"; //a=1
cout << "*p = " << *p << "\n"; //*p=1
g(a); // Jasno, ali sakriveno
cout << "a = " << a << "\n"; //a=2
cout << "*p = " << *p << "\n"; // *p=2
}
Vraćanje višestrukih vrednosti
Kao što je rečeno, pomoću naredbe return funkcije mogu vratiti samo jednu vrednost. Šta učiniti
ako je potrebno da vratite dve vrednosti iz funkcije? Jedan način da rešite ovaj problem je da funkciji
predate objekte po referenci. Kako predavanje po referenci dozvoljava funkciji da promeni originalne
objekte, ovo efektno dozvoljava funkciji da vrati više informacija. Povratna vrednost funkcije se može
rezervisati za izveštavanje o greškama.
95
Ivan P. Stanimirović Uvod u programiranje
Ovo se može ostvariti referencama, ili pokazivačima. Sledeći primer demonstrira funkciju koja
vraća tri vrednosti: dve kao pokazivačke parametre i jednu kao povratnu vrednost funkcije.
Primer. Vraćanje vrednosti pomoću pokazivača.
1:
2: // Vraćanje više vrednosti iz funkcije
3:
4: #include <iostream.h>
5:
6: typedef unsigned short USHORT;
7:
8: short Factor(USHORT, USHORT*, USHORT*);
9:
10: int main()
11: {
12: USHORT number, squared, cubed;
13: short error;
14:
15: cout << "Unesite broj (0-20): ";
16: cin >> number;
17:
18: error = Factor(number, &squared, &cubed);
19:
20: if(!error)
21: {
22: cout << "broj: " << number << "\n";
23: cout << "kvadrat: " << squared << "\n";
24: cout << "kub: " << cubed << "\n";
25: }
26: else
27: cout << "Doslo je do greske!!\n";
28: return 0;
29: }
30:
31: short Factor(USHORT n, USHORT *pSquared, USHORT *pCubed)
32: {
33: short Value = 0;
34: if (n > 20)
35: Value = 1;
36: else
37: {
38: *pSquared = n*n;
39: *pCubed = n*n*n;
40: Value = 0;
41: }
42: return Value;
43: }
U liniji 12 number, squared i cubed su definisani kao USHORT. Promenljivoj number se dodeljuje
broj baziran na korisničkom ulazu. Ovaj broj i adresa od squared i cubed se predaju funkciji Factor().
Funkcija Factor() ispituje prvi parametar, koji se predaje po vrednosti. Ako je on veći od 20
(maksimalan broj kojim ova funkcija može rukovati), ona postavlja povratnu vrednost (Value) na
jednostavnu vrednost greške (Value =1). Uočite da povratna vrednost 0 iz funkcije Factor() pokazuje
da je sve prošlo dobro, i uočite da tunkcija vraća ovu vrednost u liniji 42.
Stvarne potrebne vrednosti, kvadrat i kub promenljive number, vraćaju se menjanjem pokazivača
koji su predati funkciji.
U linijama 38 i 39 pokazivačima se dodeljuju njihove povratne vrednosti. U liniji 40 return Value
dobija uspešnu vrednost.
Jedno poboljšanje u ovom programu bi moglo biti deklarisanje sledećeg:
96
Ivan P. Stanimirović Uvod u programiranje
97
Ivan P. Stanimirović Uvod u programiranje
void main()
{ int x,y,z; void razmeni(int*, int*);
scanf("%d%d%d", &x,&y,&z);
if(x>y) razmeni(&x,&y); if(x>z) razmeni(&x,&z);
if(y>z) razmeni(&y,&z);
printf("x= %d y= %d z= %d\n",x,y,z);
}
Primer. Napisati proceduru kojom se izračunava najmanji zajednički sadržalac i najveći zajednički
delilac dva prirodna broja.
#include<stdio.h>
void unos(int *,int *); void nzds(int,int, int *,int *);
void main()
{ int x,y, nzd,nzs;
unos(&x, &y); nzds(x,y,&nzd,&nzs);
printf("Nzd unetih brojeva = %d a nzs= %d\n",nzd,nzs);
}
Primer. Sa tastature se unosi jedan ceo broj, a za njim neodređen broj celih brojeva. Napisati
proceduru kojom se izračunava minimum i maksimum unetih brojeva.
#include<stdio.h>
void minmax(int *,int*);
void main()
{ int mn,mx; minmax(&mn,&mx);
printf("Minimum je %d a maksimum %d\n",mn,mx);
}
98
Ivan P. Stanimirović Uvod u programiranje
while(scanf("%d",&n)==1)
if(n<*min)*min=n;
else if(n>*max)*max=n;
}
Primer. Napisati proceduru za deljenje dva cela broja na proizvoljan broj decimala. Deljenik, delilac
i broj decimala zadati u posebnoj proceduri.
#include<stdio.h>
#include<conio.h>
void unos(int *, int*, int *);
void deljenje(int, int, int);
main()
{ int n,i,bdec, brojilac, imenilac;
clrscr(); printf("Koliko puta? "); scanf("%d", &n);
for(i=1; i<=n; i++)
{ unos(&brojilac, &imenilac, &bdec);
99
Ivan P. Stanimirović Uvod u programiranje
Primer. a) Napisati proceduru za unošenje brojioca i imenioca jednog razlomka. U toj proceduri, po
potrebi, vrednost imenioca promeniti tako da bude pozitivan.
b) Napisati rekurzivnu funkciju za izračunavanje najvećeg zajedničkog delioca dva prirodna broja.
c) Napisati funkciju za izračunavanje najvećeg zajedničkog sadržaoca dva prirodna broja.
d) Napisati proceduru za kraćenje brojioca i imenioca zadatim prirodnim brojem.
e) Napisati proceduru za sabiranje dva razlomka. Pri sabiranju razlomaka koristiti najveći zajednički
sadržalac za imenioce jednog i drugog razlomka. Zatim skratiti brojilac i imenilac izračunatog
razlomka najvećim zajedničkim deliocem za brojilac i imenilac.
f) U glavnom programu učitati brojilac i imenilac za n razlomaka i izračunati zbir svih razlomaka.
#include<stdio.h>
#include<math.h>
#include<conio.h>
/* razlomci.c */
int nzd(int, int); int nzs(int, int); void unos(int *, int *);
void sabiranje(int, int,int, int, int *, int *);
100
Ivan P. Stanimirović Uvod u programiranje
Primer. Napisati proceduru za učitavanje i ispis kompleksnih brojeva kao i procedure za izvođenje
osnovnih aritmetičkih operacija sa kompleksnim brojevima. Napisati test program.
#include<stdio.h>
#include<math.h>
void unos(float *,float *, float *, float *);
void saberi(float, float, float, float, float *, float *);
void oduzmi(float, float, float, float, float *, float *);
void mnozi(float, float, float, float, float *, float *);
void deli(float, float, float, float, float *, float *);
void ispis(float, float);
void main()
{ float x1,y1,x2,y2,re,im;
unos(&x1,&y1,&x2,&y2);
saberi(x1,y1,x2,y2, &re,&im); printf("\nNjihov zbir je: ");
ispis(re,im); printf("\n");
oduzmi(x1,y1,x2,y2, &re,&im);
printf("\nNjihova razlika je: "); ispis(re,im); printf("\n");
mnozi(x1,y1,x2,y2,&re,&im);
printf("\nNjihov proizvod je: "); ispis(re,im); printf("\n");
deli(x1,y1,x2,y2,&re,&im);
printf("\nNjihov kolicnik je: "); ispis(re,im);
printf("\n");
}
void unos(float *re1, float *im1, float *re2, float *im2)
{ printf("Prvi kompleksni broj? "); scanf("%f%f", re1,im1);
printf("Drugi kompleksni broj? "); scanf("%f%f", re2,im2);
}
void saberi(float re1,float im1,float re2,float im2,
float *rez, float *imz)
{*rez=re1+re2; *imz=im1+im2; }
void oduzmi(float re1, float im1, float re2, float im2,
float *rez, float *imz)
{*rez=re1-re2; *imz=im1-im2; }
void mnozi(float re1, float im1, float re2, float im2,
float *rez, float *imz)
{*rez=re1*re2-im1*im2; *imz=re1*im2+re2*im1; }
void deli(float re1, float im1, float re2, float im2,
float *rez, float *imz)
{*rez=(re1*re2+im1*im2)/(re2*re2+im2*im2);
*imz=(-re1*im2+re2*im1)/(re2*re2+im2*im2);
}
void ispis(float x, float y)
{ printf("\n %f",x);
if(y<0) printf("-"); else printf("+");
printf("i*%f\n",fabs(y));
}
101
Ivan P. Stanimirović Uvod u programiranje
Primer. a) Napisati funkciju NZD(a,b) kojom se izračunava najveći zajednički delilac za prirodne
brojeve a i b.
b) Koristeći funkciju NZD(a,b) izračunati NZD(a,b,c).
d) Napisati funkciju skratic(int a, int b, int *c, int *d) koja razlomak a/b (b0) dovodi do neskrativog
razlomka c/d.
e) Napisati funkciju skrati(int a, int b, int &c, int &d) koja razlomak a/b (b0) dovodi do neskrativog
razlomka c/d.
f) U funkciji main:
- Za tri učitana prirodna broja naći njihov NZD.
- Za dva razlomka koji su učitani preko tastature i učitani operacijski znak (+ za sabiranje, - za
oduzimanje, * za množenje, / za deljenje) odrediti rezultat računanja u neskrativom obliku.
#include<stdio.h>
#include<math.h>
void operacija(int a, int b, int c, int d, char ch, int &br, int &im)
{ int as, bs, cs, ds;
skrati(a,b,as,bs); skrati(c,d,cs,ds);
switch(ch)
{ case '+': im=NZS(bs,ds), br=as*im/bs+cs*im/ds; break;
case '-': im=NZS(bs,ds), br=as*im/bs-cs*im/ds; break;
case '*': br=as*cs; im=bs*ds; break;
case '/': br=as*ds; im=bs*cs; break;
}
int nd=NZD(br, im);
im= im/nd; br=br/nd;
}
102
Ivan P. Stanimirović Uvod u programiranje
void main()
{ int a,b,c,d;
printf("a,b = ? "); scanf("%d%d",&a,&b);
printf("c= ? "); scanf("%d",&c);
printf("NZD3(%d,%d,%d)=%d\n",a,b,c,NZD3(a,b,c));
int br,im;
skratic(a,b,&br,&im); // skrati(a,b,br,im);
printf("Prvi razlomak? "); scanf("%d%d",&a,&b);
printf("Drugi razlomak? "); scanf("%d%d",&c,&d);
char op;
printf("Operacija = ? "); scanf("%c",&op); scanf("%c",&op);
operacija(a,b,c,d,op,br,im);
printf("Skraceni razlomak = "); ispis(br,im);
}
Primer. Napisati funkciju koja vraća n dana stariji datum.
Rešenje u C++:
#include<stdio.h>
int prestupna(int g)
{ return ((g%4==0) && !(g%100==0))||(g%400==0); }
void main()
{ int d,m,g,n;
scanf("%d%d%d",&d,&m,&g); scanf("%d",&n);
for(int i=1;i<=n;sutra(d,m,g),i++);
printf("%d. %d. %d.\n",d,m,g);
}
Rešenje u C:
#include<stdio.h>
int prestupna(int g)
{ return ((g%4==0) && !(g%100==0))||(g%400==0); }
103
Ivan P. Stanimirović Uvod u programiranje
void main()
{ int d,m,g,n;
printf("Datum = ? "); scanf("%d%d%d",&d,&m,&g);
printf("Posle koliko dana ? "); scanf("%d",&n);
for(int i=1;i<=n;sutra(&d,&m,&g),i++);
printf("%d. %d. %d.\n",d,m,g);
}
Primer. Napisati funkciju
int* biggest_of_two(int*, int*);
koja vraća pokazivač na minimum dva cela broja.
U glavnom programu učitati tri cela broja a, b, c a zatim izračunati njihov minimum.
#include <stdio.h>
int* biggest_of_two(int*, int*);
int main(void)
{ int a, b, c;
int *p;
scanf("%d%d%d",&a,&b,&c);
p = biggest_of_two(&a, &b);
printf("the biggest of %i and %i is %i\n", a, b, *p);
printf("the biggest of %i %i and %i is %i\n", a, b, c,
*biggest_of_two(&a, biggest_of_two(&b, &c)));
return 0;
}
104
Ivan P. Stanimirović Uvod u programiranje
**pp=*q;
i=*q***pp;
printf("i = %d\n",i); // 49
i=*q/(**pp);
printf("i = %d\n",i); // 1
}
#include<stdio.h>
#include<math.h>
float D,a,b,m,n,R1,R2,R3,x;
float th()
{ float R;
R=exp(2*x); return ((R-1)/(R+1));
}
void main()
{ scanf("%f%f%f%f",&a,&b,&m,&n);
x=a*n+b; R1=th(); x=a+m*b; R2=th();
x=a*a+b*b; R3=th(); x=a*a-b*b;
D=R1/(R3*R3)-R2*R2/th(); printf("%f\n",D);
}
105
Ivan P. Stanimirović Uvod u programiranje
(b) Rešenje pomoću procedure bez argumenata. Rezultat se dodeljuje globalnom parametrom. Takođe,
i vrednost za x se unosi preko globalnog parametra.
program TANH2;
var D,a,b,m,n,R1,R2,R3,x,y : real;
procedure th;
begin
y := exp(2*x); y := (y-1)/(y+1)
end;
begin
read(a,b,m,n);
x := a*n+b; th; R1 := y;
x := a+m*b; th; R2 := y;
x := a*a+b*b; th; R3 := y;
x := a*a-b*b; th;
D := R1/(R3*R3)- R2*R2/y; writeln(D);
end.
#include<stdio.h>
#include<math.h>
float D,a,b,m,n,R1,R2,R3,x,y;
void th()
{ y=exp(2*x); y=(y-1)/(y+1); }
void main()
{ scanf("%f%f%f%f",&a,&b,&m,&n);
x=a*n+b; th(); R1=y; x=a+m*b; th(); R2=y;
x=a*a+b*b; th(); R3=y; x=a*a-b*b; th();
D=R1/(R3*R3)- R2*R2/y; printf("%f\n",D);
}
(c) Program sa funkcijskim potprogramom sa argumentima. Rezultat se dodeljuje imenu funkcije.
Vrednost za x se unosi pomoću parametra funkcije.
program TANH3;
var D,a,b,m,n : real;
function th(x: real):real;
var R : real;
begin
R := exp(2*x); th:= (R-1)/(R+1)
end;
begin
read(a,b,m,n);
D := th(a*n+b)/(th(a*a+b*b)*th(a*a+b*b)) –
th(a+m*b)*th(a+m*b)/th(a*a-b*b);
writeln(D)
end.
#include<stdio.h>
#include<math.h>
float D,a,b,m,n;
float th(float x)
{ float R=exp(2*x);
return ((R-1)/(R+1));
}
void main()
{ scanf("%f%f%f%f", &a,&b,&m,&n);
D= th(a*n+b)/(th(a*a+b*b)*th(a*a+b*b)) -
106
Ivan P. Stanimirović Uvod u programiranje
th(a+m*b)*th(a+m*b)/th(a*a-b*b);
printf("%f\n",D);
}
(d) Rešenje pomoću procedure sa argumentima. Prvi argument je izlazni a drugi ulazni.
program TANH4;
var D,a,b,m,n,Rl,R2,R3,R4 :real;
procedure th(var y: real; x: real);
begin
y := exp(2*x); y := (y-1)/(y+1)
end;
begin
read(a,b,m,n);
th(Rl, a*n+b); th(R2, a+m*b); th(R3,a*a+b*b); th(R4,a*a-b*b);
D:=Rl/(R3*R3)-R2*R2/R4; writeln(D)
end.
#include<stdio.h>
#include<math.h>
float D,a,b,m,n,Rl,R2,R3,R4;
void th(float *y, float x)
{ *y=exp(2*x); *y=(*y-1)/(*y+1); }
void main()
{ scanf("%f%f%f%f", &a,&b,&m,&n);
th(&Rl, a*n+b); th(&R2, a+m*b); th(&R3,a*a+b*b); th(&R4,a*a-b*b);
D=Rl/(R3*R3)-R2*R2/R4; printf("%f\n",D);
}
#include<stdio.h>
#include<math.h>
float D,a,b,m,n,Rl,R2,R3,R4;
void th(float &y, float x)
{ y=exp(2*x); y=(y-1)/(y+1); }
void main()
{ scanf("%f%f%f%f", &a,&b,&m,&n);
th(Rl, a*n+b); th(R2, a+m*b); th(R3,a*a+b*b); th(R4,a*a-b*b);
D=Rl/(R3*R3)-R2*R2/R4; printf("%f\n",D);
}
U programskom jeziku FORTRAN konceptu globalnih promenljivih na neki način odgovara
koncept COMMON područja. Sve promenljive koje su zajedničke za više programskih modula
obuhvataju se sa COMMON i pamte se u zasebnom memoriskom bloku koji je dostupan svim
potprogramima koji se referenciraju na isto COMMON područje.
Primeri
Primer. (C) Za paran broj N proveriti hipotezu Goldbaha. Prema toj hipotezi, svaki paran broj veći
od 2 može se predstaviti zbirom dva prosta broja.
Rešenje se sastoji u proveri da li je za svaki prost broj i (i = 3, ... , n/2) broj n-i takođe prost. Da li
je broj prost proverava se funkcijom prost.
#define nepar(x) ((x)%2)?1:0)
#include "math.h"
int prost(long n)
{ long i,koren; int q;
koren=floor(sqrt(n)); q=(nepar(n) || (n==2);
107
Ivan P. Stanimirović Uvod u programiranje
i=3;
while ((q) && (i<=koren)) { q=((n % i) != 0); i=i+2; };
return (q);
};
void main()
{long n,i;
int q;
do { printf("\nunesite paran broj: "); scanf("%ld",&n); }
while((n<4) || ((n % 2) != 0));
i=2; q=0;
while ((i<= n/2) && (!q))
{ q=(prost(i) && prost(n-i));
if (q) printf("\nTo su brojevi %ld i %ld",i,n-i);
i++;
};
if (!q) printf("\n Hipoteza ne vazi za %ld ",n);
}
Primer. Napisati funkcijski potprogram koji izračunava n-ti stepen broja x koristeći relaciju
1, n=0
xn = (xk)2, n=2k
x(xk)2, n=2k+1
Napisati program za stepenovanje koji u beskonačnom ciklusu učitava realan broj x i prirodan broj n i
izračunava xn.
program Stepenovanje2;
type PrirodniBroj = O..Maxint;
var Pi, PiKvadrat : Real ;
function Stepen(Osnova:Real; Eksponent:PrirodniBroj): Real;
var Rezultat:Real;
begin
Rezultat := 1;
while Eksponent > 0 do
begin
while not Odd(Eksponent) do
begin
Eksponent := Eksponent div 2; Osnova := Sqr(Osnova)
end;
Eksponent:= Eksponent-1; Rezultat := Rezultat*Osnova
end;
Stepen:=Rezultat
end { Stepen };
begin
repeat
readln(x); readln(n);
Writeln(x:11:6, n:3, Stepen(x,n):11:6);
until false
end { Stepenovanje2 }.
Test primeri:
2.000000 7 128.000000
3.141593 2 9.869605
3.141593 4 97.409100
Primer. (PASCAL) Napisati funkciju koja izračunava vrednost verižnog razlomka
108
Ivan P. Stanimirović Uvod u programiranje
1
v ( m)
1
1
1
2
...
1
m2
1
m 1
m
Napisati program kojim se izračunava suma
1 1 1
S 1 ... (1) n .
v(3) v(5) v(2n 1)
program verizni_razlomci;
var s,znak:real;
i,n:integer;
function verizni(m:integer):real;
var s:real;
i:integer;
begin
s:=0;
for i:=m downto 1 do s:=1/(s+i);
verizni:=s;
end;
begin
readln(n);
s:=1.0; znak:=-1;
for i:=1 to n do
begin
s:=s+znak/verizni(2*i+1); znak:=-znak;
end;
writeln(s);
end.
Primer. Naći najveći, najmanji i drugi po veličini element između unetih realnih brojeva, bez
korišćenja nizova.
program najveci;
var max1,max2,min,x:real;
n,i:integer;
begin
write('Koliko brojeva? '); readln(n);
if n>2 then
begin
writeln('Unesi ',n,' brojeva'); read(x);
max1:=x; min:=x; read(x);
if x>=max1 then
begin
max2:=max1; max1:=x
end
else if x>=min then max2:=x
else begin
max2:=min; min:=x;
end;
for i:=3 to n do
begin
read(x);
if x>=max1 then
begin
max2:=max1; max1:=x
end
else if x>max2 then max2:=x
109
Ivan P. Stanimirović Uvod u programiranje
#include<stdio.h>
int a,z;
int Skriven(int x)
{ z=z-x; // uzgredni efekat na z
return x*x;
}
void main()
{ z=10; a=Skriven(z); printf("%d %d\n",a,z);
z=10; a=Skriven(10); a*=Skriven(z);
printf("%d %d\n",a,z);
} // { UzgredniEfekat}
Rezultat:
100 0
0 0
10000 -10
110
Ivan P. Stanimirović Uvod u programiranje
U praksi se često sreću i problemi u kojima postoji višestruka rekurzija. Jedan od takvih je problem
izračunavanja članova Fibonačijevog niza brojeva. Fibonačijeva funkcija je definisana kao:
f(n-l) + f(n-2), n>1
f(n) = 1, n=1
1, n=0
Potprogram za izračunavanje članova Fibonačijevog niza biće dvostruko rekurzivan. Dajemo
implementaciju u Pascal-u:
function Fib(n: Integer): integer;
begin
if n > 1 then
Fib := Fib(n-l) + Fib(n-2)
else Fib := 1;
end;
U ovom potprogramu rekurzija dakle nije u stvaranju jedne, već dve kopije iste funkcije. Moguće
su i trostruke, cetvorostruke, itd. rekurzije jer broj poziva kopija ničim nije ograničen. Graf poziva
ovakve dvostruke rekurzije razlikuje se od grafika rekurzija iz prethodnog primera.
111
Ivan P. Stanimirović Uvod u programiranje
#include <stdio.h>
void fun1(int);
void fun2(int);
void fun3(int);
void main()
{ printf("\n fun1(5)\n"); fun1(5);
printf("\n fun2(5)\n"); fun2(5);
printf("\n fun3(5)\n"); fun3(5);
}
void fun1(int n)
{ printf("%2d",n); if(n) fun1(n-1); return; }
void fun2(int n)
{ if(n) fun2(n-1); printf("%2d",n); return; }
void fun3(int n)
{ printf("%2d",n); if(n) fun3(n-1); printf("%2d",n); return;
}
Test primeri:
fun1(5)
5 4 3 2 1 0
112
Ivan P. Stanimirović Uvod u programiranje
fun2(5)
0 1 2 3 4 5
fun3(5)
5 4 3 2 1 0 0 1 2 3 4 5
long fact(short n)
{ if(n<=1)return(1L); else return(n*fact(n-1)); }
#include <stdio.h>
long fib(short);
void main()
{ short n;
scanf("\n %d", &n);
printf("%d-ti clan Fibonacijevog niza = %ld\n", n,fib(n));
}
long fib(short n)
{ if(n<=1)return((long)1); else return(fib(n-1)+fib(n-2));}
Broj rekurzivnih poziva pri izračunavaju Fibonačijevih brojeva može se smanjiti na sledeći način:
long fib(long a, long b, short n);
{ if(n==2)return b;
else { b=a+b; a=b-a; n--; return fib(a,b,n); }
}
113
Ivan P. Stanimirović Uvod u programiranje
Primer. Rekurzivno izračunati Akermanovu funkciju A(n,x,y), koja je definisana na sledeći način:
A(n, x, y) = x+1, za n=0
A(n, x, y) = x, za n=1, y=0,
A(n, x, y) = 0, za n=2, y=0
A(n, x, y) = 1, za n=3, y=0
A(n, x, y) = 2, za n>3, y=0
A(n, x, y) = A(n-1, A(n, x, y-1), x), inače.
#include <stdio.h>
long aker(int,int,int);
void main()
{ int x,y,n;
printf("Unesit n"); scanf("%d",&n); printf("Unesit x");
scanf("%d",&x); printf("Unesit y"); scanf("%d",&y);
printf("A(%d,%d,%d)=%ld\n",n,x,y,aker(n,x,y));
}
long aker(int n, int x, int y)
{ int pom;
if(n==0)return(x+1); if(n==1 && y==0) return(x);
if(n==2 && y==0) return(0); if(n>3 && y==0) return(2);
else { pom=aker(n,x,y-1); return(aker(n-1,pom,x)); }
}
Primer. Koristeći rekurzivnu definiciju proizvoda dva prirodna broja napisati odgovarajuću funkciju.
#include <stdio.h>
long p(int a, int b)
{ if(b==1) return(a); return(a+p(a,b-1)); }
void main()
{ int x,y;
printf("Unesi dva prirodna broja "); scanf("%d%d",&x,&y);
printf("%d*%d=%ld\n",x,y,p(x,y));
}
Primer. Napisati rekurzivni program za izračunavanje sume cifara zadatog prirodnog broja.
#include <stdio.h>
int sumacif(long n)
{ if(!n)return(0); else return(n%10+sumacif(n/10)); }
void main()
{ long k;
printf("Unesi dug ceo broj "); scanf("%ld",&k);
printf("Suma cifara od %ld=%d\n",k,sumacif(k));
}
Primer. Napisati rekurzivni program za izračunavanje količnika dva prirodna broja na proizvoljan
broj decimala.
#include <stdio.h>
void kolicnik(int ind, int n, int m, int k)
{ if(ind) printf("%d.",n/m);
else printf("%d",n/m);
if(k) kolicnik(0,(n%m)*10,m,k-1); }
void main()
{ int n,m,k;
printf("Brojilac? "); scanf("%d",&n);
printf("Imenilac? "); scanf("%d",&m);
114
Ivan P. Stanimirović Uvod u programiranje
void main()
{ cout<<"----> "<<f()<<endl; }
115
Ivan P. Stanimirović Uvod u programiranje
Podaci o statusu
Lokalni podaci
Privremene promenljive koje generiše kompilator
Za smeštaj aktivacionih slogova koristi se jedna od sledeće tri strategije: statička, pomoću steka i
dinamička. U zavisnosti od toga koja je strategija primenjena zavisi da li će ill ne biti mogući
rekurzivni pozivi potprograma.
Kod statičkog smeštanja aktivacionih slogova, kompilator unapred rezerviše fiksan memorijski
prostor čiji se sadrzaj obnavlja kod svakog poziva potprograma. To znači da kod ovakvog smestanja
nisu mogući rekurzivni pozivi potprograma jer se kod svakog novog poziva potprograma gubi
informacija o prethodnom pozivu. Ovakva tehnika primenjuje se na primer kod realizacije kompilatora
za programski jezik FORTRAN, pa se u njemu zbog toga ne mogu koristiti rekurzije.
Kod strategije koja se zasniva na primeni steka za smeštaj aktivacionih slogova koristi se stek u
koji se za svaki poziv potprograma smešta jedan aktivacioni slog. Ova tehnika dozvoljava rekurziju jer
se kod svakog novog poziva potprograma generiše novi slog i smešta u stek. Na kraju potprograma
slog se izbacuje iz steka. To znači da je u toku izvršavanja programa ovaj stek dinamički zauzet
aktivacionim slogovima onih potprograma koji su trenutno aktivni. Od veličine memorijskog prostora
koji je dodeljen steku zavisi i dubina rekurzivnih poziva potprograma. Na slici ispod prikazana je
promena strukture steka u toku izvršavanja programa u kome se poziva rekurzivni potprogram za
izračunavanje Fibonačijevih brojeva za n = 4.
116
Ivan P. Stanimirović Uvod u programiranje
117
Ivan P. Stanimirović Uvod u programiranje
Treća, dinamička strategija sastoji se u tome da se za svaki poziv potprograma generiše aktivacioni
slog koji se smešta u poseban deo memorije nazvan Heap. U ovom slučaju aktivacioni slogovi
potprograma povezuju se u dinamičku strukturu podataka koja odgovara stablu poziva potprograma.
Očigledno je da i ova tehnika dozvoljava rekurziju.
Primer.
/* spoljasnji blok */
int a=2; printf("%d\n",a) /* 2 */
/* unutrašnji blok */
int a=3; print("%d\n",a); /* 3 */
118
Ivan P. Stanimirović Uvod u programiranje
printf("%d\n",a); /*2 */
Primer.
#include<stdio.h>
int a=7;
void main()
{ void f(void);
void g(void);
{ printf("%d\n",a); /* 7 */
f(); printf("%d\n",a); /* 8 */
g(); printf("%d\n",a); /* 8 */
}
void f()
{ printf("%d\n",a); /*7 */
a++; printf("%d\n",a); /* 8 */
}
void g()
{ int a=10;
printf("%d\n",a); /* 10 */
}
Promenljiva je globalna na nivou modula ako je deklarisana van svih funkcija u modulu.
memorijski prostor se trajno dodeljuje, a memorijska klasa te promenljive je extern. Globalnost je
određena mestom deklaracije. Globalna promenljiva može da bude maskirana lokalnom
promenljivom istog imena.
Da bi globalna promenljiva bila dostupna iz drugih modula, ona mora da se u tim modulima
definiše pomoću ključne reči extern.
Primer. Izrazom oblika
extern int a;
promenljiva a se ne deklariše, već definiše, tj. ne dodeljuje se memorijski prostor, nego se C
prevodilac informiše o tipu promenljive. Eksterna promenljiva se može inicijalizovati isključivo na
mestu svoje deklaracije.
Primer. Dat je sledeći program koji se nalazi u dve datoteke (dva modula). U datoteci modul1.c se
nalazi program
119
Ivan P. Stanimirović Uvod u programiranje
#include <stdio.h>
#include “modul2.c”
char c='w';
void main()
{ void f();void g();
printf("pre funkcije f: c= %c\n",c);
f(); printf("posle funkcije f: c= %c\n",c);
g(); printf("posle funkcije g: c= %c\n",c);
}
Promenljiva c je globalna, pa se njoj može pristupiti iz drugih modula pomoću ključne reči extern.
Neka je datoteka modul2.c sledećeg sadržaja
extern char c;
void f()
{ c = 'a'; }
void g()
{ char c='b'; }
Dobijaju se sledeći rezultati:
Pre funkcije f: c=w
Posle funkcije f: c=a
Posle funkcije g: c=a
Funkcija f menja vrednost eksterne promenljive c, a to mogu i druge funkcije iz ove datoteke
(modula).
Ako datoteka modul2.c ima sadržaj
f() { extern char c; c='a'; }
takođe se menja vrednost promenljive c. Međutim, to nebi mogle da učine druge funkcije iz datoteke
modul2.c.
Statičke promenljive se koriste u dva slučaja. U prvom slučaju, omogućava lokalnoj promenljivoj
da zadrži vrednost kada se završi blok u kome je deklarisana. Druga primena je u vezi sa globalnom
deklaracijom, i omogućuje mehanizam privatnosti globalnih promenljivih.
Primer. (1.primena)
#include<stdio.h>
void fun1()
{ static int x=0; int y=0;
printf("static=%d auto = %d\n",x,y); ++x,++y;
}
void main()
{ int i; for(i=0; i<3; ++i) fun1(); }
Izlaz je:
static=0 auto=0
static=1 auto=0
static=2 auto=0
Pored promenljivih, i funkcije mogu da se definišu kao extern ili static. Memorijska klasa extern
se uzima po definiciji. Statičke funkcije su dostupne samo funkcijama iz istog modula.
120
Ivan P. Stanimirović Uvod u programiranje
Primer.
register char c;
register int i;
Promenljiva deklarisana kao registarska takođe je i automatska. Ako nema slobodnih registara u
CPU, C prevodilac ne prepoznaje grešku.
Primer. Promenljiva i deklariše se kao registarska neposredno pre upotrebe u for petlji.
register int i;
for(i=0;i<5;++i) ...
Završetak bloka u kome je deklarisana registarska promenljiva oslobađa registar.
5.8.1. Životni vek objekata
Životni vek objekta: vreme u toku izvršavanja programa u kojem objekat postoji i za koje mu se
može pristupati. Na početku životnog veka, objekat se kreira, poziva se njegov konstruktor, ako ga
ima. Na kraju životnog veka se objekat uništava, poziva se njegov destruktor, ako ga ima.
5.8.2. Vrste objekata po životnom veku
Po životnom veku, objekti se dele na:
statičke, automatske, dinamičke, tranzijentne (privremene).
Vek atributa klase = vek objekta kome pripadaju.
Vek formalnog argumenta = vek automatskog objekta.
Formalni parametri se inicijalizuju vrednostima stvarnih argumenata.
Statički i automatski objekti
Automatski objekat je lokalni objekat koji nije deklarisan kao static.
Životni vek: od njegove definicije, do napuštanja oblasti važenja.
Kreira se iznova pri svakom pozivu bloka u kome je deklarisan.
Prostor za automatske objekte se alocira na stack-u.
Statički objekat je globalni objekat ili lokalni deklarisan kao static.
Životni vek: od izvršavanja definicije do kraja izvršavanja programa.
Globalni statički objekti:
kreiraju se samo jednom, na početku izvršavanja programa,
kreiraju se pre korišćenja bilo koje funkcije ili objekta iz istog fajla,
nije obavezno da se kreiraju pre poziva funkcije main(),
prestaju da žive po završetku funkcije main().
Lokalni statički objekti počinju da žive pri prvom nailasku toka programa na njihovu
definiciju.
Primer.
int a=1;
void f() {
int b=1; // inicijalizuje se pri svakom pozivu
static int c=1; // inicijalizuje se samo jednom
cout<<"a="<<a++<<" b="<<b++<<" c="<<c++<<endl;
}
void main() {
while (a<3) f();
}
izlaz:
a = 1 b = 1 c = 1
a = 2 b = 1 c = 2
121
Ivan P. Stanimirović Uvod u programiranje
Pojam struktura podataka, nizova, slogova, skupova i datoteka je poznat i prisutan u višim
programskim jezicima od samog njihovog nastanka. U okviru strukturnih tipova podataka, vrednosti
koje tip obuhvata definisane su kao jednorodne ili raznorodne strukture podataka. U jeziku Pascal
postoji mogućnost definisanja strukturnih tipova koji omogućavaju rad sa nizovima, slogovima,
skupovima i datotekama. Skupovi se kao strukturni tipovi podataka ređe sreću kod drugih programskih
jezika, dok su nizovi, slogovi i datoteke postali standardni koncept, prisutan u mnogim programskih
jezicima (Ada, C).
PASCAL omogućava da rang za indeks niza može biti odabran od strane programera, jedina
restrikcija je rang indeksa mora da bude diskretan primitivni tip.
Za opis ovih struktura u nekim programskim jezicima se koristi ključna reč array. Takav je slučaj u
jeziku PASCAL. Opšti oblik deklaracije niza u PASCALu je
array[<tip indeksa>] of <tip elemenata>;
Razmotrimo sledeći primer u jeziku PASCAL:
type VEKTOR = array [1..10] of real;
var A,B : VEKTOR;
Ovom definicijom definisan je tip VEKTOR, kao niz od 10 elemenata tipa real. Promenljive A i B
su deklarisane kao promenljive tipa VEKTOR. Svakoj od promenljivih A i B odgovara struktura
podataka koja se sastoji od 10 komponenti tipa real. Svakoj od komponenti vektora opisanog na ovaj
način može se pristupiti preko indeksa. U nekim jezicima (Pascal) koristi se i notacija sa uglastim
zagradama na primer A[3] i A[J]. U ovakvim slučajevima indeks može da bude definisan i kao
celobrojni izraz. Ove indeksirane promenljive mogu se u programu upotrebiti svuda gde se javljaju i
proste promenljive odgovarajućeg tipa. U datom primeru A(J) i B(J) su promenljive tipa real. Evo
nekih primera koji ilustruju upotrebu niza:
A[3]:= 0.0; - Trećem elementu vektora A dodeljuje se vrednost 0;
122
Ivan P. Stanimirović Uvod u programiranje
Nizovi mogu da imaju memorijsku klasu auto, extern, static, a ne mogu biti memorijske klase
register.
Nizovi se mogu inicijalizovati u naredbi deklaracije.
Primer. Posle inicijalizacije
123
Ivan P. Stanimirović Uvod u programiranje
float x[7]={-1.1,0.2,33.0,4.4,5.05,0.0,7.7};
dobija se
x[0]=-1.1, x[1]=0.2, … x[6]=7.7.
Lista elemenata koji se koriste za inicijalizaciju vektora može biti manja od broja njegovih
elemenata. Ako je niz memorijske klase static ili extern, njegovi preostali elementi postaju 0. U
slučaju da je niz memorijske klase auto, za ove vrednosti će biti neke vrednosti koje su zaostale od
ranije u delu memorije koja se koristi za smeštanje elemenata niza. Ako extern ili static niz nije
inicijalizovan, tada kompajler automatski inicijalizuje sve elemente na 0.
Ako je niz deklarisan bez preciziranja dužine, i pritom inicijalizovan, tada se dužina niza implictno
određuje prema broju inicijalizatora.
Na primer, izraz int a[]={3,4,5,6}; proizvodi isto dejstvo kao i izraz
int a[4]={3,4,5,6};
Primer. Deklaracije nizova.
Primeri.
Primer. Izračunati broj pojavljivanja svakog velikog slova u unetom tekstu.
#include <stdio.h>
#include <ctype.h>
void main()
{ int c,i, slova[26];
for(i=0;i<26;++i) slova[i]=0;
while((c=getchar()) !=EOF)
if(isupper(c)) ++slova[c-'A'];
for(i=0;i<26;++i)
124
Ivan P. Stanimirović Uvod u programiranje
{ if(i%6==0) printf("\n");
printf("%5c:%4d", 'A'+i, slova[i]);
}
printf("\n\n");
}
Primer. Napisati program kojim se izračunava n-ti stepen broja 2, gde je n<= 500, i traženi stepen
nema više od 200 cifara.
void main()
{ int i,n,d=0,j,p, x[200]; // d+1 je broj cifara u stepenu, p je prenos
printf("\n Unesi stepen --> "); scanf("%d",&n);
x[0]=1;
for(i=0; i<n; i++)
{ p=0;
for(j=0; j<=d; j++){x[j]=x[j]*2+p; p=x[j]/10; x[j] %=10; }
if(p!=0) { d++; x[d]=p; }
}
printf("%d. stepen broja 2 je ",n);
for(i=d; i>=0; i--)printf("%d",x[i]);
}
Primer. Binarno traženje.
Posmatra se sledeći matematički problem: zadat je uređen realni niz a[0]<a[1]<…<a[n-1] i realan
broj b; ustanoviti da li se b nalazi u nizu, i ako se nalazi odrediti indeks p za koji važi a[p]=b.
Najjednostavnije, ali i najneefikasnije je takozvano linearno pretraživanje: redom se upoređuju
elementi niza a sa brojem b, do prvog elementa niza a za koji je a[i]>=b. Ako je a[i]=b, tada je p = i
traženi indeks. Ako je a[i]>b, tada se broj b ne nalazi u nizu a.
Za brzo pretraživanje se koristi algoritam binarnog pretraživanja.
Pretpostavimo da postoji p[0, n-1] takav da je a[p] = b. Izaberemo srednji element niza a sa
indeksom s = (0+n-1)/2. Ako je a[s]=b, tada je p=s traženi indeks, a pretraživanje se prekida. Ako je
ispunjen uslov b < a[s], tada se indeks p nalazi u intervalu [0,s-1], a inače se nalazi u intervalu [s+1,n-
1]. U oba slučaja, prepolovljen je interval pretraživanja.
Napisati funkciju koja prema opisanom algoritmu određuje indeks onog elementa rastućeg niza a
koji je jednak zadatoj vrednosti b, a inače vraća rezultat -1.
#include<stdio.h>
void main()
{ float br, a[100];
int n,i,p;
int bintra(float a[], int n, float b);
printf("\nBroj elemenata? "); scanf("%d",&n);
printf("Elementi niza "); for(i=0; i<n; i++)scanf("%f", &a[i]);
printf("Jedan realan broj? "); scanf("%f",&br);
p=bintra(a, n, br);
printf("Pozicija broja %f u nizu je %d\n",br,p);
}
125
Ivan P. Stanimirović Uvod u programiranje
void formiraj(int a[], int b[], int c[], int m, int n, int *k)
{ int i=0,j=0,last;
last = ((a[0]<b[0])?a[0]:b[0])-1;
*k=0;
while(i<m || j<n)
if(i==m){ for(int l=j; l<n; l++)c[(*k)++]=b[l]; j=n;}
else if(j==n){ for(int l=i; l<m; l++)c[(*k)++]=a[l]; i=m; }
else if(a[i]<b[j])
{ if(a[i]!=last) {c[(*k)++]=a[i]; last=a[i];}
i++;
}
else if(b[j]<a[i])
{ if(b[j]!=last){ c[(*k)++]=b[j]; last=b[j]; }
j++;
}
else
{ if(a[i]!=last) {c[(*k)++]=a[i]; last=a[i];}
i++; j++;
}
}
void main()
{ int i,m,n,k;
126
Ivan P. Stanimirović Uvod u programiranje
citaj(a,&m); citaj(b,&n);
formiraj(a,b,c,m,n,&k);
for(i=0; i<k;i++)printf("c[%d] = %d\n",i,c[i]);
}
Primer. Postupkom Eratostenovog sita ispisati sve proste brojeve od 2 do n. Postupak se sastoji u
sledećem:
Formira se niz koji sadrži prirodne brojeve 2 do n.
Iz niza se izbacuju svi brojevi koji su deljivi sa 2, 3. Brojevi deljivi sa 4 su izbačeni zbog
deljivosti sa 2, i tako dalje.
U nizu ostaju prosti brojevi.
#include <stdio.h>
void main() {
int a[1001], n, i, j;
scanf("%d",&n);
for (i=2; i<=n; i++) a[i]=1;
for (i=2; i<=n; i++)
if (a[i]) {
j=2*i; while (j<=n) { a[j]=0; j+=i; }
}
for (i=2; i<=n; i++) if (a[i]) printf("%d\n",i);
}
Primer. Napisati funkciju za deljenje polja P na dva dela, pri čemu u polje P1 ulaze svi elementi polja
P veći od zadatog broja k, a u polje P2, svi elementi polja P manji od k. Elementi polja P1 i P2 treba
da budu sortirani.
#include<stdio.h>
#include<iostream.h>
void main(void){
int p[20],p1[20],p2[20],n,i,j,zadati,br1,br2;
#include <stdio.h>
127
Ivan P. Stanimirović Uvod u programiranje
bool mark[33];
int main() {
int n,i,k,a[33],v[33];
scanf("%d", &n);
for(i=0; i<n; i++) scanf("%d", &a[i]);
return 0;
}
Problem ranca
#include <cstdio>
128
Ivan P. Stanimirović Uvod u programiranje
d[0]=0;
uzeti[0]=0;
return 0;
}
Primer (C) Dat je skup S od n (n 100) različitih prirodnih brojeva od kojih ni jedan nije veći od 200.
Napisati program koji pronalazi jedan podskup A datog skupa S koji zadovoljava sledeća dva uslova:
a) Suma elemenata skupa A je deljiva sa tri;
b) Od svih podskupova skupa S koji zadovoljavaju osobinu a), podskup A ima najveću sumu
svojih elemenata.
Ulazni podaci se učitavaju iz fajla zad1.dat. U prvom redu fajla se nalazi broj n, a u nastavku
fajla se nalazi n elemenata skupa S (svaki element je naveden u posebnom redu fajla).
Program treba da napravi fajl zad1.res i u njega treba da upiše sumu elemenata podskupa A (u
prvom redu fajla) i sve elemente podskupa A (u nastavku fajla, svaki element se upisuje u posebnom
redu fajla).
Primer:
zad1.dat zad1.res
4 147
29 29
15 15
11 103
103
#include <stdio.h>
int main(){
FILE *f,*g;
int am1,am2,bm1,bm2,n,i,a[100],ost,i1,i2,i3,i4;
long sumaniza;
f=fopen("zad12.dat","r");
g=fopen("zad12.res","w");
fscanf(f,"%d",&n);
am1=am2=bm1=bm2=ost=0;
129
Ivan P. Stanimirović Uvod u programiranje
sumaniza=0;
i1=i2=i3=i4=-1;
for(i=0;i<n;i++)
{
fscanf(f,"%d",&a[i]);
if(((a[i]%3)==1)&&((am1==0)||(am1>a[i])))
{
am2=am1;
am1=a[i];
i1=i;
}
else if(((a[i]%3)==1)&&((am2==0)||(am2>a[i])))
{
am2=a[i];
i2=i;
}
if(((a[i]%3)==2)&&((bm1==0)||(bm1>a[i])))
{
bm2=bm1;
bm1=a[i];
i3=i;
}
else if(((a[i]%3)==1)&&((bm2==0)||(bm2>a[i])))
{
bm2=a[i];
i4=i;
}
sumaniza+=a[i];
ost=((ost+a[i])%3);
}
if(((ost==1)&&(i1==-1)&&(i4==-1))||
((ost==2)&&(i2==-1)&&(i3==-1)))
{
fprintf(g,"0\n0\n");
fclose(f);
fclose(g);
return 0;
}
if(ost==0)
{
fprintf(g,"%ld\n",sumaniza);
for(i=0;i<n;i++)
fprintf(g,"%d\n",a[i]);
}
else if(ost==1)
{
if(am1<bm1+bm2)
{
fprintf(g,"%ld\n",sumaniza-am1);
for(i=0;i<n;i++)
if(i!=i1)
fprintf(g,"%d\n",a[i]);
}
else
{
fprintf(g,"%ld\n",sumaniza-bm1-bm2);
for(i=0;i<n;i++)
if((i!=i3)&&(i!=i4))
fprintf(g,"%d\n",a[i]);
}
}
130
Ivan P. Stanimirović Uvod u programiranje
else
{
if(bm1<am1+am2)
{
fprintf(g,"%ld\n",sumaniza-bm1);
for(i=0;i<n;i++)
if(i!=i3)
fprintf(g,"%d\n",a[i]);
}
else
{
fprintf(g,"%ld\n",sumaniza-am1-am2);
for(i=0;i<n;i++)
if((i!=i1)&&(i!=i2))
fprintf(g,"%d\n",a[i]);
}
}
fclose(f);
fclose(g);
return 0;
}
131
Ivan P. Stanimirović Uvod u programiranje
if(j>=0) grupa[j]=1;
}
while(j>=0);
printf("\nMinimalna razlika =
%f\n",minrazlika);
printf("Prva grupa ima sledece tegove:\n");
for(i=0; i<n; i++) if(grupa1[i])printf("%f ",teg[i]);
printf("\nUkupna masa tegova prve grupa je %f",
minsuma1);
printf("\nDruga grupa ima sledece tegove:\n");
for(i=0; i<n; i++) if(!grupa1[i])printf("%f ",teg[i]);
printf("\nUkupna masa tegova druge grupa je %f",
(suma-minsuma1));
}
Primer. Pretpostavimo da želite da postavite broj sobe na vratima. U prodavnici je moguće kupiti
skup plastičnih cifara. Svaki skup sadrži po jednu cifru od 0 do 9. Broj sobe je između 1 i 1,000,000.
Odrediti koliko skupova cifara je potrebno kupiti u prodavnici da bi ste ispisali broj sobe, imajući u
vidu da 6 možete iskoristiti i kao 9 i obrnuto. U prvom redu datoteke zad1.in se nalazi broj n, a u
ostalih n redova po jedan broj koji označava broj koji bi trebalo ispisati. U datoteci zad1.out upisati
minimalni broj skupova cifara koji uz pomoć kojih možemo ispisati dati broj.
zad1.in zad1.out
4 2
122 2
9999 l
12635 6
888888
Primer. U prvom redu datoteke 'zadl.in' nalazi se ceo broj n (1 n 1000). U svakom od sledećih n
redova nalaze se po dva cela broja x i y (-10000 x,y 10000) koji predstavljaju koordinate tačke u
ravni. Napisati program koji u datoteku 'zadl.out' upisuje, na dve decimale, rastojanje od koordinatnog
početka tačke koja je najbliža koordinatnom početku. Iza rastojanja, odvojeno prazninom, upisati redni
broj te najbliže tačke u datoteci.
zad1.in zad1.out
7 5.00 5
-9 12
-12 -16
5 12
15 8
3 4
-8 -6
20 -15
Primer. Meteorološka stanica meri temperaturu jednom u minutu. Stanica ima termometar koji ne daje
uvek tačne rezultate pri merenju temperature. Zbog nedostatka sredstava, odlučeno je da se umesto
novog termometra finansira izrada programa koji uklanja netačne rezultate merenja i kao rezultat daje
prosečnu temperaturu. Merenje se računa u netačno u dva slučaja:
a. Izmerena temperatura je manja od-50 stepeni;
b. Izmerena temperatura se od svake od temperatura merenih u prethodna 2 minuta i
sledeća dva minuta razlikuje za više od 2.
Napisati program koji za zadati niz izmerenih temperatura izračunava srednju vrednost ispravnih
temperatura.
U ulaznoj datoteci 'zad2.in' dati su broj n (1 n 1000) koji predstavlja broj merenja, kao i brojevi t1,
..., tn koji predstavljaju izmerene vrednosti (- 60 ti 50, i {1,...,n}). U izlaznu datoteku 'zad2.out'
upisati, na dve decimale, srednju vrednost ispravno izmerenih temperatura.
132
Ivan P. Stanimirović Uvod u programiranje
zad2.in zad2.out
5 12.00
9 11 12 13 15
7 0.16
0 0 0 2 5 0 10
Napomenimo da je izraz *(a+i) ekvivalentan sa a[i]. Takođe, može se pisati p = &(*(a+i)) umesto
izraza p = a + i, odnosno p = &a[i].
Primer. Još jedan način sumiranja nizova.
p=a; sum=0;
for(i=0;i<N;++i) sum += p[i];
Međutim, postoji razlika između pointera i nizova. Kako je ime niza a konstantni pointer, a ne
promenljiva, ne mogu se koristiti izrazi
a = p++a a+=2.
To znači da se adresa niza ne može menjati.
Primer. Napisati program koji transformiše niz celih brojeva tako da na početku budu negativni a na
kraju nenegativni elementi tog niza.
#include<stdio.h>
void main(void)
{ int niz[100], p,i,k,n;
printf("\nBroj elemenata --> "); scanf("%d",&n);
for(i=0; i<n; i++)
{ printf("niz[%d]=--> ",i+1); scanf("%d",niz+i); }
133
Ivan P. Stanimirović Uvod u programiranje
p=0; k=n-1;
while(p<k)
{ while(niz[p]<0 && p<k)p++;
while(niz[k]>=0 && p<k)k--;
if(p<k)
{ int pom=niz[p]; niz[p]=niz[k]; niz[k]=pom; }
}
for(i=0; i<n; i++)printf("niz[%d] = %d ",i,niz[i]); printf("\n");
}
Dato je jedno rešenje koje koristi ime niza kao pokazivač.
#include<stdio.h>
void main(void)
{ int niz[100], *p,*k,i,n;
printf("\nBroj elemenata --> "); scanf("%d",&n);
for(i=0; i<n; i++){printf("niz[%d]= --> ",i+1); scanf("%d",niz+i); }
p=niz; k=niz+n-1;
while(p<k)
{ while(*p<0 && p<k)p++;
while(*k>=0 && p<k)k--;
if(p<k) { int pom; pom=*p; *p=*k; *k=pom; }
}
for(i=0; i<n; i++)printf("niz[%d]= %d ",i,*(niz+i)); printf("\n");
}
Neka je, za ovaj primer zadat broj elemenata n = 4, i neka su elementi -1,2,-3,4. Neka je vrednost
pokazivača p=&a[0] jednaka heksadekadnom broju 0x0012fdf0. Ako je program napisan u
programskom jeziku C++, tada svaka vrednost tipa int zauzima po 4 bajta, pa je vrednost pokazivača
k=&a[3] jednaka heksadekadnom broju 0x0012fdfc. Adrese i sadržaj lokacija koje su zauzete
zadatim elementima niza predstavljene su u sledećoj tabeli:
Element niza Adresa prvog bajta Adresa drugog bajta Adresa trećeg bajta Adresa četvrtog bajta
a[0] 0x0012fdf0= &a[0] 0x0012fdf1 0x0012fdf2 0x0012fdf3
a[1] 0x0012fdf4= &a[1] 0x0012fdf5 0x0012fdf6 0x0012fdf7
a[2] 0x0012fdf8= &a[2] 0x0012fdf9 0x0012fdfa 0x0012fdfb
a[3] 0x0012fdfc= &a[3] 0x0012fdfd 0x0012fdfe 0x0012fdff
Primer. Sortiranje niza pointerskom tehnikom. Kao algoritam izabrano je sortirane izborom
uzastopnih minimuma.
#include<stdio.h>
void upis(int *a, int *n)
{ int i;
printf("Broj elemenata? "); scanf("%d",n);
printf("Elementi? ");
for(i=0; i<*n; i++) scanf("%d",a+i);
}
void main()
134
Ivan P. Stanimirović Uvod u programiranje
Primer.
void main()
{ double a[2], *p, *q;
p=&a[0]; q=p+1;
printf("%d\n",q-p); /* 1 */
printf("%d\n",(int)q-(int)p); /* 8 */
}
135
Ivan P. Stanimirović Uvod u programiranje
Ako je niz x smešten počev od adrese 56006(=&x[0]), odrediti lokacije i elemente niza x na koji
ukazuju pti, pti+1, pti+2 i pti+3.
Rešenje. Dodavanje jedinice pokazivaču pti automatski uvećava adresu na koju on ukazuje za 2, jer
se radi o pokazivaču na tip int. Znači, pti, pti+1, pti+2 i pti+3 ukazuju redom na adrese 56006, 56008,
56010, 56012 i na elemente x[0], x[1], x[2], x[3] niza x.
Iz prethodnog primera zaključujemo
*(x+2)=x[2], x+2=&x[2].
Izraz *x+2 jednak je izrazu (*x)+2 i predstavlja uvećanje vrednosti nultog elementa niza x za 2.
136
Ivan P. Stanimirović Uvod u programiranje
void main ()
{ float *a; int n, i;
while (1) {
printf ("n? "); scanf ("%d", &n);
if (n < 0) break;
a=(float *)malloc(n*sizeof(float));
printf ("A? "); for (i=0; i<n; scanf ("%f", &a[i++]));
redukcija (a, &n);
a=(float *)realloc(a,n*sizeof(float));
printf ("A= "); for (i=0; i<n; printf("%f ", a[i++]));
printf ("\n\n");
}
}
Primer. Iz zadatog niza izbaciti sva pojavljivanja njegovog maksimalnog elementa. Zadatak uraditi
dinamičkom alokacijom memorije.
#include<stdio.h>
#include<stdlib.h>
void main()
{ int i,n,im,k=0;
float max, *a;
scanf("%d",&n);
137
Ivan P. Stanimirović Uvod u programiranje
a=(float *)malloc(n*sizeof(float));
for(i=0;i<n;scanf("%f",&a[i++]));
im=0; max=a[0];
for(i=1;i<n;i++) if(a[i]>max) { max=a[i];im=i; }
k=im-1;
for(i=im+1; i<n; i++) if(a[i]!=max)a[++k]=a[i];
a=(float *)realloc(a,(k+1)*sizeof(float));
for(i=0;i<=k;printf("a[%d]=%f ",i,a[i++]));
}
Primer. Učitavanje, sortiranje i ispis nizova pomoću potprograma.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n,*a;
a=(int *)malloc(2000*sizeof(int));
ucitaj(a,n);
SORT(&a,n);
ispisi(a,n);
return 0;
}
Bubble sort
#include <stdio.h>
#include <math.h>
void bubbleSort(float *a, int n)
{int i,j; float p;
j=(n-1);
while(j>=1)
{for(i=0;i<j;i++)
if(a[i]>a[i+1])
{ p=a[i]; a[i]=a[i+1]; a[i+1]=p; }
j=j-1;
}
}
void main()
{int i,n;float a[10];
138
Ivan P. Stanimirović Uvod u programiranje
scanf("%d",&n);
for(i=0;i<n;i++)scanf("%f",&a[i]);
bubbleSort(a,n);
for(i=0;i<n;i++) printf("%f ",a[i]);
}
#include <stdio.h>
#include <stdlib.h>
int main() {
int n,*a,**b;
a=(int *)malloc(2000*sizeof(int));
ucitaj(a,n);
b=&a;
SORT(&b,n);
ispisi(a,n);
return 0;
}
139
Ivan P. Stanimirović Uvod u programiranje
#include<stdio.h>
#include<stdlib.h>
int sadrzi(const float *s1, int n1, float b);
void dodaj(float **s1, int *n1, float b);
void presek(const float *s1, int n1, const float *s2, int n2,
float **s3, int *n3);
void unija(const float *s1, int n1, const float *s2, int n2,
float **s3, int *n3);
/* void razlika(const float *s1, int n1, const float *s2, int n2,
float **s3, int *n3); n*/
void citaj(float **s, int *n);
void pisi(const float *s, int n, const char *f);
void presek(const float *s1, int n1, const float *s2, int n2,
float **s3, int *n3)
{ int n=0,i1=0,i2=0;
float *s=(float *) malloc((n1<n2 ? n1 : n2)*sizeof(float));
while(i1<n1 && i2<n2)
if(s1[i1]<s2[i2])i1++;
else if(s1[i1]>s2[i2])i2++;
else s[n++]=s1[i1++],i2++;
*s3=(float *)realloc(s,(*n3=n)*sizeof(float));
}
void unija(const float *s1, int n1, const float *s2, int n2,
float **s3, int *n3)
{ int n=0, i1=0, i2=0;
float *s=(float *)malloc((n1+n2)*sizeof(float));
while(i1<n1 || i2<n2)
if(i1==n1) s[n++]=s2[i2++];
else if(i2==n2)s[n++]=s1[i1++];
else if(s1[i1]<s2[i2])s[n++]=s1[i1++];
else if(s2[i2]<s1[i1])s[n++]=s2[i2++];
else s[n++]=s1[i1++],i2++;
*s3=(float *)realloc(s,(*n3=n)*sizeof(float));
}
140
Ivan P. Stanimirović Uvod u programiranje
}
else *s1=0;
}
void pisi(const float *s, int n, const char *f)
{ int i;
putchar('{');
for(i=0;i<n; i++)
{ if(i>0) putchar(','); printf(f,s[i]); }
putchar('}');
}
void main()
{ float *s1, *s2, *s3;
int n1,n2,n3;
while(1)
{ citaj(&s1,&n1); if(n1<0)break;
citaj(&s2,&n2); if(n2<0)break;
printf("s1 "); pisi(s1,n1,"%.2f"); putchar('\n');
printf("s2 "); pisi(s2,n2,"%.2f"); putchar('\n');
presek(s1,n1,s2,n2,&s3, &n3);
printf("s1*s2 "); pisi(s3,n3,"%.2f"); putchar('\n');
unija(s1,n1,s2,n2,&s3, &n3);
printf("s1+s2 "); pisi(s3,n3,"%.2f"); putchar('\n');
free(s1); free(s2); free(s3);
}
}
Primer. Za svaku vrstu robe u magacinu beleži se njena šifra i količina, kao dva cela broja. Za
magacin A dati su nizovi sa i ka od na elemenata, sa značenjem da robe sa šifrom sa[i] ima u količini
ka[i], i da ukupno ima na vrsta robe u magacinu. Za magacin B dati su analogni podaci u nizovima sb i
kb od nb elemenata. Podaci o robi su uređeni po rastu šifara. Formirati nizove sz i kz koji daju podatke
o zbirnom stanju u magacinima A i B, i koji su takođe uređeni po siframa artikala. Koristiti dinamičku
alokaciju nizova.
#include<stdio.h>
#include<stdlib.h>
void main()
{ int *sa,*ka,*sb,*kb, *sz,*kz;
int i,ia,ib,iz,na,nb,nz;
printf("Broj vrsta robe u magacinu A? "); scanf("%d",&na);
sa=(int *)malloc(na*sizeof(int)); ka=(int *)malloc(na*sizeof(int));
for(i=0; i<na; i++)
{ printf("cifra i kolicina za %d. artikal? ",i);
scanf("%d%d", &sa[i], &ka[i]);
}
printf("Broj vrsta robe u magacinu B? "); scanf("%d",&nb);
sb=(int *)malloc(nb*sizeof(int)); kb=(int *)malloc(nb*sizeof(int));
for(i=0; i<nb; i++)
{ printf("cifra i kolicina za %d. artikal? ",i);
scanf("%d%d", &sb[i], &kb[i]);
}
sz=(int *)malloc((na+nb)*sizeof(int)); kz=(int *)malloc((na+nb)*sizeof(int));
ia=ib=iz=0;
while (ia<na && ib<nb)
if(sa[ia]<sb[ib])
{ sz[iz]=sa[ia]; kz[iz++]=ka[ia++]; }
else if(sa[ia]>sb[ib])
{ sz[iz]=sb[ib]; kz[iz++]=kb[ib++]; }
else // sa[ia]=sb[ib]
{ sz[iz]=sa[ia]; kz[iz++]=ka[ia++]+kb[ib++]; }
while(ia<na)
{ sz[iz]=sa[ia]; kz[iz++]=ka[ia++]; }
while(ib<nb)
{ sz[iz]=sb[ib]; kz[iz++]=kb[ib++]; }
141
Ivan P. Stanimirović Uvod u programiranje
nz=iz-1;
sz=(int *)realloc(sz,nz*sizeof(int));
kz=(int *)realloc(kz,nz*sizeof(int));
for(i=0;i<nz; printf("sifra %d kolicina %d\n",sz[i],kz[i++]));
free(sa); free(sb); free(ka); free(kb); free(sz); free(kz);
}
Primer. Napisati program kojim se zamenjuje prvo pojavljivanje stringa s1 u stringu s stringom s2.
Stringovi s1 i s2 mogu biti različitih dužina. Sve stringove pamtiti u dinamičkoj zoni memorije i za
svaki od njih rezervisati onoliko memorijskog prostora koliko je neophodno.
#include <stdio.h>
#include <stdlib.h>
void main()
{ char *s,*s1,*s2,c;
int n,n1,n2,i,j,k;
printf("Duzine stringova = ? "); scanf("%d%d%d",&n,&n1,&n2);
scanf("%c",&c);
s=(char *)malloc(n+1); s1=(char *)malloc(n1+1); s2=(char *)malloc(n2+1);
printf("Unesite stringove\n");
gets(s); gets(s1); gets(s2);
//Pronalazi s1 u s
//i je pocetna adresa od koje trazimo u s,
// j je broj pronadjenih znakova iz s1 u s
for(i=0,j=0;i<=n-n1 && j<n1; )
{ if(s[i+j]==s1[j])j++;
else {j=0; i++; }
}
Test primer.
Duzine strigova = ? 9 3 2
Unesite stringove
rat i mir
mir
mi
Transformisani string je rat i mi
142
Ivan P. Stanimirović Uvod u programiranje
143
Ivan P. Stanimirović Uvod u programiranje
U našem slučaju, vrste matrice a date su izrazima a[0], a[1] i a[2]. S obzirom na poznata svojstva
jednodimenzionalnih nizova, važe sledeće jednakosti:
a[0]=&a[0][0], a[1]=&a[1][0], a[2]=&a[2][0] .
Osim toga, važe sledeće jednakosti:
a[i]=&a[i][0], a[i] + j = &a[i][j], a[i][j] = *( a[i] + j), &a[i][j] = a+i*2+j.
Takođe je
a[j][k]=*(a+j*duzina_vrste +k).
void main()
{ int m,n;
matrica a,b,c;
void pisi(int, int, matrica);
void citaj(int &, int &, matrica);
void saberi(int, int, matrica, matrica,matrica);
void rotiraj(int, int, matrica);
void transponuj(int, int, matrica);
citaj(m,n,a);
citaj(m,n,b);
saberi(m,n,a,b,c); pisi(m,n,c);
rotiraj(m,n,c); pisi(m,n,c);
transponuj(m,n,c); pisi(n,m,c);
}
void citaj(int &k, int &l, matrica x)
{ int i,j;
scanf("%d%d",&k,&l);
for(i=0;i<k; i++)
for(j=0; j<l; j++)
scanf("%f",x[i]+j);
}
144
Ivan P. Stanimirović Uvod u programiranje
void main()
{ int m,n,i,j, min, ind; int a[10][10], b[10], p[10];
printf("Dimenzije matrice?: "); scanf("%d%d", &m,&n);
printf("\nElementi matrice?: ");
for(i=0; i<m; i++)
for(j=0; j<n; j++) scanf("%d", &a[i][j]);
for(i=0; i<m; i++)
minunizu(a[i], n, &b[i], &p[i]);
// Moze i minunizu(a[i], n, b+i, p+i);
minunizu(b,m, &min, &ind);
i=ind; j=p[ind];
printf("Minimal-ni je na poziciji [%d,%d] i jednak je %d\n",i,j,min);
}
145
Ivan P. Stanimirović Uvod u programiranje
Primer. Napisati program koji najefikasnijim postupkom izračunava n-ti stepen matrice A. Takav
stepen se može izračunati rekurzivno sa najmanjim brojem matričnih množenja na sledeći način:
A, n=1
An = (Ak)2, n = 2k
A(Ak)2, n = 2k+1
#include<stdio.h>
void mnozi(int n, int a[10][10], int b[10][10], int c[10][10])
{ int i,j,k;
int s;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{ s=0;
for(k=0; k<n; k++) s+=a[i][k]*b[k][j];
c[i][j]=s;
}
}
146
Ivan P. Stanimirović Uvod u programiranje
void main()
{ int n,m;
int a[10][10], b[10][10];
printf("Red kvadratne matrice = "); scanf("%d", &n);
citaj(n,a);
printf("Stepen = "); scanf("%d", &m);
stepen(m,n,a,b); pisi(n,b);
}
Primer. Svaki element matrice koji predstavlja maksimum svoje vrste i minimum svoje kolone
naziva se sedlasta tačka. Pronaći sve sedlatse tačke u zadatoj matrici.
#define MAXX 100
#define MAXY 100
#include<stdio.h>
#include<conio.h>
#include<limits.h>
#include<stdlib.h>
int a[MAXX][MAXY], mini[MAXX], maxi[MAXY],m,n;
void main()
{ int i,j;
printf("Dimenzije matrice? "); scanf("%d%d",&m,&n);
printf("Elementi?\n");
for(i=0;i<m;i++)
for(j=0;j<n;j++) scanf("%d", &a[i][j]);
for(i=0;i<m;i++)maxi[i]=maximum(i);
for(j=0;j<n;j++)mini[j]=minimum(j);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
147
Ivan P. Stanimirović Uvod u programiranje
148
Ivan P. Stanimirović Uvod u programiranje
a[i][j]>a[i][j+1]);
else if(j==n-1)
return(a[i][j]>a[i-1][j] && a[i][j]>a[i][j-1] &&
a[i][j]>a[i+1][j]);
else return(a[i][j]>a[i-1][j] && a[i][j]>a[i][j-1] &&
a[i][j]>a[i+1][j] && a[i][j]>a[i][j+1]);
}
void main()
{ int vrh(int i, int j, int m, int n, int a[10][10]);
int visina(int i, int j, int m, int n, int a[10][10]);
int i,j,a[10][10], vrhovi[25],visine[25], pom,k=0,m,n;
scanf("%d%d", &m,&n);
for(i=0;i<m;i++)
for(j=0;j<n;j++) scanf("%d",&a[i][j]);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
if(vrh(i,j,m,n,a))
{ vrhovi[k]=a[i][j]; visine[k]=visina(i,j,m,n,a); k++;}
149
Ivan P. Stanimirović Uvod u programiranje
for(i=0;i<k-1;i++)
for(j=i+1;j<k;j++)
if(visine[i]<visine[j])
{ pom=visine[i]; visine[i]=visine[j]; visine[j]=pom;
pom=vrhovi[i]; vrhovi[i]=vrhovi[j]; vrhovi[j]=pom;
}
printf("\nNiz vrhova i visina:\n");
for(i=0;i<k;i++)printf("Vrh: %d visina: %d\n",vrhovi[i],visine[i]);
}
Primer. Dat je niz a0,... , ak-1 celih brojeva. Napisati program kojim se formira kvadratna matrica reda
n takva da je niz ai, i = 0,... , k-1 upisan spiralno u tu matricu u smeru kretanja kazaljke na satu.
Ukoliko niz ima manje od n2 elemenata, posle svakih k upisanih elemenata početi upisivanje od
prvog.
#include <stdio.h>
int dodi[4]={0,1,0,-1};
int dođ[4]={1,0,-1,0}; /* desno, dole, levo, gore */
void main()
{ int a[10], k, mat[20][20], n, n1, smer, i,j,br,pombr,broj;
printf("Broj elemenata u nizu? "); scanf("%d", &k);
printf("elementi niza?\n"); for(i=0;i<k;i++) scanf("%d",&a[i]);
printf("Dimenzija matrice? "); scanf("%d", &n);
n1=n; i=j=br=smer=0;
for(broj=1; broj<=n*n; broj++)
{ /* ciklus za postavljanje elemenata u matricu */
mat[i][j]=a[br];
/* i, j su indeksi matrice, a br je indeks niza */
br++;
if(br==k)br=0; /* kad br dođe do k, vraca se na 0 */
i+=dodi[smer]; j+=dođ[smer];
if(i==n1 || j==n1 || (i==n-n1&&smer>0) || j==n-n1-1)
/* sada se menja smer dodavanja */
{ if(i==n1) i=n1-1; if(j==n1) j=n1-1;
if(i==n-n1 && smer>0) i=n-n1+1;
if(j==n-n1-1)j=n-n1;
smer++; /* sledeci smer */
if(smer==4) /* upotrebljeni su svi smerovi */
{ smer=0; /* ponovo na desno */
n1--;
}
i+=dodi[smer]; j+=dođ[smer];
}
}
for(i=0;i<n;i++)
{for(j=0;j<n;j++) printf("%d ",mat[i][j]); printf("\n"); }
}
Primer. Neka je dato n koncentričnih krugova takvih da svaki od njih ima m otvorenih vrata.
Prolaskom kroz bilo koja vrata dobija se izvestan broj nenegativnih poena. Ako je data matrica A
dimenzije nm čiji element a[i,j] označava broj poena koji se osvaja prolaskom kroz j-ta vrata i-tog
kruga, napisati program koji trasira put kroz n vrata tako da se sakupi dati broj poena s.
Kroz svaka vrata se prolazi tačno jedanput.
program krugovi;
type opseg=0..10;
niz=array[opseg] of integer;
matrica=array[opseg,opseg] of integer;
var a:matrica;
150
Ivan P. Stanimirović Uvod u programiranje
x:niz;
i,j,m,n,s:integer;
q:boolean;
function suma(x:niz; k:opseg):integer;
var i,j,s1:integer;
begin
s1:=0;
for i:=1 to k do s1:=s1+a[i,x[i]];
suma:=s1;
end;
procedure trazi(k:opseg);
var i:opseg;
begin
i:=1;
while (i<=n) and not q do
begin
x[k]:=i;
if suma(x,k)<=s then
begin
if (k=n) and (suma(x,k)=s) then
begin
pisi(x,n); q:=true;
end
else trazi(k+1);
end;
i:=i+1;
end;
end;
begin
write('Uneti broj krugova i broj vrata na svakom krugu ');
readln(n,m); write('Unesi sumu '); readln(s);
writeln('Unesi broj poena na vratima ');
for i:=1 to n do
begin
for j:=1 to m do read(a[i,j]); readln;
end;
q:=false;
trazi(0); if not q then writeln('Nema resenja ');
end.
Primer. Problem n dama.
#include <stdio.h>
int a[50][50],n;
void cepaj(int);
int radi(int,int);
void ispis();
void main()
151
Ivan P. Stanimirović Uvod u programiranje
{ scanf("%d",&n); radi(0); }
void ispis()
{
int i,j;
for (i=0; i<n; i++)
{ for (j=0; j<n; j++) printf("%d ",a[i][j]); printf("\n"); }
printf("\n\n\n");
}
void radi(int j)
{ for (int i=0; i<n; i++)
if (cepa(i,j))
{ a[i][j]=1;
if (j<n-1) dalje(j+1);
else ispis();
a[i][j]=0;
}
}
int main()
{ int n,potezi[50],x[50],y[50],pomx[50],pomy[50],nizIndexa[50],i,j;
scanf("%d",&n);
for(i=0;i<n;i++)scanf("%d%d",&x[i],&y[i]);
potezi[0]=0; potezi[1]=0;
int min,rez;
for(i=2;i<=n;i++)
152
Ivan P. Stanimirović Uvod u programiranje
{ min=2000000000;
nizIndexa[0]=0;
for(j=1;j<i;j++)
nizIndexa[j]=nizIndexa[j-1]+1;
while(nizIndexa[0]<=(n-i))
{ rez=0;
for(j=0;j<i;j++)
{pomx[j]=x[nizIndexa[j]]; pomy[j]=y[nizIndexa[j]]; }
rez+=jedanRed(pomx,i)+jedanRed(pomy,i);
if(rez<min) min=rez;
plusOne(nizIndexa,n,i);
}
potezi[i]=min;
}
for(i=0;i<=n;i++)printf("%4d", potezi[i]);
printf("\n");
return 0;
}
Primer. Na obali nekog ostrva nalazi se n gradova označenih brojevima od 0 do n-1. Oko celog ostrva
je izgrađen autoput koji prolazi kroz svaki od gradova. U nizu d su data rastojanja između gradova,
tako da d[i] predstavlja dužinu autoputa između gradova i i i+1 (d[n-1] predstavlja dužinu puta između
grada n-1 i 0). Napisati program koji za sve gradove određuje niz najkraćih rastojanja do ostalih
gradova.
#include<stdio.h>
float rastojanje(int i, int j, int n, float d[10])
{ float rl,rd;
int k;
rl=rd=0;
for(k=i; k<=j-1;k++)rl=rl+d[k];
for(k=j; k<=n-1; k++)rd=rd+d[k];
for(k=0;k<=i-1;k++)rd=rd+d[k];
if(rl<rd) return(rl);
else return(rd);
}
void main()
{ float rastojanje(int i, int j, int n, float d[10]);
int k,n,i,j;
float d[10], rastojanja[10][10];
printf("Broj gradova? "); scanf("%d",&n);
printf("Rastojanja?\n"); for(k=0;k<n;k++) scanf("%f",&d[k]);
for(i=0; i<n-1;i++)
for(j=i+1;j<n;j++)
{ rastojanja[i][j]=rastojanje(i,j,n,d);
rastojanja[j][i]=rastojanja[i][j];
}
for(j=0;j<n;j++)rastojanja[j][j]=0;
for(i=0;i<=n-1;i++)
{for(j=0;j<=n-1; j++)
printf("Rastojanje između %d i %d = %f\n",i,j,rastojanja[i][j]);
printf("\n");
}
}
51. (PASCAL) Napisati funkciju kojom se utvrdjuje da li je zadata matrica A dimenzija m x n
ortonormirana. Matrica je ortonormirana ako je skalarni proizvod svakog para različitih vrsta jednak 0,
a skalarni proizvod vrste sa samom sobom 1.
Ulaz: Dva pozitivna cela broja m i n koji predstavljaju dimenzije matrice.
Izlaz: Tekst Matrica je ortonormirana, ako je matrica ortonormirana, a inače tekst Matrica nije ortonormirana.
153
Ivan P. Stanimirović Uvod u programiranje
program ortomormirana;
type opseg=1..10;
niz=array[opseg]of real;
matrica=array[opseg]of niz;
var a:matrica; m,n:opseg;ort:boolean;
begin
readln(m,n);
ucitaj(m,n,a);
ort:=isort(m,n,a);
if ort then writeln('Matrica je ortonormirana ')
else writeln('Matrica nije ortonormirana ');
end.
Test primeri:
3 3 3 3
1 0 0 1 1 0
0 1 0 0 1 0
0 0 1 0 0 1
Matrica je ortonormirana Matrica nije ortonormirana
154
Ivan P. Stanimirović Uvod u programiranje
Napisati program kojim se formira i ispisuje matrica iz koje se vidi koji gradovi imaju vezu sa
najmanje jednim presedanjem.
Ulaz: Matrica A(nn).
procedure pisiveze(brgradova:integer;a:matrica);
var i,j:integer;
begin
writeln('Matrica veze (1-da, 0-ne)');
for i:=1 to brgradova do
begin
for j:=1 to brgradova do
if a[i,j] then write('1':2)
else write('0':2);
writeln;
end;
end;
begin
write('Broj gradova? '); readln(n);
writeln('Veze između gradova?');
citajveze(n,veza);
pro(n,veza,veza,jednopres);
155
Ivan P. Stanimirović Uvod u programiranje
pisiveze(n,jednopres);
end.
Test primer:
Broj gradova? 3
Unesi veze (1-da,0-ne) izmedju gradova
1 0 1
0 1 0
0 1 1
Matrica veze (1-da,0-ne)
1 1 1
0 1 0
0 1 1
116. (PASCAL) Raspoređeno je 15 kuglica na sledeći način: u prvoj vrsti se nalazi 5 kuglica, u drugoj
4, u trećoj 3, u četvrtoj 2 i u petoj 1. Obeležiti svaku kuglicu jednim od brojeva 1,...,15, tako da svaka
kuglica ima jedinstven broj i da važi jednakost
aij=|ai-1,j-ai-1,j+1|, i= 2,3,4,5, j=1,5-i+1.
program kuglice;
type niz=array[1..15] of integer;
matrica =array[1..5,1..5] of integer;
var i,j,k,l,m,br,indu :1..15;
upotrebljen:niz;
a:matrica;
procedure ispis(a:matrica);
var i,j:1..5;
begin
for i:=1 to 5 do
begin
for j:=1 to 5-i+1 do write(a[i,j]:3);writeln
end;
end;
begin
for i:=1 to 15 do
for j:=1 to 15 do
for k:=1 to 15 do
for l:=1 to 15 do
for m:=1 to 15 do
begin
a[1,1]:=i;a[1,2]:=j;
a[1,3]:=k;a[1,4]:=l;a[1,5]:=m;
for br:=1 to 5 do
upotrebljen[br]:=a[1,br];
indu:=5;
for br:=1 to 4 do
begin
a[2,br]:=abs(a[1,br]-a[1,br+1]);
indu:=indu+1;
156
Ivan P. Stanimirović Uvod u programiranje
upotrebljen[indu]:=a[2,br];
end;
for br:=1 to 3 do
begin
a[3,br]:=abs(a[2,br]-a[2,br+1]);
indu:=indu+1;
upotrebljen[indu]:=a[3,br];
end;
for br:=1 to 2 do
begin
a[4,br]:=abs(a[3,br]-a[3,br+1]);
indu:=indu+1;
upotrebljen[indu]:=a[4,br];
end;
a[5,1]:=abs(a[4,1]-a[4,2]);
indu:=indu+1;
upotrebljen[indu]:=a[5,1];
if razliciti(indu,upotrebljen) then
begin
writeln;writeln;
ispis(a);readln;
end;
end;
end.
Test primer:
Resenje 1 Resenje 2
6 14 15 3 13 13 3 15 14 6
8 1 12 10 10 12 1 8
7 11 2 2 11 7
4 9 9 4
5 5
117. (PASCAL) Zadata je crno-bela matrica (0 definiše belu boju, a 1 crnu). Napisati program kojim
se bele oblasti te matrice boje različitim bojama (boje se definišu sa 2,3,...). Ispisati obojenu matricu.
program bojenje;
const k=20; l=20;
type matrica = array[1..k,1..l] of integer;
var m,n,i,j,boja:integer;
tabla:matrica;
prx,pry:array[1..4] of integer;
procedure ispis(m,n:integer; a:matrica);
var i,j:integer;
begin
for i:=1 to m do
begin
for j:=1 to n do write(a[i,j]:3);
writeln;
end;
end;
procedure upis(m,n:integer; var a:matrica);
var i,j:integer;
begin
for i:=1 to m do
begin
for j:=1 to n do read(a[i,j]);readln;
end;
end;
function moze(x,y:integer; a:matrica):boolean;
begin
157
Ivan P. Stanimirović Uvod u programiranje
if(x>=1)and(x<=m)and(y>=1)and(y<=n) then
moze:=a[x,y]=0
else moze:=false;
end;
procedure oboji(x,y,boja:integer; var a:matrica);
var i:integer;
begin
a[x,y]:=boja;
for i:=1 to 4 do
if moze(x+prx[i],y+pry[i],a) then
oboji(x+prx[i],y+pry[i],boja,a)
end;
begin
write('Dimenzije? '); readln(m,n);
upis(m,n,tabla);
prx[1]:=-1; pry[1]:=0; { gore }
prx[2]:=0; pry[2]:=1; { desno }
prx[3]:=1; pry[3]:=0; { dole }
prx[4]:=0; pry[4]:=-1; { levo }
boja:=1;
for i:=1 to m do
for j:=1 to n do
if tabla[i,j]=0 then
begin
boja:=boja+1; oboji(i,j,boja,tabla);
end;
ispis(m,n,tabla);
end.
Test primer:
Dimenzije? 3 4 Dimenzije? 4 5
0 0 1 0 0 0 0 0 1
0 1 1 0 0 0 1 1 0
0 0 0 1 0 0 0 0 0
2 2 1 3 1 0 0 0 1
2 1 1 3 2 2 2 2 1
2 2 2 1 2 2 1 1 2
2 2 2 2 2
1 2 2 2 1
118. (PASCAL) Napisati program kojim se određuje minimalan broj (P,Q) konja kojima se mogu
kontrolisati sva polja šahovske table dimenzije mn. (P,Q) konj je figura koja se u jednom skoku
premešta za P polja po horizontali i Q polja po vertikali. Običan šahovski konj je (1,2) konj.
program konj;
const k=30; l=30;
type matrica =array[1..k,1..l] of boolean;
var m,n,p,q,x,y,mink:integer;
tabla:matrica;
skokpox,skokpoy:array[1..8] of integer;
function moze(x,y:integer):boolean;
begin
if (x>=1)and(x<=m)and(y>=1)and(y<=n) then
moze := not tabla[x,y]
else moze:=false
end;
procedure konjana(x,y:integer);
var i:integer;
begin
tabla[x,y]:=true;
158
Ivan P. Stanimirović Uvod u programiranje
for i:=1 to 8 do
if moze(x+skokpox[i],y+skokpoy[i]) then
konjana(x+skokpox[i],y+skokpoy[i]);
end;
begin
write('p,q= ? ');readln(p,q); write('m,n= ? ');
readln(m,n);
for x:=1 to m do
for y:=1 to n do tabla[x,y]:=false;
skokpox[1]:=-q;skokpoy[1]:=p;skokpox[2]:=-p;
skokpoy[2]:=q;skokpox[3]:=p; skokpoy[3]:=q;
skokpox[4]:=q; skokpoy[4]:=p;
skokpox[5]:=q; skokpoy[5]:=-p;
skokpox[6]:=p; skokpoy[6]:=-q;
skokpox[7]:=-p; skokpoy[7]:=-q;
skokpox[8]:=-q; skokpoy[8]:=-p;
mink:=0;
for x:=1 to m do
for y:=1 to n do
if not tabla[x,y] then
begin
konjana(x,y); mink:=mink+1;
end;
writeln('Minimalni broj konja je ',mink);
end.
Test primer:
p,q= ? 1 1 p,q= ? 3 3
m,n= ? 8 8 m,n= ? 8 8
minimalan broj konja je 2 minimalan broj konja je 18
p,q= ? 1 3 p,q= ? 4 4
m,n= ? 8 8 m,n= ? 8 8
minimalan broj konja je 2 minimalan broj konja je 32
119. (PASCAL) Data je realna matrica X dimenzije mn i celi brojevi Ip i Jp, (1<= Ip<=m,
1<=Jp<=n). Svakom elementu matrice pridružuje se jedno polje na tačno određen način. Polje je
određeno sa tri elementa: koordinatama (i,j) i realnim brojem koji predstavlja njegovu visinu. Broj
X[i,j] određuje visinu polja sa koordinatama (i,j). U polju sa koordinatama (Ip,Jp) nalazi se loptica.
Loptica prelazi sa polja A na polje B ako važe sledeći uslovi:
- polja A i B su susedna, što znači da imaju zajedničku stranicu;
- visina polja B je strogo manja od visine polja A, i
- polje B ima najmanju visinu u odnosu na sva polja susedna u odnosu na A.
Loptica se zaustavlja u polju u odnosu na koje ne postoji polje na koje može da pređe. Takvo polje se
naziva završno. Odrediti polje na kome će se loptica zaustaviti kao i put od početnog polja (Ip, Jp) do
završnog.
program lopta1;
type matrica=array[1..30,1..30] of integer;
var x:matrica;
m,n,i,j,ip,jp:integer;
function moze(a,b:integer):boolean;
begin
moze:= (a>=1)and(a<=m)and(b>=1)and(b<=n)
end;
procedure uradi(ip,jp:integer; x:matrica; m,n:integer);
var q:boolean;
poz,poz1,a,b,min,min1:integer;
begin
q:=true; poz:=ip; poz1:=jp;
159
Ivan P. Stanimirović Uvod u programiranje
writeln('Put: ');
while q do
begin
min:=x[poz,poz1]; a:=poz; b:=poz1; min1:=min;
if moze(a-1,b)and(x[a-1,b]<x[poz,poz1])
and(x[a-1,b]<min) then
begin
if poz1<>b then
poz1:=b; poz:=a-1;
min:=x[a-1,b];
end;
if moze(a+1,b)and(x[a+1,b]<x[poz,poz1])
and(x[a+1,b]<min)then
begin
if poz1<>b then
poz1:=b; poz:=a+1;
min:=x[a+1,b];
end;
if moze(a,b-1)and(x[a,b-1]<x[poz,poz1])
and(x[a,b-1]<min) then
begin
if poz<>a then
poz:=a; poz1:=b-1;
min:=x[a,b-1];
end;
if moze(a,b+1)and(x[a,b+1]<x[poz,poz1])
and(x[a,b+1]<min) then
begin
if poz<>a then
poz:=a; poz1:=b+1;
min:=x[a,b+1];
end;
q:=min<>min1;min:=min1;
if q then
writeln(poz:6,poz1:6,' ',x[poz,poz1]);
end;
writeln('Zavrsno polje: ');
writeln(poz:6,poz1:6,' ',x[poz,poz1]);
end;
begin
writeln('Unesite dimenzije matrice');readln(m,n);
writeln('Unesite elemente');
for i:=1 to m do
begin
for j:=1 to n do read(x[i,j]);
readln;
end;
writeln('Unesite ip i jp:');
readln(ip,jp); uradi(ip,jp,x,m,n);
end.
Test primer:
Unesite dimenzije matrice Unesite ip i jp:
3 3 1 3
Unesite elemente Put:
1 2 3 1 2 2
6 5 4 1 1 1
7 8 9 Zavrsno polje:
1 1 1
120. (PASCAL) Napisati funkcije (rekurzivnu i iterativnu verziju) koje za datu relaciju nad
160
Ivan P. Stanimirović Uvod u programiranje
(* Iterativne funkcije *)
function refleks(n:integer; r:relacija):boolean;
var i:integer;
ind:boolean;
begin
ind:=true;
for i:=1 to n do ind:=ind and r[i,i];
refleks:=ind;
end;
161
Ivan P. Stanimirović Uvod u programiranje
ind:boolean;
begin
ind:=true;
for i:=1 to n-1 do
for j:=i+1 to n do
if (i<>j) and r[i,j] and r[j,i] then ind:=false;
antisimet:=ind;
end;
162
Ivan P. Stanimirović Uvod u programiranje
procedure uradi;
var brekv, brpor, brnekor:integer;
f:text;
r:relacija;
n:integer;
ref,sim,asim,tr,refr,simr,asimr,trr:boolean;
begin
brekv:=0; brpor:=0; brnekor:=0;
assign(f,'c:\relacije'); reset(f);
while not eof(f) do
begin
if not ucitaj(f,n,r) then
brnekor:=brnekor+1
else
begin
ref:=refleks(n,r); (* ref:=refleksr(n,r *)
sim:=simet(n,r); (* sim:=simetr(n,r); *)
asim:=antisimet(n,r);
(* asim:=antisimetr(n,r); *)
tr:=tranzit(n,r); (* tr:=tranzitr(n,r); *)
if ref and sim and tr then brekv:=brekv+1;
if ref and asim and tr then brpor:=brpor+1;
end;
end;
writeln('Iterativna verzija: ');
writeln('Bilo je ',brekv,' relacija ekvivalencije');
writeln('Bilo je ',brpor,' relacija poretka');
writeln('Bilo je ',brnekor,' nekorektnih relacija');
close(f);
end;
begin
uradi;
end.
156. (PASCAL) Mali Đurica je počeo da skija. Đurica je egzibicionista i ne skija po stazama, već
skija kako stigne. Zbog toga, služba spasavanja je rešila da napravi program koji će izračunati sva
moguća mesta na kojima se Đurica može naći. Mapa terena se zadaje kao matrica dimenzija m n,
gde svaki element matrice h[i, j], predstavlja visinu mesta sa koordinatama (i, j). Đurica se spusta
uvek u pravcu samo jedne koorditane (ne dijagonalno), i to isključivo sa mesta koje je više, na mesto
koje je niže (h[istart, jstart] > … > h[i, j] > … > h[ikraj, jkraj]). Za zadato startno mesto i mapu
terena, treba odštampati broj mesta na kojima se Đurica može naći (uključujući i startno mesto).
Ulazni podaci nalaze se u fajlu ZAD2.DAT. U prvom redu ulaznog fajla nalaze se celi brojevi m i n (1
≤ m ≤ 100, 1 ≤ n ≤ 100), gde je m broj redova, a n broj kolona mape terena. U sledećih m redova nalazi
se po n celih brojeva koji predstavljaju elemente matrice h[i, j] (0 ≤ h[i, j] ≤ 10000). U sledećem redu
nalaze se brojevi r i k koji predstavljaju red i kolonu startnog mesta (1 ≤ r ≤ m, 1 ≤ k ≤ n).
163
Ivan P. Stanimirović Uvod u programiranje
Izlazne podatke treba upisati u fajl ZAD2.RES. Fajl treba da sadrži samo jedan broj x, koji predstavlja
broj mesta na kojima se Đurica može nalaziti:
{A+,B-,D+,E+,F+,G+,I+,L+,N-,O+,P-,Q+,R+,S+,T-,V+,X+,Y+}
{M 65520,300000,600000}
const inp='zad2.dat';
out='zad2.res';
procedure radi(x,y:byte);
begin
inc(br);
mark[x,y]:=true;
if x<m then
if (a[x+1,y]<a[x,y]) and not mark[x+1,y] then
radi(x+1,y);
if y<n then
if (a[x,y+1]<a[x,y]) and not mark[x,y+1] then
radi (x,y+1);
if x>1 then
if (a[x-1,y]<a[x,y]) and not mark[x-1,y] then
radi(x-1,y);
if y>1 then
if (a[x,y-1]<a[x,y]) and not mark[x,y-1] then
radi(x,y-1);
end;
begin
assign(f,inp); reset(f);
read(f,m,n);
for i:=1 to m do
for j:=1 to n do read(f,a[i,j]);
read(f,r,k); br:=0; close(f);
radi (r,k);
assign(f,out); rewrite(f);
write(f,br); close(f);
end.
Test primeri:
ZAD2.DAT ZAD2.RES Objašnjenje: Sva mesta na
kojima se Đurica može naći su
podvučena.
6 7 14 0 0 0 10 10 10 10
0 0 0 10 10 10 10 0 0 0 10 10 10 10
0 0 0 10 10 10 10 10 2 10 6 10 0 1
10 2 10 6 10 0 1 10 3 10 7 7 4 2
10 3 10 7 7 4 2 10 4 5 7 8 10 10
10 4 5 7 8 10 10 10 3 10 10 9 10 10
10 3 10 10 9 10 10
6 5
60. (C) Napisati proceduru kojom se učitavaju elementi pravougaone matrice x dimenzija mn, gde je
m i n <=10. Napisati funkciju koja određuje najdužu rastuću seriju brojeva u nizu celih brojeva.
Koristeći ovu funkciju, napisati funkciju koja određuje indeks vrste u matrici x koja sadrži najdužu
rastuću seriju.
Ulaz: Pozitivni celi brojevi m i n koji predstavljaju dimenzije matrice x, a zatim m n elemenata matrice x.
Izlaz: Redni broj vrste u matrici x koja sadrži najdužu rastuću seriju brojeva.
164
Ivan P. Stanimirović Uvod u programiranje
#include<stdio.h>
int naj(int x[], int n)
{ int i;
float s, max;
s=max=1;
for(i=1;i<n; i++)
if(x[i]>x[i-1]) s++;
else
{
if (s>max) max=s;
s=1;
}
if(s>max) max=s;
return(max);
}
void ucitaj(int x[][10], int m, int n)
{ int i,j;
for(i=0; i<m; i++)
for(j=0; j<n; j++) scanf("%d", &x[i][j]);
}
int najduza(int a[][10], int m, int n)
{ int i,max=0, k, ind;
for(i=0; i<m; i++)
{ k=naj(a[i],n);
if(k>max)
{ max=k; ind=i; }
}
return(ind+1);
}
void main()
{ int x[10][10];
int mx, m, n;
scanf("%d%d", &m,&n);
ucitaj(x,m,n);
mx=najduza(x,m,n);
printf("Vrsta sa najduzom serijom je %d.\n",mx);
}
Test primeri:
3 5 2 3
2 7 -2 3 4 2 3 4
1 1 0 -2 3 2 1 3
2 3 4 5 0
152. (C) Napisati program koji kvadratnu matricu dimenzije dimdim popunjava prirodnim brojevima
od 1 do dim2 po spirali. Očigledno je da će maksimalni upisan broj biti dim2. Suština zadatka je naći
uslov koji treba da ispunjavaju vrste i kolone da bi došlo do skretanja u određenom pravcu. Za
skretanje udesno uslov je da je i+j<dim+1. Za skretanje naniže uslov je da je i<j. Za skretanje ulevo
uslov je da je i+j<>dim+1. Za skretanje naviše uslov je da je i>j+1.
void main()
{ int i,j,dim,brojac,kraj;int spirala[21][21];
do { printf("\nUnesite dimenziju matrice: ");
scanf("%d",&dim); }
while (dim<1 || dim>20);
brojac=0;i=1;j=0;kraj=dim*dim;
do
{
165
Ivan P. Stanimirović Uvod u programiranje
printf("\n");
for (i=1;i<=dim;i++)
{ for (j=1;j<=dim;j++)
printf("%3d ",spirala[i][j]);
printf("\n");
}
}
Rešenje 2.
#include <stdio.h>
void main()
{ int a[100][100]; int i,j,p,q,b,n,z,m,k,e,k2,e2,r;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++) a[i][j]=0;
i=1;j=1;b=1;k=n;e=m;p=0;q=1;k2=1;e2=1;z=n*m;
while (b<=z)
{ a[i][j]=b;
if((j==e)&&(i==k2)) { p=1; q=0; };
if((i==k)&&(j==e)) { q=-1; p=0; };
if((i==k)&&(j==e2)) { p=-1; q=0; };
if((j==e2)&&(i==k2)) { p=0; q=1;};
if((j==e2)&&(i==k2+1))
{ p=0;q=1;k2++;e2++;e--;k--; };
b++; i=i+p; j=j+q;
}
for (i=1;i<=n;i++)
{ printf("\n");
for (j=1;j<=m;j++) printf("%4d",a[i][j]);
}
}
Test primer:
153. (C) Napisati program kojim se u matrici dimenzija mn upisuju brojevi do zadatog broja, prateći
put kuglice koja polazi od elementa sa koordinatama (0,0) i odbija se od zidova matrice. Ostali
elementi matrice su 0.
166
Ivan P. Stanimirović Uvod u programiranje
#include<stdio.h>
main()
{ int a[100][100];
int i,j,p,q,n,m,b,k;
scanf("%d",&n); scanf("%d",&m);
for (i=0;i<n;i++)
for (j=0;j<m;j++) a[i][j]=0;
scanf("%d",&k);
i=0;j=0; p=q=1; b=2;
a[i][j]=1;i=j=1;
while (b<=k)
{ a[i][j]=b; b++;
if ((i==(n-1))||(i==0)) p=p*(-1);
if ((j==(m-1))||(j==0)) q=q*(-1);
i=i+p; j=j+q;
}
for (i=0;i<n;i++)
{ printf("\n");
for (j=0;j<m;j++)
printf("%d\t",a[i][j]);
}
}
Test primeri:
2 4 4 3 3 4
1 0 3 0 1 0 0
0 2 0 4 0 4 0
0 0 3
Još jedno rešenje
#include <stdio.h>
void main()
{ int n,m;
mat a = {{0,0}};
int cnt;
scanf("%d %d %d", &m, &n, &cnt);
int dx=1;
int dy=1;
int cx=0;
int cy=0;
int curr=0;
while (cnt--)
{
a[cx][cy] = ++curr;
cx+=dx;
cy+=dy;
if ((cx>=m)||(cx<0))
{
dx*=-1;
167
Ivan P. Stanimirović Uvod u programiranje
cx+=2*dx;
}
if ((cy>=n)||(cy<0))
{
dy*=-1;
cy+=2*dy;
}
}
ispis(m, n, a);
}
154. (C) Napisati program koji učitava dimenziju šahovske table (broj kvadrata) i veličinu svakog
kvadrata na tabli, a zatim generiše matricu koja odgovara uokvirenoj šahovskoj tabli. U gornjem
levom uglu šahovske table uvek je crni kvadrat. Crnom polju odgovara znak '*', a belom znak ' '.
#include<stdio.h>
void main()
{ char a[80][80];
int i,j,dim,vel;
clrscr();
scanf("%d%d",&dim,&vel);
generisi(dim,vel,a);
for(i=0; i<=dim*vel+1; i++)
{ for(j=0; j<=dim*vel+1; j++) putchar(a[i][j]);
printf("\n");
}
168
Ivan P. Stanimirović Uvod u programiranje
}
Rešenje 2.
#include<stdio.h>
void main()
{ char a[80][80];
int i,j,dim,vel;
clrscr();
scanf("%d%d",&dim,&vel);
generisi(dim,vel,a);
for(i=0; i<=dim*vel+1; i++)
{ for(j=0; j<=dim*vel+1; j++)
putchar(a[i][j]);
printf("\n");
}
}
Test primeri:
Primer. (C) U svakom od tri kontejnera se nalazi izvesna količina smeđih, zelenih i belih boca koje
treba da se recikliraju. Da bi staklo moglo da se reciklira u svakom kontejneru moraju da se nalaze
boce iste boje. Napisati program koji određuje minimalni broj premeštanja boca tako da posle
premestanja u svakom kontejneru budu boce iste boje. Pri jednom premeštanju se prebacuje jedna
boca iz bilo kog u neki drugi kontejner, a kontejneri su dovoljno veliki da mogu da sadrže sve boce.
U tekstualnom fajlu zad2.dat nalaze se 3 reda sa po 3 broja u svakom, koji opisuju početno
stanje: broj smeđih, zelenih i belih boca u prvom kontejneru, zatim u drugom i na kraju u trećem. U
169
Ivan P. Stanimirović Uvod u programiranje
izlazni fajl zad2.res ispisati minimalan broj premeštanja koji je potreban da se postigne to završno
stanje.
Test Primer:
zad2.dat zad2.res
1 2 3 30
4 5 6
7 8 9
#include<stdio.h>
int main(){
FILE *f,*g;
int i,j,k,m[3][3],r,a;
f=fopen("zad2.dat","r");
g=fopen("zad2.res","w");
for(i=0;i<3;i++)
for(j=0;j<3;j++)
fscanf(f,"%d",&m[i][j]);
r=-1;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
for(k=0;k<3;k++)
if ((i!=j)&&(i!=k)&&(j!=k)){
a=m[0][i]+m[1][i]+m[0][j]+m[2][j]+m[1][k]+m[2][k];
if(a<r) r=a;
else if(r==-1) r=a;
}
fprintf(g,"%d",r);
fclose(f);
fclose(g);
return 0;
}
#include<stdio.h>
#include<stdlib.h>
void main()
{ int **a, **b, m,n,i,j;
170
Ivan P. Stanimirović Uvod u programiranje
while(1)
{ printf("\nBroj vrsta i kolona? "); scanf("%d%d", &m,&n);
if(m<=0 || n<=0)break;
a=(int **)malloc(m*sizeof(int *));
for(i=0; i<m; i++)
{ a[i]=(int *)malloc(n*sizeof(int));
printf("Elementi %2d. vrste:\n",i+1);
for(j=0; j<n; scanf("%d",&a[i][j++]));
}
b=(int **)malloc(n*sizeof(int *));
for(i=0; i<n; i++)
{ b[i]=(int *)malloc(m*sizeof(int));
for(j=0; j<m; j++)b[i][j]=a[j][i];
}
printf("Transponovana matrica:\n");
for(i=0;i<n;i++)
{ for(j=0;j<m;printf("%d ",b[i][j++]));
printf("\n");
}
}
for(i=0; i<m; free(a[i++])); free(a);
for(i=0; i<n; free(b[i++])); free(b);
}
U programu koji sledi rešen je isti problem, samo što su napisane funkcije za učitavanje elemenata
matrice kao i za transponovanje matrice.
#include <stdio.h>
#include <stdlib.h>
*a = (int**) malloc(*n*sizeof(int*));
for (i = 0; i < *n; i++)
(*a)[i] = (int*) malloc(*m*sizeof(int));
for (i = 0; i < *n; i++)
for (j = 0; j < *m; j++)
scanf("%d", *(*a+i)+j); // ili &((**a)[i][j])
int main()
{ int n, m, i, j;
int** a; int** at;
Citaj(&a, &n, &m);
for (i = 0; i < n; i++)
{ for (j = 0; j < m; j++)printf("%d ", a[i][j]);
printf("\n");
}
171
Ivan P. Stanimirović Uvod u programiranje
printf("\n");
Transponuj(&at, a, n, m);
#include <stdio.h>
#include <stdlib.h>
*a = (int**) malloc(*n*sizeof(int*));
for (i = 0; i < *n; i++)
(*a)[i] = (int*) malloc(*m*sizeof(int));
for (i = 0; i < *n; i++)
for (j = 0; j < *m; j++)
scanf("%d", *(*a+i)+j); // ili &((**a)[i][j])
int main()
{ int n, m, i, j;
int** a; int** at;
Citaj(&a, &n, &m);
at = (int**) malloc(m*sizeof(int*));
for (i = 0; i < m; i++)
at[i] = (int*) malloc(n*sizeof(int));
Transponuj(&at, a, n, m);
172
Ivan P. Stanimirović Uvod u programiranje
6.6. STRINGOVI
U programskim jezicima, string je sekvenca karaktera. String konstanta može da ima proizvoljan broj
karaktera, uključujući i string bez karaktera. Broj karaktera u stringu se naziva dužina stringa.
Jedinstveni string koji ne sadrži karaktere naziva se prazan string.
Stringovi su podržani u svim modernim programskim jezicima. Tipične operacije nad stringovima
su:
• dužina (length);
• upoređenje na jednakost (equality comparison);
• leksikografsko poređenje (lexicographic comparison);
• selekcija karaktera u stringu (character selection);
• selekcija podstringa (substring selection);
• nadovezivanje (concatenation);
• konverzija stringa u numeričku vrednost i obratno.
6.6.1. Stringovi u C
U jeziku C, string je jednodimenzionalni niz elemenata tipa char koji se završava karakterom '\0'.
String se može posmatrati i kao pointer na char.
Inicijalizacija i obrada stringova
Karakteru u stringu može da se pristupi ili kao elementu niza ili pomoću pointera na char. Svaki
string se završava karakterom '\0'. String konstanta je proizvoljan niz znakova između navodnika. Svi
znaci zahvaćeni znacima navoda, kao i null znak '\0' smeštaju se u uzastopnim memorijskim
lokacijama.
Na primer, string s = "ABC" može da se zapamti u memoriju kao sekvenca od 4 karaktera s[0] =
'A', s[1] = 'B', s[2] = 'C', s[3] = '\0', od kojih je poslednji null karakter '\0'. Bez poslednjeg karaktera '\0'
niz nije kompletiran, te predstavlja samo niz karaktera.
Primer. Dodeljivanje početne vrednosti string promenljivoj.
#define MAXREC 100
void main()
{ char w[MAXREC];
…
w[0]='A'; w[1]='B'; w[2]='C'; w[3]='\0';
}
Sada je jasno da su karakter 'a' i string "a" dva različita objekta. String "a" je niz koji sadrži dva
karaktera: 'a' i '\0'.
Stringovi su nizovi karaktera, pa se mogu inicijalizovati na mestu deklaracije, kao i nizovi brojeva.
Osim toga, praktičnije je da se string inicijalizuje konstantnom vrednošću tipa string umesto “znak po
znak”.
173
Ivan P. Stanimirović Uvod u programiranje
Efekat ove naredbe da se string "abc" smešta u memoriju, a pointer p se inicijalizuje baznom adresom
tog stringa.
U slučaju kada se niz znakova zadate dužine inicijalizuje string konstantom, tada se neiskorišćeni
elementi niza inicijalizuju null znakom '\0'.
Primer. Transformacija stringa: u stringu koji se učitava zameniti svaki znak 'e' znakom 'E', dok se
svaka praznina zamenjuje prelazom u novi red i tabulatorom. Učitavanje znakova u stringu se
završava prelazom u novi red.
#include <stdio.h>
#define MAX 50
void main()
{ char line[MAX], *change(char *);
void read(char *);
printf("Unesi jedan red: ");
read(line);
printf("\n%s\n\n%s\n\n","Posle promene red je: ", change(line));
}
#include <stdio.h>
char s[105];
174
Ivan P. Stanimirović Uvod u programiranje
int main()
{
//scanf("%[^\n]s",s);
gets(s);
int p=0;
int cnt=0;
while (s[p])
cnt+=s[p++]==' ';
p=0;
while (s[p]) p++;
int pl=p+cnt-1;
while (p)
{
if (s[p-1]=='e')
s[p-1]='E';
if (s[p-1]==' ')
{
p--;
s[pl]='\t';
pl--;
s[pl]='\n';
pl--;
}
else
{
p--;
s[pl]=s[p];
pl--;
}
}
puts(s);
}
175
Ivan P. Stanimirović Uvod u programiranje
#include <stdio.h>
#include <ctype.h>
#define MAX 30
void main()
{ char line[MAX];
void read(char *);
int cnt(char *);
printf("\n Unesi string : "); read(line);
printf("\n Broj reci = %d\n", cnt(line));
}
Primer. String je deklarisan kao statički niz karaktera a zatim je inicijalizovan nekom string
konstantom. Napisati program koji ispisuje string u direktnom i inverznom poretku.
#include<stdio.h>
void main()
{ static char s[]="Konstantni string";
char *p;
p=s; printf("\nIspis stringa:\n");
while(*p) putchar(*p++);
printf("\nIspis u inverznom poretku:\n");
while(--p>=s) putchar(*p);
putchar('\n');
}
Učitavanje i ispis stringova
Vrednosti stringova se mogu i učitavati. Pri učitavanju stringova bitno je da se rezerviše dovoljno
memorijskog prostora za smeštanje stringova. Program ne može da predvidi maksimalnu dužinu
stringa i da rezerviše potreban memorijski prostor. Zbog toga je programer obavezan da predvidi
maksimalnu dužinu stringova koji se učitavaju. String može da dobije vrednost pomoću funkcije
scanf(), koristeći format %s. Na primer, možemo pisati:
scanf("%s", w);
Svi znaci, do prvog znaka EOF ili do prve praznine se uzimaju kao elementi stringa w. Posle toga se
null karakter stavlja na kraj stringa. Napomenimo da nije korišćena adresa &w u drugom argumentu
funkcije scanf(). Kako je ime niza u stvari bazna adresa niza, očigledno je w ekvivalentno sa &w[0].
Stoga je operator adresiranja ispred imena niza w nepotreban.
Za učitavanje stringova najčešće se koristi funkcija gets(). Ovom funkcijom se prihvataju svi znaci
sa tastature, sve dok se ne unese znak za novi red '\n'. Znak za prelaz u novi red se ignoriše, dok se svi
176
Ivan P. Stanimirović Uvod u programiranje
ostali karakteri dodeljuju stringu koji se učitava. Kao poslednji znak učitanog stringa uvek se postavlja
null karakter '\0'.
Prototip funkcije gets() je oblika char *gets(char *)
Ukoliko je učitavanje završeno korektno, vrednost ove funkcije je pokazivač na adresu u kojoj je
smešten prvi znak stringa s. U suprotnom slučaju, vraćena vrednost je NULL (nulta adresa, koja je u
datoteci stdio.h definisana sa 0). To znači da se kontrola pravilnosti ulaza može kontrolisati izrazom
while(gets(ime)==NULL);
Primer. Reč je data kao niz od n karaktera (n<300). Napisati program koji nalazi najduži palindrom u
toj reči. Palindrom je podniz od uzastopnih elemenata koji se jednako čita s leva i s desna.
177
Ivan P. Stanimirović Uvod u programiranje
#include <stdio.h>
void main()
{ char a[300];
int i,j,n,maxi,maxl,maxj,l;
int pal(char *, int, int);
printf("Unesi broj karaktera reci\n"); scanf("%d",&n);
printf("Unesi rec:\n"); scanf("%c", &a[0]);
for (i=0; i<n; i++) scanf("%c", &a[i]);
a[i]='\0';
maxl=0;
for (i=0; i<n; i++)
for (j=i; j<n; j++)
{ if(pal(a,i,j))
{ l=(j-i)+1; if (l>maxl){ maxl=l; maxj=j; maxi=i; }
}
}
printf("\nNajduzi palindrom je od pozicije %d do %d\n", maxi,maxj);
for (i=maxi; i<=maxj; i++) printf("%c",a[i]);
printf("\n");
}
178
Ivan P. Stanimirović Uvod u programiranje
--strpok1;
while(strpok < strpok1) if(*strpok++ != *strpok1--) return(0);
return(1);
}
Primer. Ispitati da li je uneti string palindrom
#include<cstdio>
#include<cstring>
#include<algorithm>
void main()
{
char s[100], s2[100];
int i,j,n,b;
scanf("%s",s);
n=strlen(s);
i=0; b=0;
j=n-1;
while ((i<n/2)&&(j>n/2)&&(b==0))
{
if (s[i]!=s[j]) b++;
i++;
j--;
}
if (b==0) printf("Palindrom je.\n");
else printf("Nije palindrom\n");
char *a,*c;
a=s;
c=s;
while (*c) c++;
c--;
b=1;
while ((a<c)&&b)
{
if (*a!=*c) b=0;
else {a++; c--;}
}
if (b) printf("Palindrom je.\n");
else printf("Nije palindrom\n");
strcpy(s2,s);
std::reverse(s2,s2+strlen(s2)-1);
printf("%s\n",
(!strcmp(s, s2)) ? "Nije palindrom." : "Jeste palindrom.");
}
Primer. Učitava se tekst, sve do znaka ENTER. Štampati izveštaj, u kome se nalaze dužine reči
sadržanih u tekstu, kao i broj reči date dužine.
#include<stdio.h>
#define MAX 80
int separator(char ch)
{ return(ch==','||ch==' '||ch==';'||ch=='('||ch==')'||
ch==' '||ch=='!'||ch=='?')||ch=='\n'; }
void main()
{ char ch;
int i,l=0;
int b[MAX];
for(i=1; i<=MAX; i++)b[i]=0;
while((ch=getchar()) != '\n')
{ if(!separator(ch)) l++;
179
Ivan P. Stanimirović Uvod u programiranje
Već je pokazano da se vrednosti stringova mogu ispisivati pomoću funkcije printf, koristeći format
%s. Takođe, za ispis stringova se može koristiti standardna funkcija puts. Funkcija puts ima jedan
argument, koji predstavlja pokazivač na početnu adresu stringa koji se ispisuje. Funkcija puts ispisuje
sve karaktere počev od pozicije određene argumentom funkcije do završnog karaktera \0'.
Primer. Zadati string s koristeći funkciju gets(). Napisati funkciju za izbacivanje svih nula sa kraja
stringa, kao i funkciju za izbacivanje nula sa početka učitanog stringa. U glavnom programu izbaciti
sve početne i završne nule u zadatom stringu.
#include <stdio.h>
void main()
{ char s[30];
void ukloni_kraj(char *);
void ukloni_pocetak(char *);
printf("\n Zadati string:\n"); gets(s);
ukloni_kraj(s);
printf("\nString bez zadnjih nula = "); puts(s);
ukloni_pocetak(s);
printf("\nString bez pocetnih i zadnjih nula = "); puts(s);
}
180
Ivan P. Stanimirović Uvod u programiranje
181
Ivan P. Stanimirović Uvod u programiranje
void main()
{ char *s1, *s2;
182
Ivan P. Stanimirović Uvod u programiranje
void main()
{ char ljudi[N][D+1], osoba[D+1];
int i,j,m,n=0;
//Citanje neuredjenog niza imena
do
gets(ljudi[n]);
while(strcmp(ljudi[n++],"...")!=0);
n--;
II način
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 100
#define D 40
void main()
{ char **ljudi, osoba[D+1];
int i,j,m,n=0;
ljudi=(char **)malloc(N*sizeof(char *));
//Citanje neuredjenog niza imena
do
{ ljudi[n]=(char *)malloc((D+1)*sizeof(char));
gets(ljudi[n]);
}
while(strcmp(*(ljudi +n++),"...")!=0);
n--;
183
Ivan P. Stanimirović Uvod u programiranje
if(m!=i)
{ strcpy(osoba,ljudi[i]); strcpy(ljudi[i],ljudi[m]);
strcpy(ljudi[m],osoba);
}
}
Primer. Na kružnom putu dužine mn kilometara postoji n benzinskjh stanica (1 < n < 100, 1 < m <
1000). Na stanici i ima ukupno si litara benzina. Između svake dve stanice je rastojanje m kilometara.
Automobil polazi iz jedne od stanica, a može da započne kretanje u bilo kom od dva smera. Na početku
mu je rezervoar prazan, a pri prolazu kroz svaku od stanica uzima celokupnu količinu goriva iz stanice
(rezervoar ima neograničenu zapreminu). Automobil troši b (1 b 10) litara po kilometru. Odrediti
da li postoji stanica iz koje automobil može da započne kretanje i obiđe celu stazu.
U ulaznoj datoteci 'zad3.in' dati su, redom, brojevi n, m, b, s1, ..., sn. U izlaznu datoteku 'zad3.out'
upisati reč 'MOGUĆE' ako postoji tražena stanica, a u suprotmom reč 'NEMOGUĆE'.
zad3.in zad3.out Objašnjenje
3 1 1 MOGUĆE Na putu su tri stanice. Automobil može da
2 2 0 krene iz bilo koje od prve dve.
3 1 2 NEMOGUĆE Pošto automobil troši 21 na kilometar, iz
4 0 1 koje god stanice da pode, ne može da obiđe
celu stazu.
Rezervisana reč struct služi kao informacija kompajleru da neposredno iza nje sledi opis neke
strukture. Zatim sledi neobavezni identifikator, označen sa oznaka, koji predstavlja ime strukture. Ime
dodeljeno strukturi se može kasnije koristiti pri deklaraciji promenljivih strukturnog tipa. Iza imena
strukture, između velikih zagrada, deklarišu se pojedini delovi strukture. Elementi strukture mogu biti
proizvoljnih tipova, pa i nove strukture. Iza poslednje zagrade piše se znak ';'. Između zatvorene
zagrade } i znaka ; opciono se mogu navesti imena promenljivih strukturnog tipa.
Primer. Sledećom definicijom strukture opisani su osnovni podaci o studentu: ime, broj indeksa i
upisana godina studija.
struct student { char *ime;
int indeks;
184
Ivan P. Stanimirović Uvod u programiranje
int godina;
} s1,s2,s3;
Osim toga, promenljive s1, s2, s3 se deklarišu kao promenljive koje mogu da sadrže konkretne
vrednosti saglasno tipu struct student, tj. podatke o studentima. Svaki slog o studentu sadrži tri
komponente: ime, indeks i godina. Komponenta ime je string, dok su komponente indeks i godina
celobrojnog tipa.
Struktura može da se koristi kao šablon za deklaraciju tipova podataka. Na primer, neka je
deklarisana struktura student na sledeći način:
struct student { char *ime;
int indeks;
int godina;
};
Sada se mogu deklarisati strukturne promenljive strukturnog tipa struct student. Na primer, možemo
pisati
struct student pom, razred[100];
Tek posle ovakvih deklaracija se alocira memorija za promenljivu pom i niz razred.
Objedinjavanje opisa strukture čije je ime izostavljeno sa deklaracijama promenljivih koristi se
kada se šablon strukture ne koristi na drugim mestima u programu. Na primer, možemo pisati
struct
{ char *ime;
int indeks;
int godina;
} s1,s2,s3;
Takođe, članovima strukture se mogu zadati željene vrednosti pomoću funkcija scanf() i gets():
gets(pom.ime);
scanf("%d",&pom.indeks);
scanf("%d",&pom.godina);
Ako se opis strukture navede van svih funkcija, ta struktura se može koristiti u svim funkcijama
koje su definisane posle opisa strukture. Uobičajeno je da se definicija strukture navede na početku
izvornog programa, pre opisa promenljivih i funkcija. U velikim programima opisi struktura se obično
pišu u posebnom fajlu.
185
Ivan P. Stanimirović Uvod u programiranje
186
Ivan P. Stanimirović Uvod u programiranje
Ovaj header fajl može se koristiti kao informacija u modulima koje čine program.
#include "cl.h"
#include<stdio.h>
#include<string.h>
void main()
{ int broji(student *);
student s[10];
int i;
for(i=0; i<N; i++)
{ printf("%d ti student : ",i);
gets(s[i].ime);
scanf("%d", &s[i].indeks); scanf("%d", &s[i].godina);
getchar();
}
printf("Studenata trece godine ima %d\n", broji(s));
}
187
Ivan P. Stanimirović Uvod u programiranje
Treći način:
#include "cl.h"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void main()
{ int broji(student *);
void ucitaj(student *);
student *s=(student *)malloc(N*sizeof(student));
ucitaj(s);
printf("Studenata trece godine ima %d\n", broji(s));
}
#include<stdio.h>
188
Ivan P. Stanimirović Uvod u programiranje
189
Ivan P. Stanimirović Uvod u programiranje
(*pointer_strukture).ime_člana
U poslednjem izrazu zagrade nisu neophodne.
Sve eksterne i statičke promenljive, uključujući strukturne promenljive, koje nisu eksplicitno
inicijalizovane, automatski se inicijalizuju na vrednost nula.
Primer. Neka je definisana struktura licnost na sledeći način:
struct licnost
{ char ime[30];
char adresa[50];
unsigned starost;
}
Takođe, elementima strukturne promenljive na koju ukazuje pointer osoba, može se pristupiti i na
sledeći način:
osoba->ime
osoba->adresa
osoba->starost
Formalni parametar funkcije može biti promenljiva nekog strukturnog tipa S kao i pokazivač na
strukturu S. Ukoliko je formalni parametar strukturna promenljiva, tada se kao stvarni parametar
navodi strukturna promenljiva ili neka konstantna vrednost strukturnog tipa S. U pozivu te funkcije,
kao stvarni parametar, predaje se kopija vrednosti te strukturne promenljive. Na taj način, ne menja se
vrednost strukturne promenljive koja je predata kao stvarni parametar. U slučaju kada je formalni
parametar funkcije pointer na strukturu, tada se kao stvarni parametar predaje adresa strukturne
promenljive koja se koristi kao stvarni parametar. Time je omogućeno ne samo korišćenje vrednosti
pokazivačke promenljive (pomoću operatora indirekcije), već i promena tih vrednosti.
Takođe, strukture se mogu koristiti kao elementi nizova. Nizovi struktura se deklarišu analogno
ostalim nizovima. Na primer, za definisane strukture licnost i student mogu se koristiti nizovi
struct licnost osobe[20]
struct student studenti[50]
Ovakvim deklaracijama opisan je niz struktura osobe od najviše 20 elemenata, kao i niz struktura
studenti sa najviše 50 elemenata. Svaki element niza osobe predstavlja jednu strukturnu promenljivu
tipa licnost.
Primer. U ovom primeru je definisana matrica kompleksnih brojeva i dodeljene su početne vrednosti
njenim elementima. Svaki element matrice predstavljen je parom realnih brojeva.
static struct complex
{ double real;
double imag;
} m[3][3]=
{ { {1.0,-0.5}, {2.5,1.0}, {0.7,0.7} },
{ {7.0,-6.5}, {-0.5,1.0}, {45.7,8.0} },
190
Ivan P. Stanimirović Uvod u programiranje
};
Elementi strukture mogu biti nove strukture. Struktura koja sadrži bar jedan element strukturnog
tipa naziva se hijerarhijska struktura.
Primer. Definisana je struktura licnost koja sadrži element datumrodjena strukturnog tipa datum:
struct datum
{ unsigned dan;
unsigned mesec;
unsigned godina;
}
struct licnost
{ char *ime;
datum datumrodjenja;
}
definiše strukturu pointeri sa dva ukazatelja n1 i n2 na tip int. Sada se može deklarisati strukturna
promenljiva ukaz:
struct pointeri ukaz;
void main()
{ int i1, i2;
struct { int *n1;
int *n2;
}ukaz;
ukaz.n1=&i1; ukaz.n2=&i2;
*ukaz.n1=111; *ukaz.n2=222;
/* indirektno dodeljivanje vrednosti promenljivim i1, i2 */
printf("i1=%d *ukaz.n1=%d\n", i1, *ukaz.n1);
printf("i2=%d *ukaz.n2=%d\n", i2, *ukaz.n2);
}
Primer. Dva ekvivalentna pristupa elementima strukture.
struct Simple { int a; };
int main() {
Simple so, *sp = &so;
sp->a;
so.a;
}
191
Ivan P. Stanimirović Uvod u programiranje
192
Ivan P. Stanimirović Uvod u programiranje
Sada se identifikator datum može koristiti kao samostalan tip podataka. Na primer, iskazom
datum rodjendan[10];
deklariše se vektor rodjendan kao jednodimenzionalni vektor sa elementima tipa datum.
Primer. Ime string kao tip za pokazivače na tip char uvodi se pomoću operatora typedef na sledeći
način:
typedef char *string;
Sada je
string str1, str2;
ekvivalentno sa
char *str1, *str2;
193
Ivan P. Stanimirović Uvod u programiranje
Ovaj zadatak se može uraditi uz korišćenje typedef izraza. Kompleksni brojevi se reprezentuju novim
tipom kompl.
#include <stdio.h>
#include <math.h>
typedef struct
{ float prvi,drugi; } kompl;
void upis(kompl *p); void ispis(kompl p);
kompl zbir(kompl p,kompl q); kompl proiz(kompl p,kompl q);
void main()
{ kompl a,b,c;
upis(&a); upis(&b); c=zbir(a,b); ispis(c);
c=proiz(a,b); ispis(c);
}
void ispis(kompl p)
{ printf("\n %f *i+ %f\n",p.prvi,p.drugi); }
194
Ivan P. Stanimirović Uvod u programiranje
narednih n redova su zadati centar i poluprečnik svakog kruga. Ispisati redne brojeve svaka dva kruga
koji se seku.
#include<stdio.h>
#include<math.h>
typedef struct
{double x,y; } Tacka;
typedef struct
{ Tacka O; double R; } Krug;
void main()
{ int i,j,n;
Krug a[100];
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%lf%lf%lf",&a[i].O.x,
&a[i].O.y,&a[i].R);
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(intersect(a[i],a[j]))
printf("%d %d\n",i,j);
}
#include<stdio.h>
#include<math.h>
struct Tacka{ double x,y; };
struct Krug{ Tacka O; double R; };
void main()
{ int i,j,n;
Krug K[5];
scanf("%d",&n);
for(i=0; i<n; i++) CitajKrug(&K[i]);
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(Intersect(K[i],K[j])) printf("(%d,%d)\n",i+1,j+1);
}
195
Ivan P. Stanimirović Uvod u programiranje
Primer. Retka matrica se može predstaviti brojem ne-nula elemenata kao i sledećim informacijama za
svaki ne-nula element:
- redni broj vrste tog elementa,
- redni broj kolone tog elementa, i
- realan broj koji predstavlja vrednost tog elementa.
Predstaviti retku matricu brojem ne-nula elemenata i nizom slogova, u kome svaki slog sadrži redni
broj vrste i kolone kao i vrednost svakog ne-nula elementa.
Napisati procedure za formiranje niza slogova koji predstavljaju reprezentaciju retke matrice A.
Napisati proceduru za ispis matrice.
Napisati proceduru za formiranje sparse reprezentaciju predstavlja matricu AT.
Napisati funkciju koja za zadate vrednosti i, j preko tastature izračunava vrednost elementa A[i,j].
#include<stdio.h>
struct slog
{ int i,j;
float aij;
};
void main()
{ int i,j,n;
struct slog p[10], q[10];
pravimatricu(p, &n);
printf("Matrica je: \n");
pisimatricu(p,n);
transponuj(p,n,q);
printf("Transponovana matrica: \n");
160
Ivan P. Stanimirović Uvod u programiranje
pisimatricu(q,n);
printf("i,j= ? "); scanf("%d%d", &i,&j);
printf("%10.3f\n",vrednost(n,p,i,j));
}
Primer. Modifikacija prethodnog primera. Matrica se zadaje brojem vrsta, brojem kolona, brojem ne-
nula elemenata kao i nizom slogova koji odgovaraju ne-nula elementima. Svaki takav slog je određen
sledećim informacijama za ne-nula element:
- redni broj vrste tog elementa,
- redni broj kolone tog elementa, i
- realan broj koji predstavlja vrednost tog elementa.
Napisati funkciju za formiranje retke matrice A.
Napisati funkciju za ispis nenula elemenata matrice.
Napisati funkciju za uobičajeni ispis matrice.
Napisati funkciju za formiranje sparse reprezentaciju matrice AT.
Napisati funkciju koja za zadate vrednosti i, j preko tastature izračunava vrednost elementa A[i,j].
#include<stdio.h>
struct slog
{ int i,j;
float aij;
};
struct matrica
{ int m,n,bn;
slog sp[10];
};
void pisimatricu(matrica x)
{ int i;
for(i=0; i<x.bn; i++)
printf("(%d %d): %10.3f\n",x.sp[i].i, x.sp[i].j,x.sp[i].aij);
}
161
Ivan P. Stanimirović Uvod u programiranje
void pisigusto(matrica x)
{ int i,j;
for(i=0;i<x.m; i++)
{ for(j=0; j<x.n; j++)
printf("%5.2f ",vrednost(x,i,j));
printf("\n");
}
}
void main()
{ int i,j;
matrica p, q;
pravimatricu(&p);
printf("Matrica je: \n"); pisimatricu(p); pisigusto(p);
transponuj(p,&q);
printf("Transponovana matrica: \n"); pisimatricu(q); pisigusto(q);
printf("i,j= ? "); scanf("%d%d", &i,&j);
printf("%10.3f\n",vrednost(p,i,j));
}
Primer. Definisana je struktura koja predstavlja datum:
type datum=record
dan:1..31;
mesec:1..12;
godina:0..maxint;
end;
Zatim je definisana je struktura koja sadrži jedno polje tipa datum i jedno polje tipa sting:
praznik=record
d:datum;
naziv:string[30];
end;
Ova struktura reprezentuje jedan praznik. U programu formirati niz datuma koji predstavljaju
praznike.
program Praznici;
type datum=record
dan:1..31;
mesec:1..12;
godina:0..maxint;
end;
praznik=record
d:datum;
naziv:string[30];
end;
procedure CitajPraznik(var p:praznik);
begin
with p do
begin
with d do
begin
write('Dan = ? '); readln(dan);
write('Mesec = ? '); readln(mesec);
write('Godina = ? '); readln(godina);
end;
write('Naziv praznika ? '); readln(naziv);
end; {with }
end;
procedure PisiPraznik(p:praznik);
162
Ivan P. Stanimirović Uvod u programiranje
begin
writeln(p.naziv); writeln;
writeln(p.d.dan,'.',p.d.mesec,'.',p.d.godina,'.'); writeln;
end;
var
i,n:integer;
a:array[1..30] of praznik;
begin
readln(n); writeln('Zadati podatke za ',n,' praznika:');
for i:= 1 to n do CitajPraznik(a[i]);
writeln; writeln;
for i:=1 to n do
begin
writeln(i,'. praznik:'); PisiPraznik(a[i]);
end;
end.
Rešenje u jeziku C:
#include<stdio.h>
#include<string.h>
typedef struct
{ int dan, mesec, godina; }datum;
typedef struct
{ char naziv[30];
datum d;
}praznik;
typedef struct
{ double a[30]; int n; } Poli;
163
Ivan P. Stanimirović Uvod u programiranje
Poli citaj()
{ Poli p; int i;
printf("Stepen = ? "); scanf("%d", &p.n);
printf("Koeficijenti?\n"); for(i=p.n; i>=0; scanf("%lf", &p.a[i--]));
return p;
}
void pisi(Poli p)
{ int i;
putchar('{');
for(i=p.n; i>=0; i--){ printf("%.2lf", p.a[i]); if(i>0)putchar(','); }
putchar('}');
}
void main()
{ Poli p1, p2, p3;
while(1)
{ p1=citaj(); p2=citaj();
printf("P1 = "); pisi(p1); putchar('\n');
printf("P2 = "); pisi(p2); putchar('\n');
printf("P1+P2 = "); p3=zbir(p1,p2); pisi(p3); putchar('\n');
printf("P1-P2 = "); pisi(razlika(p1,p2)); putchar('\n');
164
Ivan P. Stanimirović Uvod u programiranje
6.7.4. Unije
Unija je tip podataka koji može da sadrži (u raznim situacijama) objekte različitih tipova. Unije
određuju način manipulisanja različitim tipovima podataka u istoj memorijskoj oblasti. Svrha njihovog
postojanja je ušteda memorije. One su analogne slogovima promenljivog tipa u Pascal-u, a sintaksa im
je zasnovana na strukturama jezika C. Svrha unije je da postoji samo jedna promenljiva koja može da
sadrži bilo koju od vrednosti različitih tipova. Unije se razlikuju od struktura po tome što elementi
unije koriste isti memorijski prostor, i što se u svakom trenutku koristi samo jedan element unije.
Primer. Pretpostavimo da u tabeli simbola nekog kompajlera, konstanta može da bude int, float ili
char. Najveća ušteda memorije se postiže ako je vrednost ma kog elementa tabele memorisana na
istom mestu, bez obzira na tip. U našem slučaju je potrebna sledeća deklaracija
union tag
{ int ival;
float fval;
char *sval;
};
union tag u;
Promenljivoj koja je deklarisana kao unija prevodilac dodeljuje memorijski prostor dovoljan za
memorisanje onog člana unije koji zauzima najveći memorijski prostor. Programer mora da vodi
računa o tome koji tip se trenutno memoriše u uniji, jer je važeći tip onaj koji je najskorije memorisan.
ili
pointer_unije->clan.
Ako je int tip tekućeg člana unije u, njegova vrednost se prikazuje izrazom
printf("%d\n",u.ival);
ako je aktivni član tipa float pišemo
printf("%f\n",u.fval);
a ako je tipa char
printf("%s\n",u.sval);
Elementima strukturne promenljive u vrednosti se mogu dodeliti, na primer, iskazima
u.ival=189; ili u.fval=0.3756; ili u.sval="string";
Primer. Jednostavna unija koja sadrži jedno celobrojno i jedno realno polje.
void main()
{ union { int i;
float f;
} x;
165
Ivan P. Stanimirović Uvod u programiranje
Sada možemo pristupiti članu ival i-tog elementa tablice simbola pomoću izraza
symtab[i].u.ival;
Prvi znak stringa sval i-tog elementa tablice simbola se dobija jednim od sledeća dva ekvivalentna
izraza:
*symtab[i].u.sval;
symtab[i].u.sval[0];
Unija se može inicijalizovati samo pomoću vrednosti koja odgovara tipu njenog prvog člana. Stoga
se unija opisana u prethodnom primeru može inicijalizovati samo pomoću celobrojne vrednosti.
Primer. Osnovne geometrijske figure se mogu okarakterisati sledećom strukturom:
struct figura
{ float povrsina, obim; /* Zajednicki elementi */
int tip; /* Oznaka aktivnog elementa */
union
{ float r; /* Poluprecnik kruga */
float a[2]; /* Duzine strana pravougaonika */
float b[3]; /* Duzine strana trougla */
} geom_fig;
} fig;
Primer. Napisati program za izračunavanje rastojanja između dve tačke u ravni, pri čemu postoji
mogućnost da svaka od tačaka bude definisana u Dekartovom ili polarnom koordinatnom sistemu.
Obuhvaćeni su svi slučajevi: kada su obe tačke zadate Dekartovim koordinatama, jedna od tačaka
Dekartovim, a druga polarnim koordinatama i slučaj kada su obe tačke definisane polarnim
koordinatama.
#include<stdio.h>
#include<math.h>
typedef enum { Dekartove, Polarne }TipKor;
typedef struct
{ double x,y; } Dek;
typedef struct
{ double r,fi; } Pol;
typedef struct
{ TipKor tip;
union
{ Dek DK;
Pol PK;
};
166
Ivan P. Stanimirović Uvod u programiranje
} koordinate;
void main()
{ koordinate A,B;
double d;
ucitaj(&A); ucitaj(&B);
switch(A.tip)
{
case Dekartove:
switch(B.tip)
{ case Dekartove:
d=sqrt(pow(A.DK.x-B.DK.x,2)+pow(A.DK.y-B.DK.y,2));
break;
case Polarne:
d=sqrt(pow(A.DK.x-B.PK.r*cos(B.PK.fi),2)+
pow(A.DK.y-B.PK.r*sin(B.PK.fi),2));
break;
}
break;
case Polarne:
switch(B.tip)
{case Dekartove:
d=sqrt(pow(A.PK.r*cos(A.PK.fi)-B.DK.x,2)+
pow(A.PK.r*sin(A.PK.fi)-B.DK.y,2));
break;
case Polarne:
d=sqrt(pow(A.PK.r*cos(A.PK.fi)-B.PK.r*cos(B.PK.fi),2)+
pow(A.PK.r*sin(A.PK.fi)-B.PK.r*sin(B.PK.fi),2));
break;
}
break;
}
printf("%.4lf\n",d);
}
Primer. Napisati program za sumiranje površina n geometrijskih figura. Figura može biti krug
(određen dužinom poluprečnika), pravougaonik (određen dužinama susednih stranica) ili trougao
(određen dužinama svojih stranica).
#include<stdio.h>
#include<math.h>
void main()
{ struct pravougaonik
{ double a,b;};
struct trougao
{ double a,b,c; };
167
Ivan P. Stanimirović Uvod u programiranje
struct figura
{ int tip;
union
{ double r;
struct pravougaonik p;
struct trougao t;
};
} figure[50];
int i,n;
double pov=0,s;
scanf("%d",&n);
for(i=0; i<n; i++)
{ printf("Tip figure (0 - krug, 1-pravougaonik, 2-trougao): ");
scanf("%d",&figure[i].tip);
switch(figure[i].tip)
{ case 0:
scanf("%lf",&figure[i].r);break;
case 1:
scanf("%lf%lf",&figure[i].p.a,&figure[i].p.b);break;
case 2:
scanf("%lf%lf%lf",&figure[i].t.a,&figure[i].t.b,&figure[i].t.c);
break;
}
}
for(i=0;i<n;i++)
{ switch(figure[i].tip)
{ case 0:
pov+=3.14*figure[i].r*figure[i].r;break;
case 1:
pov+=figure[i].p.a*figure[i].p.b;break;
case 2:
s=(figure[i].t.a+figure[i].t.b+figure[i].t.c)/2;
pov+=sqrt(s*(s-figure[i].t.a)*(s-figure[i].t.b)*(s-
figure[i].t.c));
}
}
printf("Povrsina svih figura je %lf\n",pov);
}
168
Ivan P. Stanimirović Uvod u programiranje
Ista konstanta se ne može koristiti u deklaracijama različitih nabrojivih tipova podataka. Na primer,
definicije tipova
enum radnidani {pon,uto,sre,cet,pet};
enum vikend {pet,sub,ned};
su nekorektne, jer se konstanta pet pojavljuje u definiciji oba tipa. Nabrojivi tip se može definisati
koristeći operatore typedef i enum. Na primer, sledećim definicijama su uvedena dva nabrojiva tipa,
samoglasnik i dani:
typedef enum {A,E,I,O,U} samoglasnik;
typedef enum {pon,uto,sre,cet,pet,sub,ned} dani;
169
Ivan P. Stanimirović Uvod u programiranje
Promenljivoj nabrojivog tipa se može dodeliti bilo koja vrednost koja je sadržana u definiciji
nabrojivog tipa:
slovo=U;
d1=sre;
Ako se vrednosti promenljivih nabrojivog tipa ispisuju pomoću funkcije printf(), ispisuju se
celobrojne vrednosti koje su dobile na osnovu definicije nabrojivog tipa.
Za razliku od Pascala, promenljive nabrojivog tipa se ne mogu koristiti kao brojačke promenljive u
operatorima FOR ciklusa.
170
Ivan P. Stanimirović Uvod u programiranje
return dm;
}
void pisi(Din_mat dm, const char *frm, int max){ /* Ispis matrice. */
int i,j;
for(i=0; i<dm.m; i++) {
for(j=0; j<dm.n; j++) {
printf(frm,dm.a[i][j]);
putchar ((j%max==max-1 || j==dm.n-1) ? '\n' : ' ');
}
if(dm.n > max)putchar ('\n');
}
}
171
Ivan P. Stanimirović Uvod u programiranje
return dm3;
}
int main() {
while (1) {
Din_mat dm1, dm2, dm3; int m, n;
printf ("m1, n1? "); scanf ("%d%d", &m, &n);
if (m<=0 || n<=0) break;
printf("Matrl?\n"); dm1 = citaj(m,n);
printf ("m2, n2? "); scanf ("%d%d", &m, &n);
if(m<=0 || n<=0) break;
printf ("Matr2?\n"); dm2 = citaj(m,n);
if(dm1.m==dm2.m && dm1.n==dm2.n) {
dm3 = zbir(dm1, dm2); printf ("ZBIR:\n");
pisi(dm3,"%8.2f", 8); unisti(dm3);
dm3 = razlika(dm1, dm2); printf ("RAZLIKA:\n");
pisi(dm3, "%8.2f", 8); unisti (dm3);
}
if(dm1.n == dm2.m) {
dm3 = proizvod(dm1,dm2); printf("PROIZVOD:\n");
pisi(dm3, "%8.2f", 8); unisti (dm3);
}
putchar('\n');
unisti(dm1); unisti(dm2);
}
return 0;
}
6.10. Datoteke
Programi koje smo do sada koristili imali su jedan ozbiljan nedostatak. Naime, rezultati obrade
ulaznih veličina prestankom izvršavanja programa su nepovratno nestajali. Jedan od načina da se
sačuvaju podaci bio bi da se posredstvom štampača ispišu na hartiji. Međutim, ako postoji potreba da
podaci budu pristupačni nekom programu, treba ih sačuvati na magnetnim nosiocima informacija, na
primer na disku ili traci. Na taj način, na disku ili traci se mogu čuvati datoteke sa podacima koje
možemo obrađivati koliko god hoćemo puta, a da ih ne moramo učitavati sa tastature.
Datoteke su sekvencijalne strukture jednorodnih zapisa čiji broj nije unapred poznat, i koje se
zapisuju na nekom od spoljašnjih memorijskih medijuma. Ovakvi strukturni tipovi opisuju se sa file i
postali su standardni u programskim jezicima posle pojave ovog koncepta u jeziku Pascal.
Datoteke su jednorodne strukture podataka, slično poljima ali za razliku od polja, broj elemenata
datoteke se ne definiše unapred i podrazumeva se da one fizički postoje van programa na nekom od
spoljašnjih memorijskih medijuma (disku, traci, disketi itd.).
172
Ivan P. Stanimirović Uvod u programiranje
i NULL. Konstanta EOF označava kraj datoteke i ima vrednost -1. Konstanta NULL ima vrednost 0 i
vraća se kao rezultat neuspešnog poziva nekih funkcija za upravljanje datotekama.
Otvaranje i zatvaranje datoteka
Programski jezik C koristi dva osnovna tipa fajlova: tekstualni i binarni tip.
Rad sa fajlovima odvija se kroz nekoliko osnovnih aktivnosti: otvaranje fajla, čitanje i upis u fajl,
kretanje po fajlu, zatvaranje fajla.
Datoteka mora da bude otvorena pre bilo kakvog procesiranja. Prilikom otvaranja datoteke mora se
specificirati njeno ime i tip željene ulazno-izlazne operacije. Može se koristiti režim čitanja (read
mode), režim upisa (write mode), odnosno režim dodavanja (append mode). Za otvaranje datoteka
koristi se funkcija fopen iz C biblioteke. Zaglavlje ove funkcije je oblika
FILE *fopen(const char *filename, const char *mode);
Funkcija fopen() vraća pointer na otvoreni fajl. Vraćena vrednost NULL indicira grešku prilikom
otvaranja fajla. Parametar filename ime fajla, a parametar mode predstavlja način na koji se fajl otvara.
Mogući načini su opisani u nastavku:
"r" Otvara za čitanje. Ako fajl ne postoji ili ne može biti pronađen poziv ne uspeva.
"w" Otvara prazan fajl za pisanje. Ako dati fajl postoji njegov sadržaj se briše.
"a" Otvara fajl za pisanje na kraju fajla (appending) bez brisanja EOF markera pre pisanja novih
podataka na kraju postojećeg fajla. Ukoliko fajl ne postoji, kreira se novi.
"r+" Otavara fajl za čitanje i pisanje. Fajl mora da postoji.
"w+" Otvara prazan fajl za čitanje i pisanje. Ako dati fajl postoji, njegov sadržaj je obrisan.
"a+" Otvara fajl za čitanje i appednovanje. Operacija apendovanja uključuje brisanje EOF markera
pre nego se novi podaci upišu u fajl. Marker EOF se restaurira posle kompletiranja pisanja.
Ukoliko fajl sa specificiranim imenom ne postoji, on se prvo kreira.
Kad je fajl otvoren sa pristupom "a" ili "a+" sve opracije upisa se dešavaju na kraju fajla. Fajl
pointer može biti repozicioniran korišćenjem fseek ili rewind, ali se uvek vraća na kraj fajla pre bilo
koje operacije upisa u fajl. Na taj način se obezbeđuje da preko postojećih podataka nema upisa.
Mod "a" ne briše EOF marker pre dodavanja podataka u fajl. Ako se to desi MSDOS komanda
TYPE samo pokazuje podatke do originalnog EOF markera i ne pokazuje podatke dodate fajlu. Mod
"a+" briše EOF marker pre dodavanja fajlu. Posle dodavanja MSDOS komanda TYPE pokazuje sve
podatke dodate fajlu. Mod "a+" se zahteva za dodavanje stream fajlu koji je terminiran CTRL+Z EOF
markerom. Kad je specificiran neki od "r+", "w+" ili "a+" i čitanje i pisanje su dozvoljeni, a kaže se da
je fajl otovren za update. Potrebno je da se prilikom prebacivanja između čitanja i pisanja uradi
intervencija u obliku poziva fflush, fsetpos, fseek, ili rewind operacije. Tekuća pozicija može biti
specificirana fsetpos ili fseek operacijom.
Sledeći karakteri mogu biti uključeni u mod radi specifikacije prevođenja newline karaktera.
t Otvara fajl u tekstualnom modu. CTRL+Z se interpretira kao end-of-file karakter na ulazu. U
fajlu otvorenom za čitanje - pisanje sa "a+" fopen proverava CTRL+Z na kraju fajla i briše ga ako je
moguće. Ovo se radi jer korišćenje fseek i ftell za kretanje unutara fajla koji se završava sa CTRL+Z,
može da uslovi nekorektno ponašanje fseek blizu kraja fajla. Takođe, u tekstualnom modu carriage
return - line feed kombinacije na ulazu se prevode u jedan linefeeds na ulazu i obratno linefeed
karakter na izlazu se prevode u carriage return – line feed kombinacije.
b Otvara fajl u binarnom neprevedenom modu. Prevođenja koja uključuju carriage-return i
linefeed kraktere se ne vrše.
Ako je otvaranje neuspešno, tj. ako fopen() ne može da pronađe željenu datoteku, ona vraća
vrednost NULL.
Primer. Niz iskaza
173
Ivan P. Stanimirović Uvod u programiranje
#include<stdlib.h>
FILE *infile,*fopen();
infile=fopen("file","r"); }
otvara datoteku pod imenom file u režimu čitanja.
Funckija fopen() vraća ukazatelj na strukturu FILE, koja se dodeljuje promenljivoj infile istog tipa.
Neuspešno otvaranje datoteke infile se može ispitati izrazom oblika
if(infile==NULL)
printf("datoteka file ne moze se otvoriti\n");
Poziv funkcije fopen() i ispitivanje vraćenog rezultata se može ujediniti
if((infile=fopen("file","r"))==NULL)
printf("datoteka file ne moze biti otvorena\n");
Funkcijom fclose() zatvara se datoteka otvorena za čitanje ili upis. Zatvorenoj datoteci se ne može
pristupiti pre ponovnog otvaranja. Zaglavlje ove funkcije je
int fclose(FILE *file_pointer);
gde je file_pointer ukazatelj kojim se identifikuje datoteka.
Funkcija
fclose(file_pointer)
vraća vrednost EOF ako ukazatelj file_pointer nije povezan sa nekom datotekom.
Na primer, otvorena datoteka infile zatvara se izrazom
fclose(infile);
Primer.
/* FOPEN.C: This program opens files named "data"
and "data2".It uses fclose to close "data" and
_fcloseall to close all remaining files. */
#include <stdio.h>
FILE *stream, *stream2;
void main(void)
{ int numclosed;
/* Open for read (will fail if file "data" does not exist) */
if( (stream = fopen("data", "r")) == NULL )
printf("The file 'data' was not opened\n" );
else printf( "The file 'data' was opened\n" );
/* Open for write */
if( (stream2 = fopen( "data2", "w+")) == NULL )
printf("The file 'data2' was not opened\n");
else printf("The file 'data2’ was opened\n");
/* Close stream */
if(!fclose(stream))
printf( "The file 'data2' was not closed\n" );
/* All other files are closed: */
numclosed = _fcloseall();
printf("Number of files closed by _fcloseall: %u\n", numclosed);
}
Output
The file 'data' was opened
The file 'data' was opened
Number of files closed by _fcloseall : 1
174
Ivan P. Stanimirović Uvod u programiranje
fputc
175
Ivan P. Stanimirović Uvod u programiranje
char buffer[81];
int i, ch;
/* Open file to read line from: */
if( (stream = fopen("fgetc.c", "r")) == NULL ) exit(0);
/* Read in first 80 characters and place them in "buffer": */
ch = fgetc(stream);
for( i=0; (i<80) && (feof(stream)==0); i++)
{ buffer[i] = (char)ch; ch = fgetc( stream }; }
/* Add null to end string */
buffer [i] = '\0' ;
printf("%s\n", buffer); fclose(stream);
}
Primer. Kopiranje sadržaja ulazne datoteke u izlaznu datoteku. Imena datoteka data su kao parametri
funkcije main().
#include<stdio.h>
void main(int argc,char *argv[]);
{ int c; FILE *infile,*outfile;
if((infile=fopen(argv[1],"r"))==NULL)
printf("datoteka %s ne moze biti otvorena\n",argv[1]);
else if((outfile=fopen(argv[2],"w"))==NULL)
printf("datoteka %s ne moze biti otvorena\n",argv[2]);
else
{ while((c=getc(infile))!=EOF) putc(c,outfile);
printf("\n");
}
fclose(infile); fclose(outfile);
}
Primer.
/* FPUTC.C: This program uses fputc
* to send a character array to stdout.
*/
#include<stdio.h>
void main(void)
{ char strptrl[] = "This is a test of fputc!!\n";
char *p;
/* Print line to stream using fputc. */
p = strptrl;
while((*p != '\0') && fputc(*(p++), stdout)!= EOF);
}
176
Ivan P. Stanimirović Uvod u programiranje
Na primer, izrazom
fprintf(outfile,"string u datoteku\n");
upisuje se string "string u datoteku\n" u datoteku koja je identifikovana pomoću pointera outfile.
Takođe, u istu datoteku se može upisati i sledeći sadržaj:
fprintf(outfile,"string sadrzaja %s u datoteku\n",x);
Primer. Izrazom oblika
fscanf(infile,"%f",&x);
iz datoteke koja je identifikovana sa infile učitava se vrednost u formatu %f i dodeljuje promenljivoj x.
Primer. Procedure za učitavanje celog broja iz datoteke "zad2.dat" i upis istog broja u datoteku
"zad2.res".
#include<stdio.h>
void citaj(long *n)
{ FILE *f;
f=fopen("d:\\zad2.dat","r"); fscanf(f,"%ld",n); fclose(f);
}
void upis(long n)
{ FILE *f;
f=fopen("d:\\zad2.res","w"); fprintf(f,"%ld",n); fclose(f);
}
void main()
{ void citaj(long *); void upis(long);
long n;
citaj(&n); upis(n);
}
Primer. Iz prvog reda datoteke učitati broj timova. U svakom od sledećih redova datoteke zadati
sledeće podatke za svaki tim:
- naziv tima,
- broj pobeda,
- broj nerešenih rezultata, i
- broj poraza.
Sortirati tabelu prema broju osvojenih bodova. Ako dva tima imaju isti broj osvojenih bodova, sortirati
ih prema broju pobeda.
#include<stdio.h>
#include<string.h>
#define broj 10
struct klub
{ char naziv[30];
int izgubljene;
int neresene;
int dobijene;
} tabela[broj];
fscanf(f,"%d%d%d",&a[i].dobijene,&a[i].neresene,&a[i].izgubljene);
fgetc(f);
}
177
Ivan P. Stanimirović Uvod u programiranje
fclose(f);
}
void main()
{ int i,j,n, bodovi[broj]; klub as; int pb;
ucitaj(&n,tabela);
for(i=0;i<n;i++)
tabela[i].naziv[(int)strlen(tabela[i].naziv)-1]='\0';
for(i=0;i<n;i++)
bodovi[i]=tabela[i].neresene+3*tabela[i].dobijene;
for(i=0; i<n-1;i++)
for(j=i+1;j<n;j++)
if((bodovi[i]<bodovi[j])||
((bodovi[i]==bodovi[j]) &&
(tabela[i].dobijene<tabela[j].dobijene))
)
{
as=tabela[i]; tabela[i]=tabela[j];tabela[j]=as;
pb=bodovi[i];bodovi[i]=bodovi[j];bodovi[j]=pb;
}
ispis(n,tabela);
}
Funkcija feof()
Ova funkcija ispituje da li je dostignut broj datoteke. Njen opšti oblik je
int feof(FILE *file pointer)
Funkcija feof() vraća nenultu vrednost ako je dostignut kraj datoteke.
struct slog
{ int i,j;
178
Ivan P. Stanimirović Uvod u programiranje
float aij;
};
void main()
{ int i,j,n;
struct slog p[10], q[10];
pravimatricu(p, &n);
printf("Matrica je : \n"); pisimatricu(p,n);
transponuj(p,n,q);
printf("Transponovana matrica: \n"); pisimatricu(q,n);
printf("i,j= ? "); scanf("%d%d", &i,&j);
printf("%10.3f\n",vrednost(n,p,i,j));
}
179
Ivan P. Stanimirović Uvod u programiranje
Razlika između funkcija gets() i fgets() je u tome da gets() zamenjuje znak za prelaz u novi red
null karakterom '\0', dok fgets() ostavlja znak za prelaz u novi red, pa tek onda postavlja znak '\0'.
Funkcija fgets() vraća vrednost NULL kada naiđe na znak EOF.
Funkcija fputs() poziva se izrazom
int fputs(char *string, FILE *outfile);
Pozivom ove funkcije upisuje se niz karaktera, sadržani u vrednosti parametra string, u datoteku na
koju ukazuje pointer outfile. U slučaju I/O greške ova funkcija vraća rezultat EOF. Funkcije puts() i
fputs() ne dopisuju karakter '\0' na kraj upisanog stringa. Za razliku od funkcije puts(), funkcija fputs()
ne dopisuje znak za prelaz u novi red na kraj stringa koji se upisuje.
fgets
Čita string iz fajla
char *fgets( char *string, int n, FILE *stream );
Vraća string inače NULL ako je greška ili je došlo do kraja fajla.
Koristiti feof ili ferror za određivanje da li je došlo do greške.
Parametri:
string Mesto za smeštanje podataka
n Maksimalni broj karaktera za čitanje
stream Pointer na FILE strukturu
Funkcija čita string sa ulaza zadatog argumentom stream i patmi ga u stringu. Čita karaktere od
tekuće pozicije u fajlu do i uključujući prvi newline karakter, do kraja fajla ili do broja karaktera
jednakog n-1, šta se prvo desi. Rezultat zapamćen u stringu je završen null karakterom. Newline
karakter ako je pročitan je uključen u string. Funkcija fgets je slična gets funkciji, mada gets zamenjuje
newline karakter sa NULL.
/* FGETS.C: This program uses fgets to display
* a line from a file on the screen.n*/
#include <stdio.h> void main( void )
{ FILE *stream;
char line[100];
if((stream = fopen("fgets.c", "r")) != NULL)
{ if(fgets(line, 100, stream) == NULL)
printf("fgets error\n");
else
printf("%s" , line);
fclose( stream );
}
}
fclose, _fcloseall
Zatvara fajl ili sve otvorene fajlove. int fclose( FILE *stream ); int _fcloseall( void );
feof
180
Ivan P. Stanimirović Uvod u programiranje
fread
Čita podatke iz streama.
size_t fread(void *buffer, size_t size, size_t count, FILE *stream );
Funkcija fread vraća broj zaista pročitanih itema, što može biti manje ili jednako parametru count ako
se desi greška ili se stigne do kraja fajla. Koristiti feof ili ferror da bi se razlikovao uzrok.
Parametri:
buffer Loakcija za podatke
size Veličina jednog itema u bajtovima
count Maximalni broj itema za čitanje stream pointer na FILE strukturu.
Funkcija čita do count itema a svaki je size bajtova sa ulaznog strima u buffer. File pointer povezan
sa streamom je povećan za broj bajtova koji je zaista pročitan. Ako je stream otvoren u tekstualnom
modu carriage return-linefeed par je zamenjen ejdnom linefeed characterom. File pointer nije određen
ako se desila greška.
fwrite
Upisuje podatke u stream.
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
fwrite vraća broj potopunih itema koji su upisani, a sve ostalo je slično funkciji fread.
Primer.
/* FREAD.C: This program opens a file named FREAD.OUT and
* writes 25 characters to the file. It then tries to open
* FREAD.OUT and read in 25 characters. If the attempt succeeds,
* the program displays the number of actual items read.
*/
#include <stdio.h>
void main()
{ FILE *stream;
char list[30];
int i, numread, numwritten;
/* Open file in text mode: */
if((stream = fopen("fread.out" , "w+t")) != NULL)
{ for ( i=0; i<25; i++ )
list[i] = (char)('z' - i);
/* Write 25 characters to stream */
numwritten = fwrite(list, sizeof(char), 25, stream);
printf("Wrote %d items\n", numwritten);
fclose(stream);
}
else printf("Problem opening the file\n");
if((stream = fopen("fread.out", "r+t" )) != NULL)
{ /* Attempt to read in 25 characters */
numread = fread(list, sizeof(char), 25, stream );
printf("Number of items read = %d\n", numread);
printf("Contents of buffer = %.25s\n", list);
fclose(stream);
}
else printf("File could not be opened\n");
}
fseek
Premešta file pointer na specificiranu lokaciju.
181
Ivan P. Stanimirović Uvod u programiranje
void main()
{ int niz[21], m,n,i;
FILE *f=fopen("file.txt", "w+b");
niz[0]=0;
printf("Koliko brojeva u nizu?\n"); scanf("%d",&m);
for(i=1; i<m; i++) niz[i]=niz[i-1]+2;
fwrite(niz, sizeof(int), m, f);
fclose(f);
182
Ivan P. Stanimirović Uvod u programiranje
Literatura
183
Darko Drakulić
Slika 1
Slika 2.
Slika 3.
Slika 4.
Nakon ovih koraka, klikom na dugme Finish, u lijevom dijelu ekrana u dijelu Projects
pojaviće se projekat koji je kreiran, kao i datoteka (main.c) u kojoj se nalazi glavna (main)
funkcija kreiranog projekta.
Struktura programa
int main()
{
printf("Hello world!\n");
return 0;
}
Funkcija
int main()
je glavna funkcija programa i izvršavanje programa počinje od prve linije koda ove funkcije.
Svaki projekat mora u nekom od fajlova imati ovu funkciju. Ona može imati drugačiju
definiciju (može biti nekog drugog tipa, npr. void ili može imati listu argumenata).
Red
printf("Hello world!\n");
štampa tekst „Hello world“ na ekran. Funkcija printf je definisana u datoteci stdio.h i
ona na standardni izlaz (ekran) ispisuje niz karaktera koji je njen argument. Nizovi karaktera
su ograničeni dvostrukim navodnim znacima (""). Karakter \n koji se nalazi na kraju ovog
niza je specijalni karakter koji označava novi red. Osim karaktera za novi red, postoje sljedeći
specijalni karakteri:
\t – tabulator,
\b – backspace,
\“ – dvostruki navodnici,
\\ - obrnuta kosa crta (backslash).
Promjenljive i konstante
Definisanje promjenljivih
Promjenljive su objekti koji imaju svoje ime i čija se vrijednost može mijenjati tokom
izvršenja programa.
Definisanje promjenljivih u C-u vrši se na sljedeći način:
tip_promjenljive ime_promjenljive;
Tip promjenljive mora biti neki od ugrađenih tipova u C jezik ili neki od korisnički
definisanih tipova.
Četiri osnovna tipa podataka su
int - cjelobrojni tip,
float - realni tip jednostruke tačnosti,
double - realni tip dvostruke tačnosti,
char - znakovni tip, karakter.
Iz osnovnog cjelobrojnog tipa se mogu dobiti izvedeni tipovi:
short int (short),
long int (long),
unsigned int (unsigned) – pozitivan cijeli broj.
Ukoliko je potrebno definisati više promjenljivih istog tipa, to se može učiniti u jednoj
naredbi. Naredba za definisanje cjelobrojnih promjenljivih x, y i z je
int x, y, z;
Tako, npr. možemo definisati tip "cijeli_broj" i dvije promjenljive tog "novog" tipa na
sljedeći način
typedef int cijeli_broj;
cijeli_broj a;
cijeli_broj b;
Ukoliko se radi o cijelim brojevima (tip int), vrijednosti se mogu zadati u tri
različita brojna sistema. Ukoliko vrijednost počinje cifrom koja nije nula, broj se tretira kao
dekadni. Ukoliko počinje nulom, broj se tretira kao oktalni a ukoliko počinje sa 0x ili 0X broj
se tretira kao heksadekadni.
int x, y, z;
x = 123; // dekadni broj
y = 0123; // oktalni broj
z = 0x123; // heksadekadni broj
Ukoliko je promjenljiva tipa char, vrijednost mora biti jedan karakter, ograničen
jednostrukim navodnim znacima ('). Specijalni karakteri (\n, \t..) se tretiraju kao jedan
karakter, iako se, praktično sastoje od dva karaktera. Tip char je ustvari cjelobrojna
vrijednost ASCII koda karaktera.
char a, b, c, d;
a = 'a';
b = '\n';
c = '1';
d = '.';
Moguće je u istoj naredbi definisati promjenljivu i dodjeliti joj vrijednost
int x = 5;
float y = 1.2, z = 234e-1;
char c1, c2 = 'a';
Na početku je bilo riječi o funkciji printf koja štampa proizvoljan niz karaktera na
standardni izlaz. Ista funkcija se koristi za štampanje vrijednosti uz određene izmjene.
Funkcija ima sljedeći oblik
printf("niz_znakova_za_ispis", ime_promjenljive1, ...);
Niz znakova za ispis predstavlja niz karaktera, pri čemu se znakom % pokazuje mjesto
gdje treba da se upišu vrijednosti promjenljivih koje se nalaze iza niza znakova za ispis.
Nakon znaka % ide odgovarajuće slovo, koje zavisi od tipa promjenljive:
%d – cijelobrojni tip, zapisan u dekadnom sistemu,
%o – cijelobrojni tip, zapisan u oktalnom sistemu,
%x – cijelobrojni tip, zapisan u heksadekadnom sistemu,
%f – realni tip (float i double)
%c – karakter.
Rješenje 1
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a, b;
a = 5;
b = 7;
int c = a+b;
printf("Zbir je %d\n", c);
return 0;
}
Rješenje 2
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a = 5, b = 7;
printf("Zbir je %d\n", a+b);
return 0;
}
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("int: %d\n", sizeof(int));
printf("short: %d\n", sizeof(short));
printf("long: %d\n", sizeof(long));
printf("unsigned: %d\n", sizeof(unsigned));
printf("float: %d\n", sizeof(float));
printf("double: %d\n", sizeof(double));
printf("char: %d\n", sizeof(char));
return 0;
}
Izlaz ovog programa nam daje odgovor na veličinu osnovnih tipova u C-u
int: 4
short: 2
long: 4
unsigned: 4
float: 4
double: 8
char: 1
Konstante
Slično promjenljivima, konstante su objekti koji imaju svoje ime ali im se vrijednost
ne može mijenjati tokom izvršenja programa. Za definisanje konstanti koristi se ključna riječ
const ispred tipa i imena konstante.
const int x = 5;
Primjer 3. Napisati program koji sa tastature učitava dva cijela broja i štampa njihov
zbir.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a, b;
scanf("%d", &a);
scanf("%d", &b);
printf("Zbir je %d\n", a+b);
return 0;
}
Operatori
Aritmetički operatori
Aritmetički operatori, kao što im samo ime govori, služe za izvršavanje aritmetičkih
operacija. Do sada je već korišćen operator sabiranja, a postoji ukupno pet aritmetičkih
operatora:
+ sabiranje,
- oduzimane,
* množenje,
/ dijeljenje,
% ostatak pri djeljenju (samo za cijele brojeve).
Svi ovi operatori su binarni, što znači da imaju dva argumenta i njihova svrha je jasna,
osim možda posljednjeg. Npr. izraz 8%3 daje ostatak pri dijeljenju broja 8 sa brojem 3, tj.
daje vrijednost 2.
Primjer 4. Napisati program koji sa tastature čita dva cijela broja i ispisuje njihov zbir,
razliku, proizvod i količnik.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a, b;
scanf("%d", &a);
scanf("%d", &b);
printf("a + b = %d\n", a+b);
printf("a - b = %d\n", a-b);
printf("a * b = %d\n", a*b);
printf("a / b = %f\n", (float)a/b);
printf("a % b = %d\n", a%b);
return 0;
}
Svi redovi u kodu su poznati i jasni, osim
printf("a / b = %f\n", (float)a/b);
odnosno, izraza (float)a/b. U ovom izrazu se koristi tzv. cast operator.
Cast operator
Ovi operatori imaju isti smisao kao i u matematici. U ovu grupu operatora spadaju
> veće,
< manje,
<= veće ili jednako,
>= manje ili jednako,
== jednako (dvostruko jednako - jednostruko jednako je operator dodjele),
!= različito (! je znak negacije).
Osim ovih, u ovu grupu spadaju i logički vezinici.
&& logičko I,
|| logičko ILI.
Rezultat primjene ovih operatora je logička vrijednost koja može biti tačna ili netačna,
npr.
(x>4) && (x%2 == 0)
Ovaj izraz ispituje da li je x paran broj veći od 4.
O prioritetima operatora ovdje neće biti govora, za detaljnije pogledati [?].
Bitovni operatori
Rješenje.
Zbog zapisa, veličina podataka će biti ograničena na 8 bitova.
00011000 = 24 00010001 = 17 00001000 = 8
00001100 = 12 00001100 = 12 00001011 = 11
&00001000 = 8 | 00011101 = 29 ^ 00000011 = 12
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("24&12 = %d\n", 24&12);
printf("17|12 = %d\n", 17|12);
printf("8^11 = %d\n", 8^11);
printf("17>>2 = %d\n", 17>>2);
printf("21<<3 = %d\n", 21<<3);
printf("~11 = %d\n", ~11);
return 0;
}
uslov mora biti neki logički izraz. U slučaju da je uslov tačan, izvršava se
naredba1 a u suprotnom naredba2. if izraz se može pojaviti i bez else izraza. Ako je
potrebno da se izvrši više naredbi, tada je potrebno da se stave u blok, ograničen sa vitičastim
zagradama
if(uslov)
{
naredba1_1;
naredba1_2;
naredba1_3;
...
}
else
{
naredba2_1;
naredba2_2;
naredba2_3;
...
}
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a, b;
scanf("%d", &a);
scanf("%d", &b);
printf("a + b = %d\n", a+b);
printf("a - b = %d\n", a-b);
printf("a * b = %d\n", a*b);
if(b != 0)
printf("a / b = %f\n", (float)a/b);
else
printf("Greska! Dijeljenje nulom\n");
printf("a % b = %d\n", a%b);
return 0;
}
if–else naredba ima samo dvije grane – kada je uslov ispunjen i kada nije.
Međutim nekada je potrebno ispitati više uslova i u zavisnosti od njihovih vrijednosti
izvršavati određene naredbe. U tim slučajevima se koristi if-else if-else izraz, koji će
biti prikazan na sljedećem primjeru.
Primjer 8. Napisati program koji ispituje da li je uneseni broj pozitivan, negativan ili je
jednak nuli.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x;
scanf("%d", &x);
if(x > 0)
printf("Broj je pozitivan\n");
else if(x < 0)
printf("Broj je negativan\n");
else
printf("Broj je jednak nuli\n");
return 0;
}
Operator ?
U programskom jeziku C postoji operator ? i to je jedini ternani operator, tj. ima tri
operanda. Izgled operatora je
(logicki_izraz) ? vrijednost1 : vrijednost2
Ovaj operatoj provjerava istinitost logičkog izraza i u slučaju njegove tačne vrijednosti
vraća vrijednost1 a u suprotnom vraća vrijednost2.
switch
Primjer 9. Napisati program koji provjerava da li je uneseni karakter razmak, tačka ili
neki neki drugi znak.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
scanf("%c", &c);
switch(c)
{
case ' ':
printf("Uneseni karakter je razmak\n");
break;
case '.':
printf("Uneseni karakter je tacka\n");
break;
default:
printf("Uneseni karakter nije ni tacka ni
razmak\n");
}
return 0;
}
Petlje
for
Rješenje
U ovom programu je potrebno izvršiti 5 sličnih naredbi, tj. 5 poziva funkcije printf
sa različitim argumentima. U slučajevima kada se trebaju izvršiti slične naredbe koriste se
petlje. Jedan od načina da se riješi ovaj zadatak je sljedeći
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
for(i=1; i<=5; i=i+1)
printf("%d\n", i);
return 0;
}
Sva tri izraza u for petlji su opcioni, što znači da ne moraju postojati. Izraz
for( ; ; )
je ispravan izraz i predstavlja beskonačnu petlju.
Treba primjetiti da iza linije u kojoj se nalazi for petlja ne nalazi karakter ;. To je
zato što je kraj komande tek u sljedećem redu. Kao i kod if naredbe, ukoliko se for petlja
odnosi na više komandi, potrebno ih je ograničiti vitičastim zagradama {}.
while
while petlja ima iste osobine kao for petlja i sve što se može uraditi preko for
petlje može i preko while i obrnuto. while petlja ima sljedeći oblik
while(uslov)
{
komande...
}
Slično kao for petlja, samo što nema dijela za inicijalizaciju i korak, već se
inicijalizacija mora mora obaviti prije a korak u samoj petlji.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i=1;
while(i<=5)
{
printf("%d\n", i);
i++;
}
return 0;
}
do-while
Kao i while petlja, samo što se kod do-while petlje prvo izvršavaju naredbe pa se
onda provjerava uslov. do-while petlja ima sljedeći oblik
do
{
komande...
} while(uslov);
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i=1;
do
{
printf("%d\n", i);
i++;
} while(i<=5);
return 0;
}
break i continue
Nekada postoji potreba izlaska iz petlje prije potpunog ispunjenja potrebnog uslova za
izlazak. Za to se koristi naredba break.
Primjer 11. Odštampati prvi broj (ako postoji) koji je manji od 500 a djeljiv sa brojevima 3, 4,
5 i 7.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
for(i=1; i<=500; i++)
if(i%3 == 0 && i%4 == 0 && i%5 == 0 && i%7 == 0)
{
printf("%d\n", i);
break;
}
return 0;
}
Primjer 12. Odštampati sve brojeve manje od 20 koji nisu djeljivi sa brojem 3.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
for(i=1; i<=20; i++)
{
if(i%3 == 0)
continue;
printf("%d\n", i);
}
return 0;
}
goto i labele
for(...)
for(...)
{
if(...)
goto kraj;
}
...
kraj:
...
Rad sa karakterima
Kao što je već pomenuto, u programskom jeziku C tip char je ustvari cjelobrojna
vrijednost ASCII koda datog karaktera. To znači da se char može štampati i kao karakter i
kao cijeli broj
char c = 'A';
printf("%d\n", c); // štampa ASCII kod karaktera
printf("%c\n", c); // štampa izgled karaktera
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
char i;
for(i=1; i<127; i++)
printf("%d %c\t", i, i);
return 0;
}
Ako se pogleda ASCII tabela, vidi se da, recimo karakter 'A' ima vrijednost 65,
karakter 'B' vrijednost 66, karakter 'a' ima vrijednost 97, karakter 'b' ima vrijednost
98 itd. Tako da vrijednost izraza 'A' + 10 daje vrijednost 75 odnosno karakter 'K'.
U standardnoj biblioteci, osim funkcija printf i scanf postoje funkcije koje služe
za ulaz odnosno izlaz znakovnog tipa podataka. To su funkcije getchar i putchar.
Funkcija getchar() čita jedan karakter sa standardnog ulaza (tastature) i kao
rezultat vraća njegovu ASCII vrijednost, npr. kod
char c = getchar();
čita jedan karakter sa tastature i njegovu vrijednost dodjeljuje promjenljivoj c.
Kod unosa teksta, kao indikator za kraj unosa se koristi znak za kraj datoteke, koji se
označava EOF (end of file). Ako je u pitanju unos sa tastature, znak EOF se dobija
kombinacijom tastera ctrl i z.
Primjer 14. Napisati program koji sa tastature čita karaktera sve dok se ne unese
karakter EOF i ispisuje ih na ekranu.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
int i;
while(c!=EOF)
{
c = getchar();
putchar(c);
}
return 0;
}
Riješeni zadaci
Zadatak 1. Napisati program koji za uneseno n štampa sumu prvih n prirodnih brojeva i n!
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i, suma=0, fakt=1;
scanf("%d", &n);
for(i=1; i<=n; i++)
suma += i;
printf("Suma prvih %d je %d\n", n, suma);
return 0;
}
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i;
scanf("%d", &n);
return 0;
}
Zadatak 3. Odštampati sve savršene brojeve manje od 10000 (broj je savršen ako je jednak
zbiru svojih djelilaca, osim sebe samog).
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i,suma;
if (suma==n)
printf("broj %d je savrsen\n", n);
}
return 0;
}
Zadatak 4. Napisati program koji za uneseni prirodni broj štampa zbir njegovih cifara.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, suma = 0;
scanf("%d", &n);
while(n > 0)
{
suma += n % 10; // sa n%10 se dobija posljednja cifra
n /= 10;
}
printf("%d", suma);
return 0;
}
Zadatak 5. Napisati program koji za uneseni prirodan broj ispisuje broj čije su cifre u
obrnutom redoslijedu.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, obrnuti = 0;
scanf("%d", &n);
while(n > 0)
{
obrnuti = obrnuti*10 + n % 10;
n /= 10;
}
printf("%d", obrnuti);
return 0;
}
Zadatak 6. Izračunati kvadratni korjen datog broja Njutnovom metodom sa zadatom tačnosti.
Rješenje
1 æç xö
Njutnova formula glasi yi +1 = y i + ÷ , gdje je x broj za koji se traži korjen, a
2è yi ø
početna iteracija y 0 = x + 1 . Za rješavanje ovog zadatka potrebna je funkcija koja računa
apsolutnu vrijednost datog broja. To je funkcija abs(float) koja je definisana u datoteci
math.h1.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float x, y, z, eps;
scanf("Unesite broj i tacnost: ");
scanf("%f", &x);
scanf("%f", &eps);
y = x+1;
do
{
z = y;
y = .5 * (y + x/y);
} while(abs(z-y) > eps);
printf("Korjen iz %.2f je %f", x, y);
return 0;
}
1
Pregled načajnijih funkcija standardne biblioteke je prikazano u dodatku A
Zadatak 7. Napisati program koji simulira rad kalkulatora sa osnovnim operacijama +, -, *,
/. Izraz se unosi u obliku operator operand1 operand2.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
float op1,op2;
char op;
scanf ("%c", &op);
scanf ("%f", &op1);
scanf ("%f", &op2);
printf("izraz: %.2f %c %.2f\n",op1,op,op2);
switch(op)
{
case '+':
printf("vrijednost: %.2f\n", op1 + op2);
break;
case '-':
printf("vrijednost: %.2f\n", op1 - op2);
break;
case '*':
printf("vrijednost: %.2f\n", op1 * op2);
break;
case '/':
if (op2 == 0)
printf("Greska! Dijeljenje nulom\n");
else
printf("vrijednost: %.2f\n", op1 / op2);
break;
default:
printf("Greska! Pogresan operator\n");
}
return 0;
}
Rješenje
Za rješavanje ovog zadatka potrebna je funkcija koja računa kvadratni korjen datog
broja, a to je funkcija sqrt(float) koja je definisana u datoteci math.h
Moguća su tri slučaja – jednačina nema realna rješenja (D<0), ima dvostruko rješenje
(D=0) i ima dva različita rješenja (D>0).
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float a, b, c;
scanf("%f", &a);
scanf("%f", &b);
scanf("%f", &c);
printf("Jednacina: %.2f*x^2 + %.2f*x + %.2f\n", a, b, c);
return 0;
}
Zadatak 9. Napisati program koji ispituje da li se dvije prave y=a1x+b1 i y=a2x+b2 sijeku.
Rješenje
Moguća su tri slučaja – prave su paralelne, prave se poklapaju ili se sijeku u jednoj
tački.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float a1,a2,b1,b2;
scanf ("%f",&a1);
scanf ("%f",&b1);
scanf ("%f",&a2);
scanf ("%f",&b2);
printf("y =%5.2fx + %5.2f\n",a1,b1);
printf("y =%5.2fx + %5.2f\n",a2,b2);
if (a1 == a2 && b1== b2)
printf ("prave se poklapaju\n");
else if (a1 == a2 && b1 != b2 )
printf ("prave su paralelne\n");
else
{
float x=(b2-b1)/(a1-a2);
float y=a1*x+b1;
printf ("prave se sijeku u tacki
(%5.2f,%5.2f)\n",x,y);
}
return 0;
}
Rješenje
Moguća su tri slučaja. Da se krugovi ne sijeku (udaljenost među centrima je veća od
zbira poluprečnika), da se dodiruju (udaljenost među centrima je jednaka zbiru poluprečnika)
i da se dijeku (udaljenost među centrima je manja od zbira poluprečnika).
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int x1,x2,y1,y2,r1,r2;
scanf ("%d", &x1);
scanf ("%d", &y1);
scanf ("%d", &r1);
scanf ("%d", &x2);
scanf ("%d", &y2);
scanf ("%d", &r2);
if (d>r1+r2)
printf ("kruznice se ne sijeku");
else if (d<r1+r2)
printf ("kruznice se sijeku");
else
printf ("kruznice se dodiruju");
return 0;
}
Zadatak 11. Napisati program koji za uneseno n štampa romb čija je dužina stranice n, kao na
slici (na slici n=2)
*
* *
*
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i, j, k;
scanf("%d", &n);
for(i=1; i<=n; i++)
{
for(k=n; k>i; k--)
printf(" ");
for(j=0; j<i; j++)
printf("* ");
printf("\n");
}
for(i=n-1; i>0; i--)
{
for(k=n; k>i; k--)
printf(" ");
for(j=0; j<i; j++)
printf("* ");
printf("\n");
}
return 0;
}
Zadatak 12. Napisati program koji štampa sve trocifrene brojeve kod kojih je druga cifra za
dva veća od prve a treća za jedan veća od druge.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, k;
for(i=1; i<=9; i++)
for(j=3; j<=9; j++)
for(k=4; k<=9; k++)
if(j == i+2 && k == j+1)
printf("%d%d%d\n", i, j, k);
return 0;
}
Zadatak 13. Napisati program koji uneseno mali slovo pretvara u veliko.
Rješenje
Ideja: vrijednost između malog slova i njemu odgovarajućeg velikoj je konstantna za
sva slova.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char maliC;
scanf("%c", &maliC);
return 0;
}
Zadatak 14. Napisati program koji za uneseni karakter provjerava da li je malo slovo, veliko
slovo, cifra ili neki drugi karakter.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
scanf("%c", &c);
return 0;
}
Zadatak 15. Napisati program koji sa tastature čita karaktera sve dok se ne unese karakter
EOF i broji unesenie samoglasnike i suglasnike.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
int i, suglasnici=0, samoglasnici=0;
while(c!=EOF)
{
c = getchar();
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
if(c == 'a' || c == 'e' || c == 'i' || c == 'o'
|| c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' ||
c == 'U')
samoglasnici++;
else
suglasnici++;
}
printf("Samoglasnika: %d, suglasnika: %d", samoglasnici,
suglasnici);
return 0;
}
Zadaci za vježbu
å2
n
k 2
1. Napisati program koji za uneseno n izračunava sumu
k =1
¥
2. Napisati program koji za zadatu tačnost eps izračunava broj e = å
1
k = 0 k!
m
3. Napisati program koji za unesene n i m računa broj n (bez korišćenja funkcije
pow) .
æ nö
4. Napisati program koji za uneseno n i m (n > m) računa ç ÷
è mø
5. Napisati program koji učitava n, zatim učitava n brojeva i izračunava njihovu
aritmetičku sredinu.
6. Napisati program koji određuje za koliko procenata je porasla cijena C1 ako ona
sad iznosi C2.
7. Napisati program koji izračunava sumu i proizvod dva kompleksna broja x1+iy1 i
x2+iy2
8. Napisati program koji računa zbir, razliku i proizvod razlomaka a/b i c/d.
9. Napisati program koji za uneseno n izračunava n-ti stepen kompleksnog broja,
korišćenjem De Moavrove formule3
10. Napisati program koji učitava brojeve m i n i pravi Dekartov proizvod skupova
{1,2,...,n} i {1,2,...,m}.
11. Napisati program koji za uneseno n ispisuje trougao kao na slici (na slici n=3)
1
22
333
12. Napisati program koji za uneseno n štampa kvadrate brojeva 1, 2, ... , n-1.
13. Napisati program koji za uneseno x izračunava vrijednost y po formuli
ì 1
,x > 0
ï x
y =í 0, x = 0
1
ï- , x < 0
î x
14. Napisati program koji izračunava aritmetičku sredinu cifara datog broja.
15. Napisati program koji u datom četverocifrenom broju izračunava razliku između
prve i poslednje cifre.
16. Napisati program koji za unesene n i m (m<n) izračunava sumu posljednjih m
cifara broja n.
17. Napisati program koji za unesene n i m učitava n brojeva i izračunava aritmetičku
sredinu brojeva koji su veći od m.
18. Napisati program koji učitava broj m i zatim učitava brojeve sve dok im suma ne
pređe m.
19. Napisati program koji za n unijeti cijelih brojeva računa zbir negativnih.
20. Napisati program koji za uneseno n računa n-ti član Fibonačijevog niza
21. Napisati program koji za unesena tri cijela broja ispisuje najveći.
2
Za funkciju stepenovanja pogledati dodatak A
3
Za funkcije sin i cos pogledati dodatak A
22. Napisati program koji za unesena tri cijela broja ispituje da li čine Pitagorinu
trojku.
23. *Napisati program koji nalazi NZD za dva broja korišćenjem Euklidovog
algoritma.
1 1
24. *Napisati program koji za uneseno n izračunava 1 + + ... +
2 n
25. Napisati program koji za uneseno n učitava n brojeva i određuje najveći i najmanji
među njima.
26. Napisati program koji rješava jednačinu ax+b=0.
27. Napisati program koji ispituje da li je prava y=kx+n tangenta parabole y2=2px
(vrijednosti k, n i p se unose sa tastature).
28. Napisati program koji ispituje da li se sijeku prava y=kx+n i kružnica x2+y2=r2
(vrijednosti k, n i r se unose sa tastature).
29. Napisati program koji ispituje da li je vrijednost polinoma 2x3+x2-2x+1 pozitivna
ili negativna u tački n koja se unosi sa tastature.
30. Napisati program koji ispituje da li je uneseni broj Armstrongov. Amrstrongov
broj je jednak zbiru kubova svojih cifara.
31. Napisati program koji ispituje da li je uneseni broj Nivenov. Nivenov broj je broj
koji je djeljiv sumom svojih cifara.
32. Napisati program koji učitava broj b i osnovu o < 10 i zatim ispisuje broj o u
dekadnom brojnom sistemu.
33. Napisati program koji izračunava površinu pravougaonika čije su stranice
paralelne koordinatnim osama, a zada je preko dijagonalnih tjemena (x1, y1) i (x2,
y2)
34. Napisati program koji ispituje da li tačke A(x1, y1), B(x2, y2), C(x3, y3) i D(x4, y4)
čine paralelogram ABCD.
35. Napisati program koji štampa kvadrant u kojem se nalazi tačka (x1, y1).
36. Napisati program koji učitava vrijednost n (n < 180) i ispituje da li je ugao od n
stepeni oštar, prav ili tup.
37. Napisati program koji računa maksimim za unesena četiri broja.
38. Napisati program koji ispituje da li tri unesene duži mogu da naprave trougao
(koristiti nejednakost trougla).
39. Napisati program koji računa površinu trougla datog preko svojih tjemena (x1, y1),
(x2, y2), (x3, y3) (koristiti Heronov obrazac).
40. Napisati program koji provjerava da li je uneseni karakter slovo, tačka ili razmak.
41. Napisati program koji za uneseni broj n ispisuje n-ti dan u nedjelji (npr. za 1 se
ispisuje „Ponedjeljak“.
42. Napisati program koji provjerava da li tri cijela broja koja se unose sa tastature h,
m i s čine ispravno vrijeme (h:m:s).
43. Napisati program koji provjerava da li tri cijela broja koja se unose sa tastature d,
m i g čine ispravan datum (d.m.g).
44. Napisati program koji za uneseni broj n ispisuje n-ti mjesec u godini.
45. Napisati program koji provjerava da li je unesena godina prestupna.
46. Napisati program koji ispisuje ocjenu koju je student dobio na ispitu na osnovu
osvojenih bodova (5 – od 0 do 50, 6 – od 51 do 60 itd).
Funkcije
tip_funkcije predstavlja tip rezultata kojeg funkcija vraća. To može biti bilo koji
od standarnih ili korisnički definisanih tipova programskog jezika C ili tip void
ime_funkcije je proizvoljan identifikator funkcije za koje važe ista pravila kao i
za davanje imena promjenljivima
lista_argumenata je niz od nijednog, jednog ili više argumenata funkcije. Svaki
argument mora imati svoje ime i tip. U slučaju da postoji više argumenata svaki novi
je potrebno odvojiti zarezom od prethodnog.
Osim deklaracije funkcije potrebno je definisati šta ta funkcija radi. Definicija funkcije
se piše u bloku naredbi ograničenim {}. Npr. za prvu funkciju bi to izgledalo
int funkcija()
{
Tijelo funkcije
...
}
Deklaracija funkcije mora biti iznad main() funkcije, dok definicija može biti i
ispod, ali u prostijim programima je lakše napisati definiciju funkcije odmah iza deklaracije.
Pozivu ove funkcije je potrebno kao argumente zadati dva realna broja a ona kao
rezultat vraća njihov zbir
float rezultat = saberi(2.4, 3.5);
U slučaju da je funkcija tipa void, ona ne vraća nikakv rezultat. Ukoliko je potrebno
izaći iz te funkcije, može se pozvati komanda return bez vrijednosti iza nje.
Bitno je napomenuti da kod ovakvog definisanja funkcija argumenti ne mijenjaju
svoje vrijednosti nakon poziva funkcije, tj. njihova vrijednost ostaje nepromjenjena. U
sljedećem programu vrijednost promjenljive n ostaje nepromjenjena u nakon pozova funkcije
f, iako se u funkciji vrijednost argumenta uvećava za jedan.
void f(int n)
{
n++;
}
int main()
{
int n = 1;
f(n);
printf("%d\n", n);
return 0;
}
Rješenje
int faktorijel(unsigned int broj)
{
int i, fakt=1;
Rješenje
int prost(unsigned int broj)
{
int i;
for(i=2; i<broj; i++)
if(broj % i == 0)
return 0;
return 1;
}
Obzirom da u C-u ne postoji logički tip, ukoliko se radi o nekoj funkciji koja treba da
vrati vrijednost tačno/netačno, kao što je slučaj sa ovom, tada je ona tipa int i vraća 1 ako
treba da vrati tačno a 0 ako treba da vrati netačno.
Iz tog razloga ova funkcija je tipa int i u zavisnosti od (ne)ispunjenja uslova vraća se
vrijednost 0 ili vrijednost 1.
Primjer 17. Napisati program koji štampa sve proste brojeve manje od 1000.
Rješenje
Ovdje ćemo iskoristiti funkciju iz prethodnog primjera. Za svaki broj od 1000
pozivanjem funkcije iz prethodnog primjera ćemo ispitati da li je prost.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
for(i=1; i<=1000; i++)
if(prost(i) == 1)
printf("%d\t", i);
return 0;
}
Primjer 18. Napisati program koji ispisuje sve brojeve manje od 500 koji su Nivenovi i
Armstrongovi.
Rješenje
Kod zadataka koji su kompleksniji, najlakše je problem razbiti na podprobleme i za
svaki od njih uvesti funkciju. Ovdje će biti uvedene četiri funkcije – za računanje sume cifara
datog broja, za računanje sume kubova cifara datog broja i funkcija koje ispituju da li je broj
Nivenov odnosno Armstrongov.
#include <stdio.h>
#include <stdlib.h>
int sumacifara(int n)
{ //
int suma = 0 ;
for ( ; n>0; n/=10)
suma += n%10;
return suma;
}
int sumakubova(int n)
{
int suma = 0 ;
for ( ; n>0; n/=10)
suma += pow(n%10, 3);
return suma;
}
int nivenov(int n)
{
if(n % sumacifara(n) == 0)
return 1;
return 0;
}
int armstrongov(int n)
{
if(n == sumakubova(n))
return 1;
return 0;
}
int main()
{
int i;
for(i=1; i<=500; i++)
if(armstrongov(i) && nivenov(i))
printf("%d\t", i);
return 0;
}
Rekurzija
Primjer 19. Napisati rekurzivnu funkciju koja izračunava faktorijel datog broja.
Rješenje
Funkcija faktorijela se rekurzivno može predstaviti kao f(n) = n*f(n-1) sa
početnim uslovom f(1) = 1.
int faktorijel(unsigned int n)
{
if(n == 1)
return 1;
return n*faktorijel(n-1);
}
Primjer 20. Napisati rekurzivnu funkciju koja štampa prvih n prirodnih brojeva u
obrnutom redoslijedu.
Rješenje
void stampa(unsigned int n)
{
if(n == 0)
return;
printf("%d\n", n);
stampa(n-1);
}
Nizovi
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[10], i, suma=0, min, maks;
for(i=0; i<10; i++)
scanf("%d", &a[i]);
min = maks = a[0];
return 0;
}
Primjer 22. Učitati niz sa tastature dvije matrice 3x3 pronaći njihov zbir i odštampati ga na
ekranu.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int mat1[3][3], mat2[3][3], zbir[3][3];
int i, j;
printf("Unesite elemente matrice 1\n");
for(i=0; i<3; i++)
for(j=0; j<3; j++)
scanf("%d", &mat1[i][j]);
return 0;
}
Primjer 23. Napisati rekurzivnu i iterativnu funkciju koja izračunava n-ti član (n < 20)
Fibonačijevog niza.
Rješenje:
n-ti član Fibonačijevog niza zadat je rekurentnom relacijom fn = fn-1 + fn-2.
int fib_rek(int n)
{
if(n > 20)
{
printf("Greska! n mora biti manje od 20\n");
return -1;
}
if(n == 1 || n == 2)
return 1;
return fib_rek(n-1) + fib_rek(n-2);
}
int fib_iter(int n)
{
if(n > 20)
{
printf("Greska! n mora biti manje od 20\n");
return -1;
}
int niz[20], i;
niz[0] = niz[1] = 1;
for(i=2; i<20; i++)
niz[i] = niz[i-1] + niz[i-2];
return niz[n];
}
Nizovi karaktera
Ukoliko želimo da definišemo funkciju koja za argument ima niz, niz kao argument
funkcije možemo prenijeti na jedan od sljedećih načina
tip_funkcije f1(tip_niza ime_niza[]);
tip_funkcije f2(tip_niza* ime_niza);
int main()
{
int niz[2] = {1, 2};
f(niz);
printf("%d\n%d", niz[0], niz[1]);
return 0;
}
Primjer 24. Napisati funkciju koja dopisuje jedan niz karaktera na drugi.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
char prvi[10], drugi[10], rezultat[20];
scanf("%s", &prvi);
scanf("%s", &drugi);
prepis(prvi, drugi, rezultat);
printf("%s", rezultat);
return 0;
}
Riješeni zadaci
Zadatak 16. Napisati funkciju koja provjerava da li dat niz karaktera predstavlja ispravan
hekdasecimalni broj u obliku #broj i funkciju koja pretvara dati niz karaktera koji predstavlja
heksadekadni broj u dekadni.
Rješenje:
Radi lakšeg rješavanja ovog zadatka, uvešćemo pomoćne funkcije koje ispituju da li
dati karakter predstavlja cifru, slovo između a i f i slovo između A i F. U rješenju se koristi
funkcija strlen(char s[]) biblioteke string.h4 koja vraća duzinu niza karaktera s i
koja je analogna funkciji int duzina(char s[]).
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int cifra(char c)
{
if(c >= '0' && c <= '9')
return 1;
return 0;
}
int slovoa_f(char c)
{
if(c >= 'a' && c <= 'f')
return 1;
return 0;
}
int slovoA_F(char c)
{
if(c >= 'A' && c <= 'F')
return 1;
return 0;
}
4
Opis datoteke string.h dat je u dodatku A
int hexudek(char hex[])
{
int i, rez = 0;
int d = strlen(hex);
for(i=1; hex[i] != '\0'; i++)
{
if(cifra(hex[i]) == 1)
rez += (hex[i] - '0') * (int) pow(16, d-i-1);
else if(slovoa_f(hex[i]) == 1)
rez += (hex[i] - 'a' + 10) *
(int) pow(16, d-i-1);
else
rez += (hex[i] - 'A' + 10) *
(int) pow(16, d-i-1);
}
return rez;
}
int main()
{
char niz[10];
scanf("%s", &niz);
if(ispravan(niz) == 0)
printf("Broj nije ispravan\n");
else
printf("%s = %d", niz, hexudek(niz));
return 0;
}
Rješenje
U programu ćemo koristiti ugrađenu funkciju isdigit(char c) koja je definisana
u datoteci ctype.h5 koja ispituje da li je dati karakter cifra i analogna je funkciji
cifra(char c) iz prethodnoh zadatka.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
5
Opis datoteke ctype.h dat je u dodatku A
return 1;
}
int main()
{
char izraz[5];
scanf("%s", &izraz);
if(ispravan(izraz) == 0)
{
printf("Izraz nije ispravan!\n");
return -1;
}
Zadatak 18. Napisati program koji sa tastature učitava polinom (stepen < 10 i koeficijente),
štampa ga na ekran, učitava vrijednost v i štampati vrijednost polinoma u tački v.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
float koef[11];
int stepen, i;
printf("Unesite stepen polinoma:");
scanf("%d", &stepen);
printf("P(x) = ");
for(i=0; i<=stepen; i++)
printf("%.2f*x^%d + ", koef[i], i);
printf("\n");
float v, vr = 0;
printf("Unesite vrijednost v: ");
scanf("%f", &v);
return 0;
}
Zadaci za vježbu
1. Sa ulaza se unosi osnova <= 10 i broj. Provjeriti da li je taj broj ispravan broj za datu
osnovu i ako jeste izračunati njegovu vrijednost u osnovi 10.
2. Sa ulaza se unosi broj u osnovi deset i osnova <= 10. Odštampati vrijednost datog
broja u datoj osnovi
3. Napisati program koji sa tastature čita broj n (najviše 100), niz od n cijelih brojeva i
vrijednost n a zatim provjerava da li je v u nizu, na kom je mjestu i koliko u nizu ima
brojeva manjih od n
4. Za dati niz realnih brojeva ispitati da li je „testerast“ (niz je testarast ako važi
x1<x2>x3<x4>... ili x1>x2<x3>x4<...)
5. Napisati program koji ispisuje sve proste brojeve manje od 10000 koristeći
Eratostenovo sito.
6. Zadatu matricu ispisati spiralno, u smjeru kazaljke na satu, počevši od A11.*
7. Napisati program koji učitava dvije realne kvadratne matrice (prvo dimenzije pa
elemente, najviše 10x10) i ispisuje njihov proizvod.
8. Napisati program koji učitava dva polinoma i ispiruje nihov proizvod.
9. Napirati program koji izračunava n-ti stepen datog polinoma.
10. Napirati program koji izračunava n-ti izvod datog polinoma.
11. Napisati rekurzivnu funkciju koja ispisuje romb čija je dužina stranice n, kao na slici
(na slici n=2)
*
* *
*
12. Napisati program koji sa tastature učitava broj n i štampa sve permutacije tih n
elemenata.
13. Napisati funkciju koja dati realni broj prevodi u odgovarajući niz karaktera, npr.
123.123 u „123,123“
14. Napisati funkcije koje ispituju da li su sva niza karaktera jednaka i da li su jednaki na
prvih n mjesta (ne koristiti datoteku string.h)
15. Napisati funkciju koja koja dati niz karaktera razbija na dva niza karaktera date
dužine.
16. Data su dva niza karaktera. Ispitati da li je drugi niz karaktera podniz prvog.
17. Data su dva niza karaktera. Napisati program koji pravi novi niz karaktera koji se
sastoji od karaktera koji se pojavljuju u oba niza.
18. Data su dva niza karaktera. Napisati program koji pravi novi niz karaktera koji se
sastoji od karaktera koji se pojavljuju u prvom, a ne pojavljuju se u drugom nizu.
19. Napisati program koji vrši šifrovanje ulaznog teksta: svako slovo sa ulaza zamjenjuje
se sa slovom koje je na tri mjesta udaljeno od njega u abecedi.
20. Napisati funkciju koja na osnovu date reči formira šifru koja se dobija tako što se
svako slovo u riječi zameni sa naredna tri slova koja su mu susedna u abecedi. Na
primer, reč "tamo" treba da bude zamenjena sa "uvwbcdnoppqr".
21. Napisati program koji u datom tekstu uklanja sve višestruke razmake.
22. Napisati program koji iz datog teksta štampa riječi (neprekidne nizove karaktera).
Svaka riječ treba da se nalazi u novom redu.
23. Napisati funkcije koje dati niz slova pretvara u mala, odnosno u velika slova.
24. Napisati program koji radi s dvodimenzionim matricama koristeći nizove (učitavanje,
štampa i sabiranje)
25. Napisati funkciju koja provjerava da li je data matrica simetrična
26. Napisati funkciju koja provjerava da li je data matrica magični kvadrat (magični
kvadrat je kadratna matrica kod koje je suma brojeva u svakom redu i koloni jednaka)
27.
a. Napisati funkciju koja za datu matricu računa transponovanu matricu
b. Napisati funkciju koja provjerava da li je data matrica jedinična
28. Za datu matricu ispitati da li je ortogonalna (matrica je ortogonalna ako važi
A·AT = E)
Pokazivači
U principu, vrijednost same adrese nas i ne zanima, ali pomoću ovoga možemo
provjeriti jednu važnu činjenicu vezanu za alokaciju memorije za nizove.
Primjer 24. Napisati program koji štampa memorijske lokacije članova niza od 10 cijelih
brojeva.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int niz[10], i;
for(i=0; i<5; i++)
printf("Adresa clana %d: %d\n", i, &niz[i]);
return 0;
}
Ovo nam pokazuje da se elementi niza u memoriji nalaze na susjednim lokacijama, tj.
drugi element se nalazi iza lokacije na kojoj se nalazi prvi itd.
6
Rezultat ovog programa neće biti uvijek isti, moguće je da se razlikuju vrijednosti adresa.
Ako u kodu pokušamo odštampati vrijednost promjenljive „niz“, tj.
printf("Vrijednost promjenljive \"niz\": %d\n", niz);
dobićemo
Vrijednost promjenljive "niz": 2293520
Ovim je pokazano, da je promjenljiva koja označava niz, ustvari pokazivač koji
pokazuje na prvi element niza.
Da bi se definisala promjenljiva koja sadrži pokazivač na neki tip, potrebno je iza tipa
promjenljive dodati znak *. Tako dobijamo četiri tipa pokazivača, na svaki od osnovnih
tipova:
char*
int*
float*
double*
Nakon ovoga, postaje jasno šta je karakter & ispred imena promjenljive u funkciji
scanf - funkcija za argument ima adresu promjenljive a ne njenu vrijednost. Razlozi za to
biće detaljno objašnjeni u dijelu u kojem će se govoriti o pokazivačima kao argumentima
funkcija.
Obzirom da veličina tipova nije ista na svim sistemima, dobra praksa je da se pri
alokaciji koristi operator sizeof o kojem je ranije bilo govora.
U opštem slučaju, definisanje pokazivača i alokacija memorije za proizvoljan tip
podataka izgleda
TIP *p = (TIP*) malloc(sizeof(TIP));
pri čemu TIP može biti bilo koji od osnovnih ili korišnički-definisanih tipova.
Primjer 25. Napisati program koji sa tastature čita dva broja i ispisuje njihov zbir na ekranu.
Memoriju za brojeve alocirati dinamički.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p1, *p2;
p1 = (int*) malloc(sizeof(int));
p2 = (int*) malloc(sizeof(int));
scanf("%d", p1);
scanf("%d", p2);
printf("%d + %d = %d", *p1, *p2, *p1 + *p2);
free(p1);
free(p2);
return 0;
}
U ovom primjeru u funkciji scanf ne postoji karakter & ispred imena promjenljivih,
jer su promjenljive p1 i p2 pokazivači, pa oni u sebi sadrže adrese - a to je upravo ono šta
funkcija scanf očekuje za argument.
Nizovi i pokazivači
Dosadašnje korišćenje pokazivača i nije bilo tako efektno, tj. za svaku promjenljivu
smo morali definisati pokazivač i alocirati potrebnu memoriju a to se automatski dešava kada
ne koristimo pokazivače. Pokazivači pokazuju svoju snagu i svrsishodnost korišćenja kada je
potrebno alocirati memoriju za nizove. Do sada je svaki niz imao ograničenu veličinu - pri
definisanju niza smo navodili maksimalnu veličinu koliku niz može da ima. Ovo je loše iz dva
razloga. Prvi od njih je postojanje mogućnosti da je korisniku potreban veći niz, a drugi
razlog je da postoje memorijske lokacije koje alociramo bez potrebe. Nrp. ako definišemo niz
od maksimalno 100 elemenata, našem korisniku može zatrebati niz od više elemenata, ili pak,
korisniku je možda potreban niz od samo nekoliko elemenata pri čemu svi ostali elementi
zazumaju memoriju bez potrebe.
Pokazivači omogućavaju i dinamičku alokaciju nizova, tačnije omogućavaju alokaciju
memorije za proizvoljan niz u toku izvršavanja programa. Osobina niza da mu se svi elementi
nalaze jedan za drugim i da je ime promjenljive koja označava niz ustvari pokazivač na prvi
element omogućava vrlo laku alokaciju memorije za nizove.
Dovoljno je definisati pokazivač određenog tipa i alocirati onoliko memorije koliko je
potrebno za smještanje cijelog niza. U opštem slučaju, alokacija memorije za niz od n
elemenata niza proizvoljnog tipa izgleda
TIP* niz = (TIP*) malloc(sizeof(TIP)*n);
pri čemu TIP može biti bilo koji od osnovnih ili definisanih tipova.
Primjer 26. Napisati program koji sa tastature čita proizvoljan broj n, zatim definiše niz od n
cijelih, učitava elemente niza i pronalazi im aritmetičku sredinu.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i;
scanf("%d", &n);
int *niz = (int*) malloc(sizeof(int)*n);
for(i=0; i<n; i++)
scanf("%d", &niz[i]);
double zbir=0.0;
for(i=0; i<n; i++)
zbir += niz[i];
printf("%3.2f", zbir/n);
free(niz);
return 0;
}
Primjer 27. Napisati program koji sa tastature čita proizvoljan broj n, zatim definiše niz od n
realnih brojeva, učitava i štampa elemente niza pristupajući im preko njihovih adresa.
Rješenje
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i;
scanf("%d", &n);
float *niz = (float*) malloc(sizeof(float)*n);
for(i=0; i<n; i++)
scanf("%f", niz+i);
free(niz);
return 0;
}
void fv(int x)
{
x++;
}
void fa(int* x)
{
(*x)++;
}
int main()
{
int x = 5;
fv(x);
printf("%d\n", x);
fa(&x);
printf("%d\n", x);
return 0;
}
Funkcija fv za argument dobija vrijednost promjenljive x, tj. broj 5 i ona ustvari samo
tu vrijednost povećava za jedan dok vrijednost promjenljive x ostaje 5 i nakon izvršavanja
funkcije fv. Funkcija fa za argument dobija adresu promjenljive x i komandom (*x)++ se
povećava za jedan vrijednost koja se nalazi na lokaciji x, tj. mijenja se stvarna vrijednost
promjenljive x.
Poziv prve funkcije ne mjenja vrijednost promjenljive x, a poziv druge je mijenja.
Rezultat izvršavanja ovog programa je
5
6
Ova osobina se naziva bočni efekat ili side-effect jer omogućava mjenjanje vrijednosti
promjenljivih kroz pozivanje funkcija. Ova osobina omogućava da funkcija vrati više od
jedne vrijednosti. Potrebno je u glavnom programu definisati promjenljive, proslijediti
funkciji njihove adrese i nakon izvršavanja programa u tim promjenljivima dobijamo
određene rezultate.
Primjer 27. Napisati funkciju koja za dati niz nalazi minimum, maksimum i aritmetičku
sredinu.
Rješenje
#include <stdio.h>
#include <stdlib.h>
void mmas(int* niz, int d, int* min, int* max, float* as)
{
int i, suma = 0;
int mi=niz[0], ma=niz[0];
for(i=0; i<d; i++)
{
if(mi > niz[i])
mi = niz[i];
if(ma < niz[i])
ma = niz[i];
suma += niz[i];
}
*as = (float) suma / d;
*min = mi;
*max = ma;
}
int main()
{
int niz[5] = {4, 2, 8, 6, 1};
int min, max;
float as;
return 0;
}
Kada su opisivani nizovi kao argumenti funkcija rečeno je da kada je niz argument
funkcije, vrijednost elemenata niza se može promjeniti u funkciji. Sada je jasno i zašto - ime
niza je, ustvari, pokazivač na prvi elemenat niza, pa je argument ustvari adresa prvog
elementa a to omogućava i mijenjanje vrijednosti niza.
Strukture
Struktura je skup jedne ili više promjenljivih koje su grupisane radi lakše manipulacije
sa njima. Sintaksa definisanja strukture je
struct ime_strukture
{
tip1 ime1;
tip2 ime2;
...
};
Definicijom strukture se, ustvari, definiše tip imena struct ime_strukture i u
programu se mogu praviti promjenljive ovoga tipa. Svaka promjenljiva ovog tipa se sastoji od
skupa promjenljivih koje su definisane u strukturi. Tim promjenljivim se pristupa preko
operatora tačka (.) i sa njima se radi kao sa običnim promjenljivim.
Primjer 28. Napisati strukturu za čuvanje podataka o tačkama u ravni, funkciju za štampanje
tačke i funkciju za izračunavanje udaljenosti između dvije tačke.
Rješenje
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct tacka
{
float x;
float y;
};
scanf("%f", &t1.x);
scanf("%f", &t1.y);
scanf("%f", &t2.x);
scanf("%f", &t2.y);
odstampaj(t1);
odstampaj(t2);
system("PAUSE");
return 0;
}
U praksi se najčešće definiše tip koji predstavlja tip strukture, da se ne bi svaki put
morala navoditi ključna riječ struct. Tako bi npr. u prošlom primjeru mogli definisati tip
Tacka pomoću ključne riječi typedef:
typedef struct tacka Tacka;
i onda bi koristili tip Tacka umjesto struct tacka. Korišćenjem ovog novog
naziva tipa možemo definisati dvije promjenljive tipa tačka na sljedeći način:
Tacka t1, t2;
Još kraći zapis je da se pri definiciji strukture definiše i tip, u prošlom primjeru bi to
izgledalo
typedef struct tacka
{
float x;
float y;
} Tacka;
Pokazivači na strukture
Zadaci za vježbu
Algoritmi sortiranja i pretrage
Binarna pretraga
Primjer 29. Napisati funkciju koja pretražuje dati neopadajući niz pomoću algoritma binarne
pretrage
Rješenje
int BinPretraga(int* niz, int d, int x)
{ // Iterativna binarna pretraga
int lijevi = 0;
int desni = d-1;
while(lijevi <= desni)
{
int m = (lijevi+desni) / 2;
if(x == niz[m])
return m;
else if(x < niz[m])
desni = m-1;
else
lijevi = m+1;
}
return -1;
}
Bubble sort
Primjer 30. Napisati funkciju koja dati niz sortira pomoću algoritma Bubble sort
Rješenje
void SortBubble(int* niz, int duzina)
{
int i, j;
for(i=0; i<duzina; i++)
for(j=i; j<duzina; j++)
if(niz[i] > niz[j])
{
int x = niz[i];
niz[i] = niz[j];
niz[j] = x;
}
}
Sortiranje umetanjem
Primjer 31. Napisati funkciju koja dati niz sortira pomoću algoritma sortiranja umetanjem.
Rješenje
void SortUmetanje(int* a, int d)
{ // Osnovna varijanta sortiranja umetanjem
int i, j;
for(i=1; i<d; i++)
{
int x = a[i];
j = i-1;
while(j>0 && x > a[j])
{
a[j+1] = a[j];
j = j-1;
}
a[j+1] = x;
}
}
Sortiranje izborom
Primjer 32. Napisati funkciju koja dati niz sortira pomoću algoritma sortiranja izborom.
Rješenje
void SortIzborom(int* a, int d)
{ // Varijanta 1
int i, j, indexNajmanjeg;
for(i=0; i<d-1; i++)
{
indexNajmanjeg = i;
int najmanji = a[i];
for(j=i+1; j<d; j++)
{
QuickSort
Primjer 33. Napisati funkciju koja dati niz sortira pomoću algoritma QuickSort.
Rješenje
void swap(int v[], int i, int j)
{
int temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
MergeSort
Primjer 34. Napisati funkciju koja dati niz sortira pomoću algoritma MergeSort.
Rješenje
void Merge(int* a, int d1, int d2)
{ // Funkcija koja spaja dva podniza tako da se dobije
sortirani niz
int* novi = (int*) malloc(sizeof(int) * (d1+d2));
int i=0, j1=0, j2=0;
free(novi);
}
U svakom algoritmu sortiranja niz koji se sortira može biti proizvoljan: niz cijelih
brojeva, niz realnih brojeva, niz karaktera ili pak niz promjenljivih nekog korisnički
definisanog tipa. Jedini uslov je da postoji kriterijum po kojem se elementi niza mogu
upoređivati.
Primjer 35. Podaci o vektoru se sastoje od koordinata x, y i z. Napisati strukturu za čuvanje
podataka o vektoru. Sa tastature učitati broj n a zatim učitati n vektora i sortirati ih po
intenzitetu korišćenjem sortiranja umetanjem.
#include <stdio.h>
#include <stdlib.h>
typedef struct v
{ float x;
float y;
float z;
}vektor;
for(i=0;i<d; i++)
{
scanf("%f", &niz[i].x);
scanf("%f", &niz[i].y);
scanf("%f", &niz[i].z);
}
}
float intenzitet(vektor v)
{
return (float) sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
}
int main()
{
int n;
scanf("%d", &n);
vektor *niz=(vektor*)malloc(sizeof (vektor)*n);
ucitaj(niz,n);
sort(niz,n);
ispisi(niz,n);
free(niz);
return 0;
}
Stek i red
Stek je struktura podataka koja predstavlja kontejner promjenljivih istog tipa. Nad
stekom su definisane dvije operacije: push (dodaj) i pop (ukloni). Osobina steka je da se
posljednje dodat elemenat prvi uklanja sa steka. Zato se stek naziva LIFO (last-in-first-out)
struktura podataka.
Ovdje će biti prikazana dva načina implementacije steka - statički, preko niza
unaprijed definisane maksimalne dužine i dinamički - preko pokazivača na strukturu koja
predstavlja jedan elemenat steka. Stek se sastoji od elemenata koji međusobno čine povezanu
listu, kao na slici.
Svaki član liste se sastoji od nekog podatka i pokazivača na sljedeći član liste.
Posljednji član pokazuje na NULL
Primjer 36. Napisati program koji omogućava rad sa stekom cijelih brojeva.
int stek[MAXVALUE];
int brElem = 0;
void Push(int v)
{
if(brElem == MAXVALUE)
{
printf("Stek je pun\n");
return;
}
stek[brElem++] = v;
printf("Dodaje se element %d\n", v);
}
void Pop()
{
if(brElem == 0)
{
printf("Stek je prazan\n");
return;
}
printf("Uklanja se element %d\n", stek[brElem--]);
}
void Print()
{
int i;
printf("Stek: ");
for(i=0; i<brElem; i++)
printf("%d ", stek[i]);
printf("\n");
}
int main()
{
Push(5);
Push(10);
Push(0);
Print();
Pop();
Print();
return 0;
}
typedef struct el
{
int v;
struct el* sljedeci;
} Elem;
Elem* stek;
void Push(int v)
{
Elem* novi = (Elem*) malloc(sizeof(Elem));
novi->v = v;
novi->sljedeci = stek;
stek = novi;
printf("Dodaje se element %d\n", v);
}
void Pop()
{
if(stek == NULL)
{
printf("Stek je prazan\n");
return;
}
int v = stek->v;
Elem* prvi = stek;
stek = stek->sljedeci;
free(prvi);
printf("Uklanja se element %d\n", v);
}
void Print()
{
Elem* t = stek;
printf("Stek: ");
while(t != NULL)
{
printf("%d ", t->v);
t = t->sljedeci;
}
putchar('\n');
}
int main()
{
Push(5);
Push(7);
Push(6);
Print();
Pop();
Print();
Push(1);
Print();
return 0;
}
Primjer 37. Napisati program koji omogućava rad sa redom cijelih brojeva.
Red je slična struktura steku, s tim da se iz reda uklanja onaj element koji je prvi došao
u red, zato se red naziva FIFO (first-in-first-out) struktura. Red će se implementirati na dva
načina kao i stek.
int red[MAXVALUE];
int brElem = 0;
int Push(int v)
{
if(brElem == MAXVALUE)
{
printf("Red je pun\n");
return;
}
red[brElem] = v;
brElem++;
printf("Dodaje se element %d\n", v);
}
void Pop()
{
if(brElem == 0)
{
printf("Red je prazan\n");
return -1;
}
int v = red[0];
int i;
for(i=0; i<brElem; i++)
red[i] =red[i+1];
brElem--;
printf("Uklanja se element %d\n", v);
}
void Print()
{
int i;
printf("Red: ");
for(i=0; i<brElem; i++)
printf("%d ", red[i]);
printf("\n");
}
typedef struct el
{
int v;
struct el* sljedeci;
} Elem;
Elem* red;
void Push(int v)
{
Elem* novi = (Elem*) malloc(sizeof(Elem));
novi->v = v;
novi->sljedeci = red;
red = novi;
printf("Dodaje se element %d\n", v);
}
void Pop()
{
if(red == NULL)
printf("Red je prazan\n");
else if(red->sljedeci == NULL)
{
int v = red->v;
free(red->sljedeci);
red = NULL;
}
else
{
Elem *e = red;
while(e->sljedeci->sljedeci != NULL)
e = e->sljedeci;
int v = e->sljedeci->v;
free(e->sljedeci);
e->sljedeci = NULL;
printf("Uklanja se element %d\n", v);
}
}
void Print()
{
Elem* t = red;
printf("Red: ");
while(t != NULL)
{
printf("%d ", t->v);
t = t->sljedeci;
}
putchar('\n');
}
int main()
{
Push(5);
Push(7);
Push(6);
Print();
Pop();
Print();
return 0;
}
Jednostruko povezane liste
Primjer 38. Napisati program koji omogućava rad sa jednostruko povezanim listama čiji su
elementi parovi (kljuc, vrijednost). Implementirati funkcije za dodavanje elementa u listu (na
proizvoljno mjesto), pretragu liste po ključu i štampu elemenata liste.
Rješenje
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct el
{
int kljuc;
char vrijednost[10];
struct el* sljedeci;
} Elem;
void odstampaj(Elem* e)
{
if(e == NULL)
{
printf("---Kraj liste---\n");
return;
}
printf("%d %s\n", e->kljuc, e->vrijednost);
odstampaj(e->sljedeci);
}
void oslobodi_memoriju(Elem* e)
{
if(e == NULL)
return;
Elem *n = e->sljedeci;
free(e);
oslobodi_memoriju(n);
}
int main()
{
dodaj(lista, 3, "tri");
dodaj(lista, 2, "dva");
dodaj(lista, 6, "sest");
dodaj(lista, 4, "cetiri");
odstampaj(lista);
pronadji(lista, 6);
pronadji(lista, 12);
oslobodi_memoriju(lista);
return 0;
}
Primjer 39. Napisati program koji omogućava rad sa jednostruko povezanim listama čiji su
elementi parovi (kljuc, string). Implementirati funkcije za dodavanje elementa u listu tako da
lista bude sortirana po ključu i funkciju za izbacivanje elementa iz liste sa zadatim ključem
kao i štampu elemenata liste.
Rješenje
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct el
{
int kljuc;
char string[10];
struct el* sljedeci;
} Elem;
void odstampaj(Elem* e)
{
if(e == NULL)
{
printf("---Kraj liste---\n");
return;
}
printf("%d %s\n", e->kljuc, e->string);
odstampaj(e->sljedeci);
}
void oslobodi_memoriju(Elem* e)
{
if(e == NULL)
return;
Elem *n = e->sljedeci;
free(e);
oslobodi_memoriju(n);
}
int main()
{
dodaj(lista, 3, "tri");
dodaj(lista, 2, "dva");
dodaj(lista, 6, "sest");
dodaj(lista, 4, "cetiri");
dodaj(lista, 1, "jedan");
dodaj(lista, 8, "osam");
dodaj(lista, 9, "devet");
dodaj(lista, 7, "sedam");
dodaj(lista, 5, "pet");
odstampaj(lista);
izbaci(lista, NULL, 6);
odstampaj(lista);
izbaci(lista, NULL, 1);
odstampaj(lista);
izbaci(lista, NULL, 9);
odstampaj(lista);
oslobodi_memoriju(lista);
return 0;
}
Grafovi
Graf se definiše kao uređeni par G=(V,E), gde je V konačan, neprazan skup čvorova, a
E je skup grana (veza između čvorova).
Osnovni pomjovi vezani za graf su:
Stepen čvora grafa je broj grana koje uparuju taj čvor.
Dve grane su susjedne ako imaju isti čvor.
Grana koja spaja čvor sa samim sobom naziva se petljom.
Graf koji nema nijednu petlju nazivaju se prostim grafom.
Graf je regularan ako su svi čvorovi istog stepena.
Graf je usmjeren ukoliko su mu grane usmjerene, odnosno ukoliko se zna koji čvor je
početak a koji čvor je kraj grane.
Svaki graf se može grafički prikazati kao crtež koji se sastoji od tačaka i linija koje
predstavljaju čvorove i grane grafa.
Na slici ... je prikazan jedan neusmjeren graf a na slici ... usmjeren graf.
1 2
1 2
3
3
4
4 5
5
6
6
Postoje dva načina da se predstavi graf - preko matrica povezanosti i preko lista
povezanosti.
Matrica povezanosti za graf G koji ima n čvorova je matrica dimenzija nxn pri čemu je
element aij = 1 akko postoji grana između čvorova ci i cj, a aij=0 ako ne postoji grana između
tih čvorova. Jasno je da su matrice povezanosti neusmjerenih grafova simetrične.
Matrice povezanosti grafova sa slika ... i ... su
é0 0 0 1 1 0ù é0 1 0 1 1 0ù
ê0 0 1 1 0 1úú ê0 0 1 0 0 0úú
ê ê
ê0 1 0 0 0 0ú ê0 1 0 0 1 0ú
ê ú ê ú
ê1 1 0 0 0 0ú ê1 0 0 0 0 1ú
ê1 0 0 0 0 1ú ê0 0 0 0 0 1ú
ê ú ê ú
êë0 1 0 0 1 0úû êë1 0 0 0 1 0úû
Rješenje
#include <stdio.h>
#include <stdlib.h>
int **matp;
UcitajMatricu(stepen);
OdstampajMatricu(matp, stepen);
return 0;
}
1 2 4 5 NULL
2 3 NULL
3 2 5 NULL
4 1 6 NULL
5 6 NULL
6 1 5 NULL
typedef struct c
{
int v;
struct c* s;
} Cvor;
Stabla
Zadaci za vježbu
PLAN VEŽBI
1. UVOD
2. TIPOVI PODATAKA
3. GRANANJA, CIKLUSI UVOD
4. CIKLUSI NASTAVAK
5. FUNKCIJE
6. NIZOVI
7. NIZOVI NASTAVAK
8. I KOLOKVIJUM
9. MATRICE
10. MATRICE NASTAVAK
11. STRINGOVI
12. STRUKTURE
13. STRUKTURE NASTAVAK
14. II KOLOKVIJUM
NAČIN POLAGANJA
I KOL II KOL
UL ZA UL ZA DOL+AKT UKUPNO
MAX 10 35 10 35 10 100
MIN 5 20 5 20 5 55
http://csl.ftn.kg.ac.rs/forum/index.php/board,23.0.html
1
RAZVOJNO OKRUŽENJE Code::Blocks
Preuzeti sa sledećeg linka:
http://www.codeblocks.org/downloads/26
odabrati veću verziju sa uključenim MinGW GCC kompajlerom (codeblocks-12.11mingw-setup.exe)
KREIRANJE PROJEKTA
2
ODABRATI C JEZIK I NAKON TOGA UPISATI IME PROJEKTA I ODABRATI LOKACIJU
3
NAKON TOGA DOBIJAMO FAJL main.c SA UPISANIM „HELLO WORLD“ PROGRAMOM
4
U SLUČAJU NE PREPOZNAVANJA MinGW KOMPAJLERA U OKVIRU
Settings=>Compiler and debugger, TAB Tolchain Executables
5
UVOD U ALGORITME
6
Primer 2. Nacrtati algoritam za izračunavanje sledeće funkcije:
7
01 - Tipovi podataka
Podaci u programu mogu da se predstave pomoću vrednosti ili pomoću identifikatora. Podaci predstavljeni
pomoću vrednosti ne mogu da promene svoje vrednosti u toku izvršavanja programa i nazivaju se konstantama.
Podacima koji su smešteni u memoriji računara, obično, mogu da se promene vrednosti u toku izvršavanja
programa. Takvi podaci nazivaju se promenljivim podacima ili kraće promenljivama. Podaci mogu da budu
prosti ili složeni.
Prosti podaci ne mogu da se rastave na manje elemente koji bi mogli nezavisno da se obrađuju. Zato se kaže da
oni nemaju strukturu. Nazivaju se i nestrukturiranim podacima ili skalarnim podacima.
Složeni podaci se sastoje od nekoliko elemenata koji mogu da se nezavisno obrađuju. Elementi složenih podataka
mogu da budu prosti, ali i sami mogu da budu složeni. Na taj način broj različitih složenih tipova podataka, koji
mogu da se izvode polazeći od prostih tipova podataka, je neograničen. Pošto složeni podaci imaju imaju određenu
strukturu, nazivaju se i strukturiranim podacima.
Simboličke konstante
Simbolička konstanta je konstanta kojoj je dodeljen identifikator. Kasnije se u programu koristi identifikator, a ne
vrednost konstante. Simbolička konstanta se definiše direktivom define čiji je opšti oblik:
IME_KONSTANTE je identifikator koji u nastavku programa predstavlja navedenu konstantnu vrednost. Direktiva
define mora da se piše u zasebnom redu. Jednom direktivom može da se definiše samo jedna konstanta. Komentar
na kraju reda je dozvoljen. Evo nekoliko primera definisanja simboličkih konstanti:
#define MIN 0
#define MAX 1000
#define PI 3.14159
1
Bibliotečke funkcije
Ako žele da se koriste neke od bibliotečkih funkcija, potrebno je na početku programa to saopštiti prevodiocu
jezika C ime odgovarajućeg zaglavlja direktivom include čiji je opšti oblik:
#include <naziv_datoteke>
Primer:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Konverzioni karakteri
Konverzioni Opis konverzije
karakter (q)
d decimalna koncerzija označenih brojeva (tip int)
c Konverzija jednog karaktera (tip char)
s Konverzija niza karaktera (tip char[])
f konverzija realnih decimalnih brojeva u jednostrukoj tačnosti
(tip float)
lf konverzija realnih decimalnih brojeva u dvostrukoj tačnosti
(tip double)
Ulazna konverzija
Ulazna konverzija podataka vrši se pozivanjem bibliotečke funkcije scanf pomoću naredbe čiji je opšti oblik:
Prvi argument funkcije scanf je format kojim se određuju konverzije koje treba da se izvršavaju u toku unosa
podataka. Svaki podatak predstavlja identifikator numeričke promenljive u koju će biti smešten rezultat konverzije
pojednog unetog podatka. Operator & ispred identifikatora promenljive označava da se funkciji scanf dostavlja
adresa navedene promenljive. Format je tekstualni podatak (niz znakova) oblika “tekst”. Pojedinačne konverzije se
iskazuju podnizovima opšteg oblika:
%nq
koji počinju znakom % i završavaju se oznakom za vrstu konverzije (q). Između njih može da bude i izvestan broj
dopunskih parametara konverzije (n).
Izlazna konverzija
Izlazna konvrzija podataka vrši se pozivanjem bibliotečke funkcije printf pomoću naredbe čiji je opšti oblik:
Prvi argument funkcije printf je format kojim se određuju konverzije koje treba da se izvršavaju u toku ispisivanja
podataka. Svaki izraz predstavlja numerički izraz čija će vrednost da se ispisuje. Treba da se skrene pažnja da
skalarna promenljiva i numerička konstanta predstavljaju specijalne slučajeve numeričkih izraza. Format je
tekstualni podatak (niz znakova) oblika “tekst”.
2
ZADATAK 1: Napisati program koji na standardnom izlazu ispisuje pozdravnu poruku.
#include <stdio.h>
main () {
printf ("Pozdrav svima!");
return 0;
}
ZADATAK 2: Napisati program koji učitava dva cela broja i ispisuje njihov zbir na standardnom izlazu..
#include <stdio.h>
main () {
int a, b, c;
printf ("Uneti dva cela broja:");
scanf ("%d%d", &a, &b);
c=a+b;
printf ("Zbir unetih brojeva je: %d\n", c);
return 0;
ZADATAK 3: Napisati program koji učitava stranicu kvadrata i izračunava obim, površinu, dijagonalu kvadrata i
ispisuje rezultat na standardnom izlazu..
#include <stdio.h>
#include <math.h>
main () {
double a, o, p, d;
printf ("Unesi stranicu: ");
scanf ("%lf", &a);
o=4*a;
p=pow (a, 2);
d=(sqrt (2))*a;
printf ("Obim je: %.2lf\n Povrsina je: %.2lf\n Dijagonala je: %.2lf\n", o, p, d);
return 0;
}
3
ZADATAK 4. Написати програм који учитава странице квадра и израчунава: главну дијагоналу D,
површину и запремину квадра. Напомена: резултат штампати са две децимале.
#include <stdio.h>
#include <math.h>
main(){
float a, b, c; //stranice kvadra
float P, V; //povrsina, zapremina
double D; //glavna dijagonala
printf("Unesi stranice kvadra: ");
scanf("%f%f%f", &a, &b, &c);
U C jeziku postoje dva simbola za deljenje pomoću kojih se mogu postići 3 tipa deljenja.
• Celobrojno (int a)/(int b) = 5 / 3 = 1, daje ceo deo realnog broja
• Po modulu (int a)%(int b) = 5 % 3 = 2, daje celobrojni ostatak pri deljenju
• Realno (int a)/(int b) = (float) 5 / 3 = 1.67, daje realan rezultat pri deljenju celih brojeva, mora se uraditi
kastovanje u željeni tip rezultata pored jedne od celobrojnih promenljivih (float)
ZADATAK 5: Napisati program koji ucitava dva cela broja a ispisuje zadnju cifru prvog broja, rezultat
celobrojnog deljenja, ostatak pri deljenju kao i realan rezultat na standardnom izlazu.
#include <stdio.h>
main () {
int a, b, c, d, e;
float f;
printf ("Unesi dva cela broja: ");
scanf ("%d%d", &a, &b);
c = a%10;
printf ("Zadnja cifra unetog broja %d je: %d\n", a, c);
d = a / b;
e = a % b;
f = (float) a / b;
printf ("d = %d, e = %d, f = %f \n", d, e, f);
return 0;
}
4
02 - Grananja
Osnovna selekcija: if – else
Osnovnom selekcijom se vrši uslovno izvršavanje jedne od dve moguće naredbe. Standardni i strukturirani
dijagrami toka ove upravljačke strukture prikazani su na slikama 2a i 2b, respektivno. Ukoliko logički izraz uslov
ima vrednost logičke istine (≠0), izvršava se naredba 1. Ako je vrednost uslova logička neistina (=0), izvršava se
naredba 2.
LOGIČKE OPERACIJE
== provera identičnosti
!= ne identično
<= manje ili jednako
>= vece ili jednako
! negacija
&& i
|| ili
if (uslov) if (uslov){
naredba_1; naredba_1;
else naredba_2;
naredba_2; } // nema else
if (uslov){ if(uslov_1)
naredba_11; naredba_1;
naredba_12; else if(uslov_2)
... naredba_2;
naredba_1M; else if( ... )
}else{ ...
naredba_21; else if(uslov_N)
naredba_22; naredba_N-1;
... else
naredba_2N; naredba_N;
}
1
ZADATAK 6: Napisati algoritam i program koji učitava dva cela broja i na standardnom izlazu ispisuje koji je
veći od ta dva broja.
#include <stdio.h>
main (){
int a, b;
printf ("Uneti dva cela broja:");
scanf ("%d%d", &a, &b);
if (a>b)
printf("Veci je broj %d\n", a);
else if(b>a)
printf("Veci je broj %d\n", b);
else
printf("Brojevi su jednaki\n”);
return 0;
}
2
ZADATAK 7: Napisati program koji učitava ceo broj, proverava da li je učitani broj paran ili neparan i ispisuje
odgovarajuću poruku na standardnom izlazu.
#include <stdio.h>
main (){
int a;
printf ("Unesi ceo broj: ");
scanf ("%d", &a);
if (a%2 == 0)
printf ("Broj je paran\n");
else
printf ("Broj je neparan\n");
return 0;
}
ZADATAK 8: Napisati C program koji učitava ceo broj c i realan broj x pri čemu je x > 0 . Zatim izračunava i
štampa vrednost funkcije f i to na sledeći način
- ukoliko je c < 0 računa se i štampa f = sin x 2 − x 5 + x − 2
- ukoliko je 0 ≤ c ≤ 8 računa se i štampa f =| sin 31x − x 3 | + | x 2 − 3 x | +1
- ukoliko je c > 8 računa se i štampa f = log 2 x + e −3 x
NAPOMENA: abs(x) za int, fabs(x) za float i double
#include <stdio.h>
#include <math.h>
int main(){
int C;
float X;
double f;
if (C<0) {
f = sin( pow( X, 2 )) - pow( X, 5 ) + X - 2;
}else if (C<=8) {
f = fabs(sin( 31 * X) - pow( X, 3 )) + sqrt( fabs( pow( X, 2 ) - 3*X )) + 1;
}else {
f = log( 2*X ) + exp( -3*X );
}
printf("\nVrednost funkcije je %lf \n", f);
return 0;
}
3
ZADATAK 9: Napisati program koji ucitava 3 cela broja a ispisuje na standardnom izlazu najmanji od njih.
4
Primer 2. Nacrtati algoritam za izračunavanje sledeće funkcije:
ZADATAK 10: Napisati program koji unosi dva cela broja a i b i jedan ceo broj n na osnovu koga se izvrsava
odredjena operacija nad brojevima a i b i to ako je:
• n=1, c=a+b
• n=2, c=a-b
• n=3, c=a/b
• n=4, c=a%b
• n=6, c=a*b
#include<stdio.h>
int main(){
int n;
int a, b, c;
5
c=a+b;
printf("\nZbir je %d \n", c);
break;
case 2:
c=a-b;
printf("\nRazlika %d\n", c);
break;
case 3:
c=a/b; // 2=5/2
printf("\nCelobrojno deljenje %d\n", c);
break;
case 4:
c=a%b; //1=5/2
printf("\nDeljenje po modulu %d\n", c);
break;
case 6: //brojevi ne mora da idu po redu
c=a*b;
printf("\nMonozenje %d\n", c);
break;
default: printf("Nekorektna operacija\n");
}
return 0;
}
ZADATAK 11: Napisati program koji za uneti broj meseca (na primer, 1=Januar, 2=Februar, itd.) ispisuje njegov
broj dana. U slučaju unete vrednosti 2 pitati korisnika da li je godina prestupna.
#include<stdio.h>
int main(){
int mesec, ch;
printf("Uneti redni broj meseca\n");
scanf("%d",&mesec);
switch(mesec){
case 1:case
1 case 3:case
3 case 5:case
5 case 7:case
7 case 8:case
8 case 10:
10 case 12:
12 printf("31 dan\n"); break;
break
case 4:
4 case 6:
6 case 9:
9 case 11:
11 printf("30 dana\n"); break;
break
case 2:
2 printf("Da li je godina prestupna (d-1/n-0)?\n");
scanf("%d",&ch);
if(ch == 1)
printf("29 dana\n");
else
printf("28 dana\n");
break;
break
default:
default printf("Nekorektan broj meseca\n");
break;
break
}
return 0;
}
6
CIKLUSI UVOD
Ciklusi
Ciklusi su upravljačke strukture koje omogućavaju ponovljeno izvršavanje neke naredbe. Broj ponavaljanja može
biti poznat a može i zavisiti od ispunjenja određenog logičkog uslova.
IZRAZ 1 predstavlja predstavlja pripremu za ulazak u ciklus (može da obuhvata i više radnji razdvojenih
zarezom). Služi za postavljanje potrebnih početnih vrednosti.
USLOV 2 je logički izraz koji predstavlja uslov za nastavljanje ciklusa.
IZRAZ 3 predstavlja završne radnje na kraju svakog prolaska kroz ciklus, tj. pripremne radnje za naredni prolazak
kroz ciklus. Te radnje, najčešće, predstavljaju menjanje brojača koji kontroliše broj prolazaka kroz ciklus.
7
Ciklus sa izlaskom na vrhu: WHILE
Standardni i strukturirani dijagrami toka osnovnog ciklusa sa izlazom na vrhu kao i programska sintaksa prikazani
su na slici.
while (uslov){
naredba_1;
naredba_2;
...
naredba_N;
}
Na početku svakog prolaska kroz ciklus izračunava se vrednost logičkog izraza uslov, i ako se dobija logička istina
(≠0), izvršava se naredba. Ciklus se završava kada vrednost uslova postane logička neistina (=0). Treba da se uoči,
može se desiti da naredba ne bude ni jednom izvršavana.
do{
naredba_1;
naredba_2;
...
naredba_N;
}while(uslov);
Kod ciklusa sa izlazom na dnu prvo se izvršava naredba koja čini sadržaj ciklusa pa se proverava vrednost
logičkog izraza uslov, i ako se dobija logička istina (≠0), skoči se na ponovno izvršavanje naredbe. Ciklus se
završava kada vrednost uslova postane logička neistina (=0). Naredba se uvek izvršava bar jednom.
NAPOMENA: idealan kada je potrebno prvo izvršiti naredbu pa proveriti da li je ispunje uslov, to treba raditi
sve dok se ne ispuni uslov
int main(){
int n;
int i; // iterator kroz petlje
do{
printf("Unesi n!\n");
scanf("%d",&n);
}while(n<4);
8
printf("\nPOMOCU FOR PETLJE!\n");
for(i=1; i<=n; i++)
printf("%d ", i);
return 0;
}
Primer 2. Nacrtati algoritam za množenje dva prirodna broja koristeći operaciju sabiranja.
9
VEŽBE 03
CIKLUSI
#include<stdio.h>
int main(){
int i,n;
int fakt=1; /*obavezno postavljanje promenljive na vrednost
koja ne utice na operaciju koja se nad njom obavlja*/
printf("Izracunavanje n!\nUkucajte broj (<33)?");
scanf("%d",&n);
for(i=1; i<=n; i++)
fakt*=i;
printf("%d!=%d\n",n,fak);
return 0;
}
1
ZADATAK 12: Napisati program kojim se na ekranu dobijaju permutovane cifre unetog celog broja.
#include<stdio.h>
int main(){
int broj, cifra;
printf("Ukucajte ceo broj?\n");
scanf("%d",&broj);
printf("Permutovan broj je\n");
#include<stdio.h>
int main() {
int n, i;
float suma=0; /*obavezno postavljanje promenljive na vrednost
koja ne utice na operaciju koja se nad njom obavlja*/
float x;
printf("Ukupno brojeva?\n");
scanf("%d",&n);
for (i=0; i<n; i++){
printf("Ukucajte %d. broj?", i+1);
scanf("%f",&x);
suma+=x;
}
2
}
ZADATAK 14: Napisati program kojim se unosi jedan ceo broj sa tastature i ukoliko je broj veći od 10 zahteva se
ponovni unos sve dok se ne unese odgovarajući broj.
#include<stdio.h>
int main(){
int broj;
do {
printf ("Ukucajte ceo broj?\n");
scanf ("%d",&broj);
}
while(broj>10);
printf("\nKonacno je unet broj %d", broj);
return 0;
}
ZADATAK 15: Napisati program koji ucitava cele brojeve dok se ne ucita nula i koji prikazuje njihov zbir na
standardnom izlazu.
3
Upravljačke stukture ciklusa: break i continue
Naredba continue prosleđuje tok kontrole na sledeću iteraciju najbliže do, for ili while naredbe u kojoj se
pojavljuje, čime se preskaču preostale naredbe u telu petlje.
4
ZADATAK 16a: Napisati program koji ucitava ceo pozitivan broj a ispituje da li je on prost ili ne i rezultat
ispisuje na standardnom izlazu.
#include <stdio.h>
main (){
int a, i=2, prost = 1; // 1 je logicki tačan izraz, 0 je logicki netačan
printf("Unesi ceo pozitivan broj: ");
scanf("%d", &a);
if( prost )
printf("Broj %d je prost\n", a);
else
printf("Broj %d je slozen\n", a);
return 0;
}
5
ZADATAK 16b: Napisati program koji nalazi proizvod 4 cela broja koja unosi korisnik. U slučaju da korisnik
unese nulu, preskočiti je.
#include <stdio.h>
int main(){
int i,broj,proizvod;
for(i=1,proizvod=1;i<=4;++i){
printf("Unesite broj %d:",i);
scanf("%d",&broj);
if(broj==0)
continue; / *Kada je broj jednak nuli, preskače se sledeća naredba proizvod*=broj i nastavlja se ciklus. */
proizvod*=broj;
}
printf("Proizvod iznosi %d",proizvod);
return 0;
}
ZADATAK 17: Napisati program koji ucitava cele brojeve a, b, c i prebrojava i ispisuje na standardnom izlazu
cele brojeve iz intervala [a,b] koji su deljivi sa c. Demonstrirati rešenje pomoću while i for cikljusa.
ZADATAK 18: Napisati program koji ucitava cele brojeve dok se ne ucita pozitivan broj deljiv sa 4 a da nije
manji od 10 a prikazuje na standardnom izlazu srednju vrednost svih brojeva koji su neparni ili deljivi sa 3 i 6.
#include <stdio.h>
#include <math.h>
int main () {
int a, broj=0;
float srvr=0;
6
do{
printf("Unesi broj: ");
scanf("%d", &a);
ZADATAK 19: Napisati program koji za zadati prirodan pozitivan broj n ispisuje najpre da li je deljiv i sa 6 i sa 7.
Ako je deljiv izračunava se suma oblika , ako nije a paran je računa se suma oblika
S=sin(1)-sin(2)+…+sin(n). Za sve ostale računa se suma oblika S=
#include <stdio.h>
#include <math.h>
int main(){
int n,i,z; // z predstavlja operaciju (+ , -) koja ce u svakom ciklusu menjati (z=-z)
double s=0;
Domaci: Napisati program koji izračunava sumu S3 koja samo umesto sume razlomaka ima jednu razlomačku crtu
7
04 – FUNKCIJE
Kada je reč o funkcijama prvo treba objasniti funkciju Main(). Ova funkcija kao rezultat vraća void ili
int, a može se uključiti string[] args parametar, pa su moguće sledeće verzije ove funkcije:
void main(){}
NAPOMENA:
int argc – broj ulaznih argumenata od kojih je ime programa uvek jedan
char* argv – niz stringova prosledjenih prilikom poziva programa
Funkcije su programske celine koje imaju ulogu da odrade jedan deo ili eventualno ceo problem koji
se traži u zadatku. Definicija funkcije sastoji se od zaglavlja i tela funkcije. Zaglavlje funkcije sadrži
identifikator (ime funkcije), par zagrada ‘(‘ i ‘)’ između kojih se opcionalno nalazi lista argumenata
funkcije sa definicijama argumenata funkcije. Telo funkcije je skup izvršnih iskaza i deklaracija
promenljivih korišćenih u funkciji.
1
ZADATAK 18: Napisati program koji računa hipotenuzu pravouglog trougla pomoću funkcije.
#include <stdio.h>
#include <math.h>
double hipotenuza (float a, float b){
double c;
c = sqrt ( pow(a, 2) + pow (b, 2));
return c;
}
int main(){
float a, b;
printf(“Uneti stranice pravouglog trugla \n”);
scanf(“%f%f”, &a, &b);
printf (“Hipotenuza je: %lf \n”, hipotenuza(a, b));
return 0;
}
ZADATAK 19. Napisati program za izračunavanje sume kvadrata od 1 do n za dva cela broja.
Rešenje: Funkcija int suma_kvadrata(int n) je deklaracija funkcije, koja kao rezultat vraća int i zove se
suma_kvadrata. Int n predstavljaju formalne ulazne argument funkcije. To znači da funkciuja prihvata
jedan int a ali se on pri pozivu ne mora zvati n. Kada funkcija vraća neki rezultat (nije void) unutar
funkcije (najčešće na kraju) mora da postoji komanda return kojom se vraća vrednost rezultata; gde se kao
rezultat funkcije vraća vrednost promenljive. Funkcija se poziva tako što se u glavnom programu napiše
ime funkcije sa odgovarajućim argumentima funkcije. Kada se pozove funkcija, u zagradi stoje stvarni
argumenti.
#include<stdio.h>
int suma_kvadrata(int n){
int i;
int suma = 0;
for(i=1; i <= n; i++){
suma += i*i;
}
return suma;
}
int main(){
int n, m, rezN, rezM;
printf(“Uneti dva cela broja \n”);
scanf(“%d%d”, &n,&m);
rezN = suma_kvadrata (n); // funkcije se mogu neograniceno puta pozivati
printf("Suma kvadrata od 1 do %d : %d\n", n, rezN);
rezM = suma_kvadrata (m);
printf("Suma kvadrata od 1 do %d : %d\n", m, rezM);
2
}
ZADATAK 20. Napisati program u kome se definiše funkcija prost() koja ispituje da li je broj prost i
funkcija main() koja njenim korišćenjem štampa sve proste brojeve do datog prirodnog broja n.
#include<stdio.h>
#include<math.h>
int prost(int n){
int i;
for (i=2; i<=sqrt(n); i++) //dovoljno je ici do koren iz 3
if(n%i == 0)
return 0; //nije prost = 0
return 1; //jeste prost = 1
}
int main() {
int i, n;
printf("Uneti broj\n");
scanf("%d", &n);
printf("Prosti brojevi su\n");
for( i=2; i <= n; i++)
if(prost(i) == 1) //isto kao i if(prost(i)),
if(prost(i)) ne mora da se stavi ==1,
printf("%d\n", i);
return 0;
}
ZADATAK 21: Napisati funkciju koja izracunava faktorijel datog prirodnog broja a potom glavni
program koji ucitava brojeve a i b a ispisuje (a!/b!.)2. Napomena: faktorijal negativnih brojeva je 0,
faktorijal od 0 i 1 je 1.
#include <stdio.h>
#include <math.h>
int Faktorijel(int n) {
if(n<0)
return 0;
else if(n==0 || n==1)
return 1;
else{
int f=1, i=2;
for(i=2; i<=n; i++){
f *= i;
}
return f;
}
}
main(){
3
int a, b;
double c;
printf("Unesi dva cela broja: ");
scanf("%d %d", &a, &b);
c = pow((double)Faktorijel(a)/Faktorijel(b), 2);
printf("Vrednost je %.4lf \n", c);
return 0;
}
VEŽBA: Izračunati sledeći izraz: r= (a!+b!)/(a+b)!
ZADATAK 22: Napisati funkciju koja izračunava površinu trougla. Poznate su koordinate temena
trougla u X-Y koordinatnom sistemu. Funkcija treba da ima jedan argument, a koordinate se zadaju
pre poziva funkcije kao celi brojevi.
gde je S poluobim trougla tj.
#include<stdio.h>
#include<math.h>
double povrsinaTrougla (int x1, int y1, int x2, int y2, int x3, int y3 ){
double a, b, c, s;
a = sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));
b = sqrt(pow((x2 - x3), 2) + pow((y2 - y3), 2));
c = sqrt(pow((x3 - x1), 2) + pow((y3 - y1), 2));
s = (a + b + c)/2;
return sqrt(s * (s-a) * (s-b) * (s-c));
}
int main (){
int x1, y1, x2, y2, x3, y3;
printf("\nPovrsina trogla je :%.2lf \n", povrsinaTrougla(x1, y1, x2, y2, x3, y3));
return 0;
}
ZADATAK 23: Napisati program kojim se stampaju svi petocifreni brojevi(ako ih ima) koji su
jednaki sumi faktorijala svojih cifara. U programu koristiti funkcije.
#include <stdio.h>
int fakt(int n){
int i, f=1;
for ( i=1; i <= n; i++ )
f *= i;
return f;
4
}
int sumaFakt(int n){
int suma = 0, zadCifra;
while(n!=0){
zadCifra = fakt(n % 10);
suma += zadCifra;
n /= 10;
}
return suma;
}
int main(){
int i;
for(i=10000; i <= 99999; i++)
if (i == sumaFakt(i))
printf("%d ", i);
return 0;}
5
VEŽBE 05 – NIZOVI
Podatak nizovnog tipa predstavlja niz podataka međusobno ISTIH tipova. Oni se nazivaju elemetima niza i
identifikuju se pomoću rednog broja (indeksa) elemenata niza. Prvi element niza u jeziku C obavezno ima indeks
0, drugi 1 itd.
Definisanje nizova vrši se pomoću sledeće naredbe:
Inicijalizacija početne vrednosti pri definisanju pišu u obliku niza vrednosti međusobno razdvojenih zarezima
stavljenih između para vitičastih zagrada ({}). To treba da su konstante koje po tipu odgovaraju osnovnom tipu
navedenom u opisu tipa na početku naredbe za definisanje podataka.
Evo nekoliko primera za definisanje jednodimenzionalnih nizova sa inicijalizatorima:
Indeksi u jeziku C su celi brojevi od 0 do n–1, gde je n broj elemenata (tj. dužina) niza. Pristup elementima niza
naziva se indeksiranjem. Indeksiranje u jeziku C smatra se binarnim operatorom i obeležava se sa [].
1
ZADATAK 20: Napisati program kojim se ucitava niz n celih brojeva n<=20 i ispisuje ga na standardnom
izlazu uz sumu svih elemenata niza. (a – bez funkcija, b – preko funkcija)
2
A) Bez funkcija
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
main (){
int a[DIM], suma;
int i, n;
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
3
void ispis(int a[], int n){
int i;
printf ("\nElementi niza: \n");
for (i=0; i<n; i++)
printf(“%d ”,a[i]);
} // treba je pozvati u main-u
main (){
int a[DIM], s;
int i, n;
do{
printf ("\nDuzina niza (najvise %d)je: ", DIM);
scanf ("%d", &n);
}while (n<=0 || n>DIM); // unos odgovarajuce dimenzije niza preko do while
unos(a, n);
s = suma(a, n);
return 0;
}
ZADATAK 20a : Napisati program kojim se ucitava niz n realnih brojeva n<=20 a ispisuje na standardnom
izlazu zbir i srednju vrednost svih pozitivnih elemenata.
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
main (){
double a[DIM], zbir;
int i, n, poz;
4
if (n<=0 || n>DIM) // provera dimenzije niza
exit (1); // prekid u slucaju netacne dimenzije. Nije lose ali bolje sa do while !!!
//unos elemenata niza void unos(double a[], int n){ // pre main-a
int i;
printf ("Unesite clanove niza: \n"); printf ("Unesite clanove niza: \n");
for (i=0;i<n;i++){ for (i=0; i<n; i++){
printf(“\n a[%d]=”, i); printf(“\n a[%d]=”, i);
scanf ("%lf", &a[i]); scanf ("%lf", &a[i]);
} }
} // treba je pozvati u main-u
// sumiranje elemenata niza double srvr(double a[], int n){ // pre main-a
zbir = 0; poz = 0; int i, zbir = 0, poz = 0;
for (i=0;i<n;i++){ for (i=0; i<n; i++){
if (a[i]>0){ if (a[i]>0){
zbir += a[i]; zbir += a[i];
poz++; poz++;
} }
} }
return zbir/poz;
} // treba je pozvati u main-u
printf ("Zbir pozitivnih elemenata je: %.2lf\nSrednja vrednost pozitivnih je: %.2lf\n", zbir, zbir/poz);
return 0;
}
ZADATAK 21: Napisati program koji ucitava niz n realnih brojeva n<=20 a ispisuje na standardnom izlazu
najveci clan niza.
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
main (){
double a[DIM], max;
int i, n;
if(n<=0 || n>DIM)
exit(1);
5
//max obavezno postaviti na PRVI element iz double maxf(double a[], int n){ // pre main-a
skupa u kojem se trazi resenje. int i;
max = a[0];
max=a[0]; for (i=1; i<n; i++)
for (i=1; i<n; i++){ if(a[i]>max)
if(a[i]>max) max=a[i];
max=a[i]; return max;
} }
printf("Najveci element je: %.2f\n", max); printf("Najveci element je: %.2f\n", maxf(a,n));
return 0;
}
ZADATAK 22: Napisati program koji ucitava niz n realnih brojeva n<=20 a ispisuje na standardnom izlazu
elemente niza sortirane u neopadajućem poretku.
int n = 6; KORAK I j
1 0 1
for (i = 0, j = i+1; i< n-1; i++, j++) 2 1 2
3 2 3
4 3 4
5 4 5
6 5(i<n-1 = false) 6
int n = 6; KORAK I j
1 0 1
for (i = 0; i< n-1; i++) 2 0 2
for (j = i+1; j<n; j++) 3 0 3
4 0 4
j uvek vece od i 5 0 5
6 0 6 (j<6 = false)
zavrsi se cela unutrasnja petlja (j) pa se tek 7 1 2
8 1 3
onda spoljna (i) uveca za 1
9 1 4
10 1 5
11 1 6 (j<6 = false)
12 2 3
13 2 4
14 2 5
15 2 6 (j<6 = false)
16 3 4
17 3 5
18 3 6 (j<6 = false)
19 4 5
20 4 6 (j<6 = false)
21 5 6 (j<6 = false)
6
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
void unos(int a[], int n){
int i;
printf ("Unesite clanove niza: \n");
for (i=0; i<n; i++){
printf(“\n a[%d]=”, i);
scanf ("%d", &a[i]);
}
}
void ispis (int a[], int n){
inti;
for (i=0;i<n;i++)
printf(“%d, ”,a[i]);
}
main (){
int a[DIM], max;
int i, j, n, tmp;
ZADATAK 23: Napisati program koji učitava 2 niza od n elemenata n<=20 a ispisuje na standardnom
izlazu skalarni proizvod odgovarajućih članova datih nizova.
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
7
void unos(int a[], int n){
int i;
printf ("Unesite clanove niza: \n");
for (i=0; i<n; i++){
printf(“\n a[%d]=”, i);
scanf ("%d", &a[i]);
}
}
main (){
int a[DIM], b[DIM], sp=0;
int i, n;
unos(a, n);
unos(b, n);
ZADATAK 24: Napisati C program koji formira niz A[8] od celih brojeva koji se učitavaju jedan po jedan sa
tastature. Program treba da sve elmente niza A koji su izmedju 5 I 10 a nalaze se na neparnim pozicijama prekopira
u niz B.
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
main (){
int n, a[DIM], b[DIM], i, k;
printf("\nPocetni niz:\n");
for(i=0; i<n; i++){
printf("\na[%d]=", i);
scanf("%d", &a[i]);
}
8
for(i=0; i<k; i++) // dimenzija niza B je K
printf("%d ", b[i]);
}
9
VEŽBE 06
NASTAVAK NIZOVI
ZADATAK 25: Napisati program koji učitava niz od n elemenata n<=20 i cele brojeve K i X a
ispisuje niz koji nastaje kada se na K-to mesto datog niza umetne broj X.
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
main (){
int a[DIM],k ,x;
int i, n;
return 0;
}
ZADATAK 25 :a: Napisati program koji učitava niz od n elemenata n<=20 i ceo broj K. Iz niza
treba izbaciti element na K-toj poziciji i prikazati dobijeni niz.
1
ZADATAK 26: Napisati program koji učitava niz od n elemenata n<=50, obrće ga i ispisuje
novodobijeni niz na standardnom izlazu.
#include <stdio.h>
#include <stdlib.h>
#define DIM 50
main(){
int a[DIM], n, i, j;
printf("\nDuzina niza (max %d): ", DIM);
scanf("%d", &n);
if(n <= 0 || n > DIM) exit(1);
for(i=0;i<n;i++)
printf(" %d", a[i]);
printf("\n");
}
ZADATAK 27: Napisati program koji stvara i ispisuje slučajan celobrojni niz zadate dužine koji
se sastoji od jednocifrenih decimalnih brojeva, izvrši uređivanje niza po neopadajućem redosledu
vrednosti brojeva i ispisuje rezultujući niz.
#include <stdio.h>
#include <stdlib.h>
#define DIM 500
main (){
int n, a[DIM], i, j;
2
printf("\nPocetni niz:\n\n");
for(i=0; i<n; i++)
a[i] = rand() / ((double)RAND_MAX + 1) * 10;
/*Sortiranje niza*/
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(a[i] > a[j]){
int b = a[i];
a[i] = a[j];
a[j] = b;
}
printf("\nSortirani niz:\n\n");
for(i=0; i<n; i++)
printf("%d ", a[i]);
return 0;
}
VEZBA : NAPRAVITI LOTO IZVLACENJE (6 od 39, da se ne ponavljaju)
A[i]=(rand()%39)+1
ZADATAK 28: Napisati C program koji formira niz C[8] od celih brojeva koji se učitavaju
jedan po jedan sa tastature. Program treba da nađe sumu svih parnih elemenata DO PRVE
NULE U NIZU.
#include <stdio.h>
int main(){
int C[8];
int i, s;
i++;
}
3
printf("Suma = %d \n", s);
return 0;
}
ZADATAK 29: Iz niza a u niz B prebaciti sve PROSTE brojeve koji se nalaze ISPRED
PRVOG PARNOG BROJA U NIZU.
#include <stdio.h>
#include <stdlib.h>
#define DIM 20
4
main (){
int a[DIM], b[DIM];
int i, n;
unos(a, n);
int k;
k= prebaci(a,n,b);
ispis(b,k);
return 0;
}
5
VEŽBE 07
MATRICE
Matrice predstavljaju dvodimenzionalne nizove (nizove nizova) koje pored stadardnih nizova karakteriše i još
jedna dimenzija. Definicija matrica izvšava se u sledećem formatu:
TIP naziv_matrice [BR_VRSTA][BR_KOLONA]
gde su BR_VRSTA i BR_KOLONA maksimalno dozvoljene dimenzije koje se mogu koristiti u programu za rad.
Anotacija je ista kao i kod nizova i kreće od 0. Kvadratne matrice ( BR_VRSTA = BR_KOLONA ) imaju dve
dijagonale, glavnu i sporednu.
ZADATAK 29. Napisati program za sabiranje matrica a i b dimenzije n i štampanje rezultujuće matrice c.
void ispis(int
ispis a[][10],int n, int m){ printf("Uneti elemente matrice b\n");
int i,j; unos(b, n, m);
for(i=0; i<n; i++){
for(j=0; j<m; j++) printf("Zbir matrica a i b je:\n");
printf("%d\t", a[i][j]); zbir(a, b, c, n, m);
printf("\n");
} ispis(c, n, m);
} return 0;
}
void zbir(int a[][10], int b[][10], int c[][10], int n, int m){
int i, j;
for(i=0; i<n; i++){
for(j=0; j<m; j++){
c[i][j] = a[i][j] + b[i][j];
}
}
}
1
ZADATAK 29. Napisati C program koji učitava jedan po jedan realan broj i formira matricu A[5][5]. Zatim
program treba da odredi sumu svih elemenata prve kolone i sumu druge vrste ove matrice i da ispita koja je suma
veća. Zatim odštampati poruku o tome koja je suma veća.
#include <stdio.h>
int main(){
float a[5][5];
int i,j;
float spk, sdv;
spk=0.0;
for(i=0; i<5; i++) // i se menja a j = 0 (fiksno pa ne treba petlja)
spk+=a[i][0];
sdv=0.0;
for(j=0; j<5; j++) // j se menja a i = 1 (fiksno pa ne treba petlja)
sdv+=a[1][j];
printf("Suma elemenata prve kolone je: %f\n\n", spk);
printf("Suma elemenata druge kolone je: %f\n\n", sdv);
2
ZADATAK 30. Napisati C program koji učitava jedan po jedan realan broj i formira matricu A[7][5]. Program
treba da izračuna u kojoj koloni je najmanji element (pretpostavka da ima samo jedan najmanji element u celoj
matrici), da odštampa tu najmanju vrednost i da odštampa tu kolonu.
#include <stdio.h>
int main(){
float a[7][5];
int i, j, k, v;
float min=a[0][0];
v=0;
k=0;
for(i=0; i<7; i++)
for(j=0; j<5; j++)
if(min>a[i][j]) {
min=a[i][j];
v=i;
k=j;
}
3
ZADATAK 31. Napisati program kojim se za random generisanu matricu sumu elemenata i-te vrste upisuje na i-tu
poziciju niza b, a srednja vrednost pozitivnih elemenata i-te kolone se upisuje na i-tu pozciju niza c.
#include <stdio.h>
A00 A01 A02 B0
#include <math.h> A10 A11
A11 A12 B1
#define DIM 20
void ispisMat (int a[][DIM], int n, int m){ C0 C1 C2
printf ("Elementi matrice su \n");
for (int i =0;i<n;i++){
for (int j=0;j<m;j++)
printf("%d\t", a[i][j]);
printf("\n"); for(i=0; i<m; i++){ //po vrstama
} s=0;
} for(j=0; j<n; j++)
s+=a[i][j];
void ispisNiz (int a[], int n){
b[i]=s;
printf ("Elementi niza su \n");
}
for (int i =0;i<n;i++)
printf("%d\t",a[i]);
for(j=0; j<n; j++){ //po kolonama
printf("\n");
sr=0;
}
br=0;
for(i=0; i<m; i++)
int main(){
if (a[i][j]>0){
int a[DIM][DIM], int b[DIM], int c[DIM];
sr+=a[i][j];
int i, j, m, n, s, sr, br;
br++;
}
printf("Uneti dimenzije matrice A\n");
c[j]=sr/br;
scanf(“%d %d”, &m, &n);
}
// unos elemenata pomocu rand
ispisNiz(b,m);
for(i=0; i<m; i++)
ispisNiz(c,n);
for(j=0; j<n; j++)
a[i][j]=rand();
ispisMat(a,n,m);
return 0;
}
4
ZADATAK 32. Napisati program kojim se nakon što se unesu elementi matrice unose i indeksi dve vrste čiji
elementi treba da se zamene.
5
VEŽBE 08
MATRICE - DIJAGONALE
VRSTE =>
GLAVNA DIJAGONALA SPOREDNA DIJAGONALA
KOLONE =>
ZADATAK 32: Napisati program koji učitava n (vrsta) i m (kolona) matrice a potom učitava elemente matrice,
ispisuje zbir elemenata na glavnoj i sporednoj dijagonali te matrice.
#include <stdio.h>
#include <stdlib.h>
#define N 5
printf("Zbir na glavnoj dijagonali je: %d\nZbir na sporednoj dijagonali je: %d\n", glavnadija, sporedna);
}
ZADATAK 33: Napisati program kojim se učitava matrica nxm. Naći aritmetičku sredinu svih elemenata matrice,
naći maksimalni element ISPOD sporedne dijagonale matrice, aritmetičku sredinu elemenata na sporednoj
dijagonali i najmanji element na glavnoj dijagonali.
#include <stdio.h> main (){
#include <stdlib.h>
#define N 5 int a[N][N], max, min;
void unos (int a[][4], int n){ … } int i, j, n, zbir, sp;
void ispis (int a[][4], int n){ … }
int maxis (int a[][4], int n){ printf("Unesi dimenzije matrice ");
/* max ispod sporedne dijagonale*/ scanf("%d %d", &n);
/*vazno je postaviti max na prvi iz skupa u kojem
se trazi maksimalni*/ unos(a, n);
int i, j,, max=a[1][n-
max=a[1][n-1]; ispis(a, n);
#include <stdio.h>
#include <stdlib.h>
#define N 20
main (){
int a[N][N], b[N];
int i, j, n, k;
printf("Unesi dimenziju matrice \n");
scanf("%d", &n);
ZADATAK 32: Napisati funkcije za transponovanje matrice a dimenzije n I kreiranje jedinicne matrice.
void transponovanje(int a[][DIM], int n){ void jedinicna(int a[][DIM],int n ){
for(i = 0; i < n; i++) int i,j;
for(j = i; j < n; j++) { for(i=0;i<n;i++)
int p = a[i][j]; for(j=0;j<n;j++)
a[i][j] = a[j][i]; if (i==j)
a[j][i] = p; a[i][j]=1;
} else
} a[i][j]=0;
}
3
4
VEŽBE 09
STRINGOVI ( nizovi karaktera )
1
ZADATAK 58. Napisati program koji učitava jedan znak sa tastature i proverava da li je slovo ili cifra.
ZADATAK 59: Napisati program koji učitava jedan znak i ispituje li je on malo slovo, veliko slovo,
samoglasnik ili suglasnik.
#include <stdio.h>
#include <ctype.h>
void main (){
char a, b;
printf("Unesi jedan znak: ");
a = getchar();
getchar
if(isalpha(a)) {
if(isupper
isupper(a))
isupper
printf("Znak %c je veliko slovo!\n", a);
else if(islower
islower(a))
islower
printf("Znak %c je malo slovo!\n", a);
b = tolower(a);
tolower
if(b=='a' || b=='e' || b=='i' || b=='o' || b=='u')
printf("Znak %c je samoglasnik!\n", a);
else printf("Znak %c je suglasnik!\n", a);
}
}
ZADATAK 60 : Napisati program koji učitava string (niz karaktera) ne duži od 40 karaktera. Ispisati
koliko ima karaktera (tj. koliko je dugačak string), cifara, slova i praznih mesta u tom stringu.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define DIM 40
void main (){
char a[DIM];
int n, i=0, s=0, c=0, b=0;
printf("Unesi string ne duzi od 40 karaktera: ");
gets(a);
gets
n = strlen(a);
strlen
2
printf("U nizu '%s' ima %d karaktera!\n", a, n);
for(i=0; i<n; i++) {
if(isalpha
isalpha(a[i]))
isalpha
s++;
else if(isdigit
isdigit(a[i]))
isdigit
c++;
else if(isspace
isspace(a[i]))
isspace
b++;
}
printf("U nizu '%s' ima %d slova, %d cifara i %d praznih mesta!\n", a, s, c, b);
}
ZADATAK 61: Napisati program koji učitava string (niz karaktera) ne duži od 80 karaktera. Ispisati isti
string samo sva mala slova u njemu zameniti velikim.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define DIM 80
int main (){
char a[DIM];
int i = 0;
printf("Unesi string ne duzi od %d: ", DIM);
gets(a);
gets
return 0;
}
ZADATAK 62: Napisati program koji učitava string (niz karaktera) ne duži od 80 karaktera i još jedan
karakter. Ispisati string koji nastaje izbacivanjem učitanog karaktera.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define DIM 80
void main (){
char a[DIM], b;
int i=0;
printf("Unesi string ne duzi od %d znakova: ", DIM);
gets(a);
gets
printf("Unesi znak koji treba izbaciti iz stringa: ");
3
b = getchar();
getchar
for(i=0; i< strlen(a);
strlen i++) {
if(a[i] != b)
putchar(a[i]);
putchar
}
putchar('\n');
}
#include<stdio.h>
int main() {
char c;
int i;
printf("\t\t Tablica ASCII kodova\n\n");
for(c=' ';c<' '+19;++c){
for(i=0;i<95;i+=19)
printf("%3d %c ",c+i,c+i);
putchar('\n');
}
return 0;
}
// moze I prostije
// for(i=0;i<127;i++)
// printf("%d = %c ", i, i);
4
VEŽBE 10
STRUKTURE
Struktura je skup jedne ili više promenljivih, koje mogu biti različitih tipova, grupisanh zajedno radi lakše
manipulacije. Strukture pomažu pri organizaciji kompleksnih podataka, posebno u velikim programima, jer one
omogućuju obradu grupe međusobno povezanih promeljivi kao jedne cjeline. Primer strukture Tacka vidi se na
slici. Tačka je definirana uređenim parom koordinata, pravougaonik se može definisati parom tačaka i sl.
typedef komandom se definiše da se u daljem delu koda umesto struct Tacka koristi skraćeno TACKA kao i bilo
koji drugi standardan tip promenljive.
• Članu određene strukture pristupa se sledećim izrazom
IME_STRUKTURE. IME_ CLANA // pristup preko operatora “.”
• Operatorom "." povezujemo ime strukture i ime člana. Ispis koordinata za sturkturu TACKA A, npr.,
printf("%d, %d", A.x, A.y);
Takođe moguća je kombinacija typedef i deklaracije structure u jednom koraku kao u sledećem primeru:
main(){
TACKA t1, t2, t3;
}
Strukture možemo ugnjezditi. Pravougaonik možemo predstaviti parom tačaka koje označavaju dijagonalno
suprotne tačke.
typedef struct rect{
struct point pt1;
struct point pt2;
}RECT;
main{
rect a;
printf(“%d”, a.p1.x)
}
//ispisuje X koordinatu tacke p1 pravougaonika a
1
ZADATAK 64: Definisati strukturu za teme trougla a zatim izracunati povrsinu trougla ako su date koordinate
temena trougla.
#include <stdio.h>
#include <math.h>
struct Tacka{
double x, y;
};
main(){
TACKA t1, t2, t3;
double povrsina, a, b, c, s;
printf("Unesi kordinate prve tacke: ");
scanf("%lf %lf", &t1.x, &t1.y);
printf("Unesi kordinate druge tacke: ");
scanf("%lf %lf", &t2.x, &t2.y);
printf("Unesi kordinate trece tacke: ");
scanf("%lf %lf", &t3.x, &t3.y);
a=sqrt(pow(t1.x-t2.x,2)+pow(t1.y-t2.y,2));
b=sqrt(pow(t1.x-t3.x,2)+pow(t1.y-t3.y,2));
c=sqrt(pow(t2.x-t3.x,2)+pow(t2.y-t3.y,2));
s=(a+b+c)/2;
povrsina=sqrt(s*(s-a)*(s-b)*(s-c));
printf("Povrsina trougla je: %.2lf!\n", povrsina);
}
ZADATAK 65: Definisati strukturu za rad sa kompleksnim brojevima a potom napisati program koji ucitava 2
kompleksna broja a prikazuje njihov zbir, razliku, proizvod, kolicnik, moduo prvog i konjugovano kompleksan
drugom. VEZBA
#include <stdio.h>
#include <math.h>
struct Kb{
double x, y;
};
main(){
struct Kb z1, z2, zbir, razlika, pr, ko, kk;
double mo;
printf("Unesi prvi kompleksan broj: ");
scanf("%lf %lf", &z1.x, &z1.y);
printf("Unesi drugi kompleksan broj: ");
scanf("%lf %lf", &z2.x, &z2.y);
zbir.x=z1.x+z2.x;
zbir.y=z1.y+z2.y;
2
razlika.x=z1.x-z2.x;
razlika.y=z1.y-z2.y;
pr.x=z1.x*z2.x-z1.y*z2.y;
pr.y=z1.y*z2.x+z1.x*z2.y;
ko.x=(z1.x*z2.x+z1.y*z2.y)/(pow(z2.x, 2)+pow(z2.y, 2)) ;
ko.y=(z1.y*z2.x-z1.x*z2.y)/(pow(z2.x, 2)+pow(z2.y, 2)) ;
mo=sqrt(pow(z1.x, 2)+pow(z1.y, 2));
kk.x=z2.x;
kk.y=-z2.y;
printf("Zbir je (%.2lf,%.2lf)\nRazlika je (%.2lf,%.2lf)\n", zbir.x, zbir.y, razlika.x, razlika.y);
printf("Proizvod je (%.2lf,%.2lf)\nKolicnik je (%.2lf,%.2lf)\n", pr.x, pr.y, ko.x, ko.y);
printf("Moduo prvog broja je: %.2lf\nKonjugovano kompleksan sa drugim je (%.2lf,%.2lf)\n", mo, kk.x,
kk.y);
}
ZADATAK 66: Deklarisati strukturu za rad sa razlomcima a potom napisati program koji ucitava 3 razlomka a, b,
c i prikazuje razlomak a2-b/c. VEZBA
#include <stdio.h>
#include <math.h>
struct Razlomak{
int br, im;
};
main() {
struct Razlomak a, b, c, d, e, f;
printf("Unesi brojilac i imenilac prvog razlomka: ");
scanf("%d %d", &a.br, &a.im);
printf("Unesi brojilac i imenilac drugog razlomka: ");
scanf("%d %d", &b.br, &b.im);
printf("Unesi brojilac i imenilac treceg razlomka: ");
scanf("%d %d", &c.br, &c.im);
d.br=pow(a.br, 2);
d.im=pow(a.im, 2);
e.br=b.br*c.im;
e.im=b.im*c.br;
f.br=d.br*e.im-e.br*d.im;
f.im=d.im*e.im;
printf("Rezultat izraza a*a-b/c=%d/%d!\n", f.br, f.im);
}
ZADATAK 67: Deklarisati strukturu tacka a potom strukturu pravougaonik (opisuje se pomocu 2 tacke, gornjeg
levog i donjeg desnog temena), pretpostavlja se da su stranice paralelne koordinatnim osama a potom napisati
program koji ucitava 2 pravougaonika a prikazuje njihove povrsine.
#include <stdio.h>
3
}TACKA;
main(){
PRAVOUGAONIK p1, p2;
double p;
printf("Unesi temena prvog pravougaonika: ");
scanf("%lf %lf %lf %lf", &p1.gl.x, &p1.gl.y, &p1.dd.x, &p1.dd.y);
printf("Unesi temena drugog pravougaonika: ");
scanf("%lf %lf %lf %lf", &p2.gl.x, &p2.gl.y, &p2.dd.x, &p2.dd.y);
p=(p1.gl.y-p1.dd.y)*(p1.dd.x-p1.gl.x);
ZADATAK 68. Napisati program koji za zadato tekuće vreme određuje naredno vreme.
#include<stdio.h>
int main(){
VREME tekuce, naredno;
naredno = tekuce;
if(++naredno.sekund==60){
naredno.sekund=0;
if(++naredno.minut==60){
naredno.minut=0;
if(++naredno.sat==24)
naredno.sat=0;
}
}
4
ZADATAK 69. Napisati program koji za dva studenta opisana preko imena, i proseka ispisuje podatke o onom sa
boljim prosekom sa napomenom o duzini imena (strlen).
#include <stdio.h>
#include <string.h>
#define DIM 20
main(){
STUD a, b;
5
VEŽBE 11
Nastavak struktura
ZADATAK 46. Napisati program za formiranje strukture student sa karakteristikama: Ime, Prezime, broj indeksa,
srednja ocena. Za uneti broj studenata n, sortirati studente prema srednjoj oceni i ispisati na ekranu.
#include <stdio.h>
#define DIM 20
struct Student{
char ime[DIM];
char prezime[DIM];
int br_indeksa;
float sred_ocena;
};
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(a[i].sred_ocena < a[j].sred_ocena) {
pom = a[i];
a[i] = a[j];
a[j] = pom;
1
}
}
main(){
int n, i, j;
STUD a[DIM];
printf("Unesite broj studenata: ");
scanf("%d", &n);
unos(a,n);
sort(a,n);
ispis(a,n);
}
2
ZADATAK 47. Definisati strukturu GRAD sa podacima članovima: ime, broj stanovnika, prosečan dohodak
radnika. Napisati program kojim se unose podaci o gradovima u Srbiji i štampati na ekranu ime grada sa najvećim
brojem stanovnika. Izračunati ukupan dohodak svih unetih gradova.
#include <stdio.h>
#define DIM 10
#define N 20
main(){
GRAD NizGradova[DIM];
int i, n, max, max_index = 0;
float uk_dohodak = 0.0;
printf("Unesi broj gradova(max %d): ", DIM);
scanf("%d", &n);
uk_dohodak += NizGradova[i].dohodak;
}
max = NizGradova[0].br_stan;
for(i=0;i<n;i++)
if(NizGradova[i].br_stan > max) {
max = NizGradova[i].br_stan;
max_index = i;
}
3
ZADATAK 48. Napisati program koji ispisuje podatke o najskupljem mercedesu iz niza auta opisanih preko
marke i cene.
#include <stdio.h>
#define DIM 20
struct Auto{
char marka[DIM];
int cena;
};
int maxMerc(AUTO a[], int n){ // vraca poziciju najveceg mercedesa ako postoji ili -1 ako ne postoji
int i,j, poz;
AUTO max;
4
unos(a,n);
poz = maxMerc(a,n);
if(poz != -1)
printf("\n Cena najskupljeg mercedesa je %d \n", a[poz].cena);
else
printf("\n Nema mercedesa u nizu !!! \n");
}
5
Zadaci sa vežbi iz
Programskog jezika „C“
Tehnički Fakultet Čačak, školska 2007/2008 godina
Zadatak 1. Napisati program koji ispisuje sve trocifrene Amstrongove brojeve, Amstrongovi
brojevi su oni brojevi koji su jednaki zbiru kubova svojih cifara.
#include<stdio.h>
#include<stdio.h>
Zadatak 3. Napisati program koji za uneti mesec ispisuje broj dana u mesecu.
#include<stdio.h>
2
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
printf("Uneti redni broj meseca\n");
scanf("%d",&mesec);
switch(mesec)
{
case 1:case 3:case 5:case 7:case 8:case 10: case 12: printf("31 dan\n"); break;
case 4: case 6: case 9: case 11: printf("30 dana\n"); break;
case 2: printf("Da li je godina prestupna (d/n)?\n"); scanf("%c",&ch); scanf("%c",&ch);
if((ch=='d')||(ch=='D'))
printf("29 dana\n");
else
printf("28 dana\n"); break;
default: printf("Nekorektan broj meseca\n");
}
return 0;
}
Zadatak 4. Napisati program koji za uneti datum ispisuje datum sledećeg dana.
#include<stdio.h>
switch (m) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12: brdana=31; break;
case 4: case 6: case 9: case 11: brdana=30; break;
case 2: brdana=28+p; break;
}
if ( d < brdana )
d++;
else if (m!=12) {
d=1;
m++;
}
else {
d=1;
m=1;
g++;
}
printf("Datum sledeceg dana je: %d/%d/%d\n",d,m,g);
3
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
return 0;
}
#include<stdio.h>
#include<math.h>
if(a){
d=b*b-4*a*c;
if(d>0){
vrsta=Realni;
x1=(-b+sqrt(d))/(2*a);
x2=(-b-sqrt(d))/(2*a);
}
else if (d==0){
vrsta=Dvostruki;
x1=(-b/(2*a));
}
else {
vrsta=Kompleksni;
x1=(-b/(2*a));
x2=x1;
y1=sqrt(-d)/(2*a);
y2=-y1;
}
}
else if(b){
vrsta=Linearna;
x1=-c/b;
}
else
vrsta = Pogresna;
switch(vrsta){
case Realni: printf("Realni koreni su %lf i %lf\n",x1,x2);break;
case Dvostruki: printf("Dvostruki realni koren je: %lf",x1);break;
case Kompleksni: printf("Kompleksni koreni su:(%lf + %lf) i (%lf - %lf)",x1,y1,x2,y2);
break;
4
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
case Linearna: printf("Resenje linearne jednacine je: %lf",x1);break;
case Pogresna: printf("Podaci nemaju smisla!!!");break;
}
printf("\n");
return 0;
}
#include<stdio.h>
#include<stdio.h>
5
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
Zadatak 8. Permutovanje cifara broja.
#include<stdio.h>
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
srand( (unsigned)time(NULL) );
while ( ch != 0x1B )
{
if ( kbhit() )
{
ch = getch();
switch ( ch )
{
case 0x20: printf( "%d\n",rand()%100 ); break;
default: printf( "Greska!\n" ); break;
}
}
}
6
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
return 0;
}
Zadatak 10. Napisati program u kome se definiše funkcija prost() koja ispituje da li je broj
prost i funkcija main() koja njenim korišćenjem štampa sve proste brojeve do datog prirodnog
broja n.
#include<stdio.h>
#include<math.h>
int prost(int n)
{
int i;
for (i=2;i<=sqrt(n);i=i+1)
if(n%i==0)
return 0;
return i;
}
Zadatak 11. Napisati program kojim se štampaju svi trocifreni brojevi (ako ih ima) koji su
jednaki sumi faktorijela svojih cifara.
#include<stdio.h>
int fakt(int n)
{
int p=1,i;
for(i=2;i<=n;i++)
p*=i;
return p;
}
7
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
printf("Trocifreni brojevi jednaki sumi faktorijela svojih cifara su:\n");
for(n=100;n<1000;n++)
{
a=n%10;
b=n/10%10;
c=n/100;
if(n==fakt(a)+fakt(b)+fakt(c)) printf("%d\n",n);
}
return 0;
}
#include<stdio.h>
for(i=0;i<n;i++)
{
printf("a[%d]= ",i+1);
scanf("%d",&a[i]);
}
}
for(i=0;i<n;i++)
8
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
pomerilevo(a,n);
ispis(a,n);
printf("\n");
return 0;
}
Zadatak 13. Izdvajanje niza iz k-te paralele dijagonale kvadratne matrice, i njegovo sortiranje.
#include<stdio.h>
for(i=0;i<n;i++)
printf("%d\n",a[i]);
}
9
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
if(j-i == k)
b[p++]=a[i][j];*/
Zadatak 14. Napisati program koji od unete matrice formira niz na taj način što od
maksimalnog elementa oduzme minimalan u svakoj vrsti matrice.
#include<stdio.h>
10
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
scanf("%d",&a[i][j]);
}
}
for(j=0;j<k;j++)
if(a[i][j]>max[i])
max[i]=a[i][j];
}
for(i=0;i<v;i++)
{
min[i]=a[i][0];
for(j=0;j<k;j++)
if(a[i][j]<min[i])
min[i]=a[i][j];
}
for(i=0;i<v;i++)
b[i]= max[i]-min[i];
}
Zadatak 15. Napisati program koji menja elemente iz dve vrste matrice.
11
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
#include<stdio.h>
12
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
Zadatak 16. Napisati program koji za uneti niz brojeva određuje koliko ih ima do prvog
negativnog.
#include<stdio.h>
Zadatak 17. Napisati program koji sve negativne elemente niza stavlja na kraj tog niza.
#include <stdio.h>
13
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
{
printf("a[%d]=",i);
scanf("%f",&a[i]);
}
}
Zadatak 18. Napisati program koji za slučajno uneti niz brojeva, sažima niz na taj način što
sve iste elemente koji su jedan za drugim sabira i postavlja na prvo mesto pojavljivanja tog
broja u nizu.
14
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
for(i=0;i<n;i++)
{
k=i;
j=i+1;
pom=a[k];
while(a[k] == a[j])
{
pom=pom+a[j];
j++;
i++;
}
b[p++]=pom;
}
return p;
}
15
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
printf("\nUnesi elemente niza");
upis(a,n);
br = sazimanje(a,b,n);
printf("\n");
ispis(a,n);
printf("\n");
ispis(b,br);
printf("\n");
}
Zadatak 19. Napisati program koji na početak niza stavlja one elemente koji se pojavljuju
samo jedanput u nizu, a zatim ostale elemente po redosledu po kome su učitani u niz.
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
return k;
}
16
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
int main(int argc, char *argv[])
{
int n,a[50],b[50],c[50],k=0,e=0,i;
for(i=0;i<n;i++)
{
if (brponavljanja(a,n,a[i]) == 1)
b[k++]=a[i];
else
c[e++]=a[i];
}
printf("\n");
ispis(a,n);
printf("\n");
ispis(b,k);
printf(" ");
ispis(c,e);
}
#include<stdio.h>
int main(int argc, char *argv[])
{
char film[]=”Tango argentino”;
char *pok;
pok=film;
puts(pok);
puts(++pok);
film[5]=’\0’;
puts(film);
puts(++pok);
}
Rešenje:
Tango argentino
ango argentino
17
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
Tango
ngo
#include<stdio.h>
#include<string.h>
int main(int argc, char *argv[])
{
char ime[]=”Bingo”;
char *pok;
pok=ime+strlen(ime);
while(--pok >= ime)
puts(pok);
}
Rešenje:
o
go
ngo
ingo
Bingo
#include<stdio.h>
#include<string.h>
int main(int argc, char *argv[])
{
char s1[28]=”ani ceo”;
char s2[40]=”Ko rano r”;
char *s3=”dan zeva.”;
strcat(s1,s3);
strcat(s2,s1);
puts(s2);
}
18
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
a)
void kopi(char *s1, char *s2)
{
while (*s2=*s1)
{
s1++;
s2++;
}
}
b)
int palindrom(char *s)
{
char *p=s+strlen(s)-1;
while(s<p && *s==*p)
{s++; p--;}
return (s>=p);
}
c)
char *nadji_prvi(char *s, char c)
{
while(*s && *s!=c) s++;
if(*s) return s
}
d)
void brisi_znak(char *s, char c)
{
char *p=s;
while(*p)
{
if(*p!=c) *s++=*p;
p++;
}
*s=’\0’;
}
e)
int pos(char *s1, char *s2)
{
if(strstr(s1,s2)!=NULL) return strstr(s1,s2) – s1;
else return -1;
}
Zadatak 25. Napisati funkciju kojom se iz stringa s briše d znakova počev od pozicije p, pri
čemu počev od pozicije p u stringu s ima barem d znakova.
19
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
Zadatak 26. Napisati program koji za uneti string i neki broj ispisuje samo one karaktere sa
pozicija gde se u broju u njegovom binarnom zapisu javlja broj 1.
#include <stdio.h>
/*Nizovi i pokazivaci*/
#include<stdio.h>
int main(int argc, char *argv[])
{
float a,b,c,fniz[5]={0.01,0.1,0.5,1.0,10.0};
float *p_fniz;
char tekst[]={"Ovo je znakovni niz\n"};
char *p_tekst;
int i;
20
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
p_fniz=fniz;
a=*p_fniz; // a=fniz[0]
b=*(p_fniz+2); // b=fniz[2]
p_fniz=&fniz[2];
c=*(p_fniz+2); // c=fniz[4]
printf("a=%f b=%f c=%f\n",a,b,c);
//ispis stinga
for(i=0;tekst[i]!='\0';++i)putchar(tekst[i]);
// ispis stringa na drugi nacin
for(p_tekst=tekst;*p_tekst!='\0';++p_tekst)putchar(*p_tekst);
return 0;
}
#include<stdio.h>
21
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
Zadatak 29. Napisati program kojim se iz stringa s brise svaki znak koji odgovara bilo kom
znaku stringa t.
#include <stdio.h>
#include <string.h>
Zadatak 30. Program za odredjivanje dužine stringa koji se učitava sa komnadne linije.
#include<stdio.h>
22
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
++l;
++p;
}
return l;
}
Zadatak 31. Napisati program koji iz datog stringa s izbacuje sve komentare, s tim što u
komentaru nema komentara.
#include <stdio.h>
#include <string.h>
Zadatak 32. Napisati program koji odredjuje broj reči u stringu s i dužinu najduže reči, reci su
razdvojene blanko simbolima.
#include<stdio.h>
for(i=0;*(s+i);i++)
if(*(s+i)==' ')
{
if(brojslovaureci>maksimalnarec) maksimalnarec=brojslovaureci;
brojslovaureci=0;
}
23
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
else
{
if(!brojslovaureci)brojreci++;
brojslovaureci++;
}
if(brojslovaureci>maksimalnarec) maksimalnarec=brojslovaureci;
printf("%d %d\n",brojreci,maksimalnarec);
return 0;
}
Zadatak 33. Napisati program koji odredjuje prosečan broj slova u rečima parne dužine.
#include<stdio.h>
if(k>0)
if(k%2==0)
{
br++;
q+=k;
}
24
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
#include<stdio.h>
#include<stdlib.h>
int n1,n2,n3,i,j;
double *s1, *s2, *s3;
s1=malloc(n1*sizeof(double));
printf("Elementi prvog skupa su: ");
for(i=0;i<n1;scanf("%lf",&s1[i++]));
if (n1==0) putchar('\n');
s2=malloc(n2*sizeof(double));
printf("Elementi drugog skupa: ");
for(i=0;i<n2;scanf("%lf",&s2[i++]));
if (n2==0) putchar('\n');
s3=malloc((n1+n2)*sizeof(double));
for(n3=0;n3<n1;n3++)
s3[n3]=s1[n3];
for(j=0;j<n2;j++){
for(i=0;i<n1;i++)
if(s2[j]==s1[i]) break;
if(i==n1) s3[n3++]=s2[j];
}
s3=realloc(s3,n3*sizeof(double));
free(s1);
free(s2);
free(s3);
}
#include<stdio.h>
25
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
#include<string.h>
#include<stdlib.h>
do {
ime=malloc(MAX_DUZ*sizeof(char));
gets(ime);
if((duz=strlen(ime))==0)
{
free(ime);
break;
}
for(i=br_imena-1;i>=0;i--)
if( strcmp(imena[i],ime) > 0 )
imena[i+1]=imena[i];
else break;
imena[i+1]=ime;
}
while(++br_imena<MAX_IME);
#include<stdio.h>
26
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
FILE *fp;
char s[256];
if((fp=fopen("knjiga.txt","r"))==NULL)
{
perror("Greska");
return;
}
while(fgets(s,256,fp)!=NULL)k++;
printf("Fajl ima %d linija\n",k);
fclose(fp);
}
Zadatak 37. Napisati program kojim se sadržaj fajla test.dat formiran od velikih slova alfabeta
šifriran šalje u fajl sifra.dat. Znak se šifrira tako što se zamenjuje sledećim ASCII znakom, a
znak Z zamenjuje sa A.
#include<stdio.h>
Zadatak 38. U tekstualnom fajlu odrediti najdužu liniju. Ako ima više linija najveće dužine
odrediti prvu među njima.
#include<stdio.h>
#include<string.h>
27
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
if((fp=fopen("test.txt","r"))==NULL)
{
printf("Greska\n ");
return;
}
maxl=0;
while(fgets(s,256,fp)!=NULL)
if(strlen(s)>maxl)
{
maxl=strlen(s);
strcpy(maxs,s);
}
printf("Najduza linija\n%s\n ima duzinu %d\n",maxs,maxl);
fclose(fp);
}
Zadatak 39. Napisati program za učitavanje datoteke pod imenom ulaz.dat i formiranje
datoteke sa nazivom izlaz.dat koja sadrži samo one redove ulazne datoteke ulaz.dat u kojima
se nalazi reč “fakultet”.
#include<stdio.h>
#include<string.h>
28
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
Zadatak 40. Napisati program koji čita podatke iz datoteke ULAZ.TXT (ime studenta, broj
bodova na prijemnom ispitu), broji sve studente koji imaju broj bodova veći od proseka i
upisuje podatke o takvim studentima u datoteku IZLAZ.TXT.
#include<stdio.h>
#define DIM 10
typedef struct student{
char ime[20];
int brBodova;
};
29
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
Zadatak 41. U datoteci IMENIK.TXT nalaze se sledeci podaci: ime, prezime i broj telefona
telefonskog pretplatnika. Napisati program koji vrsi sortiranje imenika prema prezimenu
pretplatnika i za zadato prezime prikazuje telefonski broj pretplatnika na standardnom izlazu.
#include<stdio.h>
#include<string.h>
#define DIM 10
30
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
printf("%s\t%s\t%s\n", nizImenik[i].prezime, nizImenik[i].ime, nizImenik[i].broj);
printf("Ukupan broj telefonskih pretplatnika je: %d\n",n);
printf("Zadati prezime pretplatnika: ");
scanf("%s", &trazi);
for(i=0; i<n; i++){
if(strcmp(nizImenik[i].prezime,trazi)==0){
printf("Broj telefoma trazenog pretplatnika je:\n");
printf("%s\t%s\t%s\n", nizImenik[i].prezime, nizImenik[i].ime, nizImenik[i].broj);
}
}
fclose(in);
return 0;
}
31
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
REŠENI ZADACI SA PRVOG KOLOKVIJUMA IZ PROGRAMSKIH JEZIKA
Zadatak 1. Napisati program koji za uneti broj ispisuje koliko ima jedinica u njegovom
binarnom zapisu.
#include<stdio.h>
Zadatak 2. Napisati program koji uneti niz pomera za n cifara u desno. Zadatak rešiti preko
funkcija.
#include<stdio.h>
void unosniza(int a[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("a[%d]=",i+1);
scanf("%d",&a[i]);
}
}
void ispisniza(int a[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
void pomeri(int a[], int n, int koliko)
32
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
{
int i,pom,j;
for(j=0;j<=koliko;j++)
{
pom=a[n-1];
for(i=n-1;i>=0;i--)
a[i]=a[i-1];
a[0]=pom;
}
}
int main(int argc, char *argv[])
{
int a[25],n,k;
printf("Unesi broj elemenata niza: ");
scanf("%d",&n);
unosniza(a,n);
printf("Unesi broj za koji pomeras niz u desno: ");
scanf("%d",&k);
printf("Niz posle pomeranja u desno je:\n");
pomeri(a,n,k);
ispisniza(a,n);
return 0;
}
Zadatak 3. Napisati program koji za unetu matricu vrši razmenu elemenata po vrstama na taj
način što negativne elemente stavlja na kraj svake vrste.
#include<stdio.h>
void unosmatrice(int a[][20],int v,int k)
{
int i,j;
for(i=0;i<v;i++)
for(j=0;j<k;j++)
{
printf("a[%d][%d]=",i+1,j+1);
scanf("%d",&a[i][j]);
}
}
void ispismatrice(int a[][20],int v,int k)
{
int i,j;
for(i=0;i<v;i++)
{
for(j=0;j<k;j++)
printf("%d ",a[i][j]);
printf("\n");
}
33
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
}
void uredimatricu(int a[][20], int v, int k)
{
int i,j,pom,vrsta;
for (vrsta=0;vrsta<v;vrsta++)
{
i=0;
j=k-1;
while(i<j)
{
if(a[vrsta][i]>0)
i++;
else
if(a[vrsta][j]>0)
{
pom=a[vrsta][i];
a[vrsta][i]=a[vrsta][j];
a[vrsta][j]=pom;
j--;
}
}
}
}
int main(int argc, char *argv[])
{
int a[20][20],v,k;
printf("Unesi broj vrsta i kolona matrice: ");
scanf("%d %d",&v,&k);
unosmatrice(a,v,k);
uredimatricu(a,v,k);
ispismatrice(a,v,k);
return 0;
}
Zadatak 4. Napisati program koji za uneti broj ispisuje koliko ima nula u njegovom binarnom
zapisu.
#include<stdio.h>
int brnula(int broj)
{
int i,br=0;
for(i=0;i<8;i++)
{
if((broj & 128)==0)
br++;
broj<<=1;
}
return br;
}
34
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
int main(int argc, char *argv[])
{
int broj;
printf("Unesi broj: ");
scanf("%d",&broj);
printf("Broj nula je %d\n",brnula(broj));
return 0;
}
Zadatak 5. Napisati program koji uneti niz pomera za 2. cifre u desno, pa za 3. cifre u levo.
Zadatak raditi prko funkcija.
#include<stdio.h>
void unosniza(int a[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("a[%d]=",i+1);
scanf("%d",&a[i]);
}
}
void ispisniza(int a[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
void pomeri(int a[], int n, int smer, int koliko)
{
int i,pom,j;
switch(smer)
{
/*pomeranje u levo */
case 1:{
for(j=0;j<koliko;j++)
{
pom=a[0];
for(i=0;i<n-1;i++)
a[i]=a[i+1];
a[n-1]=pom;
}
} break;
/*pomeranje u desno */
case 2: {
for(j=0;j<koliko;j++)
{
pom=a[n-1];
35
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
for(i=n-1;i>=0;i--)
a[i]=a[i-1];
a[0]=pom;
}
} break;
}
}
int main(int argc, char *argv[])
{
int a[25],n;
printf("Unesi broj elemenata niza: ");
scanf("%d",&n);
unosniza(a,n);
pomeri(a,n,2,2);
printf("Niz posle pomeranja u desno za dve pozicije:\n");
ispisniza(a,n);
pomeri(a,n,1,3);;
printf("Niz posle pomeranja u levo za tri pozicije:\n");
ispisniza(a,n);
return 0;
}
Zadatak 6. Napisati program koji za unetu matricu vrši razmenu elemenata po kolonama na taj
način što negativne elemente stavlja na kraj svake kolone.
#include<stdio.h>
void unosmatrice(int a[][20],int v,int k)
{
int i,j;
for(i=0;i<v;i++)
for(j=0;j<k;j++)
{
printf("a[%d][%d]=",i+1,j+1);
scanf("%d",&a[i][j]);
}
}
void ispismatrice(int a[][20],int v,int k)
{
int i,j;
for(i=0;i<v;i++)
{
for(j=0;j<k;j++)
printf("%d ",a[i][j]);
printf("\n");
}
}
36
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
int i,j,pom,kolona;
for (kolona=0;kolona<k;kolona++)
{
i=0;
j=v-1;
while(i<j)
{
if(a[i][kolona]>0)
i++;
else
if(a[j][kolona]>0)
{
pom=a[i][kolona];
a[i][kolona]=a[j][kolona];
a[j][kolona]=pom;
j--;
}
}
}
}
#include<stdio.h>
int broj_cifara(int n)
int s=0;
while(n)
37
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
{
s++;
n=n/10;
return s;
int dan,mesec,godina,n,s,brdana;
scanf("%d%d%d",&dan,&mesec,&godina);
scanf("%d",&n);
s=broj_cifara(dan)+broj_cifara(mesec)+broj_cifara(godina)+3;
do
switch(mesec)
case 1: case 3: case 5: case 7: case 8: case 10: case 12: brdana=31;break;
dan++;
else if (mesec!=12) {
dan=1;
mesec++;
38
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
}
else {
dan=1;
mesec=1;
godina++;
while( s < n );
return 0;
39
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
REŠEI ZADACI SA DRUGOG KOLOKVIJUMA IZ PROGRAMSKIH JEZIKA
Zadatak 1. На пријему је n особа, нумерисаних бројевима 0, 1, 2... , n-1. Свака особа има
највише два непријатеља. Дата је матрица Аnxn тако да а[i][j]=1 ако је особи i
непријатељ особа ј, иначе a[i][j]=0. Матрица А је симетрична у односу на главну
дијагоналу (a[i][j]=a[j][i]). Написати функцију којом се особе распоређују у три групе
тако да су у свакој групи само пријатељи.
#include <stdio.h>
#include <stdlib.h>
40
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
for (i=0;i<n;i++) {
if (provera(m,a,x,j,i,n)==0)
a[j++]=x[i];
else
if (provera(m,b,x,k,i,n)==0)
b[k++]=x[i];
else
c[l++]=x[i];
}
#include<stdio.h>
#include<string.h>
struct Roba{
41
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
int sifra;
char naziv[20];
int kolicina;
float cena;
};
for(i=0;i<n;i++)
{
k=i;
j=i+1;
pom=roba[k].kolicina;
while(roba[k].sifra == roba[j].sifra) {
pom=pom+roba[j].kolicina;
j++;
i++;
}
fprintf(out,"%d %s %d %.2fdin\n",roba[k].sifra,roba[k].naziv,pom,roba[k].cena);
}
}
42
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
in=fopen("magacin.txt", "r");
for(i=0;i<n;i++){
fscanf(in,"%d%s%d%f",&roba[i].sifra,&roba[i].naziv,&roba[i].kolicina,&roba[i].cena
);
}
sredi(roba,n);
}
Zadatak 3. Написати програм на програмском језику C који учитава један занковни низ
(стринг) S1 и један цео број М, а затим формира нови знаковни низ S2 само од оних
знакова на чијим су позицијама одговарајући битови броја М једнаки нули. Сматрати
да се цео број представља у 8-битној локацији, а да знаковни низ може имати највише 8
знакова. На крају, програм исписује нови знаковни низ S2.
#include <stdio.h>
43
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
printf("Novi string S2: %s\n", S2);
}
, .
Zadatak 4. Izračunati i ispisati vrednost z po formuli: , 16.8 2 ,
ako se x menja od x1 do x2 sa korakom 1. Ako nije ispunjen uslov definisanosti, uzeti da je
vrednost promenljive z jednaka 1. Koristiti funkcije kod kojih se vrši prenošenje parametara
po referenci.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define min 19.2
#define max 16.8
44
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
float x1,x2,h,d1,d2,z[30];
int j=0;
printf("Unesi granice x1, x2 i korak h: ");
scanf("%f%f%f",&x1,&x2,&h);
while( x1 <= x2 )
{
if (x1==-1)
z[j]=1;
else
{
koren(x1,&d1);
razl(x1,&d2);
z[j]=d1*d2;
}
j++;
x1=x1+h;
}
ispis(z,j);
system("PAUSE");
}
Zadatak 5. Написати програм на програмском језику C који учитава један занковни низ
(стринг) S1 и један цео број m, а затим формира нови знаковни низ S2 тако што од низа
S1 узме све елементе од p-тог до q-тог, уклони све карактере “a” уколико постоје и
нађе суму квадрата од броја k(број елемената низа S2) до m. Уколико је та сума већа од
41*m решење исписати на стандардном излазу, у супротном решење запамтити у
датотеци. Задтак решити коришћењем функција које своје параметре преносе преко
референци.
#include<stdio.h>
#include<string.h>
45
VEŽBE IZ PROGRAMSKOG JEZIKA „C“ 2007/2008
void sredi(char *s)
{
char *t;
t=s;
while(*s && *s!='a')
{
*s=*t;
t++;
s++;
}
*s='\0';
}
printf("Unesite string:");
gets(s1);
printf("unesite p,q i m:");
scanf("%d%d%d",&p,&q,&m);
seci(s1,p,q);
sredi(s1);
dim=strlen(s1);
kv(s1,m,&kvadrat,dim);
if (kvadrat>41*m)
fprintf(out,"%f je vece od %d",kvadrat,41*m);
else
fprintf(out,"%f nije vece od %d",kvadrat,41*m);
46
Увод у програмски језик C
Задаци за вежбу
1
1. Програм за демонстрацију операције инкремента (++) пре и после имена променљиве
#include <stdio.h>
x=c++;
printf( "\nNakon naredbe x=c++\n");
printf("\tvrednost promenljive x je %d\n", x );
printf("\tvrednost promenljive c je %d\n\n", c );
x=++c;
printf( "\nNakon naredbe x=++c\n");
printf("\tvrednost promenljive x je %d\n", x );
printf("\tvrednost promenljive c je %d\n\n", c );
return 0;
2
2. Програм за демонстрацију операције декремента (--) пре и после имена променљиве
#include <stdio.h>
x=c--;
printf( "\nNakon naredbe x=c--\n");
printf("\tvrednost promenljive x je %d\n", x );
printf("\tvrednost promenljive c je %d\n\n", c );
x= --c;
printf( "\nNakon naredbe x= --c\n");
printf("\tvrednost promenljive x je %d\n", x );
printf("\tvrednost promenljive c je %d\n\n", c );
return 0;
3
3. Написати програм који наизменично исписује знак + или знак -. Укупан број појављивања знакова је 10.
Сваки знак треба да се налази у посебном реду.
Решење 1:
while ( brojac <= 10 ) /* sve dok je brojac manji ili jednak 10, radi */
{
znak = (brojac % 2) ? ('-') : ('+'); /* parne vrednosti +, neparne - */
/* Ispis na ekran */
printf( "%c \n", znak );
while ( brojac <= 10 ) /* sve dok je brojac manji ili jednak 10, radi */
{
/* Ispisi na ekran */
printf("%c\n",(brojac % 2) ? ('-'):('+')); /* parni +, neparni - */
4
4. Написати програм који захтева од корисника да унесе два цела броја а потом исписује њихову суму
Решење 1
5
Решење 3. (He мора се уводити променљива sum)
/* Sabiranje dva broja */
#include <stdio.h>
6
5. Написати програм који очекује од корисника да унесе два цела броја а потом употребом релационих
оператора (==, !=, <,<=, >, >=) исписује однос унетих бројева.
Решење 1.
/* Upotreba if naredbe, relacionih operatora i operatora dodele */
#include <stdio.h>
7
Решење 2. (Обзиром да if наредбе обухватају само једну наредбу витичасте заграде нису неопходне)
/* Upotreba if naredbe, relacionih operatora i operatora dodele */
#include <stdio.h>
8
6. Применом while петље и оператора ++ и – – написати програм који исписује табелу димензија десет
врста и пет колона и то тако да су парне врсте попуњене знацима $ $ $ $ $, а непарне знацима # # # # #.
#include <stdio.h>
while ( vrsta >= 1 ) /* kruzi u while petlji dve dok vrsta ne bude < 1 */
{
kolona =1; /* postavi prom. kolona na 1 pri ulasku u while petlju */
while ( kolona <= 5 ) /* sve dok je kolona manje i jednako 5... */
{
printf( "%c", (vrsta % 2) ? ('$'): ('#') ); /* Ispis na ekran */
kolona++; /* isto sto i kolona = kolona + 1 ili kolona += 1*/
} /* kraj unutrasnje while petlje */
9
7. Напишите програм који очекује од корисника да унесе тачно 5 целих бројева а потом израчунава њихову
средњу вредност. Све дефинисане променљиве морају бити целобројне.
/* inicijalizacija */
zbir = 0; /* inicijalizacija promenljive zbir */
brojac = 1; /* inicijalizacija promenljive brojac */
/* faza obrade */
while ( brojac <= 5 ) /* sve dok je brojac manji ili jednak 5... */
{
printf( "Unesite vrednost: " ); /* Ispis poruke na ekran */
scanf( "%d", &vrednost ); /* ucitaj unetu vrednost */
zbir = zbir + vrednost ; /* dodaj unetu vrenost prom. zbir */
brojac = brojac + 1; /* inkrement promenljive brojac */
} /* kraj while petlje */
/* zavrsna faza */
srednja_vred = zbir / 5; /* celobrojno deljenje, odbacivanje decimalnog dela */
Напомена:
Променљива zbir и променљива srednja_vred су целобројне променљиве (типа int ) па је
резултат дељења srednja_vred = zbir / 5 цео број тј. одбацује се децимални део
10
Решење 2 (Превазилажење проблема целобројног дељења)
/* inicijalizacija */
zbir = 0; /* inicijalizacija promenljive zbir */
brojac = 1; /* inicijalizacija promenljive brojac */
/* faza obrade */
while ( brojac <= 5 ) /* sve dok je brojac manji ili jednak 10... */
{
printf( "Unesite vrednost: " ); /* Ispis poruke na ekran */
scanf( "%d", &vrednost ); /* ucitaj unetu vrednost */
zbir = zbir + vrednost ; /* dodaj unetu vrenost prom. zbir */
brojac = brojac + 1; /* inkrement promenljive brojac */
} /* kraj while petlje */
Напомена:
Променљива zbir типа int а променљива srednja_vred је типа float. Без обзира на то
резултат дељења zbir/5 је цео број. Да би се превазишао овај проблем довољно је да бар
један операнд буде типа float или double. У овом примеру је извршена привремена
конверзија типа променљиве zbir из типа int у тип float наредбом (float)zbir.
11
Решење 3 (Претходно решење без променљиве srednja_vred )
/* inicijalizacija */
zbir = 0; /* inicijalizacija promenljive zbir */
brojac = 1; /* inicijalizacija promenljive brojac */
/* faza obrade */
while ( brojac <= 5 ) /* sve dok je brojac manji ili jednak 10... */
{
printf( "Unesite vrednost: " ); /* Ispis poruke na ekran */
scanf( "%d", &vrednost ); /* ucitaj unetu vrednost */
zbir = zbir + vrednost ; /* dodaj unetu vrenost prom. zbir */
brojac = brojac + 1; /* inkrement promenljive brojac */
} /* kraj while petlje */
12
8. Напишите програм који очекује од корисника да унесе произвољан број целих бројева а потом
израчунава њихову средњу вредност. Крајем уноса се сматра унос броја -1.
#include <stdio.h>
/* inicijalizacija */
zbir = 0; /* inicijalizacija promenljive zbir */
brojac = 0; /* inicijalizacija promenljive brojac */
/* Obrada */
/* Procitaj prvu vrednost od korisnika */
printf( "Unesite vrednost, -1 za prekid: " ); /* Prikaz na ekran */
scanf( "%d", &vrednost ); /* Ucitaj unetu vrednost */
/* zavrsna faza */
/* Ako je uneta bar jedna vrednost */
if ( brojac != 0 )
{
/* izracunaj srednju vrednost svih unetih vrednosti */
srednja_vred = ( float )zbir / brojac; /* privremena promena tipa */
13
9. Демонстрација рада са битским операторима
#include <stdio.h>
14
10. Напишите програм који на основу унетих података исписује број студената који су положили испит
односно број студената који нису положили испит.
Корисник за сваког студента који је положио испит уноси вредност 1, а за сваког студента који није
положио испит уноси вредност 2.
Корисник уносом вредности било ког целог броја изузев 1 или 2 покреће процедуру обраде унетих
података и испис жељених вредности
Pешење 1
do
{
printf( "Unesite rezultat ( 1=polozio, 2=pao ): " ); /* Ispis na ekran */
scanf( "%d", &rezultat );
/* zavrsna faza */
printf( "Broj studenata koji su polozili ispit %d\n", polozilo );
printf( "Broj studenata koji nisu polozili ispit %d\n", palo );
15
Pешење 2
do
{
printf( "Unesite rezultat ( 1=polozio, 2=pao ): " ); /* Ispis na ekran */
scanf( "%d", &rezultat );
/* zavrsna faza */
printf( "Broj studenata koji su polozili ispit %d\n", polozilo );
printf( "Broj studenata koji nisu polozili ispit %d\n", palo );
Напомена:
У другом решењу је примењена бесконачна do while петља, услов је увек испуњен
while(1). Напуштање петље је омогућено наредбом break.
16
11. Применом for петље табеларно испишите вредности куба бројева од 1 до 10.
printf("\nPreostalo je:\n");
17
13. Применом for петље и оператора ++ и – – написати програм који исписује табелу произвољних
димензија и то тако да је табела попуњена знацима #.
/* Prikaz na ekran */
printf( "Unesite dva cela broja: " );
scanf( "%d%d", &x, &y ); /* procitaj vrednosti za x i y */
18
14. Употребом while петље испишите вредности од 1 до 10 тако да свака буде у новом реду
15. Употребом fоr петље испишите вредности од 1 до 10 тако да свака буде у новом реду
Pешење 1
#include <stdio.h>
19
Pешење 2
i = 1;
for( ; i < 11; i++) /* uslov ponavljanja */
{
printf ( "%d\n", i ); /* ispis vrednosti brojaca */
} /* kraj for petlje */
Напомена:
Сваки од три елемента унутар округлих заграда for петље може да се изостави (напише на другом
месту). Приметите да је иницијализација променљиве i (i=0) обављена пре почетка for петље.
Pешење 3
/* Upotreba while petlje */
#include <stdio.h>
i = 1;
for( ; i < 11; ) /* uslov ponavljanja */
{
printf ( "%d\n", i ); /* ispis vrednosti brojaca */
i++;
} /* kraj for petlje */
Напомена:
Сваки од три елемента унутар округлих заграда for петље може да се изостави (напише на другом
месту). Приметите да је: иницијализација променљиве i (i=0) обављена пре почетка for петље и
операција инкремента променљиве i (i++) обављена унутар тела for петље.
20
Решење 4
/* Upotreba for petlje */
#include <stdio.h>
i = 1;
for( ; ; ) /* uslov ponavljanja */
{
printf ( "%d\n", i ); /* ispis vrednosti brojaca */
i++;
if(i > 10)
break;
} /* kraj for petlje */
Напомена:
Сваки од три елемента унутар округлих заграда for петље може да се изостави (напише на другом
месту). Приметите да је: иницијализација променљиве i (i=0) обављена пре почетка for петље,
услов напуштања for петље је реализован унутар тела петље ( if(i > 10)break; ) и операција
инкремента променљиве i (i++) обављена унутар тела for петље.
#include <stdio.h>
21
17. Употребом fоr петље испишите непарне бројеве од 1 до 20.
#include <stdio.h>
18. Употребом fоr петље израчунајте збир свих парних бројева од 1 до 100.
22
19. Демострација примене наредбе break за напуштање for петље
23
21. Демострација примене наредбе continue за “прескакање” једног корака унутар for петље
24
22. Демострација примене наредбе continue за “прескакање” једног корака унутар while петље
25
Увод у програмски језик C
Карактери и стрингови
Задаци за вежбу
1
Програм за демонстрацију функција isdigit, isalpha, isalnum, и isxdigit
int main()
{
printf( "%s\n%s%s\n%s%s\n\n", "Prema funkciji isdigit: ",
isdigit('8') ? ("8 je ") : ("8 nije "), "cifra",
isdigit('#') ? ("# je ") : ("# nije "), "cifra" );
2
Програм за демонстрацију функција islower, isupper, tolower, toupper
#include <stdio.h>
#include <ctype.h>
int main()
{
printf( "%s\n%s%s\n%s%s\n%s%s\n%s%s\n\n", "Prema funkciji islower:",
islower( 'p' ) ? "p je " : "p nije ", "malo slovo",
islower( 'P' ) ? "P je " : "P nije ", "malo slovo",
islower( '5' ) ? "5 je " : "5 nije ", "malo slovo",
islower( '!' ) ? "! je " : "! nije ", "malo slovo" );
printf( "%s%c\n%s%c\n%s%c\n%s%c\n",
"m konvertovano u veliko slovo je ", toupper( 'm' ),
"7 konvertovano u veliko slovo je ", toupper( '7' ),
"$ konvertovano u veliko slovo je ", toupper( '$' ),
"K konvertovano u malo slovo je ", tolower( 'K' ) );
3
Програм за демонстрацију функција isspace, isgraph
#include <stdio.h>
#include <ctype.h>
int main()
{
printf( "%s\n%s%s%s\n%s%s%s\n%s%s\n\n", "Prema funkciji isspace:",
"Novi red", isspace('\n') ? " je " : " nije ", "beli znak",
"Tab", isspace('\t') ? " je " : " nije ", "beli znak",
isspace( '%' ) ? "% je " : "% nije ", "beli znak" );
Напишите програм који конвертује стринг "99.50" у поменљиву типа double и потом поменљиву типа
double дели са 3 и исписује резултат.
#include <stdlib.h>
int main()
{
char str_a[]="99.50";
double nova; /* promenljiva koja cuva konvertovani string */
nova = atof(str_a);
Напомена: Да пи исписали знаке навода унутар наредбе printf морате користити ескејп
секвенцу ( printf("String \"%s\"...)
4
Напишите програм који конвертује стринг "3245" у поменљиву типа int и потом од поменљиве типа int
одузима 245 и исписује резултат.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str_a[]="3245";
int celo; /* promenljiva koja cuva konvertovani string */
celo = atoi(str_a);
Напишите програм који од корисника захтева да унесе једну линију текста а потом исписује унети текст
уназад
Решење 1:
#include<stdio.h>
#include<string.h>
int main()
{
char linija_teksta[80]; /* definisanje niza od 80 elemenata */
char *ptr; /* pokazivac na char promenljivu */
int indeks_poklapanja;
int i;
indeks_poklapanja=ptr - linija_teksta - 1;
/* moze i ovako: indeks_poklapanja=ptr-&linija_teksta[0] - 1; ili
indeks_poklapanja=ptr-&linija_teksta - 1; */
for(i=indeks_poklapanja;i>=0;i--)
{
printf("%c", linija_teksta[i]);
}
printf("\n");
return 0; /* oznacava uspesan kraj programa */
} /* kraj funkcije main */
5
Решење 2:
#include<stdio.h>
#include<string.h>
int main()
{
char linija_teksta_a[80]; /* definisanje niza od 80 elemenata */
char linija_teksta_b[80]; /* definisanje niza od 80 elemenata */
char *ptr; /* pokazivac na char promenljivu */
int indeks_poklapanja;
int i;
6
Напишите програм који од корисника захтева да унесе једну линију текста а потом исписује унети текст. За
прихват унетог текста користити функцију а за испис функцију
Решење 1
int main()
{
char znak; /* promen. u koju se upisuje znak koji unese korisnik */
char recenica[80]; /* niz od 80 elemenata */
int i = 0; /* brojac inicijalizovan na 0 */
7
Решење 2
#include <stdio.h>
int main()
{
char znak; /* promen. u koju se upisuje znak koji unese korisnik */
char recenica[80]; /* niz od 80 elemenata */
int i = 0; /* brojac inicijalizovan na 0 */
Дефинишите стринг Happy Birthday to You и запишите га у низ x . Дефинишите још двс низа: y и z.
Применом наредбе strcpy ископирајте садржај стринга x у стринг y, а потом првих 14 знакова низа y
ископирајте у низ z. Прикажите садржај сва три стринга.
Решење 1
/* Primena funkcija strcpy i strncpy */
#include <stdio.h>
#include <string.h>
int main()
{
char x[] = "Happy Birthday to You"; /* inicijalizacija niza x */
char y[ 25 ]; /* definisanje niza y */
char z[ 15 ]; /* definisanje niza z */
8
Решење 2
#include <stdio.h>
#include <string.h>
int main()
{
char x[] = "Happy Birthday to You"; /* inicijalizacija niza x */
char y[ 25 ]; /* definisanje niza y */
char z[ 15 ]; /* definisanje niza z */
9
Дефинишите низ (стринг) s1 од 20 елемената и иницијализујте га на вредност "Srecna ",
дефинишите низ (стринг) s2 и иницијализујте га на вредност "Nova godina " и дефинишите стринг s3 од
40 елемената та тако да буде "празан". Применом функције strcat спојте садржаје стринга s1 и s2,
испишите вредност новодобијеног стринга. Дописите првих 7 знакова новодобијеног стринга s1 на стринг s3
и исписите садржај стринга s3. На садржај стринга s3 допишите садржај стринга s1 и испишите садржај
стринга s3.
/*strcat, strncat */
#include <stdio.h>
#include <string.h>
int main()
{
char s1[20] = "Srecna "; /* inicijalizacija niza s1 */
char s2[] = "Nova godina "; /* inicijalizacija niza s2 */
char s3[40] = ""; /* inicijalizacija niza s3 као "prazаn" niz */
10
Дефинишите низ (стринг) s1 и иницијализујте га на вредност "Happy New Year". Дефинишите низ
(стринг) s2 и иницијализујте га на вредност "Happy New Year". Дефинишите низ (стринг) s3 и
иницијализујте га на вредност " Happy Holidays". Применом наредбе strcmp поредите њихоове
мођусобне односе.
#include <stdio.h>
#include <string.h>
int main()
{
const char s1[] = "Happy New Year"; /* inicijalizacija stringa */
const char s2[] = "Happy New Year"; /* inicijalizacija stringa */
const char s3[] = "Happy Holidays"; /* inicijalizacija stringa */
return 0;
Употребом функције strchr одредите да ли се знаци 'n' и 'z' налазе у стрингу "Ovo je jedan test"
/* strchr */
#include <stdio.h>
#include <string.h>
int main()
{
const char niz_znakova[] = "Ovo je jedan test"; /* inicijalizacija niza */
char znak1 = 'n';
char znak2 = 'z';
return 0;
} /* kraj funkcije main */
11
Употребом функције strstr одредите да ли се и на којим местима стринг "def" појављује у стрингу
"abcdefabcdef"
/* strstr */
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcdefabcdef"; /* string koji se pretrazuje */
char str2[] = "def"; /* string koji se trazi */
char *pch;
do
{
pch=strstr(pch, str2);
if(pch != NULL)
{
printf("String \"%s\" se nalazi u stringu \"%s\" na poziciji %2d\n",
str2, str1, pch-str1+1);
pch++;
} /* kraj if naredbe */
}while(pch != NULL);
return 0;
} /* kraj funkcije main */
/* strlen */
#include <stdio.h>
#include <string.h>
int main()
{
/* initialize 3 char pointers */
const char str1[] = "abcdefghijklmnopqrstuvwxyz";
const char str2[] = "tri";
const char str3[] = "Kikinda";
12
Увод у програмски језик C
Функције
Задаци за вежбу
1. Написати програм који исписује квадрате вредности од 1 до 10. Рачунање квадрата реализовати у
посебној функцији.
Решење:
printf( "\n" );
} /* kraj main */
Решење:
#include <stdio.h>
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
6 5 4 3 2 1
7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
Испис вредности реализовати у потпрограму (функцији) broji_unazad( int x) са једним улазним
аргументом.
Решење:
int main()
{
int br;
return 0;
} /* kraj funkcije main */
#include <stdio.h>
int main()
{
int x=6, y=10;
return 0;
} /* kraj funkcije main */
/* definicija funkcije */
void zameni(int *a, int *b) /* funkcija nema povratnu vrednost, tip void */
{
/* u promenljivu a je preslikana adresa promen. x */
/* u promenljivu b je preslikana adresa promen. y */
int temp;
temp= *a; /* u promen. temp upisi vrednost na koju pokazuje pointer a, tj.
vrednost prom. x */
*a = *b; /* na adresu na koju ukazuje pointer a upisi vrednost sa adrese
na koju ukazuje pointer b */
*b = temp; /* na adresu na koju ukazuje pointer b upisi vrednost promen. temp*/
} /* kraj funkcije zameni */
5. Написати програм који у четири реда исписује по пет случајних вредности између 1 и 6.
(Симулација бацања коцке). Користити функцију rand().
rand
Генерише псеудослучајан број.
декларација (прототип)
int rand( void );
Пвратна (Return) вредност
Враћа псеудослучајан број у распону од 0 до вредности дефинисане константом RAND_MAX.
(32767), <stdlib.h>.
Уколико желите да се псеудослучајне вредности не понављају користите функцију srand пре
позива функције rand.
Решење:
#include <stdio.h>
#include <stdlib.h>
/* ponovi 20 puta */
for ( i = 1; i <= 20; i++ )
{
/* uzmi slucajan (random) broj izmedju 1 i 6 i ispisi ga */
printf( "%10d", 1 + ( rand() % 6 ) ); /* moduo po 6 daje vrednosti od 0 do 5 */
Сваки пут када покренете овај програм добићете исте вредности. Каква је то функција rand?
Проучите наредна два примера
6. Испитајте фреквенцију појављивања бројева од 1 до 6 применом функције rand() на узорку од 6000
покушаја.
Решење:
#include <stdio.h>
#include <stdlib.h>
int i;
int vrednost; /* dobijena vrednost od generatora pseudoslucajnih brojeva 6 */
int i;
int vrednost; /* dobijena vrednost od generatora pseudoslucajnih brojeva 6 */
for(i=1;i<7;i++)
printf( "\t%d%13d\n", i,frekvencija[i] );
#include <stdlib.h>
#include <stdio.h>
/* petlja 10 puta */
for ( i = 1; i <= 10; i++ )
{
/* uzmi slucajnu vrednost od 1 do 6 i ispisi je */
printf( "%10d", 1 + ( rand() % 6 ) );
#include <stdlib.h>
#include <stdio.h>
#include <time.h> /* sadrzi prototip funkcije time */
/* petlja 10 puta */
for(i = 1; i <= 10; i++)
{
/* uzmi slucajnu vrednost od 1 do 6 i ispisi je */
printf( "%10d", 1 + ( rand() % 6 ) );
faktorijel = 1;
for(i=broj; i>=1; i--)
{
faktorijel *= i; /* faktorijel = faktorijel * i; */
}
Функција faktorijel користи рекурзију да би одштампала факторијеле бројева од 0 до 10. Ова рекурзивна
функција прво тестира broj да би видела да ли је он различит од 1 и 0, и у том случају враћа вредност 1
што је уједно и прекид рекурзије односно напуштанје функције faktorijel.
Ако је улазни аргумент (broj) већи од 1 наредба return(broj*faktorijel(broj-1)); у ствари
позива функцију faktorijel са аргументом кој је за један мањи (broj-1)
11. Напишите програм који рачина Фибоначијеву вредност од унетог броја.
Fibonacci-јев низ почиње бројем 0 и 1 а има својство да је сваки наредни елемент низа једнак збиру
претходна два елемента низа, тј.
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
#include <stdio.h>
/* prikazi rezltat */
printf( "Fibonacci( %ld ) = %ld\n", indeks, rezultat );
if (broj==0 || broj==1)
return broj;
for(i=1;i<broj;i++)
{
n=n_minus1+n_minus2;
n_minus2=n_minus1;
n_minus1=n;
}
return n;
} /* kraj funkcije fibonacci */
Решење2
#include <stdio.h>
/* prikazi rezltat */
printf( "Fibonacci( %ld ) = %ld\n", indeks, rezultat );
#include <stdio.h>
#include <string.h> /* potrebno zbog funkcije strchr() */
#include<stdlib.h> /* potrebno zbog funkcije atoi() */
#include <ctype.h> /* potrebno zbog funkcije isdigit() */
int main()
{
int dan;
int mesec;
int godina;
int pom;
kontrola=1;
do
{
printf("\nUnesite datum u formatu dd.mm.gggg ili dd.mm.gg, x za prekid\n" );
gets(niz); /* ucitaj unos korisnika */
duzina=strlen(niz); /* odredi broj unetih karaktera */
if(!kontrola)
{
ptr=strchr(ptr+1, '.'); /* pozicija drugog delimitera */
if((ptr - niz+1) != 6)
{
printf("Pozicija delimitera ('.') nije odgovarajuca");
kontrola=1;
}
}
}
if(kontrola)
continue;
if( !( isdigit(niz[i]) ) )
{
printf("datum moze sadrzati samo brojeve\n");
kontrola =1;
break;
}
}
}while(kontrola);
return 0;
}
int proveri_datum( int xd, int ym, int yg )
{
int max_dana;
int prestupna=0;
switch(ym)
{
case 4:
case 6:
case 9:
case 11:
max_dana = 30;
break;
case 2:
if (prestupna)
max_dana=29;
else
max_dana=28;
break;
default:
max_dana=31;
break;
}
if(xd>max_dana)
return 3; /* broj dana u mesecu nije odgovarajuci */
return 0;
}
Увод у програмски језик C
Задаци за вежбу
НИЗОВИ
1. Иницијализујете низ од 10 елемената на вредност 50 применом for петље, испишите вредности низа
у облику табеле.
/* Inicijalizacija niza */
#include <stdio.h>
#include <stdio.h>
int main()
{
/* Deklarisanje niza dimenzija 2 x 5 */
int x[2][5] = { {1, 2, 3, 4, 5},
{2, 4, 6, 8, 10} };
/* Inicijalizacija niza */
#include <stdio.h>
6. Напишите програм који из низа од 10 елемената типа float, произвољно иницијализованог, издваја
елемент који садржи највећу вредност.
int main()
{
#define BR_ELEMENATA 10
max = niz[0];
for (i = 1; i < BR_ELEMENATA; i++)
{
if (niz[i] > max) max = niz[i];
/* Primetite da i pocinje od 1 */
}
return 0;
}
7. Анкетирано је четрдесет студената о квалитету хране у мензи. Сваки студент је дао оцену од 1 до 10.
Написати програм који који ће одредити и исписати фреквенцију (број) појављивања сваке оцене.
(Нпр. две јединице, три четворке....)
#include <stdio.h>
/* prikazi rezultate */
printf( "Ocena Broj glasova\n" );
return 0;
} /* kraj funkcije main */
8. Дефинисати низ од 10 елемената. Иницијализовати елементе низа на произвољне вредности мање
од 30. Написати програм који исписује вредност сваког елемента низа а поред њега, у виду
хистограма, број звездица једнак вредности елемента низа.
#include <stdio.h>
int main()
{
/* inicializacija niza n */
int n[VELICINA] = { 19, 3, 15, 7, 11, 9, 13, 5, 17, 1 };
int i; /* brojac za elemente polja */
int j; /* brojac zvezdica */
return 0;
} /* kraj funkcije main */
9. Написати програм који применом методе bubble sort сортира елементе низа
#include <stdio.h>
#define DIMENZIJA 10
int main()
{
/* inicijalizacija niza a */
int a[DIMENZIJA] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };
int prolaz; /* brojac prolaza */
int i; /* brojac poredjenjar */
int priv; /* privremeno cuvanje vrednosti */
/* bubble sort */
for ( prolaz = 1; prolaz < DIMENZIJA; prolaz++ )
{
for ( i = 0; i < DIMENZIJA - 1; i++ )
{
/* poredi vrednost susednih elemenata i yameni im mesta ako je
vrednost prvog elementa veca od drugog */
if ( a[i] > a[i + 1] )
{
priv = a[i];
a[i] = a[i + 1];
a[i + 1] =priv;
} /* kraj if */
} /* kraj unutrasnje for petlje */
} /* kraj spoljasnje for petlje */
/* Ispis vrednosti */
for ( i = 0; i < DIMENZIJA; i++ )
printf( "%4d", a[ i ] );
printf( "\n" );
return 0;
} /* kraj funkcije main */
Увод у програмски језик C
Задаци за вежбу
ПОКАЗИВАЧИ
1. Демонстрација рада са показивачима.
#include <stdio.h>
int main()
{
int broj_a;
int *ptr_br;
float real1, real2;
float *ptr_re;
broj_a=4;
real1=3.2f;
ptr_re=&real1;
real2= *ptr_re;
printf("%f\n",real2);
return 0;
} /* kraj funkcije main */
После извршења наредбе ptr_br = &broj_a; показивач ptr_br показује на адресу где је
смештена променљива broj_a. Наредбом broj_a = broj_a + *ptr_br + 1; променљива
broj_a добија вредност 4+4+1 ...
#include <stdio.h>
int main()
{
int broj_a, broj_b, broj_c;
int *ptr_br;
broj_a=8;
broj_b=4;
ptr_br=& broj_c; /* pokazivac pokazuje na adresu promen. broj_c */
*ptr_br= broj_a + broj_b; /* isto sto i broj_c = broj_a + broj_b */
printf("\n%d\n",broj_c);
return 0;
} /* kraj funkcije main */
3. Написати програм који путем показивача приступа 5. и 7. елементу низа и исписати њихове
вредности. Низ треба да има 10 елемената. Затим, такође, путем показивача у 5. елемент низа
уписати вредност збира 6 и 7. елемента низа. Елементи низа могу да имају проиѕвољну вредност.
#include <stdio.h>
int main()
{
int niz[10]={10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int broj_a;
int *ptr_br;
printf("\n%d\n",*(ptr_br-1));
printf("\n%d\n",niz[5]);
return 0;
} /* kraj funkcije main */
4. Коришћењем показивача: уписати све елементе низа од 10 елемената а потом исписати сваки парни
елемент низа.
Решење 1
#include <stdio.h>
int main()
{
int niz[10];
int i;
int *pok;
i=1;
for(pok=niz; pok <= &niz[9]; pok++)
{
printf("upisite %d. element niza\n",i);
scanf("%d", pok);
i++;
}
i=2;
for(pok=&niz[1];pok <= &niz[9]; pok = pok+2)
{
printf("%d. element je: %d\n",i, *pok);
i+=2;
}
return 0;
}
Решење 2
#include <stdio.h>
int main()
{
int niz[10];
int i;
int *pok;
return 0;
}
Напомена: приметите да су наредбе унутар петље раздвојене зарезом (,) и тача-зарезом (;).
5. Демонстрација рада са показивачима
#include <stdio.h>
main()
{
int a[8] = {1,23,17,4,-5,100,55,44};
int *pa, *pb;
int x, y;
#include <stdio.h>
#include <stdlib.h> /* potrebno zbog malloc i free funkcije */
main()
{
int number;
int *ptr;
int i;
if(ptr!=NULL)
{
for(i=0 ; i<number ; i++)
{
*(ptr+i) = i;
}
for(i=number ; i>0 ; i--)
{
printf("%d\n", *(ptr+(i-1))); /* prikazi u suprotnom redosledu */
}
#include <stdio.h>
#include <stdlib.h> /* potrebno zbog malloc i free funkcije */
main()
{
float *ptr_c1, *ptr_c2, *ptr_m1, *ptr_m2;
int i;
free(ptr_c1);
free(ptr_c2);
free(ptr_m1);
free(ptr_m2);
}
else
printf("Nema dovoljno memorije\n");
}
8. Рад са realloc функцијом
#include<stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
int i;
if(ptr!=NULL)
{
printf("\n Nakon naredbe ptr = realloc(ptr, 7*sizeof(int));... \n");
for(i=0 ; i<7 ; i++)
printf("*(ptr+%d) ukazuje na vrednost %d\n", i, *(ptr+i));
*(ptr+5) = 32;
*(ptr+6) = 64;
Задаци за вежбу
1
1. Написати програм који усписује у фајл (klijenti.dat) податке о броју рачуна, имену клијента и стању на
рачуну. Број оваквих записа треба да је произвољан, све док корисник не унесе Ctrl+Z.
Решење:
int main()
{
int broj_racuna; /* broj racuna korisnika */
char ime[ 30 ]; /* ime korisnika */
double stanje; /* stanje na racunu */
} /* kraj main */
Функција feof( stdin ) одређује да ли је прочитан end-of-file индикатор у дефинисаном улазу. У овом
примеру је дефинисани улаз тастатура (stdin), мада дефинисани улаз може бити и фајл уколико се из њега
читају подаци. Уколико функција прочита ознаку (Ctrl+Z) za крај фајла (end-of-file), функција feof враћа
вредност 1.
Приликом рада са овим програмом унесите вредности тако да неки од корисника имају стање на рачуну 0
неки позитивно стање а неки негативно (ради рада у наредним примерима)
2
2. Прочитати све податке из фајла (претходни пример), и испишите их на екран у одговарајућем формату.
Решење:
/* citanje podataka iz fajla*/
#include<stdio.h>
int main()
{
int broj_racuna; /* broj racuna korisnika */
char ime[ 30 ]; /* ime korisnika */
double stanje; /* stanje na racunu */
} /* kraj main */
3
3. Написати програм који из фајла формираног у првом задатку чита податке и на основу захтева
корисника:
а. исписује податке о рачунима који имају стање 0
б. исписује податке о рачунима који имају негативно стање
в. исписује податке о рачунима који имају позитивно стање
г. прекида рад
Решење:
#include<stdio.h>
int main()
{
int zahtev;
int broj_racuna; /* broj racuna korisnika */
char ime[ 30 ]; /* ime korisnika */
double stanje; /* stanje na racunu */
FILE *prt_na_fajl; /* prt_na_fajl = fajl pointer */
while(zahtev !=4)
{
fscanf( prt_na_fajl,"%d%s%lf", &broj_racuna, ime, &stanje );
switch(zahtev)
{
case 1:
printf( "\nRacuni sa stanjem NULA:\n" );
/* citaj sadrzaj fajla do kraja (sve do eof) */
while ( !feof( prt_na_fajl ) )
{
if ( stanje == 0 )
printf( "%-14d%-16s%7.2f\n", broj_racuna, ime, stanje );
/* procitaj broj racuna, ime i stanje iz fajla */
fscanf( prt_na_fajl, "%d%s%lf", &broj_racuna, ime, &stanje );
} /* kraj while */
break;
4
case 2:
printf( "\nRacuni sa stanjem u MINUSu:\n" );
/* citaj sadrzaj fajla do kraja (sve do eof) */
while ( !feof( prt_na_fajl ) )
{
if ( stanje < 0 )
printf( "%-14d%-16s%7.2f\n", broj_racuna, ime, stanje );
/* procitaj broj racuna, ime i stanje iz fajla */
fscanf( prt_na_fajl, "%d%s%lf", &broj_racuna, ime, &stanje );
} /* kraj while */
break;
case 3:
printf( "\nRacuni sa POZITIVNIM stanjem:\n" );
/* citaj sadrzaj fajla do kraja (sve do eof) */
while ( !feof( prt_na_fajl ) )
{
if ( stanje > 0 )
printf( "%-14d%-16s%7.2f\n", broj_racuna, ime, stanje );
/* procitaj broj racuna, ime i stanje iz fajla */
fscanf( prt_na_fajl, "%d%s%lf", &broj_racuna, ime, &stanje );
} /* kraj while */
break;
}/* kraj switch */
printf("Kraj rada\n");
fclose( prt_na_fajl ); /* fclose zatvara fajl */
} /* kraj else */
5
4. Дефинишите 100 рачуна применом структуре. Елементи структуре трегба да буду: број рачуна, презиме
клијента, име клијента и стање на рачуну. Иницијализујте вредност сваке структуре на вредности 0 за
број рачуна, празан стринг за име и презиме и 0 за стање на рачуну. Упишите 100 оваквих структура у
фајл применом наредбе fwrite
int main()
{
int i; /* brojac racuna od 1 do 100 */
6
5. У бинарни фајл формиран у претходном примеру унесите потребне податке. Корисник треба да има
могућност да унесе број рачуна од 1 до 100 и да за тај рачун унесе податке (име презиме и стање).
int main()
{
struct podaci_klijenta klijent = { 0, "", "", 0.0 };
FILE *ptr_fajl; /* fajl pointer */
7
6. Написати програм који чита податке записане у облику рачуна (структура) у претхосном задатку.
int main()
{
struct podaci_klijenta klijent = { 0, "", "", 0.0 };
8
OSNOVE C JEZIKA
#include<stdio.h>
void main()
{
printf("Zdravo svete!\n");
}
Funkcija void main() je glavna funkcija i postoji samo jedna ova funkcija u C programu.
“()”označava da main nema argumenata. printf je funkcija za štampanje poruke “Zdravo svete!.
Karakter ‘\n’ predstavlja oznaku za novu liniju. Svaki iskaz se mora završiti karakterom ’;’, koji
ima ulogu terminatora iskaza. Karakteri ‘{‘ i ‘}’ objedinjuju više pojedinačnih iskaza u jednu
programsku celinu i oni su obavezni jer se tu izvršava neka obrada.
scanf je funkcija slična printf. Razlika je što se argumenti funkcije printf prenose sa
vrednošću, dok se kod scanf prenose svojom adresom, jer se učitana vrednost mora vratiti u
pozivajući program. To se postiže navođenjem karaktera ’&’ (operator adresiranja) ispred
argumenta u listi argumenata. Npr.
Imena promenljivih se grade od velikih i malih slova, cifara od 1 do 9 i karaktera (donja crta _ ).
Ime ne sme počinjati cifrom, niti sme sadržati rezervisane reči. Nedozvoljeni znaci su i
matematički operatori (+, -, *, /, %).
Variable names are case sensitive – imena promenljivih su osetljiva na mala i velika slova..
1
Osnovni tipovi podataka
Osnovni tipovi podataka su int, float, double i char.
Podaci tipa int su celobrojne vrednosti. Tu spadaju celobrojne konstante, promenljive,
izrazi i funkcije. Opseg celobrojnig vrednosti je različit i može se menjati primenom
kvalifikatora long, short i unsigned. Kvalifikator long povećava opseg vrednosti celobrojnih
promenljivih. Kvalifikator short ispred int smanjuje opseg celobrojnih promenljivih. Kvalifikator
unsigned ispred int deklariše promenljivu tako da može memorisati samo pozitivne vrednosti.
Promenlljive tipa float ili double memorišu vrednosti realnih brojeva, odnosno, vrednosti
sa decimalnim (pokretnim) zarezom. Promenljive daklarisane kao double mogu memorisati oko
dva puta više decimalnih cifara od promenljivih tipa float.
Promenljive i konstante tipa char memorišu karaktere. Konstante tipa char dobijaju se
stavljanjem karaktera između jednostrukih navodnica, npr. ‘A’, ‘1’, itd. ‘A’ treba razlikovati od
“A”, jer “A” predstavlja konstantni niz karaktera koji u C jeziku ima posebnu predstavu i
tretman.
Primeri:
int bob=32;
Creates variable "bob" and initializes it to the value 32. (Kreirana promenljivba "bob" i izvršena
inicijalizacija na 32.)
boolean yes=1;
Creates variable "yes" as type "char" and sets its value to 1.
2
Tablica operatora.
Konstante (nepromenjive)
Odnosni operatori
Odnosni operatori se npr. koriste ako želite napraviti program koji će iz baze podataka odrediti
osobe sa više od 30 godina i slično.
3
Odnosne naredbe – naredbe uslova
Kao i aritmetički operatori, odnosni operatori su binarni tj. uspoređuju dva operanda. Naredba sa
dva operanda i odnosnim operatorom zove se odnosna naredba (eng. relational expression.)
Rezultat odnosne naredbe je Boolean vrednost odnosno istinu ili laž (true ili false). S ovom
tablicom možete videti kako to funkcioniše.
U ovoj tablici se koriste konkretne ( literal ) vrednosti koje ne mogu biti promenjene. 4 je
konkretna vrednost (konstanta), i ona se ne može menjati (moglo bi se menjati da se umesto
konstanta koriste promenljive).
Ako se koristi oblik ++x to znači da se x prvo uvećava pa tek onda koristi u izrazu. Oblik x++
znači da se x prvo koristi u izrazu pa tek onda uvećava. Anaklogno važi za operaciju --.
x+=2 je x=x+2
x/2 je x=x/2
x*=2 je x=x*2
x%=2 je x=x%2
The following keywords are reserved and may not be used as an identifier for any other purpose.
4
Elementarne algoritamske strukture
Algoritamske strukture se dele u tri osnovne grupe:
Linijska (sekvencija)
Razgranata (selekcija)
Ciklična (iteracija)
Linijska struktura:
Karakteristika linijske strukture je da se svi elementi izvršavaju samo jednom i koraci se odvijaju u nizu
jedan za drugim bez ponavljanja ili "skretanja".
Primjer u BASIC-u Primjer u C-u
INPUT a, b #include <stdio.h>
zbir = a + b
PRINT zbir void main () {
END int a, b, zbir;
printf("a,b? ");
scanf("%d%d", &a, &b);
zbir = a + b;
printf("a + b = %d\n", zbir);
}
Razgranata struktura:
Razgranata struktura će se pojaviti kod algoritma koji ima blok odlučivanja kao što su IF i CASE, pri čemu
se vrši testiranje određenog uslova a prema rezultatu (obično TRUE ili FALSE) algoritam se grana i
nastavlja tok jednom od grana- opcija. Primjer na slici je tipičan gdje se otklanja blokiranje programa
provjerom da li je djelilac jednak nuli. Ako je djelilac različit od nule, daće rezultat dijeljenja, u suprotnom
će dati samo poruku da dijeljenje nulom nema smisla i nastaviti dalje prema sledećoj proceduri ili kraju
programa.
Primjer u BASIC-u Primjer u C-u
INPUT a,b #include<stdio.h>
IF b <> 0 THEN
PRINT a/b void main () {
ELSE float a, b;
PRINT "Ne mogu
deliti nulom" scanf("%f%f", &a, &b);
END if (b == 0) {
printf("Ne mogu deliti
nulom\n");
} else {
printf("a : b = %f\n", a /
b);
}
}
Ciklična struktura
Ciklični algoritam će se pojaviti kada treba isti posao uraditi više puta. Postoji više varijanti ove srtukture,
a dve osnovne poele su:
5
Broj iteracija (ponavljanja) je unapred poznat. Primer ove petlje je na slici i tu se obično koristi
petlja FOR.
Iteracija se vrši dok se ne zadovolji određen uslov. Koriste se petlje tipa WHILE...DO.
Kod Iteracije sa proverom istinitosti uslova (da li je uslov zadovoljen) postoje varijante s proverom uslova
na ulazu u petlju, odnosno na kraju petlje. Razlika između ove dvije varijante je što kod provere istinitosti
uslova na kraju petlje program mora proći bar jednom kroz petlju.
Primjer u BASIC-u Primjer u C-u
zbir = 0 #include <stdio.h>
INPUT b
FOR a = 1 TO b void main() {
zbir = zbir + a int a, b, zbir = 0;
NEXT a
PRINT zbir scanf("%d", &b);
END for (a = 1; a <= b; a++) {
zbir += a;
}
printf("%d\n", zbir);
}
Primer algoritma kada nije poznat konačan broj iteracija sa provjerom na početku petlje
Primer algoritma kada nije poznat konačan broj iteracija sa proverom na kraju petlje
6
2. /*Primer za operatore inkrementiranja i dekrementiranja*/
#include<stdio.h>
void main()
{
int a=0,b=0,c=0;
printf("\na=%d b=%d c=%d\n",a,b,c);
a=++b + ++c;
printf("a=%d b=%d c=%d\n",a,b,c);
a=b++ + c++;
printf("\na=%d b=%d c=%d\n",a,b,c);
a=++b + c++;
printf("\na=%d b=%d c=%d\n",a,b,c);
a=++c + c;
printf("\na=%d b=%d c=%d\n",a,b,c);
}
3. /*Napisati program kojim se obračunavaju troškovi putovanja ako je udaljenost S
kilometara, potrošnja automobila na 100 km L litara, a cena litra goriva C dinara.*/
#include<stdio.h>
void main()
{
float s,l,c,t;
printf("Rastojanje u kilometrima\n");
scanf("%f",&s);
printf("Potrosnja u litrima na 100 km\n");
scanf("%f",&l);
printf("Cena goriva u dinarima\n");
scanf("%f",&c);
t=2*s/100*l*c;
printf("Troskovi putovanja su %0.2f dinara\n",t);
}
4./*Napisati program koji datom prirodnom četvorocifrenom broju:
a) izračunava proizvod cifara;
b) izračunava razliku sume krajnjih i srednjih cifara broja;
c) izračunava sumu kvadrata cifara;
d) određuje broj koji se dobija ispisom cifara u obrnutom porektu.*/
a)
#include<stdio.h>
void main()
{
int n,a,b,c,d,proizvod;
printf("Uneti cetvorocifren broj\n");
scanf("%d",&n);
a=n%10;
b=((n%100)/10);
c=((n/100)%10);
d=n/1000;
proizvod=a*b*c*d;
printf("Proizvod cifara broja %d je: %d\n",n,proizvod);
}
7
b)
#include<stdio.h>
void main()
{
int n,a,b,c,d,razlika;
printf("Uneti cetvorocifren broj\n");
scanf("%d",&n);
a=n%10;
b=((n%100)/10);
c=((n/100)%10);
d=n/1000;
razlika=(a+d)-(b+c);
printf("Razlika sume krajnjih i srednjih cifara broja %d je: %d\n",n,razlika);
}
c)
#include<stdio.h>
void main()
{
int n,a,b,c,d,suma;
printf("Uneti cetvorocifren broj\n");
scanf("%d",&n);
a=n%10;
b=((n%100)/10);
c=((n/100)%10);
d=n/1000;
suma=a*a+b*b+c*c+d*d;
printf("Suma kvadrata cifara broja %d je: %d\n",n,suma);
}
d)
#include<stdio.h>
void main()
{
int n,a,b,c,d,suma;
printf("Uneti cetvorocifren broj\n");
scanf("%d",&n);
a=n%10;
b=((n%100)/10);
c=((n/100)%10);
d=n/1000;
suma=1000*a+100*b+10*c+d;
printf("Broj %d u obrnutom redosledu je: %d\n",n,suma);
}
5./*Napisati program u kome se unose vrednost ASCII koda (npr. 66) i štampa znak tog
koda.*/
#include <stdio.h>
void main()
{
int ascii;
printf("Uneti ASCII ko nekog znaka: ");
scanf("%d", &ascii);
printf("%d je ASCII kod za %c.\n", ascii, ascii);
}
8
If iskaz
if je kontrolna struktura za ostvarivanje programskih granjanja. Prosta forma ovog iskaza je:
if (izraz)
iskaz;
sledeci_iskaz;
if(izraz1)
iskaz1;
else if(izraz2)
iskaz2;
.....
else
iskazn;
If statements
if ( statement is TRUE )
Execute this line of code
Else
if ( TRUE ) {
/* Execute these statements if TRUE */
}
else {
/* Execute these statements if FALSE */
}
*) Primer:
#include <stdio.h>
9
Osnovne bibliotečne funkcije <math.h>
sin(x) - sin(x)
cos(x) - cos(x)
tan(x) - tg(x)
exp(x) - ex
log(x) - log e (x), x>0
log10(x) - log 10 (x), x>0
pow(x,y) - x y
sqrt(x) - x , x>=0
fabs(x) - |x| apsolutna vrednost od x
ceil(x) – vrednost funkcije je najmanja celobrojna vrednost koja nije manja od x (zaokružuje naviše).
floor(x) - vrednost funkcije je najveća celobrojna vrednost koja nije veća od x (zaokružuje na najbliži
manji ceo broj).
Examples
Sample value Floor [ ] Ceiling [ ] Fractional part { }
−2.7 −3 −2 0.3
−2 −2 −2 0
12/5 = 2.4 2 3 2/5 = 0.4
2.7 2 3 0.7
#include<stdio.h>
void main()
{
int broj,a_vred;
printf("Ukucajte ceo broj?");
scanf("%d",&broj);
a_vred=broj;
if(a_vred<0) a_vred=-a_vred;
printf("Apsolutna vrednost broja %d je %d\n", broj, a_vred);
}
#include<stdio.h>
void main()
{
char c;
printf("Ukucajte karakter?");
scanf("%c",&c);
if(c>='a'&&c<='z')
printf("Karakter %c je malo slovo\n",c);
10
else if(c>='A'&&c<='Z')
printf("Karakter %c je veliko slovo\n",c);
else if(c>='0'&&c<='9')
printf("Karakter %c je cifra\n",c);
else
printf("Karakter %c je specijalni karakter\n",c);
}
#include<stdio.h>
void main()
{
int c1,c2,c3,n;
printf("Uneti trocifren broj\n");
scanf("%d",&n);
c1=n%10;
c2=n/10%10;
c3=n/100;
if(c1*c1*c1+c2*c2*c2+c3*c3*c3==n)
printf("Broj %d je Armstrongov\n",n);
else
printf("Broj %d nije Armstrongov\n",n);
}
#include<stdio.h>
11
void main()
{
double x,y;
printf("Uneti vrednost za x\n");
scanf("%d",&x);
if (x<=-2)
y=1/x;
else
if (x<2)
y=2*x;
else
if (x<5)
y=1/x;
else
if (x<=7)
y=3*x-1;
else
y=1/x;
printf("y=%f ",y);
11. Napišite program koji učitava dva cela broja i, ako su oba parna ispisuje njihovu sumu;
inače treba ispisati proizvod.
#include <stdio.h>
main ( ) {
int prvibroj , drugibroj ;
return 0 ;
}
#include <stdio.h>
main () {
int c,nb,nt,nl;
nb=0;
nt=0;
nl=0;
while ((c = getchar()) != EOF){
if(c ==' ')
12
++nb;
if (c =='\t')
++nt;
if (c =='\n')
++nl;
}
printf("%d%d%d\n" , nb, nt, nl ) ;
}
13. Napisati program koji za uneti prirodan broj n ispituje da li je deljiv sa 5 i štampa
odgovarajuće obaveštenje.
#include <stdio.h>
main ( ) {
int n;
printf("Unetite prirodan broj:");
scanf("%d",&n);
if (n%5==0){
printf("Broj je deljiv sa 5\n");
}
else{
printf("Broj nije deljiv sa 5\n");
}
return 0;
}
Naredba switch
13
break naredbe ili kraja switch naredbe. Nakon toga program se nastavlja prvom naredbom
iza switch naredbe.
- Ako izraz nije jednak ni jednoj konstanti, onda se izvršava naredba koja dolazi posle ključne
reči default (ako postoji) i sve naredbe iza nje, sve do kraja switch naredbe.
- Slučaj default ne mora biti nužno prisutan u switch naredbi. Ako nije, i ako nema
podudaranja vrednosti izraza i navedenih konstanti, program se nastavlja prvom naredbom
iza switch naredbe.
Primer:
switch(operator) {
case'z':
printf("%g\n",a+b);
break;
case'o':
printf("%g\n",a-b);
break;
case'm':
printf("%g\n",a*b);
break;
default:
printf("Nedopustena operacija!");
}
#include <stdio.h>
void main()
{
char ch;
int ct1 = 0;
int ct2 = 0;
while ((ch = getchar()) != '#')
{
switch(ch)
{
case '.' : putchar('!'); ++ct1; break;
case 'a' : putchar('A'); ++ct2; break;
default : putchar(ch);
}
}
printf("\n");
printf("Zamenjeno je %d . sa !\n", ct1);
printf("Zamenjeno je %d slova a with A\n", ct2);
}
14
15./*Napisati program koji za uneti broj meseca (na primer, 1=Januar, 2=Februar, itd.)
ispisuje njegov broj dana. U slučaju unete vrednosti 2 pitati korisnika da li je godina
prestupna.*/
#include<stdio.h>
void main()
{
int mesec;
char ch;
printf("Uneti redni broj meseca\n");
scanf("%d",&mesec);
switch(mesec)
{
case 1:case 3:case 5:case 7:case 8:case 10: case 12: printf("31 dan\n"); break;
case 4: case 6: case 9: case 11: printf("30 dana\n"); break;
case 2: printf("Da li je godina prestupna (d/n)?\n"); scanf("%c%c",&ch,&ch);
if((ch=='d')||(ch=='D'))
printf("29 dana\n");
else
printf("28 dana\n");
break;
default: printf("Nekorektan broj meseca\n");
}
}
16. Napisati program koji na ulazu ima prirodan broj a i realan broj x. Program treba da
izračuna vrednost funkcije y i da je odštampa i to na sledeći način:
- ako je a = 1 tada je y = 3x-2
- ako je a = 2 tada je y = sin(2x)-3x+1
- ako je a = 3 tada je y = x 3 - x+1
- a ako je a bilo šta drugo onda je y = x.
#include <stdio.h>
#include <math.h>
main ( ) {
int a;
double x, y;
switch (a){
case 1: y=3*x-2; break;
case 2: y=sin(2*x)-3*x+1; break;
case 3: y=pow(x,3)-x+1; break;
default: y=x; break;
}
printf("rezultujuca funkcija je:%.4lf\n", y);
}
15
- ako je a = 1 tada je y = |x| + |x-5|....................................................y = fabs(x)+fabs(x-5)
- ako je a = 2 tada je y najveći ceo broj koji nije veći od x..............y = floor(x)
- ako je a = 3 tada je y = sin(x+5)-e x ...............................................y = sin(x+5)+exp(x)
- ako je a = 4 tada je y najmanji ceo broj ne manji od x...................y = ceil(x)
While petlja
while(uslov_petlje)
while_iskaz;
sledeci_iskaz;
While iskaz se izvršava sve dok je uslov_petlje istinit (različit od nule), a kad je neistinit
onda se prelazi na sledeci_iskaz;. While_iskaz se izvršava jednom ili više puta, zavisno od
uslova_petlje.
17./*Program za izračunavanje sume prvih n=10 celih brojeva, pri čemu se koriste različite
petlje*/
#include <stdio.h>
void main()
{
int i,n=10,S=0;
i=1;
while (i <= n)
{
S+=i;
i++;
}
printf("\n Suma je %d\n", S);
}
16
18./*Program za štampanje tabele koja pretvara Fahrenheitove stepene u Celzijuse. Za
Fahrenheitove stepene koristiti redom brojeve od 0, 20, ..., 300. celsius=5*(fahr-32)/9*/
#include<stdio.h>
void main()
{
int n, brojac=0;
float suma=0, x;
printf("Ukupno brojeva?\n");
scanf("%d",&n);
while(brojac<n)
{
printf("Ukucajte %d. broj?", brojac+1);
scanf("%f",&x);
suma+=x;
brojac+=1;
}
printf("Srednja vrednost ovih borjeva je %6.2f\n",suma/n);
}
17
Do-while petlja
do
do_iskaz;
while(uslov_petlje)
sledeci_iskaz;
#include<stdio.h>
void main()
{
int broj;
printf("Ukucajte ceo broj?\n");
scanf("%d",&broj);
printf("Permutovan broj je\n");
do
{
printf("%d",broj%10);
broj/=10;
}
while(broj);
printf("\n");
}
For petlja
pocetni_izraz, postavlja početne parametre petlje (može ih biti više, pri čemu se
razdvajaju zarezom). uslov_petlje predstavlja uslov koji je potreban da bi se petlja nastavila, a
ako je uslov_petlje jednak 0 (neistinit) telo petlje se ne izvršava i kontrola se prenosti na
sledeci_iskaz.
#include<stdio.h>
void main()
{
int n, brojac=1;
float suma=0, x;
printf("Ukupno brojeva?\n");
scanf("%d",&n);
for(;brojac<=n;++brojac,suma+=x) /*for(;...) - brojac je na pocetku postavljen na 1*/
{
printf("Ukucajte %d. broj?", brojac);
scanf("%f",&x);
}
printf("Srednja vrednost ovih brojeva je %6.2f\n",suma/n);
}
FUNKCIJE
Funkcija je programska celina koja uzima neke ulazne podatke, izvršava određen niz naredbi i
vraća rezultat svog izvršavanja.
gde je tip_p tip podatka koji će funkcija vratiti kao rezultat svog izvršavanja. Unutar zagrada
nalazi se deklaracija formalnih argumenata funkcije. Prvi argument, arg_1, je promenljiva tipa
tip_1 itd. Deklaracije pojedinih argumenata međusobno se odvajaju zarezima. Unutar vitičastih
zagrada pojavljuje se telo funkcije koje se sastoji od deklaracija promenljivih i izvršnih naredbi.
poruka()
{ /*Zaglavlje funkcije*/
printf(“Zdravo!\n”); /*Telo funkcije su svi iskazi izmedju { i }*/
}
Primer :
#include <stdio.h>
Sledeća funkcija pretvara mala slova (engleske abecede) u velika.
char malo_u_veliko(char z) {
char c;
c= (z >= 'a' && z <= 'z') ? ('A' + z - 'a') : z;
return c;
}
19
Poziv funkcije:
int main(void) {
char malo, veliko;
printf("Unesite malo slovo: ");
scanf("%c", &malo);
veliko = malo_u_veliko(malo);
printf("\nUneseno slovo = %c\n",veliko);
return 0;
}
char malo_u_veliko(char z)
{
if(z >= 'a' && z <= 'z')
return('A' + z - 'a');
else
return z;
}
1) max = a>b ? a : b
2) if(a>b) max=a;
else max=b;
Primer:
#include <stdio.h>
int main(void)
{
int x,y;
printf("Unesite dva cela broja: ");
scanf("%d %d", &x,&y);
maximum(x,y);
return 0;
}
20
void maximum(int x, int y)
{
int z;
if(x>y) z=x;
else z=y;
printf("\nMaksimalna vrednost =%d\n",z);
return;
}
#include<stdio.h>
suma_kvadrata(int n)
{
int i;
long suma=0;
for(i=1; i<=n; suma+=(long)i*i,++i);
printf("Suma kvadrata od 1 do %d je %ld\n",n,suma);
}
main()
{
suma_kvadrata(10);
suma_kvadrata(15);
suma_kvadrata(20);
}
24./*Napisati program u kome se definiše funkcija prost() koja ispituje da li je broj prost i
funkcija main() koja njenim korišćenjem štampa sve proste brojeve do datog prirodnog
broja n.*/
#include<stdio.h>
#include<math.h>
int prost(int n)
{
int i;
for (i=2;i<=sqrt(n);i=i+1)
if(n%i==0)
return 0;
return i;
}
void main()
{
int i,n;
printf("Uneti broj\n");
scanf("%d",&n);
printf("Prosti brojevi su\n");
for(i=2;i<=n;i=i+1)
21
if(prost(i)) printf("%d\n",i);
}
#include<stdio.h>
#include<math.h>
int sumadelioca(int n)
{
int s=1,i;
for (i=2;i<=sqrt(n);i++)
if(n%i==0) s+=i+(n/i)*(i!=n/i); //uslov (i!=n/i) izost. duplir. faktora npr. za 36
return s;
}
void main()
{
int s,i,n;
printf("Uneti broj n\n");
scanf("%d",&n);
printf("Trazeno svojstvo do %d imaju:\n",n);
for(i=2;i<=n;i=i+1)
{
s=sumadelioca(i);
if(s<=i&&sumadelioca(s)==i) printf("%5d%5d\n",i,s);
}
}
22
21./*Napisati program kojim se štampaju svi trocifreni brojevi (ako ih ima) koji su jednaki
sumi faktorijela svojih cifara.*/
#include<stdio.h>
int fakt(int n)
{
int p=1,i;
for(i=2;i<=n;i++)
p*=i;
return p;
}
void main()
{
int n,a,b,c;
printf("Trocifreni brojevi jednaki sumi faktorijela svojih cifara su:\n");
for(n=100;n<1000;n++)
{
a=n%10;
b=n/10%10;
c=n/100;
if(n==fakt(a)+fakt(b)+fakt(c)) printf("%d\n",n);
}
}
int getchar(void);
int putchar(int);
Funkcija getchar čita jedan znak sa standardnog ulaza (tastature). Funkcija nema argumenata pa je
sintaksa poziva:
c_var=getchar();
Funkcija putchar šalje jedan znak na standardni izlaz (ekran). Ona uzima jedan argument (znak koji
treba ispisati) i vraća celobrojnu vrednost. Najčešće poziv funkcije ima oblik
putchar(c_var);
pri čemu se vraćena vrednost ignoriše.
D O D A T A K
Naredba break
Naredba break služi za zaustavljanje petlje i izlazak iz switch naredbe. Može se koristiti sa for,
while i do-while petljom. Pri nailasku na naredbu break kontrola programa se prenosi na prvu
naredbu iza petlje ili switch naredbe unutar koje se break nalazi.
Primer:
int i;
while(1){
scanf("%d",&i);
if (i<0) break;
.........
}
23
while(1) je beskonačna petlja. Iz nje se izlazi ukoliko se učita negativan broj.
Naredba goto
Naredba continue
Naredba continue koristi se unutar for, while i do-while petlje. Nakon nailaska na continue
preostali deo tela petlje se preskače i program nastavlja sa sledećim prolazom kroz petlju.
int i;
while{1){
scanf("%d",&i);
if (i<0) continue;
.........
}
Sada nam u delu koda koji obrađuje pozitivne brojeve treba neki drugi način izlaza iz petlje.
Primer:
scanf("%d",&i);
while{i<=100){
.......
if (i<0) goto error;
.........
scanf("%d",&i);
}
.......
/* detekcija greske */
error: {
printf("Greska : negativna vrednost!\n");
exit(-1);
}
Naredbe break i continue mogu se izvesti pomoću goto naredbe. Na primer, kod
for(...) {
.......
24
if (...) continue;
........
}
je ekvivalentan s
for(...) {
.......
if (...) goto cont;
.......
cont: ;
}
1 / x n , n 0
može se izvršiti sledeća rekurzivna formula:
1, n0
stepen x, n x stepen x, n 1, n 0
1 / stepen x,n , n 0
na osnovu ovoga se formira sledeća rekurzivna funkcija:
#include<stdio.h>
double stepen(double x, int n)
{
if (n==0) return 1;
if(n>0) return x*stepen(x,n-1);
if(n<0) return 1/stepen(x,-n);
}
void main()
{
int n;
double x;
printf("Uneti vrednosti realnog broja\n");
scanf("%lf",&x);
printf("Uneti vrednosti stepena\n");
scanf("%d",&n);
printf("Vrednost %d stepena broja %lf je %lf\n",n,x,stepen(x,n));
25
int a[20];
gde int deklariše tip svih elemenata niza, kojih ima 20 (broj između uglastih zagrada). Da bi se
dodelila početna vrednost elementima niza na ovaj način, mora se staviti ključna reč static pre
deklaracije. Npr.:
static int ocena[5]={6,7,8,9,10};
deklariše celobrojni niz čije su početne vrednosti 6, 7, 8, 9, 10. Ili slično imamo:
static char slova[5]={‘a’,’e’,’i’,’o’,’u’};
Ovim se uvodi niz broj koji se sastoji iz 100 celobrojnih promenljivih sa imenima broj[0],
broj[2], broj[3],...., broj[99] . Prema tome indeksiranje elemenata niza je od 0, a ne od 1.
29. /*Napišite funkciju koja kao argumente uzima niz realnih brojeva i ceo broj n (koji
označava dužinu niza). Funkcija treba uzlazno da sortira niz. Napišite i kako se funkcija
poziva (pretpostavite da imate učitani niz sa n elemenata)*/
#include <stdio.h>
int main(void){
double a[50];int n;
...
sort(a, n);
}
int main(void){
double a[50];int n;
...
sort(a, n);
}
26
Česte greške:
sort(a[], n);
sort(a[n], n);
sort(a[0], n);
32./*Napisati program za određivanje broja maksimalnih elemenata niza. U rešavanju koristiti funkciju za
unos članova niza.*/
27
#include <stdio.h>
void citaj(float a[],int n)
{
int i;
printf("Uneti niz \n");
for(i=0;i<n;i++)
{
printf("a[%d]=",i);
scanf("%f",&a[i]);
}
}
28
int BrojPoz(float a[],int n)
{
int k=0,i;
for(i=0;i<n&&a[i]>=0;i++)
k++;
return k;
}
proizvod(float a[],int n)
{
int i,k=0;
float p=1;
for(i=0;i<n&&k<2;i++)
{
if(a[i]==0)k++;
if(k==1&&a[i]!=0)
p*=a[i];
}
return p;
}
void main()
{
float a[100];
int n;
printf("Uneti broj elemenata niza\n");
scanf("%d",&n);
citaj(a,n);
printf("Suma elemenata niza koji prethode prvoj nuli u nizu je %f\n", suma(a,n));
printf("Broj elemenata koji prethode prvom negativnom elementu je %d\n",BrojPoz(a,n));
printf("Proizvod elemenata niza izmedju prve i druge nule je %f\n",proizvod(a,n));
}
34./*Dat je niz realnih brojeva. Napisati program koji sažima niz uklanjanjem elemenata čija je
vrednost jednaka zadatom broju X.*/
#include <stdio.h>
void citaj(float a[],int n)
{
int i;
printf("Uneti niz \n");
for(i=0;i<n;i++)
scanf("%f",&a[i]);
}
void pisi(float a[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%f\t",a[i]);
}
void main()
{
float a[100],x;
int k=-1,i,n;
printf("Uneti broj elemenata niza\n");
scanf("%d",&n);
printf("Uneti x\n");
scanf("%f",&x);
citaj(a,n);
29
for(i=0;i<n;i++)
if(a[i]!=x)
a[++k]=a[i];
n=k+1;
printf("Novi niz je\n");
pisi(a,n);
prinf("\n");
}
35. /*Dat je niz realnih brojeva. Napisati funkciju koja:
d) ispisuje sve elemente niza koji se u nizu pojavljuju tačno jedanput;
e) proverava da li u nizu postoji par jednakih elemenata;
#include <stdio.h>
void citaj(float a[],int n)
{
int i;
printf("Uneti niz \n");
for(i=0;i<n;i++)
scanf("%f",&a[i]);
}
void tacnojednom(float a[],int n)
{
int k,i,j;
for(i=0;i<n;i++)
{
k=0;
for(j=0;j<n;j++)
if(a[i]==a[j])
k++;
if(k==1)
printf("%f\n",a[i]);
}
}
void parjednakih(float a[],int n)
{
int k,i,j;
for(i=0;i<n-1;i++)
{
k=0;
for(j=i+1;j<n;j++)
if(a[i]==a[j])
k++;
if(k==1)printf("%f\n",a[i]);
}
}
void main()
{
float a[100];
int n;
printf("Uneti broj elemenata niza\n");
scanf("%d",&n);
citaj(a,n);
printf("Elementi koji se pojavljuju tacno jedanput su:\n");
tacnojednom(a,n);
printf("Par jednakih je \n");
parjednakih(a,n);
}
30
36./*Napisati program koji za uneti niz a od n elemenata, prebacuje negativne elemente na kraj niza bez
obzira na njihov poredak*/
#include <stdio.h>
void citaj(float a[],int n)
{
int i;
printf("Uneti niz \n");
for(i=0;i<n;i++)
{
printf("a[%d]=",i);
scanf("%f",&a[i]);
}
}
void uredi(float a[],int n)
{
float pom;
int i,j;
i=0; j=n-1;
while(i<j)
if(a[i]>0) i++;
else
{
if(a[j]>0)
{
pom=a[i];
a[i]=a[j];
a[j]=pom;
j--;
}
}
}
void pisi(float a[],int n)
{
int i;
printf("Formirani niz\n");
for(i=0;i<n;i++)
printf("a[%d]=%5.2f\n",i,a[i]);
}
void main()
{
float a[100];
int n;
printf("Uneti broj elemenata niza\n");
scanf("%d",&n);
citaj(a,n);
uredi(a,n);
pisi(a,n);
}
37. /*Dat je niz celih brojeva A dimenzija n. Napisati funkciju na programskom jeziku C koja
vraca zbir poslednjih 8 clanova niza A.*/
31
#include<stdio.h>
void main(){
int A[DIM];
int i, n;
int zbir=0;
printf("Unesite elemenateniza:\n");
for(i=0; i<n; i++)
scanf("%d", &A[i]);
return zbir;
}
VIŠEDIMENZIONALNI NIZOVI
Označavanje matrice M od i vrste i j kolona M[i][j], ili višedimenzionalnog vektora Z[i][j][k] itd.
Dvodimenzionalni vektori se inicijalizuju na sličan način kao jednodimenzionalni. Inicijalizacioni
elementi se navode po vrstama. Vitičaste zagrade se mogu koristi za izdvajanje inicijalizacionih
elemenata jedne vrste od druge. Inicijalizacija matrice M je:
Npr:
int x[10];
int y[10][20];
int z[15][25][35];
...
32
printf("%d", y[7][13]);
scanf("%d", &y[2][0]);
scanf("%d", &z[6][24][10]);
Kod prosleđivanja višedimenzionalnih polja u funkciju, u zaglavlju funkcije se moraju navesti dimenzije
polja osim prvog.
#include<stdio.h>
void main()
{
int vrsta,kol;
float scalar;
static float matrica[3][5]={
{7.0,16.83,55.131,13.1,12.91},
{15.0,10.9,42.99,0.0,7.7},
{-2.2,1.1,2.2,4.4,9.9}
};
printf("Originalna matrica:\n");
for(vrsta=0;vrsta<3;++vrsta)
{
for(kol=0;kol<5;++kol)
printf("%10f",matrica[vrsta][kol]);
printf("\n");
}
printf("\n Scalar?\n");
scanf("%f",&scalar);
for(vrsta=0;vrsta<3;++vrsta)
for(kol=0;kol<5;++kol)
matrica[vrsta][kol]*=scalar;
printf("\n Matrica posle skalarnog mnozenja:\n");
for(vrsta=0;vrsta<3;++vrsta)
{
for(kol=0;kol<5;++kol)
printf("%10f\t", matrica[vrsta][kol]);
printf("\n");
}
}
39. /*Napisati program za sabiranje matrica a i b dimenzije n i štampanje rezultujuće matrice c*/
#include <stdio.h>
void citaj(int a[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
}
void zbir(int a[][10],int b[][10],int c[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
{
33
for(j=0;j<n;j++)
{
c[i][j]=a[i][j]+b[i][j];
printf("%d\t",c[i][j]);
}
printf("\n");
}
}
void main()
{
int a[10][10],b[10][10],c[10][10];
int n;
printf("Uneti broj vrsta i kolona matrice a i b\n");
scanf("%d",&n);
printf("Uneti elemente matrice a\n");
citaj(a,n);
printf("Uneti elemente matrice b\n");
citaj(b,n);
printf("Zbir matrica a i b je:\n");
zbir(a,b,c,n);
}
#include<stdio.h>
void citaj(float m[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%f",&m[i][j]);
}
void mnozenje(float m1[][10], float m2[][10],float m3[][10],int n)
{
int i,j,k;
for(i=0;i<n;++i)
for(j=0;j<n;++j)
for(m3[i][j]=0,k=0;k<n;++k)
m3[i][j]+=m1[i][k]*m2[k][j];
}
void pisi(float m[][10],int n)
{
int i,j;
for(i=0;i<n;++i)
{
for(j=0;j<n;++j)
printf("%5.2f\t",m[i][j]);
printf("\n");
}
}
void main()
{
float m1[10][10],m2[10][10],m3[10][10];
int n;
printf("Uneti dimenziju matrica \n");
scanf("%d",&n);
printf("Uneti elemente matrice m1\n");
34
citaj(m1,n);
printf("Uneti elemente matrice m2\n");
citaj(m2,n);
printf("\n\nProizvod matrica m1*m2\n");
printf("...................................\n");
mnozenje(m1,m2,m3,n);
pisi(m3,n);
}
#include <stdio.h>
void citaj(int a[][10],int n)
{
int i,j;
printf("Uneti elemente matrice \n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
}
void transponovana(int a[][100],int n)
{
int i,j,p;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
p=a[i][j];
a[i][j]=a[j][i];
a[j][i]=p;
}
}
void pisi(int a[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%\t",a[i][j]);
printf("\n");
}
}
void main()
{
int a[100][100];
int n;
printf("Uneti broj vrsta i kolona matrice\n");
scanf("%d",&n);
citaj(a,n);
transponovana(a,n);
pisi(a,n);
}
35
#include <stdio.h>
void citaj(float a[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf(”%f”,&a[i][j]);
}
float maksimalni(float a[][10],int n)
{
int i,j;
float max=a[0][0];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(max<a[i][j]) max=a[i][j];
return max;
}
float sumaispodgd(float a[][10],int n)
{
float s=0;
int i,j;
for(i=1;i<n;i++)
for(j=0;j<i;j++)
s+=a[i][j];
return s;
}
float sumaiznadsd(float a[][10],int n)
{
float s=0;
int i,j;
for(i=0;i<n-1;i++)
for(j=0;j<n-1-i;j++)
s+=a[i][j];
return s;
}
void main()
{
float a[10][10];
int n;
printf(“Uneti broj vrsta i kolona matrice a \n”);
scanf(“%d”,&n);
printf(“Uneti elemente matrice a\n”);
citaj(a,n);
printf(“Maksimalni element matrice a je: %f\n\n”,maksimalni(a,n));
printf(“Suma elemenata ispod glavne dijagonale je: %f\n\n”,sumaispodgd(a,n));
printf(“Suma elemenata iznad sporedne dijagonale je: %f\n\n”,sumaiznadsd(a,n));
}
II način
#include <stdio.h>
void citaj(float a[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
36
for(j=0;j<n;j++)
scanf("%f",&a[i][j]);
}
float maksimalni(float a[][10],int n)
{
int i,j;
float max=a[0][0];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(max<a[i][j]) max=a[i][j];
return max;
}
float sumaispodgd(float a[][10],int n)
{
float s=0;
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i>j)
s+=a[i][j];
return s;
}
float sumaiznadsd(float a[][10],int n)
{
float s=0;
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i+j<n-1)
s+=a[i][j];
return s;
}
void main()
{
float a[10][10];
int n;
printf("Uneti broj vrsta i kolona matrice a \n");
scanf("%d",&n);
printf("Uneti elemente matrice a\n");
citaj(a,n);
printf("Maksimalni element matrice a je: %f\n\n",maksimalni(a,n));
printf("Suma elemenata ispod glavne dijagonale je: %f\n\n",sumaispodgd(a,n));
printf("Suma elemenata iznad sporedne dijagonale je: %f\n\n",sumaiznadsd(a,n));
}
43. Data je matrica celih brojeva x dimenzije nxn. Napisati program za sortiranje matrice po
vrstama u rastućem poretku.
#include<stdio.h>
void citaj(int x[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("x[%d,%d]=",i,j);
scanf("%d",&x[i][j]);
37
}
}
void pisi(int x[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%3d",x[i][j]);
printf("\n");
}
}
void razmeni(int*a,int*b)
{
int pom;
pom=*a;*a=*b;*b=pom;
}
void sort(int a[][10],int n)
{
int i,j,k;
for(i=0;i<n;i++)
for(j=0;j<n-1;j++)
for(k=j+1;k<n;k++)
if(a[i][j]>a[i][k])
razmeni(&a[i][j],&a[i][k]);
}
main()
{
int n;
int x[10][10];
printf("\nUneti broj vrsta matrice:");
scanf("%d",&n);
printf("\nUnesi elemente matrice po vrstama :\n");
citaj(x,n);
sort(x,n);
printf("matrica posle sortiranja je:\n");
pisi(x,n);
}
44. Napisati funkciju za soritranje matrice a dimenzije nxn po kolonama u rastućem redosledu.
void sort(int a[][10],int n)
{
int i,j,k;
for(j=0;j<n;j++)
for(i=0;i<n-1;i++)
for(k=i+1;k<n;k++)
if(a[i][j]>a[k][j])
razmeni(&a[i][j],&a[k][j]);
}
45. Napisati funkciju za soritranje elemenata na glavnoj dijagonali matrice a dimenzije nxn u
rastućem redosledu.
void sort(int a[][10],int n)
{
int i,j;
for(i=0;i<n-1;i++)
38
for(j=i+1;j<n;j++)
if(a[i][i]>a[j][j])
razmeni(&a[i][i],&a[j][j]);
}
46. Napisati funkciju za soritranje elemenata spredne dijagonale matrice a dimenzije nxn u
rastućem redosledu.
void sort(int a[][10],int n)
{
int i,j;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(a[i][n-i-1]>a[j][n-j-1])
razmeni(&a[i][n-i-1],&a[j][n-j-1]);
}
47. Data je matrica M dimenzije nxn. Formirati niza A dimenzije n od maksimalnih elemenata
matrice po vrstama.
#include<stdio.h>
void citaj(int x[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("x[%d,%d]=",i,j);
scanf("%d",&x[i][j]);
}
}
void pisi(int x[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d\n",x[i]);
}
void niza(int n, int M[][10], int A[])
{
int i, j;
for(i=0; i<n; i++)
{
A[i]=M[i][0];
for(j=1; j<n; j++)
if(A[i]<M[i][j])
A[i]=M[i][j];
}
}
main()
{
int n, j, i;
int M[10][10], A[10];
printf("\nUneti broj vrsta matrice:");
scanf("%d",&n);
printf("\nUnesi elemente matrice po vrstama :\n");
citaj(M,n);
niza(n,M,A);
printf("Dobijeni niz je:\n");
39
pisi(A,n);
}
48. Data je matrica x dimenzije nxn. Napisati program koji koristi funkciju za sortiranje v vrste
matrice x.
#include<stdio.h>
void citaj(int x[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("x[%d,%d]=",i,j);
scanf("%d",&x[i][j]);
}
}
void pisi(int x[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%3d",x[i][j]);
printf("\n");
}
}
void razmeni(int*a,int*b)
{
int pom;
pom=*a;*a=*b;*b=pom;
}
void sort(int a[][10],int n, int v)
{
int i,j;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(a[v][i]>a[v][j])
razmeni(&a[v][i],&a[v][j]);
}
main()
{
int n, v;
int x[10][10];
printf("\nUneti broj vrsta matrice:");
scanf("%d",&n);
printf("\nUnesi elemente matrice po vrstama :\n");
citaj(x,n);
printf("\nUneti indeks vrste koja se sortira:");
scanf("%d",&v);
sort(x, n, v);
printf("Matrica posle sortiranja je:\n");
pisi(x,n);
}
40
49. Učitati kvadratnu matricu M sa tastature i formirati matricu realnih brojeva C na čijoj glavnoj
dijagonali se dobijaju prosečne vrednosti pojedinih vrsta matrice M, a svi ostali elementi su
jedinice.
#include<stdio.h>
#define DIM 100
void main(){
int M[DIM][DIM];
float C[DIM][DIM];
static float sumaRedova[DIM];//Početne vrednosti su nule
int i, j, n;
printf("\n\n");
}
POKAZIVAČI (POINTERI)
Primer (pokazivači) :
#include<stdio.h>
void kvadrat(int*x,int*y)
{
*y=*x**x;
printf("Unutar funkcije: x=%d, y=%d.\n",*x,*y);
}
main()
{
int x=3,y=5;
printf("Prije poziva: x=%d, y=%d.\n",x,y);
kvadrat(&x,&y);
printf("Nakon poziva: x=%d, y=%d.\n",x,y);
return 0;
}
42
znači, ovo predstavlja indirektan pristup celobrojnim promenljivim. Adresni operator & se koristi u
funkciji scanf za prenos učitane vrednosti u pozivajuću funkciju main().
Operator indirekcije * omogućava indirektno pristupanje promenljivoj koristeći pokazivač na tu
promenljivu. Ako je x deklarisana kao int, tada se iskazom
x=*prom;
promenljivoj x dodeljuje vrednost promenljive na koju pokazivačj prom ukazuje. Operatori * i & su
inverzni.
U C jeziku postoji specijalni operator za indirektnu selekciju članova strukture. To je operator ->.
Operator -> je operator selekcije članova strukture sa pokazivačem na strukturu.
char *malloc(unsigned n)
int *pint;
pint=(int*)malloc(200); /* izdvaja 200 bajtova. Vrednost f-je je pokazivač na char
koji se kast operatorom konvertuje u pokazivač na int tip.*/
2. char *calloc(n, size). Rezerviše memorijski blok dovoljan za memorisanje n elemenata svaki
veličine size bajtova, znači n*size. Rezervisan memorijski blok je inicijalizovan na 0. U slučaju
uspešne rezervacije calloc vraća pokazivač na char, koji pokazuje na rezervisan memorijski blok.
U protivnom, vraća 0.
char *calloc(unsigned n, unsigned vel) /*n je br. elemenata za koje treba izdvojiti memoriju,
a vel memorijski prostor koji zauzima svaki
element.*/
3. void free(pokaz). Oslobađa memorijski blok, koji je rezervisan funkcijama calloc i malloc.
Argument pokaz je pokazivač na char, koji pokazuje na memorijski blok za oslobađanje. Funkcija
free ne vraća nikakvu vrednost.
4. char *realloc(pokaz, size). Oslobađa rezervisani memorijski blok i rezerviše novi veličine size
bajtova. Argument pokaz je pokazatelj na char i defimniše memorijski blok, koji se realocira.
Argument size je unsigned i određuje veličinu realociranog memorijskog bloka. Ako je
realociranje uspoešno realloc vraća pokazivač na char, koji pokazuje na memorijski blok. U
protivnom, realloc vraća 0.
43
void main(void)
{
int a=10, b=5, r_zbir, r_razlika;
int (*pointer[2])(int *,int *);
pointer[0]=zbir;
pointer[1]=razlika;
r_zbir=(*pointer[0])(&a,&b);
r_razlika=(*pointer[1])(&a,&b);
printf("zbir =%d razlika=%d\n",r_zbir,r_razlika);
}
44
for(p_tekst=tekst;*p_tekst!='\0';++p_tekst)putchar(*p_tekst);
}
54./*Data je kvadratna matrica celih brojeva a dimenzije n i prirodan broj k<n. Napisati program
koristeći funkciju koja realizje simetrično preslikavanje u odnosu na sporednu dijagonalu, trougla
određenog pozicijama (0,0), (0,k-1) i (k-1,0) u odgovarajući trougao i obrnuto.*/
#include <stdio.h>
void citaj(int a[][10],int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
}
45
{
for(j=0;j<n;j++)
printf("%d\t",a[i][j]);
printf("\n");
}
}
void main()
{
int a[10][10];
int n,k;
printf("Uneti broj vrsta i kolona matrice a \n");
scanf("%d",&n);
printf("Uneti elemente matrice a\n");
citaj(a,n);
printf("Uneti k \n");
scanf("%d",&k);
printf("Dobijena matrica je:\n");
f(a,n,k);
pisi(a,n);
}
#include <stdio.h>
main()
{
int m,n,k,l,p,q,r;
void kavdrat_kub(); /*deklaracija f-je*/
kavdrat_kub(2,4,&p,&q); /*poziv f-je*/
printf("p=%d q=%d\n",p,q);
scanf("%d%d%d%d",&m,&n,&k,&l);
kavdrat_kub(m,n,&p,&q); /*poziv f-je*/
printf("p=%d q=%d\n",p,q);
kavdrat_kub(m-k,n+l,&p,&r); /*poziv f-je*/
printf("p=%d q=%d\n",p,r);
}
void kvadrat_kub(int m, int n, int *kv, int *kub) /*definicija f-je*/
{
int i;
*kv=*kub=0;
for(i=m;i<=n;i++)
{
*kv+=i*i;
*kub+=i*i*i;
}
}
56. /*Napisati program koji unosi jedan po jedan elemenat celobrojnog niza (vektora) B[9]. Kada je
unošenje završeno određuje se koji je najveći broj u ovom nizu i na kojoj poziciji se nalazi i štampa
se ovaj element, njegov indeks, i niz B.*/
#include <stdio.h>
main()
{
46
int B[9], max, ind_max, i;
for(i=0;i<9;i++){
printf("Uneti sledeci element niza:\n");
scanf("%d",&B[i]);
}
max=B[0];
ind_max=0;
for(i=0;i<9;i++){
if(B[i]>max){
max=B[i];
ind_max=i;
}
}
printf("\n");
x+2=&x[2]
*(x+2)=x[2]
*(x+i)=x[i]
#include<stdio.h>
void main()
{
int n,i,broj, ocena[50];
47
float prosek(); /*deklaracija f-je prosek*/
II način: (Operatori - int x[] i int *x su ekvivalentni, jer oba deklarišu primenljivu x kao pokazivač
na niz celih brojeva )
2. Napisati funkciju kojom se realizuje ciklično premeštanje vrednosti elemenata niza a[0],
a[1],...a[n-1] za jedno mesto u levo.
Traženo premeštanje se realizuje tako što vrednost a[0]sklanjamo u pomoćnu promenljivu pom, a zatim u
n-1 koraka vrednost premeštamo ulevo kroz dodele: a[0]=a[1], a[1]=a[2], ..., a[n-2]=a[n-1], i dodelom
a[n-1]=pom sačuvanu vrednost od a[0] kopiramo u a[n-1].
48
}
II način: Ako bi umesto deklaracije int a[]; stavili int *a; { a[i] je isto što i *(a+i) }
STRINGOVI
String je niz znakova koji završava nul znakom '\0' (ASCII kod 0)
<string.h> sadrži skup funkcija za manipulaciju stringovima, npr:
strlen, strcpy, strcat, strcmp …
Stringovne konstante se navode unutar dvostrukih navodnika:
"Pero Peric", "A", "" (prazni niz), "23"
String dužine 10 (npr. "Pero Peric") zauzima 11 byteova u memoriji.
Primeri deklaracije:
char niz [velicina];
char *niz; (uz obvezni malloc kasnije)
Ispis stringa : koristi se format %s, npr. printf("%s", niz)
Primeri učitavanja stringa:
gets(niz);
scanf("%s", niz);
scanf("%[^\n]", niz);
Prototipovi bibliotecnih funkcija su dati u nekoliko standardnih fajlova zaglavlja. Npr. standardni fajlovi
su:
- stdio.h-sadrzi definisane funkcije printf , scanf , putchar i getchar
- assert.h-assertions
- ctype.h-definisane su funikcije za ispitivanje karaktera
- float.h-ograničenja sistema za realne tipove podataka
- limits.h-ograničenja sistema za celobrojne tipove podataka
- math.h - matematicke funkcije
- setjmp.h-nelokalni skokovi
- signal.h-javljanje grešaka i signala
- stdarg.h-lista parametara promenljive dužine
- stdlib.h-utility functions; number conversions, memory allocation, exit and system, Quick Sort
- string.h-funkcije stringova
- time.h-vremenske i datumske funkcije
49
- putchar(c) - funkcija za ispisivanje znaka c na ekranu.
- gets(s) - funkcija za čitanje jednog reda teksta
- puts(s)-funkcija za ispisivanja jednog reda teksta
- getc(c)-unos jednog karaktere
- putc(c)-štampanje jednog karaktera
- stdin-standardni ulazni tok
- stdout-standardni izlazni tok
- stderr-standardne greške
- EOF-end of file
- printf(“format”, arg1,...)-štampanje formatiranih podataka
- sprintf(s,“format”, arg1,...)-štampanje u string s
- scanf(“format”, &ime1,...)-unos formatiranih podataka
- sscanf(s,“format”, &ime1,...)-unos iz stringa s
- FILE *fp-deklaracija pokazivača na fajl
- fopen(“ime”,”mod-režim”)-pokazivač na ime fajla (mod: r-čitanje(read), w-upis(write), a-dodavanje
(append))
- fprintf(fp,“format”,arg1,...)-upis u fajl
- fscanf(fp,“format”,arg1,...)-čitanje iz fajla
- fclose(fp)-zatvaranje fajla
- ferror(fp)-nenulta vrednost ukoliko je greška
- feof(fp)-nenulta vrednost ukoliko je kraj datoteke
- fgets(s,max,fp)-čita liniju u string s (< max karaktera) iz datoteke fp
- fputs(s,fp)-ispisuje string s u datoteku fp
50
57. Napišite program koji učitava jednu reč maksimalne dužine 17 znakova i ispisuje:
a) tu reč
b) tu reč bez prvog znaka
c) treće slovo te reči (pretpostavite da je reč dovoljno dugačka)
#include <stdio.h>
int main(void) {
char rec[18];
return 0;
}
59/*Napisati program kojim se ucitavaju znaci sve dok se ne unese # i onda daje izvestaj o broju
ucitanih praznina, novih linija i broju svih ostalih ucitanih karaktera.*/
#include <stdio.h>
void main()
{
char ch;
int praznina = 0, nl = 0,ostalo = 0;
while ((ch = getchar()) != '#')
{
if (ch == ' ')
praznina++;
else if (ch == '\n')
nl++;
else
ostalo++;
}
printf(" Broj praznina: %d\n Novih linija: %d\n Ostali karakteri: %d\n", praznina, nl, ostalo);
}
51
{
unsigned i;
for(i=0;*s!='\0';++s,++i);
return(i);
}
main()
{
char demo[]="Uvod u C jezik";
printf("Duzina niza demo je %d\n",strlen(demo));
}
#include<stdio.h>
#include<string.h>
void main(){
char buffer[80];
int brojSlova;
char lozinka[80];
int provera;
char novi [ ]= "Student ";
printf("Uneti recenicu:\n");
/*scanf("%s", buffer);*/
/*Bolje je koristiti gets jer scanf uzima string sa tastature samo do prvog razmaka u recenici*/
gets(buffer);
52
/*Funkcija strcat spaja dva stringa u jedan i pamti rezultat u prvom argumentu*/
strcat(novi, buffer);
printf("Dobijen je novi string: %s\n", novi);
}
62. /*Zadatak pokazuje vezu pointera i nizova karaktera (stringova) . Pokazivač sa inicijalizuje
adresom početka niza (njegovim imenom), a zatim se pomeranjem za jedan u pokazivaču pamti
ostatak niza, sve dok se ne dođe do zadnjeg elementa u nizu karaktera.*/
#include<stdio.h>
#include<string.h>
void main(){
char niz[ ]= "Marko Markovic";
int i;
char *pniz;
pniz=niz;
printf("String je:\n");
for(i=0; i<(int)strlen(pniz); i++)
printf("%s\n", pniz+i);
}
return l;
}
53
int uct = 0,lct = 0;
while ((ch = getchar()) != EOF)
if (isupper(ch))
uct++;
else if (islower(ch))
lct++;
printf("\n");
printf("velikih slova: %d\n", uct);
printf("malih slova: %d\n", lct);
66./*Napisati program kojim se iz stringa s briše svaki znak koji odgovara bilo kom znaku stringa t.*/
#include <stdio.h>
#include <string.h>
void main()
{
char s[50], t[50];
int i,j;
gets(s);
gets(t);
for(i=j=0;s[i];i++)
if(!strchr(t,s[i]))
s[j++]=s[i];
s[j]='\0';
puts(s);
}
67./*Napisati program koji iz datog stringa s izbacuje sve komentare oblika /*...*/, s tim što u komentaru
nema komentara*/
#include <stdio.h>
#include <string.h>
void main()
{
char s[100], *p,*q;
gets(s);
while(p=strstr(s,"/*"))
{
q=strstr(s,"*/");
strcpy(p,q+2);
}
puts(s);
}
54
68./*Napisati program koji iz datog stringa s određuje prosečan broj slova u rečima parne dužine*/
#include <stdio.h>
void main()
{
char s[100];
int i,k=0,br=0;
float q=0;
gets(s);
for(i=0;s[i];i++)
if(s[i]!=' ') k++;
else
if(k>0)
{
if(k%2==0)
{
br++; q+=k;
}
k=0;
}
if(k>0)
if(k%2==0)
{
br++;
q+=k;
}
printf("Prosecan broj simbola u recima parne duzine je %f\n",q/br);
}
69. /*Napisti program za ucitavanje neuredjenog spiska imena prekog glavnog ulaza, po jedno ime iz
svakog reda, sve dok umesto prezimena i imena ne procita dve tacke sa znakom razmaka izmedju. Po
zavrsetku citanja imena treba urediti i potom ispisati na glavnom izlazu, po jedno ime u svakom redu*/
#include<stdio.h>
#include<string.h>
#define N 100
#define D 40
void main()
{
char ljudi[N][D+1];
int i, n=0;
/*Citanje neuredjenog niza imena*/
printf("Neuredjen niz prezimena i imena?\n\n");
do
gets(ljudi[n]);
while(strcmp(ljudi[n++],". .")!=0);
n--;
/*Uredjivanje niza imena*/
for(i=0; i<n-1;i++){
int j,m=i;
for(j=i+1;j<n;j++)
if(strcmp(ljudi[j],ljudi[m])<0)m=j;
if(m!=i){
char osoba[D+1];
55
strcpy(osoba , ljudi [i]);
strcpy(ljudi[i],ljudi[m]);
strcpy(ljudi[m],osoba );
}
}
/*Ispisivanje uredjenog niza imena*/
printf("\nUredjeni niz imena:\n\n");
for(i=0;i<n;puts(ljudi[i++]));
}
71. /* Napišite funkciju koja kao argument prima jedan string i iz njega briše svako treće slovo.
Napišite i program koji pokazuje kako se funkcija upotrebljava.*/
#include <stdio.h>
#include <ctype.h>
56
if (! (isalpha(s[i]) && ++br % 3 == 0) )
s[j++] = s[i];
}
s[j] = '\0';
}
72. /*Napišite funkciju koja kao argument prima jedan string i iz njega briše svako treće slovo.
Napišite i program koji pokazuje kako se funkcija upotrebljava.*/
#include<stdio.h>
#include<string.h>
#define BR_ST 7
#define D_IME 15
#define D_PRZ 25
main(){
char ime[BR_ST][D_IME];
char prezime[BR_ST][D_PRZ];
char rez[BR_ST][D_IME+D_PRZ+2];
char Najduzi[D_IME+D_PRZ+2];
int i, Max;
int D[BR_ST];
57
}
Max=0;
for(i=0;i<BR_ST;i++){
if(Max<D[i]){
Max=D[i];
strcpy(Najduzi, rez[i]);
}
}
printf("\nNajduzi tekst - kombinacija imena i prezimena je:%s\n ", Najduzi);
return 0;
}
74. /* Napišite funkciju int palindrom(char *s) koja vraća 1 ako je string s palindrom; inače treba vratiti
0. Funkcija treba biti case-insensitive (tj. ne sme praviti razliku između velikih i malih slova) i mora
ignorisati sve znakove koji nisu slovo. Pri tome ne sme menjati string s. Npr. string “Ana voli:
Milovana!” treba prepoznati kao palindrom.*/
char *string;
int len;
printf("Duzina stringa: ");
scanf("%d", &len);
string = (char*)malloc((len+1)*sizeof(char));
scanf("%s", string);
Ukoliko je string definisan kao pokazivač pre njegovog korištenja (scanf, printf) obavezno treba
alocirati memoriju za njega
Napomena:
char string[20] -> sizeof(string) je 20
char *string -> sizeof(string) je 4
75. Napišite funkciju koja kao argument uzima string, i iz njega briše sve samoglasnike. Dodatno,
napišite i program koji pokazuje kako se funkcija upotrebljava.
58
void brisi_samoglasnike(char s[]) {
int i, j = 0;
for (i = 0; s[i] != '\0'; i++) {
char c = tolower(s[i]);
if (!(c == 'a' || c == 'e' ||
c == 'i' ||
c == 'o' || c == 'u'))
s[j++] = s[i];
}
s[j] = '\0';
}
return 0;
}
59
STRUKTURE PODATAKA
Strukture su skupovi heterogenih elemenata (jedan elemenat je char, drugi je int itd.). U C jeziku
postoji mogućnost grupisanja logički povezanih promenljivih različitog tipa u jednu celinu, strukturu.
Koristeći ključnu reč struct možemo definisati strukturu datum sa tri celobrojne komponente, koje
predstavljaju dan, mesec i godinu. Ovo se deklariše:
struct datum {
int dan;
int mesec;
int godina;
};
Struktura datum sadrži tri elementa tipa int: dan, mesec i godina, koji se nazivaju članovima
strukture. Ključna reč struct definiše strukturu tako da promenljive mogu biti deklarisane kao tip struct
datum. Za selekciju članova strukture koristi se operator .(tačka), tako što se specificira ime promenljive,
operator tačka i ime člana. Operator . ima najviši prioritet među operatorima C jezika i istog je prioriteta
sa operatorom selekcije elementa vektora (uglaste zagrade). Selekcija člana strukture ima opštu formu
ime_promenljive.ime_clana
77. /*Napisati program za formiranje strukture student sa karakteristikama Ime, Prezime, broj
indeksa, srednja ocena. Za uneti broj studenata n, sortirati studente prema srednjoj oceni i ispisati
na ekranu*/
#include<stdio.h>
typedef struct student{
char Ime[20],Prezime[20];
int broj_indeksa;
60
float srednja_ocena;
};
void razmeni(struct student *a, struct student *b)
{
struct student pom;
pom=*a;
*a=*b;
*b=pom;
}
void sort(struct student STF[], int n)
{
int i, j;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(STF[i].srednja_ocena<STF[j].srednja_ocena)
razmeni(&STF[i],&STF[j]);
}
void main()
{
int n;
int i;
struct student STF[100];
printf("Unesite broj studenata: \n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Unesi ime: \n");
scanf("%s",STF[i].Ime);
printf("Unesi prezime: \n");
scanf("%s",STF[i].Prezime);
printf("Unesi broj indeksa: \n");
scanf("%d",&STF[i].broj_indeksa);
printf("Unesi srednju ocenu: \n");
scanf("%f",&STF[i].srednja_ocena);
}
sort(STF,n);
for(i=0;i<n;i++)
{
printf("student broj %d\n",i+1);
printf("Ime:%s\n",STF[i].Ime);
printf("Prezime:%s\n",STF[i].Prezime);
printf("Broj indeksa: %d\n",STF[i].broj_indeksa);
printf("Srednja ocena: %5.2f\n\n\n",STF[i].srednja_ocena);
}
}
#include<stdio.h>
#define DIM 10
typedef struct student{
char ime[20];
int brBodova;/*Ukupna suma bodova svakog studenta: ocene + prijemni*/
};
void razmeni(struct student *a, struct student *b){
struct student tmp;
tmp=*a;
*a=*b;
*b=tmp;
62
}
void sort(struct student niz[], int n){
int i, j;
for(i=0; i<n-1; i++)
for(j=i; j<n; j++)
if(niz[i].brBodova<niz[j].brBodova)
razmeni(&niz[i], &niz[j]);
}
void main(){
struct student nizStudenata[DIM];
int n, i, j;
static int ocene[5];
int bodovi;
static int sumaOcena[DIM];/*Suma ocena iz prethodnog skolovanja*/
printf("Uneti broj studenta koji je polagao prijemni: ");
scanf("%d", &n);
for(i=0; i<n; i++){
printf("Uneti ime studenta: ");
scanf("%s", &nizStudenata[i].ime);
printf("Uneti cetiri ocene iz prethodnog skolovanja: ");
for(j=0; j<4; j++){
scanf("%d", &ocene[j]);
sumaOcena[i]+=ocene[j];
//printf("Suma ocena je: %d\n", sumaOcena[i]);
}
printf("Uneti broj bodova sa prijemnog: ");
scanf("%d", &bodovi);
nizStudenata[i].brBodova=sumaOcena[i]+bodovi;
printf("Ukupna suma bodova svakog studenta: ocene + prijemni je: %d\n",
nizStudenata[i].brBodova);
}
sort(nizStudenata, n);
printf("Rang lista studenata je:\n\n");
for(i=0; i<n; i++)
printf("%s\t%d\n", nizStudenata[i].ime, nizStudenata[i].brBodova);
#include<stdio.h>
#define DIM 10
typedef struct grad{
char ime[20];
int brStan;
float dohodak;
};
void main(){
struct grad nizGradova[DIM];
int i, n;
float ukupanDohodak=0.0;
int najveci;
int indeksNajvecegGrada;
printf("Uneti koliko gradova ima: ");
63
scanf("%d", &n);
for(i=0; i<n; i++){
printf("Uneti ime grada: ");
scanf("%s", &nizGradova[i].ime);
printf("Uneti broj stnovnika: ");
scanf("%d", &nizGradova[i].brStan);
printf("Uneti dohodak: ");
scanf("%f", &nizGradova[i].dohodak);
ukupanDohodak+=nizGradova[i].dohodak;
}
printf("Ukupan dohodak svih gradova je: %6.2f\n", ukupanDohodak);
najveci=nizGradova[0].brStan;
indeksNajvecegGrada=0;
for(i=0; i<n; i++){
if(nizGradova[i].brStan>najveci){
najveci=nizGradova[i].brStan;
indeksNajvecegGrada=i;
}
}
printf("Grad sa najvise stanovnika je %s\n", nizGradova[indeksNajvecegGrada].ime);
}
RAD SA DATOTEKAMA
if(in_file==NULL)
printf(“Datoteka file1 ne moze biti otvorena\n”);
Da bi se izvršila neka operacija datoteka mora biti otvorena, pozivanjem odgovarajuće
funkcije i specificiranjem imena datoteke. Prilikom otvaranja datoteke, mora se specificirati tip
željene ulalzno/izlazne operacije. Npr. ako se želi pročitati sadržaj datoteke, specificira se režim
čitanja "r"(eng. read mode); ako se neki sadržaj upisuje u datoteku, specificira se režim upisa "w"
(eng. write mode); ako se želi dodati neki sadržaj, specificira se režim dodavanja "a" (eng.
append mode). Da bi se ažurirao sadržaj datoteke (naizmenično čitanje i pisanje), prethodnim
oznakama se dodaje znak +, nezavisno koji je osnovni režim rada. Pri radu sa binarnim
datotekama prethodnim oznakama se dodaje i slovo b.
Iza svakog od ovih formata može se dodati ili b (za binarne datoteke) ili t za tekstualne
datoteke. Ako se ne navede ništa, podrazumijeva se da se radi o tekstualnim datotekama.
dat je pokazivač datoteke koji je pridružen datoteci koja se zatvara. Vrednost funkcije je nula u
slučaju uspeha, a smibolička konstanta EOF u slučaju otkrivanja greške.
Funkcija koja čita iz datoteke dat najviše br podataka veličine vel bajtova u memoriju
počev od adrese niz:
int fread(void *niz, int vel, int br, FILE *dat);
65
FILE*file_pointer;
Na pr. pozivom putc(‘z’,in_file); u datoteku in_file upisujemo karakter ‘z’.
Pozicioniranje na mesto u datoteci dat čija je udaljenost pomeraj bajtova od označene
reperne tačke data je funkcijom:
int fseek(FILE*dat, long pomeraj, int reper);
Moguće reperne tačke obeležavaju se sibmoličkim konstantama SEEK_SET (početak datoteke),
SEEK_CUR (trenutna pozicija u datoteci) ili SEEK_END (kraj datoteke). Sledeće čitanje ili
pisanje vršiće se počevši od ovako odabrane pozicije u datoteci. Funkcija za pozicioniranje na
početak datoteke dat je:
void rewind(FILE *dat);
#include<stdio.h>
void main()
{
int k=0;
FILE *fp;
char s[256];
if((fp=fopen("knjiga.txt","r"))==NULL)
{
perror("Greska");
return;
}
while(fgets(s,256,fp)!=NULL)k++;
printf("Fajl ima %d linija\n",k);
fclose(fp);
}
83. /*Napisati program kojim se sadržaj fajla test.dat formiran od velikih slova alfabeta šifriran šalje u fajl sifra.dat. Znak se šifrira tako što se
zamenjuje sledećim ASCII znakom, a znak Z zamenjuje sa A.*/
#include<stdio.h>
void main()
{
int c;
FILE *inf,*outf;
inf=fopen("test.dat","r");
outf=fopen("sifra.dat","w");
while((c=fgetc(inf))!=EOF)
{
if('A'<=c&&c<'Z')
c++;
else c='A';
putc(c,outf);
}
fclose(inf);
fclose(outf);
}
84. /*U tekstualnom fajlu odrediti najdužu liniju. Ako ima više linija najveće dužine odrediti prvu među njima.*/
#include<stdio.h>
#include<string.h>
void main()
{
66
unsigned k=0,maxl;
char s[256],maxs[256];
FILE *fp;
if((fp=fopen("test.txt","r"))==NULL)
{
printf("Greska\n ");
return;
}
maxl=0;
while(fgets(s,256,fp)!=NULL)
if(strlen(s)>maxl)
{
maxl=strlen(s);
strcpy(maxs,s);
}
printf("Najduza linija\n%s\n ima duzinu %d\n",maxs,maxl);
fclose(fp);
}
85. /*Napisati program koji poredi dva fajla i ispisuje prvu liniju u kojoj se razlikuju.*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXLINE 100
void main()
{
FILE *fp1;
FILE *fp2;
void filecomp(FILE *fp1, FILE *fp2);
if((fp1=fopen("prvi.txt","r"))==NULL)
{
perror("Ne moze se otvoriti prvi.txt");
return;
}
if((fp2=fopen("drugi.txt","r"))==NULL)
{
perror("Ne moze se otvoriti drugi.txt");
return;
}
filecomp(fp1,fp2);
fclose(fp1);
fclose(fp2);
}
void filecomp(FILE *fp1,FILE *fp2)
{
char line1[MAXLINE], line2[MAXLINE];
char *lp1,*lp2;
do
{
lp1=fgets(line1, MAXLINE, fp1);
lp2=fgets(line2, MAXLINE, fp2);
if(lp1==line1&&lp2==line2)
{
67
if(strcmp(line1,line2)!=0)
{
printf("Prva razlika je u liniji\n%s\n",line1);
lp1=lp2=NULL;
}
}
else
if(lp1!=line1&&lp2==line2)
printf("Kraj prvog fajla u liniji \n%s\n",line2);
else
if(lp1==line1&&lp2!=line2)
printf("Kraj drugog fajla u liniji \n%s\n",line1);
}
while(lp1==line1&&lp2==line2);
}
86./*Napisati program za učitavanje datoteke pod imenom ulaz.dat i formiranje datoteke sa nazivom izlaz.dat koja sadrži samo one redove ulazne
datoteke ulaz.dat u kojima se nalazi reč “fakultet”.*/
#include<stdio.h>
#include<string.h>
void main()
{
FILE *ulaz;
FILE *izlaz;
char buffer[80];
char trazenaRec[]="fakultet";
if((ulaz=fopen("ulaz.dat","r"))==NULL)
printf("Datoteka ulaz.dat nije otvorena.");
if((izlaz=fopen("izlaz.dat","w"))==NULL)
printf("Datoteka izlaz.dat nije otvorena.");
while(!feof(ulaz)){
fgets(buffer,80,ulaz);
if(strstr(buffer,trazenaRec)!=NULL){
printf("%s",buffer); /*stamanje na ekranu*/
fprintf(izlaz,"%s",buffer);
}
}
fclose(ulaz);
fclose(izlaz);
}
87. /*Napisati program koji cita podatke iz datoteke ULAZ.TXT (ime studenta, broj bodova na
prijemnom ispitu), broji sve studente koji imaju broj bodova veci od proseka i upisuje podatke o
takvim studentima u datoteku IZLAZ.TXT.*/
#include<stdio.h>
#define DIM 10
typedef struct student{
char ime[20];
int brBodova;
};
int main(){
struct student nizStudenata[DIM];
int i;
68
int brojStudenata=0;
int suma=0;
float prosek;
FILE *ulaz;
FILE *izlaz;
ulaz=fopen("ulaz.txt", "r");
if(ulaz==NULL){
printf("Ulazna datoteka nije otvorena!\n");
return 1;
}
izlaz=fopen("izlaz.txt", "w");
if(izlaz==NULL){
printf("Izlazna datoteka nije kreirana!\n");
return 1;
}
while(!feof(ulaz)){
fscanf(ulaz, "%s%d", &nizStudenata[brojStudenata].ime,
&nizStudenata[brojStudenata].brBodova);
suma+=nizStudenata[brojStudenata].brBodova;
brojStudenata++;
}
prosek=(float)suma/brojStudenata;
for(i=0; i<brojStudenata; i++)
if(nizStudenata[i].brBodova>prosek)
fprintf(izlaz, "%s\t%d\n", nizStudenata[i].ime, nizStudenata[i].brBodova);
fclose(ulaz);
fclose(izlaz);
return 0;
}
88. /*Napisati program za nalazenje i stampanje na ekranu zbira ASCII kodova svih znakova
zadate datoteke pod imenom ULAZ.TXT*/
#include<stdio.h>
#include<string.h>
int main(){
FILE *in;
int ascii;
int suma=0;
in=fopen("ulaz.txt", "r");
if(in==NULL){
printf("Ulazni fajl nije otvoren!");
return 1;
}
while(!feof(in)){
ascii=fgetc(in);
suma+=ascii;
printf("%c=\t%d\n",ascii, ascii);
//putc(fgetc(in), stdout);
}
printf("Suma svih znakova je: %d\n",suma);
fclose(in);
return 0;
}
89. /*U datoteci IMENIK.TXT nalaze se sledeci podaci: ime, prezime i broj telefona telefonskog
pretplatnika. Napisati program koji vrsi sortiranje imenika prema prezimenu pretplatnika i za
zadato prezime prikazuje telefonski broj pretplatnika na standardnom izlazu.*/
69
#include<stdio.h>
#include<string.h>
#define DIM 10
typedef struct telefonski_imenik{
char ime[10];
char prezime[20];
char broj[10];
};
void razmeni(struct telefonski_imenik *a, struct telefonski_imenik *b){
struct telefonski_imenik tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
void sort(struct telefonski_imenik niz[], int n){
int i, j;
for(i=0; i<n-1; i++)
for(j=i+1; j<n; j++)
if(niz[i].prezime<niz[j].prezime)
razmeni(&niz[i], &niz[j]);
}
int main(){
struct telefonski_imenik nizImenik[DIM];
int n, i;
FILE *in;
char trazi[20];
in=fopen("imenik.txt", "r");
if(in==NULL){
printf("Ulazni fajl nije otvoren!");
return 1;
}
i=0;
while(!feof(in)){
fscanf(in, "%s%s%s", &nizImenik[i].ime, &nizImenik[i].prezime, &nizImenik[i].broj);
i++;
}
fflush(in);
n=i+1;
sort(nizImenik, n);
printf("\nTelefonski imenik sortiran po prezimenu pretplatnika je:\n\n");
for(i=0; i<n; i++)
printf("%s\t%s\t%s\n", nizImenik[i].prezime, nizImenik[i].ime, nizImenik[i].broj);
printf("Ukupan broj telefonskih pretplatnika je: %d\n",n);
printf("Zadati prezime pretplatnika: ");
scanf("%s", &trazi);
for(i=0; i<n; i++){
if(strcmp(nizImenik[i].prezime,trazi)==0){
printf("Broj telefoma trazenog pretplatnika je:\n");
printf("%s\t%s\t%s\n", nizImenik[i].prezime, nizImenik[i].ime,
nizImenik[i].broj);
}
}
fclose(in);
return 0;
}
90. /*Datoteka sadrzi proizvoljan broj tacaka u ravni predstavljenih (x, y) koordinatama. Napisati
program koji za ucitanu tacku odredjuje minimalno rastojanje od tacaka u navedenoj datoteci.*/
70
#include<stdio.h>
#include<math.h>
int main(){
FILE *in;
double rastojanje;
int x0, y0, x, y;
int brojacTacaka=0;
double minimalnoRastojanje;
int i;
double nizRastojanja[100];
in=fopen("tacke.txt", "r");
if(!in){
printf("Ulazna datoteka ne postoji!\n");
return 1;
}
printf("Uneti x i y koordinatu referentne tacke: ");
scanf("%d%d", &x0, &y0);
while(!feof(in)){
fscanf(in, "%d%d", &x, &y);
if(x0<x && y0<y)
rastojanje=sqrt(pow(x-x0, 2) + pow(y-y0, 2));
else if(x0>x && y0>y)
rastojanje=sqrt(pow(x0-x, 2) + pow(y0-y, 2));
else if(x0<x && y0>y)
rastojanje=sqrt(pow(x-x0, 2) + pow(y0-y, 2));
else if(x0>x && y0<y)
rastojanje=sqrt(pow(x0-x, 2) + pow(y-y0, 2));
71
if ((stednja=fopen("stedise.dat","r+b"))==NULL)
/*Datoteka postoji, citanje broja zapisa u datoteci*/
fread(&veldat, sizeof veldat, 1, stednja);
else{
/*Datoteka ne postoji, stvaranje prezne datoteke*/
stednja=fopen("stedise.dat","w+b"); veldat=0;
fwrite(&veldat, sizeof veldat, 1, stednja);
}
/*Dodavanje zapisa o novim stedisama*/
while(1){
/*Citanje podataka o stedisi*/
printf("\nSifra stedise? "); scanf("%d",&sifra);
if(sifra==0) break; /*Zavrsetak programa*/
printf("Prezime stedise? ");
scanf("%s", stedisa.ime.prezime);
printf("Licno ime stedise? ");
scanf("%s", stedisa.ime.licno_ime);
stedisa.stanje=0;
/*Priprema za upisivanje podataka u datoteku*/
if(sifra>veldat){
/*Novi zapis je iza kraja datoteka, promena velicine datoteke*/
fseek(stednja, 0L, SEEK_END);
while(++veldat<sifra) fwrite(&prazno, sizeof prazno, 1, stednja);
veldat=sifra;
}else
/*Novi zapis je pre kraja datoteke, nalazenje njegovog mesta*/
fseek(stednja, (sizeof veldat)+(long) (sifra-1)*(sizeof stedisa),
SEEK_SET);
/*Upisivanje podataka u datoteku*/
fwrite(&stedisa, sizeof stedisa, 1, stednja);
rewind(stednja); fwrite(&veldat, sizeof veldat, 1, stednja);
}
}
92. /*Ispisivanje sadrzaja datoteke o stedisama*/ stedpisi.c
#include<stdio.h>
#include"stedisa.h"
typedef struct{char prezime[16], licno_ime[16];} Ime_i_prezime;
typedef struct{Ime_i_prezime ime; double stanje;} Stedisa;
void main(){
FILE*stednja;
Stedisa stedisa;
unsigned int sifra;
unsigned int veldat;
unsigned int i, k;
/*Otvaranje datoteke o stedisama*/
if((stednja=fopen("stedise.dat","r+b"))==NULL) exit(1);
fread(&veldat, sizeof veldat, 1, stednja);
/*Ispisivanje podataka o pojedinim stedisama*/
for(sifra=1;sifra<=veldat;sifra++){
/*Citanje sledeceg zapisa iz datoteke*/
printf("%3d", sifra);
fread(&stedisa, sizeof stedisa, 1, stednja);
72
if(stedisa.ime.prezime[0]!='\0'){
/*Prikaz podataka o postojecem stedisi*/
k=printf("%s%s", stedisa.ime.prezime, stedisa.ime.licno_ime);
for(i=k; i<34; i++) putchar(' ');
printf("%8.2f\n",stedisa.stanje);
}else
/*Prazan zapis, stedisa ne postoji*/
printf("***Ne postoji stedisa sa ovom sifrom***\n");
}
}
93. /*Azuriranje zapisa u datoteci o stedisama*/ stedazur.c
#include<stdio.h>
typedef struct{char prezime[16], licno_ime[16];} Ime_i_prezime;
typedef struct{Ime_i_prezime ime; double stanje;} Stedisa;
void main(){
FILE*stednja;
Stedisa stedisa;
unsigned int sifra;
unsigned int veldat;
double promena;
/*Otvaranje datoteke o stedisama*/
if((stednja=fopen ("stedise.dat", "r+b"))==NULL) exit(1);
fread(&veldat, sizeof veldat, 1, stednja);
/*Azuriranje stanja uloga pojedinih stedisa*/
while(1){
/*Citanje sifre sledeceg stedise za obradu*/
printf("\nSifra stedise?", " ");
scanf("%d",&sifra);
if(sifra==0)break;
if(sifra<=veldat){
/*Citanje zatecenih podataka o stedisi iz datoteke*/
fseek(stednja, (sizeof veldat)+(long)(sifra-1)*(sizeof stedisa),
SEEK_SET);
fread(&stedisa, sizeof stedisa, 1, stednja);
if(stedisa.ime.prezime[0]){
/*Prikazivanje zatecenih podataka o stedisi*/
printf("Stedisa=%s %s\n",stedisa.ime.prezime,
stedisa.ime.licno_ime);
printf("Staro stanje=%8.2f\n", stedisa.stanje);
/*Citanje promene stanja uloga*/
printf("Promena stanja? ");
scanf("%lf",&promena);
stedisa.stanje+=promena;
/*Upisivanje novog sadrzaja zapisa o stedisi u datoteku*/
fseek(stednja, -(long) (sizeof stedisa), SEEK_CUR);
fwrite(&stedisa, sizeof stedisa, 1, stednja);
}else
printf("***Ne postoji stedisa sa tom sifrom***\n");
}else
printf("***Ne postoji stedisa sa tom sifrom***\n");
}
}
73
74
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Microsoft Visual Studio 2013 predstavlja integrisano okruženje za razvoj softvera. Sastoji se od sledećih
celina:
Visual C++,
Visual Basic,
Visual C#
MSDN Library.
Druge…
Visual studio C++ je okruženje koje omogućava razvoj i pisanje programa u programskom jeziku C++,
a samim tim i u programskom jeziku C.
Pri kreiranju projekta potrebno je uneti naziv projekta u polje Project name, i eventualno promeniti
direktorijum na disku gde će projekat biti kreiran (polje Location). Po unosu naziva projekta aktiviraće
se taster OK. Klikom na ovaj taster pojaviće se prozor za izbor tipa konzolnog projekata koji se želi
kreirati (slika 4). U ovom slučaju ne treba ništa menjati jer je već odabrana opcija za kreiranje praznog
projekta (An empty project). Da bi se kreirao projekat potrebno je kliknuti na taster Finish. Ukoliko
želite možete klikunit i na dugme next. U tom slučaju će Vam biti prikazan sledeći prozor sa
dodatnim popcijama.
Slika 3. Izgled prozora za izbor tipa konzolnog projekta koji će biti kreiran
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
izmežu C++ File ili Header File (slika 4). Potrebno je uneti željeni naziv datoteke u polje File
name i kliknuti na taster OK.
Po kreiranju i dodavanju nove datoteke u projekat potrebno je uneti odgovarajući sadržaj (ukucati
program). Za to se koristi centralni deo glavnog prozora (slika 5). Visual Studio poseduje neke napredne
opcije za prikaz izvornog koda programa kao što su bojenje ključnih reči i komentara.
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Kartica ClassView je izvorno namenjena za prikaz informacija o klasama definisanim u C++
programu. Kako programski jezik C ne podržava rad sa klasama u prikazu vezanom za ovu karticu
pobrojane su samo funkcije definisane u datotekama koje projekat sadrži. Duplim klikom na naziv
funkcije otvara se odgovarajuća datoteka i postavlja se na početak odgovarajuće funkcije. Na slici 6
ilustrovani su FileView i ClassView prikazi.
4
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Prekompajlirani hederi
Prekompajlirani hederi predstavljaju C i C++ heder fajlove koji se pre kompajliranja pripreme i
prebace u intermediate formu koju kompajler može brže da kompajliura. Ova forma se naziva još i
prekompajlirani heder.Korišćenje ovakvih hedera može skratiti vreme kompajliranja, naročito kada
se primeni na velike heder fajlove. Problem kompajliranja velikog broja uključenih fajlova postoji i
kod drugih programskih jezika i svaki od njih ga rešava na neki svoj način. Demonstrirajmo
primerom kako se to rešava u C++ jeziku. Uzmimo za primer dprojekat koji ima dodata dva fajla
heder fajl header.h i sors fajl source.cpp:
//header.hpp
...
//source.cpp
#include "header.hpp"
...
U slučaju da je opcija za prekompajlirane hedere uključena, kompajler će generisati prekompajlirani
heder fajl header.pch. Kada sledeći put budete kompajlirali fajlove, ukoliko se vreme zadnje
promene fajla header.h nije promenilo, računar će preskočiti kompajliranje i iskoristiti već postojeći
header.pch fajl. U suprotnom novi fajl heaader.pch će biti kreiran, a stari obrisan.
Prilikom korišćenja visual studia 2013 postoji fajl stdafx.h koji predstavlja prekompajlirani heder za sve one
biblioteke koje želite da uključite u vaš program, a koje se retko menjaju. To znači da sve include direktive
treba pisati u vom fajlu.
5
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Debagiranje programa
Pored sintaksnih grešaka koje se otkrivaju u toku prevođenja, program može da sadrži i logičke
greške koje sprečavaju da se izvršava na način koji je programer predvideo. Ovakve greške se
nazivaju bug-ovi, a proces njihovog uklanjanja debugging. Proces debagiranja podrazumeva
postavljanje prekidnih tačaka u kojima će se izvršenje programa privremeno prekinuti u cilju
očitavanja vrednosti pojedinih promenljivih i sl. Postavljanje (ili uklanjanje) prekidnih tačaka vrši
se pozicioniranjem kursora na odgovarajuću liniju i klikom na dugme u obliku šake (vidi sliku 11).
Druga varijanta za dodavanje (ili uklanjanje) prekidne tačke je desni klik na odgovarajuću
programsku liniju i izbor stavke Insert/Remove Brakepoint iz padajućeg menija. Za startovanje
izvršenja programa u ovom modu koristi se stavka iz menija Build/Start Debug/Go, taster F5 ili
odgovarajuća prečica iz linije sa alatima (vidi sliku 10).
Za kontrolu izvršenja koriste se komande menija Debug. Značenja pojedinih komandi su sledeća:
Go (taster F5) – nastavlja izvršenje do naredne prekidne tačke.
Restart (kombinacija tastera Ctrl+Shift+F5) – resetuje izvršenje programa u modu za
6
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
debagiranje.
Stop Debugging (kombinacija tastera Shift+F5) – prekida debagiranje programa.
Step Into (taster F11) – ulazi u funkciju koja čeka na izvršenje. Ukoliko je u pitanju neka
druga naredba izvršava je i prelazi na narednu liniju u kodu.
Step Over (taster F10) – izvršava funkciju ili naredbu i prelazi na narednu liniju u kodu.
Step Out (kombinacija tastera Shift+F11) – izvršava tekuću funkciju do kraja i izlazi na nivo iz
koga je pozvana.
Run to Cursor (kombinacija tastera Ctrl+F10) – izvršava program do linije koda na koju
ukazuje položaj kursora.
Po zaustavljanju izvršenja moguće je očitati vrednosti pojedinih promenljivih i prikaz konteksta
(funkcija) iz kojeg se došlo do prekidne tačke. Očitavanje vrednosti promenljivih se može izvršiti
na nekoliko načina:
1. Zadržati pokazivač miša iznad naziva promenljive negde u kodu, što će rezultovati ispisivanjem
vrednosti pored pokazivača.
2. Dodavanjem naziva promenljive čije se praćenje želi u panelu Watch (desno ispod koda).
3. Direktno, ukoliko je promenljiva automatski izlistana u spisku promenljivih koje se trenutno
koriste (panel levo ispod koda).
7
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 1: Napisati i pokrenuti program.
void main()
{
printf("Moj prvi program u C jeziku\n");
}
8
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Osnovni opsezi i veličina podataka razlikuju se od računara do računara i uglavnom zavise od arhitekture procesora.
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Konverzioni znaci za različite tipove podataka
\Konverzacioni znak Opis
%c Jedan karakter znakovnog tipa
%d Označeni ceo broj
%e Broj u pokretnom zarezu, e -notacija
%E Broj u pokretnom zarezu, E -notacija
%f Broj u pokretnom zarezu, decimalna not.
%i Označeni ceo broj
%X Neoznačeni heksadecimalni broj (A do F)
%x Neoznačeni heksadecimalni broj (a do f)
%s Karakterni niz
ESCAPE KARAKTERI
Escape karakteri se koriste za definisanje nekih specijalnih znakova koje inače nije moguće napisati u string konstantama.
Ovo je lista specijalnih znakova:
Escape sequence Description Representation
\' single quote byte 0x27
\" double quote byte 0x22
\? question mark byte 0x3f
\\ backslash byte 0x5c
\0 null character byte 0x00
\a audible bell byte 0x07
\b backspace byte 0x08
\f form feed - new page byte 0x0c
\n line feed - new line byte 0x0a
\r carriage return byte 0x0d
\t horizontal tab byte 0x09
\v vertical tab byte 0x0b
OPERATORI
U programskom jeziku C direktno je moguća primena osnovnih matematičkih operatora +, -, *, / i operatora koji ne
postoje u drugim programskim jezicima: inkrement i dekrement. Ostale matematičke operatore možemo uključiti iz skupa
datoteka zaglavlja koji sadrži datoteku <math.h> i koja se po potrebi u procesu strukturnog programiranja uključuje u
izvorni program naredbom #include .
Aritmetički operatori u C jeziku Komentar
Dodela vrednosti (=)
Aritmetički operatori (+, -, *, /, % )
Inkrement (++) Efekti primene izraza su različiti
Dekrement (--) Efekti primene izraza su različiti
+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=
Relacioni operatori ( ==, !=, >, <, >=, <= ) Koristimo ih kod logičkih izraza (npr. IF naredbe)
Logički operatori ( !, &&, || ) Za povezivanje više logičkih izraza
Uslovni operator (uslov ? iz1; iz2) a>b ? a : b
Operatori nad bitovima ( &, |, ^, ~, <<, >> )
sizeof(data_type) x = sizeof (char);
cast operator int i; float f = 3.14; i = (int) f;
Direktiva #include <stdio.h> u zaglavlju programa - uključuje stdio.h biblioteku koja je deo paketa C kompajlera i sadrži
informacije o ulazno/izlaznim funkcijama za računar. Naziv potiče od STanDard Imput/Output.
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Prioritet Operatora
U sledećoj tabeli možete naći operatore u C jeziku od najvećeg ka najmanjem prioritetu:
Level Precedence group Operator Description Grouping
1 Scope :: scope qualifier Left-to-right
++ -- postfix increment / decrement
() functional forms
2 Postfix (unary) Left-to-right
[] subscript
. -> member access
++ -- prefix increment / decrement
~! bitwise NOT / logical NOT
+- unary prefix
3 Prefix (unary) &* reference / dereference Right-to-left
new delete allocation / deallocation
sizeof parameter pack
(type) C-style type-casting
4 Pointer-to-member .* ->* access pointer Left-to-right
5 Arithmetic: scaling */% multiply, divide, modulo Left-to-right
6 Arithmetic: addition +- addition, subtraction Left-to-right
7 Bitwise shift << >> shift left, shift right Left-to-right
8 Relational < > <= >= comparison operators Left-to-right
9 Equality == != equality / inequality Left-to-right
10 And & bitwise AND Left-to-right
11 Exclusive or ^ bitwise XOR Left-to-right
12 Inclusive or | bitwise OR Left-to-right
13 Conjunction && logical AND Left-to-right
14 Disjunction || logical OR Left-to-right
= *= /= %= += -=
assignment / compound assignment
15 Assignment-level expressions >>= <<= &= ^= |= Right-to-left
?: conditional operator
16 Sequencing , comma separator Left-to-right
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 2. Sastaviti program na programskom jeziku C za formatiranje ulaza u pokretnom zarezu.
void main()
{
/* deklaracija podataka */
float f_pro;
double d_pro;
/*dodela vrednosti*/
f_pro = 106,11;
d_pro = -0,0000654;
/*štampanje vrednosti promenljivih */
printf ("Promenljiva f_pro=%2f\n", f_pro);
printf ("Promenljiva d_pro=%.11f\n", d_pro);
printf ("Promenljiva f_pro=%e\n", f_pro);
printf ("Promenljiva d_pro=%G\n", d_pro) ;
}
Zadatak 3. Sastaviti program na programskom jeziku C za unos proizvoljnog karaktera i za štampanje ASCII
koda tog karaktera.
#include<stdio.h>
void main()
{
char ch;
printf("Unesite proizvoljan karakter.\n");
scanf("%c",&ch); /*naredba za unos podataka*/
printf("ASCII kod unetog karaktera %c je %d\n",ch,ch);
}
Prepišite izlaz iz programa:
Zadatak 4. Napisati program na C jeziku za štampanje dva cela broja x i y u kao i njihovog inkrementa i
dekrementa koristeći prefiksni i postfiksni operator.
Napomena: Operator inkrementa se koristi da bi se povećala vrednost promenljive za jedan. Operator dekrementa se
koristi da bi se smanjila vrednost promenljive za jedan. Pravila po kojima se primenjuje postfiksni i prefiksni zapis
operatora dekrementa na celobrojne promenljive i izraze su potpuno analogna pravilima upotrebe operatora inkrementa i
mogu se sagledati iz navedenog primera.
void main()
{
int x,y;
x=10; y=10;
printf("Vrednost izraza ++x je %d\n",++x);
printf("Vrednost izraza y++ je %d\n",y++);
printf("Nakon inkrementiranja vrednost za x je %d\n",x);
printf("Nakon inkrementiranja vrednost za y je %d\n",y);
printf("Vrednost izraza --x je %d\n",--x);
printf("Vrednost izraza y-- je %d\n",y--);
printf("Nakon dekrementiranja vrednost za x je %d\n",x);
printf("Nakon dekrementiranja vrednost za y je %d\n",y);
}
4
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Upisati rezultate rada programa i objasniti razliku između prefiksnog i postfiksnog operatora:
Zadatak 5. Šta označavaju vitičaste zagrade u jeziku C? Zašto koristimo ove zagrade pri definiciji main (ili bilo
koje druge ) funkcije
5
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Predprocesorske direktive
Preprocessor directives are lines included in the code of programs preceded by a hash sign (#). These lines are not program
statements but directives for the preprocessor. The preprocessor examines the code before actual compilation of code
begins and resolves all these directives before any code is actually generated by regular statements.
These preprocessor directives extend only across a single line of code. As soon as a newline character is found, the
preprocessor directive is ends. No semicolon (;) is expected at the end of a preprocessor directive. The only way a
preprocessor directive can extend through more than one line is by preceding the newline character at the end of the line
by a backslash (\).
#define TABLE_SIZE 100
Zadatak 2: Sastaviti program na programskom jeziku C za upotrebu funkcije rand() kojom se uključuje generator
slučajnih brojeva i štampa celobrojni slučajni broj i njegova dvostruka vrednost. Štampati i slučajan borj između 0 i
9. Štmpati slučajan broj između 10 i 19.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
void main()
{
int slucajan, dvostruki, x, y;
srand (time(NULL)); /* initialize random seed: */
slucajan = rand();
dvostruki = slucajan*2;
x = rand() % 10; /*slucajan izmedju 0 i 9*/
y = rand() % 10 + 10; /*slucajan izmedju 10 i 19*/
printf("Slucajan broj je %d\n", slucajan);
printf("Dvostruki slucajan broj je %d\n", dvostruki);
printf("Jos neki slucajni brojevi %d, \t %d \n", x, y);
}
Prepišite izlaz iz programa. Funkcija rand() je deo koje biblioteke?
#include <stdio.h>
void main()
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
{
int x, y, z; x = 10; y= 3; z = ( x / y ) * y;
if (x == z)
{ printf ( "Vrednosti x-a i z-a su jednake\n");
printf ( "Vrednost x-a je %d\n", x );
printf ( "Vrednost z-a je %d\n", z );
}
if ( x <= z)
{ printf ("Vrednost x-a je < ili = od vredriosti z-a\n");
printf( "Vrednost x-a je %d\n", x );
printf( "Vrednost z-a je %d\n", z );
}
if ( x >= z)
{ printf ( "Vrednost x-a je > ili = od vredriosti z-a\n" );
printf ( "Vrednost x-a je %d\n", x );
printf ( "Vrednost z-a je %d\n", z );
}
}
Prepisati rezultat:
#include<stdio.h>
#include<math.h>
void main()
{
double a,b,c;
double x1,x2,pom;
a = 1; b = 1; c = -2;
pom = sqrt(b*b-4*a*c);
x1 = ( (-b) + pom ) / 2 * a;
x2 = ( (-b) - pom ) / 2 * a;
printf("Vrednost prvog korena x1 = %f\n",x1);
printf("Vrednost drugog korena x2 = %f\n",x2);
}
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 5: Napisati isti program ali u opštem obliku kada se veličine a, b i c učitavaju sa tastature.
Napisati izvorni kod programa:
Zadatak 6: Napisati program na C jeziku za izračunavanje ukamaćene vrednosti ako je poznata mesečna
kamatna stopa, period oročavanja u mesecima i iznos glavnice. Štampati dobijene rezultate i proveriti
matematičku postavku programa.
Napomena: Koristiti pow funkciju iz biblioteke math.h koja izračunava x na y. Kamata se računa kao glavnica *
(1+kamata/100)period.
#include <stdio.h>
#include <math.h>
void main( )
{
double stopa, period, glavnica;
printf( "Unesite mesecnu kamatnu stopu: " ) ;
scanf( "%lf", &stopa ) ; /* ulaz u pokretnom zarezu */
/* konverzija u procente */
stopa = stopa / 100.0;
printf( "Unesite glavnicu: " );
scanf( "%lf", &glavnica );
printf( "Unesite vreme orocavanja u mesecima: " );
scanf( "%lf", &period ) ;
printf( "Ukamacena vrednost je = %.2f\n",
glavnica * pow( (1.0+stopa), period));
}
Proveriti izlaz iz programa za sledeće vrednosti: Kamatna stopa: 1, glvnica: 100, oročavnje: 3 meseca. Koliko će
iznositi krajnja vrednost?
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
For petlja
ulaz
izraz 1
izraz 3
T
izraz 2 naredba
N
izlaz
Upravljačke informacije kod for petlje, za razliku od while petlje, su smeštene na jednom mestu i to na vrhu iteracije.
Petlja for je definisana, što znači da unapred znamo koliko puta će petlja da se izvrši, a njena osnovna konstrukcija je:
Inicijalizacija – inicijalizacije vrednosti brojača. i = 0
Uslov – na primer upoređenje brojača sa graničnom vrednošću. i < 10
Inkrementirnje – ažuriranje brojača pri svakoj iteraciji. i ++
Prema tome, opšti oblik naredbe for je: for ( izraz1, izraz2, izraz3 )
naredba
uz napomenu da neki od izraza u for petlji može ostati prazan i tada se za taj izraz smatra da ima vrednost true..
Zadatak 1 Napisati program na C jeziku za prikaz neparnih brojeva manjih ili jednakih 20 korišćenjem for petlje.
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
While petlja
Ulaz
T
izraz naredba
Izlaz
Zadatak 2. Napisati program na C jeziku za izračunavanje zbira celih brojeva upotrebom while petlje.
Izračunavanje se prekida kada se unese ‘0’;
void main()
{
long sum = 0L;
int num;
printf("Unesite broj za sumiranje Ili 0 za izlaz\n");
scanf("%ld", &num);
while (num != 0)
{
sum = sum+num;
printf("Unesite naredni broj za sabiranj ili 0 za quite :::::::: %d \n ", num);
scanf("%ld", &num);
}
printf("Zbir unetih brojeva je %ld.\n", sum);
}
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 3. Napisati program u C jeziku za permutovanje cifara celog broja - while iskaz: (npr. 54321 u 12345 )
Postupak: celi broj 54321 delimo po modulu 10 - rezultat je 1
celi broj 54321 delimo sa 10 - rezultat je 5432
celi broj 5432 delimo po modulu 10 - rezultat je 2
celi broj 5432 delimo sa 10 - rezultat je 543
celi broj 543 delimo po modulu 10 - rezultat je 3
celi broj 543 delimo sa 10 - rezultat je 54
celi broj 54 delimo po modulu 10 - rezultat je 4
celi broj 54 delimo sa 10 - rezultat je 5
celi broj 5 delimo po modulu 10 - rezultat je 5
Petlja se prekida jer broj postaje nula !!!
#include <stdio.h>
void main()
{
int broj;
printf("Ukucajte ceo broj ? ");
scanf("%d", &broj );
printf("Permutovani broj je ");
while ( broj )
{
printf("%d", broj % 10);
broj = broj/10;
}
printf("\n");
}
Zadatak 4. Napisati program na C jeziku za određivanje srednje vrednosti n celih pozitivnih brojeva –pomoću
while petlje. Testirati program za vrednosti n=4, brojevi su redom 34.345, 234.2876, 45.98, 453.32. Koliki je
rezultat?
Zadatak 5. Razmotrite izraz : double ans = 18.0/squared(2+1). Izračunati vrednost izraza ako je funkcija makro
squared() definisana kao:
A. #define squared(x) x*x
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 6. Napisati algoritam na programskom jeziku C koji vrednosti 3 promenljive rotira za k mesta u levo.
Vrednosti promenljivih i vrednost promenljive k zadaje korisnik. Prikazati vrednost promenljivih nakon rotacije.
Zadatak 7 Šta je mrtva petlja?Napisati primer mrtve petlje za for i while naredbe i objasniti.
4
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
ulaz
naredba
T
izraz
izlaz
Rešenje:
#include <stdio.h>
void main() /* Program za izracunavanje faktorijela */
{
int i, fak;
long n ;
i = 1; n = 1;
printf("lzracunavanje n!\nUkucajte broj ? ");
scanf("%d", &fak);
do{
n *= i;
i++;
} while (i <= fak);
printf("%d! = %ld\n", fak,n);
}
Koliko puta se izvrši naredba n *= i. Napisati isti program koristeći samo for petlju:
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Prekid izvršenja trenutnog ciklusa petlja, preskakanja svih ostalih naredbi i prelazak na sledeću iteraciju sa
obavlja naredbom continue.
Zadatak 2. Primer programa u kome se koristi naredba break u kombinaciji sa naredbom switch za
izračunavanje broja samoglasnika u delu proizvoljnog teksta:
void main()
{
char ch;
int a_ct,e_ct,i_ct,o_ct,u_ct;
a_ct=e_ct=i_ct=o_ct=u_ct=0;
printf("Unesi priozvoljan tekst; Unesi # za izlaz.\n");
while((ch=getchar())!= '#')
{
switch (ch)
{
case 'a' : a_ct++; break;
case 'A' : a_ct++; break;
case 'e' : e_ct++; break;
case 'E' : e_ct++; break;
case 'i' : i_ct++; break;
case 'I' : i_ct++; break;
case 'o' : o_ct++; break;
case 'O' : o_ct++; break;
case 'u' : u_ct++; break;
case 'U' : u_ct++; break;
default: break;
} /* kraj switch */
} /* dok petlji nije kraj */
printf("Broj samoglasnika: A E I O U\n");
printf("%4d %4d %4d %4d %4d\n", a_ct,e_ct,i_ct,o_ct,u_ct);
}
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 3. Sastaviti program na C jeziku za rešavanje sistema linearnih jednačina primenom Kramerovog
pravila:
1
x1 , x2 2 , x3 3 , , xn n
i praktično rešiti sistem jednačina:
x1 + x2 + 2x3 = 9
4x1 - x2 + 3x3 = 11
-2x1 + 2x2 + x3 = 5
1 1 2 9 1 2 1 9 2 1 1 9
gde je : 4 1 3 , 1 11 1 3 , 2 4 11 3 , 3 4 1 11
2 2 1 5 2 1 2 5 1 2 2 5
void main()
{
int x1, x2, x3; int a1, a2, a3; int b1, b2, b3;
int c1, c2, c3; int r1, r2, r3;
Zadatak 4. For petlja i do while petlja se mogu transformisati u while petlju. Transformišite sledeće primere
a) Primer 1: Prevesti dati izraz koristeći while petlju:
int i , ret = 1;
for ( i = 2; i <= n; i++)
ret ∗= i ;
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
4
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
VEŽBA 6 –Funkcije
1. Potprogrami i struktura programa
Potprogrami predstavljaju mehanizam koji direktno podržava funkcionalnu dekompoziciju kao jednu od
osnovnih metoda strukturnog programiranja. Oni su samostalni segmenti programskog koda koji se pozivaju radi
obavljanja konkretno specificiranog zadatka. Potprogram može biti neograničeno puta pozivan iz istog ili u okviru
različitih programa. Programski jezik C sadrži module (biblioteke) u kojima se nalaze grupe deklaracija promenljivih i
deklaracija potprograma kao jedinice fizičke dekompozicije. Ovakav pristup za direktnu posledicu ima stvaranje opštih
programskih rešenja i mogućnost višestrukog korišćenja istog programskog koda u različitim softverskim proizvodima.
Svaki podprogram se sastoji od:
Deklaracije kojom se definiše interfejs potprograma prema programu, koja uključuje ime potprograma, listu
parametara koja ne mora biti neprazna i opciono tip vraćene vrednosti
Tela potprograma koje se sastoji od deklaracija i naredbi.
PROCEDURA:je tip potprograma koji takođe može prihvatiti nijednu, jednu ili više vrednosti u obliku
argumenata. Na osnovu prihvaćene vrednosti rezultat procedure može biti nijedna ili više vrednosti.
Programski jezik c ne podržava kreiranje procedura.
Rezervisana reč void se koristi kao oznaka za povratnu vrednost kada funkcija ne vraća ništa.
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
void main()
{
zvezde(); /* poziv korisnicke funkcije */
printf("%s \n",IME); /*poziv funkcije iz standardne biblioteke*/
printf("%s \n",ADRESA);
printf("%s \n",MESTO);
zvezde();
}
1.1 Sagledati tok glavnog programa i potprograma i utvrditi u kojoj programskoj liniji nastaju "tačke prekida"
glavnog program i kada se kontrola prebacuje na izvršavanje potprograma.
1.3 Zašto je neophodno prvo deklarisati funkciju zvezde()? Šta bi se desilo da nismo deklarisali funkciju? Da li je
moguće napisati funkciju tako da se deklaracija i definicija funkcije obave zajedno? Kako?
1.4 Koristeći isti program umesto konstanti IME, ADRESA i MESTO uneti vase podatke. Kompajlirati,
linkovati i izvršiti ovako modifikovan program.
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 2. Poziv funkcija sa 2 argumenata: Sastaviti program na C jeziku za izračunavanje minimuma dva cela
broja. U glavnom programu obezbediti štampanje oba broja i njihovog minimum. Potprogramu treba kao
parameter da primi dva broja i da vrati manji od njih.
#include<stdio.h>
int imin ( int n, int m); // Deklaracija funkcije
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 4. Napisati program za izračunavanje hipotenuze pravouglog trougla. U glavnom program izvršiti unos
vrednosti prve i druge katete i štampati vrednost hipotenuze. U potprogramu izračunati vrednost hipotenuze.
void main ( )
{ int x = 5, y = 10;
printf("U programu oriqinalne vrednosti: x = %d a y = %d.\n", x, y);
promeni(x,y);
printf("U programu nakon poziva funkcije je: x = %d a y = %d.\n", x, y);
}
4
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
5.1 Napisati reaultate rada programa. Zašto promenljive x i y nisu zamenile vrednosti u glavnom program, a
jesu unutar funkcije? Izmeniti i napisati kod programa funkcije promeni tako da promenljive x i y zamene mesta
i u glvnom programu. Problem možete rešiti pomoću pokazivača ili referenci.
5
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
VEŽBA 7 –Nizovi
2. Pokazivači
Pokazivač je promenljiva koja sadrži adresu objekta ili funkcije. Rad sa pokazivačkim promenljivama je veoma
teško razumeti bez razumevanja koncepta indirekcije, odnosno koncepta posrednog pristupa. Objekti programskog
rešenja se uvek memorišu u određenom programskom bloku, i to na tačno određenoj memorijskoj lokaciji. Pokazivači
omogućuju indirektni pristup vrednostima programskih promenljivih korišćenjem njihovih memorijskih adresa. U
neposrednoj vezi sa pokazivačima su dva specijalna operatora programskog jezika.operator adresa-od u oznaci & je
operator koji daje memorijsku adresu objekta na koga je primenjen; posredni operator * je operator kojim se upravlja
memorijskim lokacijama u pokazivačkim promenljivama.
Adresni operator & je unarni operator vrlo visokog prioriteta, Što je slučaj i sa ostalim unarnim operatorima.
Ovaj operator predstavlja način da se sazna memorijska lokacija gde je taj objekat smešten u memoriji računara.
Asocijativnost ovog unarnog operatora je s desna na levo, a opseg vrednosti koji može da ima je skup nenegativnih celih
brojeva (unsigned int). Operator indirekcije * omogućava deklarisanje pokazivačke promenljive i indirektni pristup do
vrednosti za koje su korišćene pokazivačke promenljive. U razvoju programskih rešenja se vrlo često informacija o
memorijskoj adresi promenljive ili funkcije čuva i kasnije koristi. Za implementaciju ovog koncepta je neophodno
obezbediti mesto u memoriji gde se smešta informacija o adresi programskog objekta, koju dobijamo deklarisanjem
pokazivačke promenljive. Paradigma pokazivačkih promenljivih u C jeziku bi izgledala:
Pokazivači se često koriste u sprezi sa nizovima kako bi se lakše dolazilo do određenog člana niza što predstavlja
adekvatnu upotrebu aritmetičkih operacija nad pokazivačima. Dozvoljene operacije su sabiranje i oduzimanje celobrojnih
podataka, dodela vrednosti jednog pokazivača drugom, poređenje dva pokazivača, poređenje pokazivača i nule kao
celobrojne vrednosti, oduzimanje vrednosti pokazivača istog tipa.
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Deklaracija Niza
Svaki niz mora biti deklarisan pre nego što se može koristiti:
type variable_name[lengthofarray];
Ilustrujmo to primerima:
double height[10]; float width[20]; int min[9]; char name[20];
U C jeziku elemnti niza počinju od pozicije (indeksa) 0. Elementi niza se nalaze ne susednim memoriskim lokacijama.
Samo ime niza ustvari predstavlja pokazivač na memorisku lokaciju prvog elemnta niza. Zato je moguće pristupiti bilo
kom elementu niza navođenjem odgovarajućeg indeksa tog elementa:
m=height[0];
Inicijalizacija Niza
Inicijalizacija niza predstavlja dodelu inicijalne vrednosti svim njegovim članovima. Sledeći kod ilustruje deklaraciju i
inicijalizaciju niza:
int myArray[5] = {1, 2, 3, 4, 5}; //istovremena deklaracija i inicijalizacija
int studentAge[4]; studentAge[0]=14; studentAge[1]=13;
studentAge[2]=15; studentAge[3]=16;
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
1.2 Deklarisati niz od 4 elemenata tipa char i inicijalizovati sve članove niza na vrednost ‘a’. Ilustrovati oba na;ina
inicijalizacije:
1.4 Šta će se desiti ukoliko pokušamo da petom elemntu ovog niza dodelimo vrednost ‘m’
Zadatak 2. Napisati program kojim se određuje redni broj maksimalnog elementa u celobrojnom nizu X od N
elemenata.
Rešenje:
start
N, (X(I), I=1,N)
IMAX=1
I=2,N
X(IMAX)<X(I) ne
da
IMAX=I
(X(I),I=1,N)
IMAX,X(IMAX)
kraj
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 3. Primer prenosa argumenata funkcije pokazivačkim promenljivim za realizaciju sabiranja članova
niza.
#include <stdio.h>
#define VELIC 10
long sump(int *pok, int vel);
void main()
{
static int niz[VELIC] = {20,10,5,39,4,16,19,26,31,20};
long odgovor;
odgovor = sump(niz, VELIC);
printf("Suma niza je: %ld.\n", odgovor);
}
Zadatak 4. Napisati program za štampanje niza i množenje elemenata niza konstantnom vrednošću.
#include <stdio.h>
#define VELICINA 5
void main()
{
double dip[VELICINA] = {20.0, 17.66, 8.2, 15.3, 22.22};
int i;
for(i = 0; i < VELICINA; i++)
dip[i] *= mnozi;
printf("\n");
for(i = 0; i < n; i++)
printf("%8.3f ", dip[i]);
printf ("\n");
}
4
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 4.1. Izmeniti kod iz prethodnog zadatka tako da se svaki element niza uveća (umesto pomnoži) za neku
konstantnu vrednost koja se unosi sa tastature.
Zadatak 4.2 Izmeniti kod iz prethodnog zadatka tako da se štampanje niza i množenje niza obavi u potprogramu.
5
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 5. Razmotriti rad programa pisanog u C programskom jeziku, koji sortira dati vektor ar =
{7,3,9,2,11,20,17,19,6,4} korišćenjem metode "bubble sort" algoritma. Program se najpre sastoji u pisanju
funkcije "swap" koja vrši zamenu vrednosti dve promenljive i smešta ih u dve memorijske lokacije. Zatim tu
funkciju koristimo da bi izvršili sortiranje datog vektora. "Bubble sort" ispituje svake dve ćelije vektora i ako nisu
sortirane - svapuje ih. Ako se obezbedi upoređenje i svapovanje n-1 put nad svim ćelijama vektora, on će biti
kompletno sortiran.
#include <stdio.h>
void swap (int *a, int *b);
void main()
{
int ar[10] = {7, 3, 9, 2, 11, 20, 17, 19, 6, 4};
int i,j,n;
6
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 6: Napisati program u programskom jeziku C koji određuje broj elemenata niza koji se javljaju samo
jednom.
Zadatak 7: Napisati program u programskom jeziku C koji za dva uneta niza A i B proverava da li ovi nizovi
imaju zajedničkih elemenata. Ukoliko zajednički elementi postoje, od njih se formira novi niz C i na kraju
zadataka štampa na standardni izlaz.
7
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
#include <stdio.h>
void main()
{
char c=' ';
int i;
Zadatak 2 Poređati sledeći niz naredbi u odgovarajući redosled tako da program odštampa jednostavnu poruku
“Ja s am student prve godine”
1. return 0;
2. const char msg[] = MSG1;
3. }
4. #define MSG1 "All your base are belong to us!"
5. int main(void){
6. #include <stdio.h>
7. puts(msg);
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 4. Sastaviti program koji iz skupa unetih karaktera (na primer: ’’Ja sam rodjen 1990. god u 12. mesecu,
i u petak!’’) izračunava broj unetih slova, brojeva i ostalih karaktera. Tekst se unosi sa tastature, a program se
prekida pritiskom na ctrl+Z, a zatim enter.
Zadatak 5. Napisati program konvertuje velika u mala slova. Recenica se unosi sa tastature a program se prekid
unošenjem karaktera %.
Zadatak 6 Napisati program na programskom jeziku C koji učitava dva znakovna niza, čije se dužine unose kao
podatak sa tastature, izvrši nadovezivanje drugog na prvi, okrene “naopako“ dobijeni niz i ispiše ga na
standardnom izlaznom uređaju. Znakovni nizovi su maksimalne dužine 200 karaktera.
6.1 Da li je moguće deklariati niz sledećim izrazom int niz[n], gde je n neka promenljiva. Zašto?
6.3 Napisati koje još naredbe znate za rad sa nizovima i kratko objanisiti šta rade:
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
6.4 Da li je moguće promeniti veličinu već deklarisnaog niza. Zašto?
Zadatak 7. Sastaviti program na jeziku C za učitavanje imena gradova uz njihovo uređivanje po abecednom
redosledu i ispisivanje rezultata. U svakom redu se učitava po jedno ime sve dok se ne učita prazan red.
Program:
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
VEŽBA 9 –Matrice
Multidimenzijalni nizovi
U C jeziku mogu postojati i višedimenzijalni nizovi. Probajmo da to ilustrujemo primerom jedne matrice dimenzija 4 x
5:
Neka je ime naše matrice X. Za pristup elemntu matrice mramo da koristimo dva indeksa, jedan za red a drugi za vrstu
matrice. Izraz bi u ovom slučaju izgledao X [i] [j], gde je i indeks reda, a j indeks kolone. To znači da bi X [0] [0]
referencirao vrednost 10, X [2] [1] referencira vrednost 9. Ukratko, multidimenzijalni nizovi se definišu na isiti način
kao i obični nizovi samo što korite veći broj indeksa za pristup svojim elementima. Mi ćemo za sada raditi samo sa
dvodimenzijalnim nizovima. Deklarisanje ovakvog niza se može uraditi ovako:
float table [50] [50];
char line [24] [40];
Prvi primer definiše matricu (dvodimenzionalni niz) float vednosti koja ima 50 vrsta i 50 kolona. To znači da će ukupan
broj elementata biti 50x50=2500. Drugi primer deklariše matricu char elemenat sa 24 vrsta i 40 kolona. Ukupan broj
elemenata je 24 x 40 = 1920 elemenata.
Pokažimo još jedan primer matrice 3 x 4 sa vrednostima {1, 2, 3, 4, 5, 6, 7, 8, 9, 10. 11, 12, };
Values [0] [0] = 1 Values [0] [1] = 2 Values [0] [2] = 3 Values [0] [3] = 4
Values [1] [0] = 5 Values [1] [1] = 6 Values [1] [2] = 7 Values [1] [3] = 8
Values [2] [0] = 9 Values [2] [1] = 10 Values [2] [2] = 11 Values [2] [3] = 12
Prvi indeks označava vrstu a drugi kolonu. Prvi indeks može uzeti vrednosti od 0 do 2 što ukupno čini 3 vrst. Drugi
indeks može uzeti vrednosti od 0 do 3 što ukupno čini 4 kolone. Ova matrica se može deklarisati i inicijalizovti i na
sledeći način:
int values [3] [4] = {
{ 1, 2, 3, 4 }
{ 5, 6, 7, 8 }
{ 9, 10, 11, 12 }
};
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 1. Sastaviti program na programskom jeziku C koji štampa sadržaj kvadratne matrice 5 * 5 vrstu po
vrstu, a potom sporednu dijagonalu, sleva-udesno. Matricu formirati generatorom slučajnih brojeva RAND()
#include <stdio.h>
void main()
{
int a[5][5], n, i, j;
for (i=0; i<5; i++)
{
/*alocira memoriju za n elemenata vrste koji su tipa int*/
for (j=0; j<5; j++)
a[i][j] = rand()%10;
}
Prepisati rezultate rada programa. Napisati na drugi način izraz printf(" %d", *(*(a+i)+5-1-i)).
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Napisati rezultate rada programa:
ulazni nizovi: obrnuti izlazni niz
Zadatak 3. Napisati program na C++ jeziku koji izračunava sumu svih elemenata u svakom redu pojedinačno,
pravougaone matrice [4x4].
1 2 3 4
5 6 7 8
A=
9 10 11 12
13 14 15 16
void main()
{
int mat[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int i,j,s=0;
for(i=0;i<4; i++)
{
printf("\nSuma %d reda je:",i+1);
for(j=0;j<4; j++)
s=s+mat[i][j];
printf("%2d\n",s);
s=0;
}
}
Napisati rezultat rada programa:
Zadatak 4. Napisati program na C jeziku koji će izračunati sumu elemenata na glavnoj dijgonali proizvoljne
marice dimenzija 5x5.
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Otvaranje fajla
Za otvaranje fajlova se koristi funkcija fopen. Svaki fajl se mora otvoriti pre korišćenja i zatvoriti nakon korišćenja
kako bi sve promene na fajlu bile zapamćene. Ukoliko fajl ne postoji ova funkcija će ga kreirati, otvoriti, inicijalizovati
objekat tipa FILE, koji sadrži sve informacije neophodne za kontrolu toka (stream) podataka. Pogledaj mo deklaraciju
ove funkcije:
FILE *fopen( const char * filename, const char * mode );
U ovom primeru filename je string literal i predstavlja putanju i ime fajla. Mode predstavlja pristupni mod i može imati
sledeće vrednosti:
Mod Opis
Otvara tekstualni fajl kako bi se izvršio upis. Ako fajl ne postoji , novi fajl će biti kreiran i program
w
če izvršiti upis na početak fajla.
Otvara tekstualni fajl za upis. Ako fajl ne postoji novi fajl će biti kreiran. Upis će izvršiti dodavanje
a
sadržaja na već postojeći sadržaj fajla.
Otvara tekstualni fajl za čitanje i pisanje. Sav sadržaj fajla se briše. Ukoliko fajl ne postoji kreira
w+
se novi fajl.
Otvara teksualni fajl za čitanje i pisanje. Kreira fajl ukoliko ne postoji. Čitanje će početi na
a+
početku fajla, ali pisanje će izvršiti dodavanje sadržaja na kraju fajla.
Ukoliko želite da koristite binarne fajlove onda morate koristiti sledeće modove:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
Zatvaranje fajla
Za zatvaranje fajla koristite funkciju fclose(). Deklaracija ove funkcije je:
int fclose( FILE *fp );
Ova funkcija vraća nulu ukoliko je poziv uspešan ili EOF ukoliko postoji greška pri zatvaranju fajla. Ova funkcija
ustvari prazni bafer koji se koristi za rad sa fajlom, zatvara fajl i oslobađa memoriju koja se koristila za fajl. EOF je
konstanta definisana u zaglavlju stdio.h fajla i najčešće ima vrednost -1.
Upis u fajl
Najjednostavnija funkcija za upis jednog karaktera u fajl je:
int fputc( int c, FILE *fp );
Ova funkcija vrši upis jednog karaktera koji ima vreedsnot c na tok podataka referenciran sa fp. U našem primeru fp će
referencirati neki fajl. Funkcija će prilikom upisa izvršiti internu konverziju karaktera u tip unsigned char. Funkcija
vraća karakter koji je upisan u slučaju da je funkcija uspešno izvršena, u suprotnom vraća EOF.
1
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 1: Primer upisa u fajl.
#include <stdio.h>
void main()
{
FILE *fp;
fp = fopen("test.txt", "w+");
fprintf(fp, "This is testing for fprintf...\n");
fputs("This is testing for fputs...\n", fp);
fclose(fp);
}
1.1 Šta će se desiti ukoliko fajl "test.txt" ne posotji?
Čitanje fajla
Sledeća funkcija vrši čitanje jednog karaktera u fajl:
int fgetc( FILE * fp );
Funkcija fgets() vrši čitanje jednog karaktera iz toka podataka referenciranog sa fp. Povratna vrednost funkcije je
pročitani karakter ukoliko je ona uspešna. Ukoliko je došlo do greške funkcija će vratiti EOF.
Za čitanje stringa se može koristiti i funkcija int fscanf(FILE *fp, const char *format, ...). Ona će prekinuti čitanje
nakon prvog blanko znaka. Ukoiko je uspena funkcija će vratiti broj argumenata koji su pročitani. Na primer funkcija
fscanf(fp, "%s %s", ime, prezime); će vratiti vrednost 2 ukoliko je uspešna ili EOF ako je neuspešna.
Ilustrujmo ovo primerom:
2
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 3: Fajlovi zad4.txt sadrži podatke o poenima koje su studenti osvojili na ispitu iz predmeta programski
jezici 1. Za svakog studenta je zapamćen broj poena koje je student dobio na ispitu. Odštampati imena svih
studenata koji su položili ispit. Ispit su položili svi studenti koji imaju više od 50 poena. Listu odštampati na
standardni ulaz i u fajl rezultati.txt. Primer fajla zad4.txt je:
Pera Peric 30
Ivana Stojicic 65
Marko Knezevic 45
Milutin Milankovic 80
void main()
{
FILE *fp, *fpr;
char ime[20], prezime[20];
int i=1, rez=0, r1=0, r3=0;
fp = fopen("zad3.txt", "r");
fpr = fopen("rez.txt", "w");
while (fscanf(fp, "%s", ime) != EOF)
{
r1 = fscanf(fp, "%s", prezime);
r3 = fscanf(fp, "%d", &rez);
3.1 Gde se nalazi datoteka rez.txt i koji je njen sadržaj nakon izvršenja programa?
3.2 Zašto se u naredbi fscanf(fp, "%s", prezime); promenljiva prezime koristi bez operatora referenciranja &, a
promenljiva rez u naredbi fscanf(fp, "%d", &rez) se koristi sa ovim operatorom?
3.3 Da li možete da napišete program tako da se sve tri promenljive ime, prezime i rez čitaju odjednom?
Dovoljno je napisati samo deo koda koji se razlikuje od trenutnog rešenja. Koliku će vrednost u tom slučaju
vratiti funkcija fscanf?
3
Visoka tehnička škola strukovnih studija u Nišu
Laboratorijske vežbe iz Programskih jezika I
Zadatak 4: Fajl zad4.txt sadrži odlomak jednog našeg poznatog romana. Tokom kucanja odlomka greškom je
umesto slova “lj” kucano slovo q i umesto slova “nj”, slovo w . Izvršiti ispravku grešaka pri kucanju ovog
odlomka i unete ispravke upisati u fajl rez4.txt. Izbrojati koliko je izmena ukupno bilo. Primer sadržaja fajla
zad4.txt je: “Vesti o qubicastom cvetu qiqanu mozete naci na wegovm blogu”. Napisati program, šta štampa program na
standardni izlaz i sadržaj fajla rez4.txt nakon izvršenja programa.
4
PRIMERI PROGRAMA ZA PRIPREMU PRVOG
KOLOKVIJUMA
/* abs funkcija za PRIMER APSOLUTNE VREDNOSTI CELOG BROJA */
#include <stdio.h>
#include <math.h>
int main(void)
{
int number = -1234;
#include <stdio.h>
#include <math.h>
int main(void)
{
double result;
double x = 4.0;
result = exp(x);
printf("'e' dignuto na stepen %lf (e ^ %lf) = %lf\n",
x, x, result);
return 0;
}
/* log funkcija za PRIMER LOGARITMA REALNOG BROJA */
#include <math.h>
#include <stdio.h>
int main(void)
{
double result;
double x = 8.6872;
result = log(x);
printf("Prirodni logaritam %lf je %lf\n", x, result);
return 0;
}
#include <stdio.h>
#include <math.h>
int main(void)
{
double result, x = 0.5;
result = sin(x);
printf("Sinus od %lf je %lf\n", x, result);
return 0;
}
#include <stdio.h>
#include <math.h>
/*program za resavanje vrednosyi polinoma*/
/* polynomial: x**3 - 2x**2 + 5x - 1 */
int main(void)
{
double array[] = { -1.0, 5.0, -2.0, 1.0};
double result;
result = poly(2.0, 3, array);
printf("Polinom: x**3 - 2.0x**2 + 5x - 1 na 2.0 je %lf\n", result);
return 0;
}
#include <math.h>
#include <stdio.h>
int main(void)
{
double x = 2.0, y = 3.0;
#include <math.h>
#include <stdio.h>
float main(void)
{int n=5;
double x = 32.0,rezultat;
rezultat=pow(x,1./n);
printf("%d_ti koren broja %lf je: %lf\n",n, x,rezultat);
return 0;
}
#include <math.h>
#include <stdio.h>
int main(void)
{
double x = 4.0, resultat;
resultat = sqrt(x);
printf("KVADRATNI KOREN %lf JE %lf\n", x, resultat);
return 0;
}
#include <math.h>
#include <stdio.h>
int main(void)
{
double result;
double x = 800.6872;
result = log10(x);
printf("LOGARITAM BROJA %lf JE %lf\n", x, result);
return 0;
}
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i;
printf("Deset slucajnih brojeva od 0 do 99 su:\n\n");
for(i=0; i<10; i++)
printf("%d\n", rand() % 100);
return 0;
}
Napisati program za generisanje slučajnog broja, izračunati njegovu dvostruku vrednost i prikazati sledeći
slučajni broj.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void main()
{
int slucajan, dvostruki;
slucajan = rand();
dvostruki = slucajan*2;
printf("Slucajan broj je %d\n", slucajan);
printf("Dvostruki slucajan broj je %d\n", dvostruki);
printf("Naredni slucajan broj je %d\n", rand());
}
#include <stdio.h>
return 0;
}
Primer za štampanje rezultata množenja (od 1*1 do 9*9 u redovima po 9 ).
#include<stdio.h>
void main()
{
int i,j;
for(i=1;i<10;i++)
{
for(j=1;j<10;j++)
printf("%3d",i*j);
printf("\n");
}
}
#include<stdio.h>
void main()
{
int n;
printf("Unesi ceo broj: ");
scanf("%d",&n);
if(n>=0)
printf("Broj je pozitivan !\n");
if(n<0)
printf("Broj je negativan !\n");
}
#include<stdio.h>
void main()
{
int n;
printf("Unesi ceo broj: ");
scanf("%d",&n);
if(n>=0)
printf("Broj je pozitivan !\n");
else
printf("Broj je negativan !\n");
}
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
void main()
{
float delta,a,b,c,x1,x2;
printf("Unesite a : ");
scanf("%f",&a);
printf("Unesite b : ");
scanf("%f",&b);
printf("Unesite c : ");
scanf("%f",&c);
delta=b*b-(4*a*c);
printf("Podkorena velicina delta je:%f",delta);
if(delta<0)
{
printf("Jednacina nema resenja !\n");
exit(0);
}
if(delta==0)
{
x1=-b/(2*a);
printf("E Jednacina ima dva ista resenja !\n");
printf("x1=x2=%f",x1);
exit (0);
}
x1=(-b+sqrt(delta))/(2*a);
x2=(-b-sqrt(delta))/(2*a);
1- Program matematika
2- Program finansija
3- Program zabave
4- Exit
upotrebom while naredbe i if, else if strukture za startovanje svih stavki iz menija.
#include<stdio.h>
#include<stdlib.h>
void main()
{
int choice;
while(1)
{
printf("\n\nMeni:\n");
printf("1- Program matematika\n2- Program finansija\n");
printf("3- Program zabave\n4- Exit");
printf("\n\nVas izbor -> ");
scanf("%d",&choice);
if(choice==1)
printf("\nProgram matematika Runs. !");
else if(choice==2)
printf("\nProgram finansija Runs. !");
else if(choice==3)
printf("\nProgram zabave Runs. !");
else if(choice==4)
{
printf("\nKraj programa!.\n");
exit(0);
}
else
printf("\nPogresan izbor");
}
}
Isti zadatak samo upotrebom naredbe switch i case.
#include<stdio.h>
#include<stdlib.h>
void main()
{
int choice;
while(1)
{
printf("\n\nMeni:\n");
printf("1- Program matematika\n2- Program finansija\n");
printf("3- Program zabave\n4- Exit");
printf("\n\nVas izbor -> ");
scanf("%d",&choice);
switch(choice)
{ case 1 :
printf("\nProgram matematika Runs. !");
break;
case 2 :
printf("\nProgram finansija Runs. !");
break;
case 3 :
printf("\nProgram zabave Runs. !");
break;
case 4 :
{
printf("\nKraj programa!.\n");
exit(0);
}
default:
printf("\nPogresan izbor");
}
}}
x 2 ⋅ sin( x ) − 1
Napisati program za izračunavanje funkcije y = 3
.
x
#include <stdio.h>
#include <math.h>
void main()
{
double x,y,pom;
printf("Unesite broj\n");
scanf("%lf",&x);
pom=pow(x,1./3.);
y=(x*x*sin(x)-1)/pom;
printf("Vrednost izraza je %lf a vrednost korena %lf\n",y,pom);
}
//Operator inkrementa
#include <stdio.h>
void main()
{
int x, y;
x = 10;
y =10;
printf("Vrednost izraza ++x je %d\n", ++x);
printf("Vrednost izraza y++ je %d\n", y++);
printf{"Nakon inkrementiranja vrednost x-a je %d\n",x);
printf{"Nakon inkrementiranja vrednost y-a je %d\n", y);
}
//Operator dekrementa
#include <stdio.h>
void main()
{
int x, y;
x = 10;
y = 10;
printf( "Vrednost izraza --x je %d\n", --x);
printf( "Vrednost izraza y-- je %d\n", y--) ;
printf( "Nakon dekrementiranja vrednost x-a je %d\n",x);
printf( "Nakon dekrementiranja vrednost y-a je %d\n", y);
}
//Operator dodeljivanja
#include <stdio.h>
void main()
{
int x, y;
x = 6;
y = 6;
if ( x = 7)
{
printf( " Prvi <if> je zadovoljen\n" );
}
else
{
printf( " Prvi <if> nije zadovoljen\n" );
}
if ( y == 7 )
{
printf( " Drugi <if> je zadovoljen\n" );
}
else
printf( " Drugi <if> nije zadovoljen\n" );
}
#include <stdio.h>
void main()
{
long num, sum = 0L;
int status;
printf("Unesite broj za sumiranje\n");
printf("Ili q za izlaz\n");
status = scanf("%ld", &num);
while (status==1)
{
sum = sum+num;
#include <stdio.h>
void main()
{
int broj;
for (broj=1;broj<=20;broj=broj+2)
printf("\n%d",broj);
}
Postavimo sada sledeći zadatak: za zadani prirodan broja treba ispisati sve njegove delitelje.
#include <stdio.h>
int main(void)
{
long num; // broj koji proveravamo
long div; // potencijalni delitelj
unsigned flag = 0; // prim broj?
printf("Unesite celi broj ili q za izlaz: ");
while(scanf("%ld",&num) == 1)
{
for(div=2; (div*div) <= num; ++div)
{
if(num % div == 0)
{
if(div * div != num)
printf("%d je deljiv sa %d i %d\n", num, div,
num/div);
else
printf("%d je deljiv s %d.\n", num, div);
flag=1;
}
}
if(flag == 0) printf("%ld je prom broj.\n",num);
printf("Unesite celi broj ili q za izlaz: ");
}
return 0;
}
U sledećem primeru učitavaju se dva broja i jedan znak koji predstavlja izbor računske operacije. U
zavisnosti od učitanog znaka izvršava se jedna od četiri računske operacije.
#include <stdio.h>
int main(void)
{
float a,b;
char operacija;
printf("Upisati prvi broj: ");
scanf(" %f",&a);
printf("Upisati drugi broj: ");
scanf(" %f",&b);
printf("Upisati operaciju: zbir(z), oduzimanje(o),\n");
printf(" mnozenje(m),deljenje(d) :");
scanf(" %c",&operacija);
if(operacija=='z')
printf("%f\n",a+b);
else if(operacija=='o')
printf("%f\n",a-b);
else if(operacija=='m')
printf("%f\n",a*b);
else if(operacija=='d')
printf("%f\n",a/b);
else
printf("Nedopustena operacija!\n");
return 0;
}
U sledećem primeru učitavaju se dva broja i jedan znak koji predstavlja izbor njihovog odnosa (< manje, >
veće, = jednako ). U zavisnosti od učitanog znaka ispituje se jedan od tri odnosa za poređenje ova dva
broja.Ako je odnos tačan štampati poruku "Izabrali smo pravi odnos brojeva a i b", a ako nije "Izabrali
smo pogresan odnos brojeva a i b". U slučaju da se unese pogrešan znak za poređenje štampati poruku
"Nedopusteni znak za odnos brojeva!" .
#include<stdio.h>
#include <stdio.h>
int main(void)
{
float a,b;
char znak;
printf("Upisati prvi broj: ");
scanf(" %f",&a);
printf("Upisati drugi broj: ");
scanf(" %f",&b);
printf("Upisati znak poredjenja: manje <, vece >,\n");
printf(" jednako = :");
scanf(" %c",&znak);
if(znak=='<')
{if(a<b) printf("Izabrali smo pravi odnos brojeva a i b\n");
else printf("Izabrali smo pogresan odnos brojeva a i b\n");}
else if(znak=='>')
{if(a>b) printf("Izabrali smo pravi odnos brojeva a i b\n");
else printf("Izabrali smo pogresan odnos brojeva a i b\n");}
else if(znak=='=')
{if(a==b) printf("Izabrali smo pravi odnos brojeva a i b\n");
else printf("Izabrali smo pogresan odnos brojeva a i b\n");}
else
{printf("Nedopusteni znak za odnos brojeva!\n");}
return 0;
}
#include <stdio.h>
/* Srednja vrednost upisanih brojeva (razlicitih od 0). */
int main(void)
{
int i=0;
double sum=0.0,x[];
printf(" Upisite niz brojeva !=0, ili nulu za kraj.\n");
printf(" x[0]= "); scanf("%lf",&x);
while (x!=0.0){
sum+=x;
printf(" x[%d]= ",++i);
scanf("%lf",&x);
}
sum/=i;
printf(" Srednja vrednost = %f\n",sum);
return 0;
}
⎧− 1 broj < 0
⎪
s=⎨ 0 broj = 0
⎪ 1 broj > 0
⎩
#include<stdio.h>
void main()
{
int s, broj;
printf("Unesite broj za odredjivanje uslova:");
scanf("%d",&broj);
s=(broj < 0) ? -1 : ((broj==0) ? 0 : 1);
printf("Vrednost izraza za uneti broj %d je s=%d\n",broj,s);
}
RAD SA NIZOVIMA KARAKTERA
//PROGRAM 1.
#include <stdio.h>
int main()
{
printf("Alert: zvucni ili vizuelni signal \a\n");
printf("Po\bvratnik ili b\backspace: sakrij me\b \n");
printf("Upravljacki znak carriage return, \r, pomera aktivnu poziciju do inicijalne pozicije
tekuce linije.\n");
printf("Form feed. \f\n");
printf ("Horizontalni\ttab\n");
printf("Vertikalni tab \v je trikovit, jer mu je ponasanje nije specificirano pod izvesnim
uslovima\n");
return 0;
}
/* Posle unosa sa tastature se za uneti EOF (uglavnom control-D ili control-Z karakter, ali ne
obavezno), stampa 0. Inace, stampa se 1. Akoje Vas input stream baferovan (a verovatno jeste),
onda morate pritisnuti ENTER taster pre nego dobijete izlaznu poruku */
//PROGRAM 2.
#include <stdio.h>
int main()
{
printf("Na mom sistemu vrednost za EOF je %d\n\n", EOF);
return 0;
}
1
//PROGRAM 3.
//PROGRAM 4.
#include<stdio.h>
void main( ) {
char c;
printf("Unesite jedan proizvoljni karakter:");
c = getchar( );
putchar('\n');//Prelazak u novi red
printf("Uneli ste karakter:");
putchar(c);//Stampanje unetog karaktera
putchar('\n');//Prelazak u novi red
}
2
//PROGRAM 5.
//Unos i štampanje karaktera
#include<stdio.h>
void main( ) {
char c[30];
printf("Unesite niz proizvoljnih karaktera:");
gets(c);
printf("\n");//Prelazak u novi red
printf("Uneli ste karakter:");
puts(c);//Stampanje unetog karaktera
printf("\n");//Prelazak u novi red
}
//PROGRAM 6.
//Unos i štampanje karaktera
#include <stdio.h>
main()
{ int vrednost;
vrednost='A';
printf("%s\nkarakter=%3c\nvrednost=%3d\n","Veliko slovo",vrednost,vrednost);
vrednost='a';
printf("%s\nkarakter=%3c\nvrednost=%3d\n","Malo slovo",vrednost,vrednost); }
//PROGRAM 7.
//Unos i štampanje karaktera
#include <stdio.h>
void main()
{
int c1, c2;
c1 = getchar();
printf("------------\n");
c2 = getchar();
3
printf("c1 = %d, c2 = %d\n",c1, c2);
printf("c1 = %c, c2 = %c\n",c1, c2);
putchar(c1); /* isto je kao i printf("%c",c1); */
putchar(c2); /* isto je kao i printf("%c",c2); */
putchar('\n');
/* Za ispisivanje karaktera a */
putchar('a');
/* dozvoljeno je : printf("abc"); printf("a"); */
/* nedozvoljeno je : printf('a'); putchar('abc'); putchar("abc"); */
}
//PROGRAM 8.
//Program čita jedan karakter i ispisuje ga.
#include <stdio.h>
void main()
{
int c; /* Karakter - obratiti paznju na int */
printf("Unesite jedan proizvoljni karakter:");
c = getchar(); /* cita karakter sa standardnog ulaza */
printf("\nUneli ste karakter:");
putchar(c); /* pise karakter zapamćen u promenljivoj c na standardni izlaz */
putchar('\n'); /* prelazak u novi red */
printf("Ispisuje malo a:");
putchar('a'); /* ispisuje malo a */
printf("\nIspisuje ASCI 97:");
putchar(97); /* ekvivalentno prethodnom */
putchar('\n');/* prelazak u novi red */
}
4
//PROGRAM 9.
//Program čita ceo izraz i ispisuje ga.
#include <stdio.h>
int main()
{
char my_string[50];
printf("Otkucaj nesto!\n");
gets(my_string);
printf("Otkucao si:%s\n", my_string);
return 0;
}
//PROGRAM 10.
//Program čita ceo izraz i ispisuje ga pomoću funkcija gets i puts.
#include <stdio.h>
int main()
{
char my_string[500];
printf("Otkucaj nesto!\n");
gets(my_string);
printf("Otkucao si:\n");
puts(my_string);
return 0;
}
5
//PROGRAM 11.
//Unos i štampanje karaktera
Program učitava broj karaktera sa ulaza sve dok se ne otkuca znak za kraj unosa EOF. EOF
se može generisati kucanjem Control /Z.
#include <stdio.h>
main()
{ int ch, i = 0;
//PROGRAM 12.
//Unos i štampanje niza karaktera
/*Program koristi getchar da učita liniju sa standardnog ulaza
stdin, postabvlja takav ulaz u buffer, onda završava string pre
štampanja linije na ekranu. */
#include <stdio.h>
void main( void )
{
char buffer[81];
int i, ch;
printf( "Enter a line: " );
/* Read in single line from "stdin": */
for( i = 0; (i < 80) && ((ch = getchar()) != EOF)
&& (ch != '\n'); i++ )
buffer[i] = (char)ch;
/* Terminate string with null character: */
buffer[i] = '\0';
printf( "%s\n", buffer );
}
6
//PROGRAM 13.
//Unos i štampanje karaktera
Program konvertuje ulazne karaktere u velika slova. Da bi ovo učinili moramo dodati
funkciju toupper iz biblioteke za konverziju karaktera ctype.h
void main()
{ int ch;
while((ch = getchar()) != EOF)
putchar(toupper(ch));
}
//PROGRAM 14.
#include <stdio.h>
void main()
{ char line[256]; /* Definiše string dužine 256 karaktera koji se pamti kao ulazna linija */
7
//PROGRAM 15.
//Unos i štampanje karaktera
//PROGRAM 15.
//Unos i štampanje karaktera
#include <stdio.h>
#include <string.h>
main()
{char linija_teksta[81];
while( fgets(linija_teksta,81, stdin)!= NULL)
/* Unos u liniju teksta se prekida i petlja sa kontrolnim karakterom Ctrl/z */
{continue;}
printf("Linija je : %s\n",linija_teksta);}
8
//PROGRAM 17.
/*(Funkcije getchar(), putchar() ) NCP koji sadržaj standardnog ulaza štampa znak po znak
na standardni izlaz sve do markera kraja ulaza.*/
#include <stdio.h>
main()
{ int znak;
znak=getchar(); /*promenljivoj znak se dodeljuje znak sa ulaza */
while( znak !=EOF) //End of file Ctrl/Z
{ putchar(znak); /*dodeljeni znak se kopira na izlaz */
znak=getchar(); } }
//PROGRAM 18.
#include <stdio.h>
void main()
{
int znak; /*prihvata znak sa ulaza */
long linije=0 ; /*brojac linija */
long br_znak=0; /*brojac znakova na ulazu */
while ( (znak=getchar() ) != EOF)
{ br_znak++;
if (znak=='\n') linije ++;
}
printf("Prelazaka u novi red: %ld, karaktera: %ld \n",linije,br_znak);
}
9
//PROGRAM 19.
10
//PROGRAM 20.
//Unos i štampanje karaktera
#include <stdio.h>
main()
{
char c=' ';
int i;
printf ("\t\tTablica ASCII kodova \n \n");
linija:
i=0;
znak:
printf("%3d %c ",c+i,c+i);
i=i+19;
if (i<95) goto znak;
printf("\n");
c=c+1;
if (c<' '+19) goto linija;
}
//PROGRAM 21.
//NCP koji pronalazi najduzu liniju sa ulaza. Nije poznat ukupan broj linija, ali svaka linija
nema vise od 80 karaktera ( izlaz CTRL/Z).
#include <stdio.h>
#include <string.h>
#define MAX_DUZINA_LINIJE 81
main()
11
{
char linija[MAX_DUZINA_LINIJE];
char najduza_linija[MAX_DUZINA_LINIJE];
int duzina_linije = 0;
int duzina_najduze_linije = 0;
najduza_linija[0] = '\0';
while( fgets(linija, MAX_DUZINA_LINIJE, stdin) != NULL)
{
duzina_linije=strlen(linija);
if (duzina_linije>duzina_najduze_linije)
{strcpy(najduza_linija, linija);
duzina_najduze_linije = duzina_linije;}
}
printf("Najduza linija je : %s\n",najduza_linija);
}
//PROGRAM 22.
// NCP koji stampa liniju sa ulaza pod uslovom da linija nema vise od 80 karaktera.
#include <stdio.h>
void main( void )
{
char buffer[81];
int i, ch;
12
//PROGRAM 23.
//PROGRAM 24.
/*Uraditi program za unos niza karaktera ”Moram da položim drugi kolokvijum iz Programskih
jezika 1” u vektor Niz1. Odštampati ovaj niz karaktera u potpunoj formi, i izračunati dužinu ovog
unetog niza. Iskopirati sadržaj vektora Niz1 u vektror Niz2 i utvrditi dali su to isti nizovi.
Prebrojati koliko praznina (blanko karaktera) ima u nizu Niz1.*/
#include <stdio.h>
#include <string.h>
void main()
{ int brojznak=0,i=0;
char Niz1[81],Niz2[81];
printf("Unesi clanove niza Niz1, za kraj Ctrl/z/");
while( fgets(Niz1,81, stdin)!= NULL)
/* Unos u liniju teksta se prekida i petlja sa kontrolnim karakterom Ctrl/z */
{continue;}
printf("Linija niza Niz1 je : %s\n",Niz1);
printf("\nDuzina niza po broju karaktera je:%d\n",(strlen(Niz1)-1));
strcpy(Niz2,Niz1);
printf("Linija niza Niz2 je : %s\n",Niz2);
13
if (strcmp(Niz1,Niz2)==0)//Komparacija-uporedjivanje dva niza
{ printf("Ovo su jednaki NIZOVI!\n");}
else
printf("Ovo nisu jednaki NIZOVI!\n");
while (Niz1[i]!='\n')
{ if(Niz1[i]==' ')brojznak++;i=i+1;}
printf("Broj blanko znakova u nizu Niz1 je:%ld \n",brojznak); }
//PROGRAM 25.
/*Sastaviti program koji iz skupa unetih karaktera ( naPRIMER: rečenice ’’Ja sam rodjen
1990. god u 12. mesecu, i u petak!!’’izračunava broj unetih slova, brojeva i ostalih
karaktera.*/
#include<stdio.h>
#include<conio.h>
main( )
{
int slovo, broj, ostalo, c;
slovo = broj = ostalo = 0;
while( (c=getchar( )) != EOF )
if( ('A'<=c && c<='Z') || ('a'<=c && c<='z') )
++ slovo;
else if( '0'<=c && c<='9' ) ++broj;
else ++ostalo;
printf("Uneli ste:%d slova, %d brojeva,%d ostalih\n", slovo, broj, ostalo);
}
//PROGRAM 26.
//Formatiranje izlaza
14
#include <stdio.h>
#define IME "Srbija"
#define ADRESA "Ul. Beogradska 20."
#define MESTO "18000 Nis"
#define LIMIT 65
void main()
{void zvezde(void);/*deklaracija funkcije bez argumenata*/
zvezde(); /*poziv korisnicke funkcije */
printf("%s \n ",IME) ; /*poziv funkcije iz standardne biblioteke*/
printf("%s\n", ADRESA);
printf("%s\n", MESTO) ;
zvezde ( ) ;} /*definicija korisnicke funkcije */
void zvezde() /*funkcija nema argumenata*/
{ int brojac;
for(brojac=l;brojac<=LIMIT;brojac++)
putchar ( '*' );
putchar ( '\n' ) ; }
//PROGRAM 27.
//Program koji kopira ulaz svakog karaktera direktno na izlaz. `%' označava kraj ulaza.
#include <stdio.h>
void main( ) {
char c;
while( (c=getchar( )) != '%' )
putchar(c);
}
15
//PROGRAM 28.
//Program konvertuje velika u mala slova
#include <stdio.h>
void main( ) {
char c;
while( (c=getchar( )) != '%' )
if( 'A'<=c && c<='Z' )
putchar(c+'a'-'A');
else
putchar(c);
}
//PROGRAM 29.
//Program broji karaktere, brojeve i praznine u tekstu. Završava se unosom %.
#include <stdio.h>
void main( ) {
int let, dig, other, c;
let = dig = other = 0;
while( (c=getchar( )) != '%' )
if( ('A'<=c && c<='Z') || ('a'<=c && c<='z') )
++let;
else if( '0'<=c && c<='9' ) ++dig;
else ++other;
printf("%d slova, %d broja, %d ostalih karaktera\n", let, dig, other);
16
//PROGRAM 30.
//Izračunavanje dužine zapisanog stringa, IZLAZ ENTER.
#include <stdio.h>
void main( ) {
int n, c;
char line[100];
n = 0;
while( (c=getchar( )) != '\n' ) {
if( n < 100 )
line[n] = c;
n++;
}
printf("duzina stringe je: = %d\n", n);
}
//PROGRAM 31.
//Dužina stringa sa izlazom ENTER
void main( ) {
int n;
char line[100];
n = 0;
while( (line[n++]=getchar( )) != '\n' );// Karakter \n kao ENTER za kraj
line[n] = '\0';
printf("Duzine stringa je %d:\t%s", n, line);
}
17
OPŠTI ZADACI
#include<stdio.h>
#include<math.h>
void main()
{int a,b,c,m;
printf("\nUnesite vrednosti za a , b i c\n");
scanf("%d%d%d",&a,&b,&c);
m=a;
if(b<m) m=b;
if(c<m) m=c;
printf("Minimum brojeva a=%d b=%d i c=%d je broj %d\n",a,b,c,m);}
18
/2.3* Program za permutovanje cifara
nenegativriog celog broja - do-while iskaz */
#include<stdio.h>
#include<math.h>
void main()
{int broj;
printf("Ukucajte ceo broj ? ");
scanf("%d", &broj );
printf("Permutovani broj je ");
do
{printf("%d", broj%10);
broj =broj/10;}
while (broj);
printf("\n"); }
/2.4* Program za odredjivanje srednje vrednosti n celih pozitivnih brojeva -for iskaz */
#include<stdio.h>
#include<math.h>
void main()
{
int n,brojac;
float suma =0, x ;
printf("Ukupno brojeva ? ");
scanf("%d", &n);
for (brojac=1 ; brojac<=n; ++brojac, suma+=x )
{
printf("Ukucajte %d broj ?",brojac);
scanf("%f",&x);
}
printf("Srednja vrednost ovih brojeva je %f\n", suma/n);
}
19
/2.5* Program za izracunavanje faktorijela */
#include <stdio.h>
#include <math.h>
void main()
{
int i, n;
long fak = 1;
printf("lzracunavanje n!\nUkucajte broj ? ");
scanf("%d", &n);
for ( i=1; i<=n; ++i)
fak *= i;
printf("%d! = %ld\n", n, fak);
}
#include <stdio.h>
#include <math.h>
void main()
{
float operand1, operand2;
char op;
printf("Ukucajle lzraz ? \n");
scanf("%f%c%f", &operand1, &op, &operand2);
switch (op)
{
case '+':
printf("%f\n", operand1+operand2);
break;
case '-':
printf("%f\n", operand1-operand2 );
20
break;
case '*':
printf("%f\n", operand1*operand2 );
break;
case '/':
printf("%f\n", operand1/operand2);
break;
default:
printf("Nepoznat operator\n");
}}
#include <stdio.h>
void main( )
{ int c, prazno=0, interp=0;
while((c=getchar())!=EOF)
switch(c)
{ case ' ':
prazno++;
break;
case '.':
case ',':
case ':':
case ';':
interp++;
break;
default:
break; }
printf("\nBroj praznina: %d", prazno);
printf("\nBroj znakova tacka, zarez, dvotacka i tacka-zarez: %d\n", interp); }
21
#include<stdio.h>
#include<math.h>
void main()
{
static int mat[2][3]={{0,1,2},{3,4,5}};
int i,j;
for(i=1;i<=2;++i)
{
printf("Elementi %d.reda su:\n",i);
for(j=1;j<=3;++j)
printf("kolona%d:%d\n",j,mat[i-1][j-1]);
}
printf("\n");
}
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Članove matrice uneti u program kao konstantne celobrojne veličine, a kao izlaz iz
programa predvideti štampanje ove matrice u pokazanom formatu kao polazne matrice i
štampanje nove matrice u istom obliku ali čiji su svi članovi sada pomnoženi skalarom 2.
22
{
for(j=0;j<4;j++)
{printf("%2d ",2*mat[i][j]);}printf("\n");}}
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Članove matrice uneti u program kao konstantne celobrojne veličine, a kao izlaz iz
programa predvideti štampanje ove matrice u pokazanom formatu kao polazne matrice i
štampanje nove matrice u istom obliku ali sada unazad od člana a44,a43,a42a41,......,a11.
23
2.11 Napisati program na C++ jeziku koji izračunava sumu svih elemenata u svakom redu
pojedinačno, pravougaone matrice [4x4].
1 2 3 4
5 6 7 8
A=
9 10 11 12
13 14 15 16
#include<stdio.h>
#include<math.h>
void main()
{int mat[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int i,j,s=0;
printf("\nPolazna matrica je\n");
for(i=0;i<4; i++)
{
for(j=0;j<4; j++)
{printf("%2d ",mat[i][j]);}printf("\n");}
for(i=0;i<4; i++)
{printf("\nSuma %d reda je:",i+1);
for(j=0;j<4; j++)
{s=s+mat[i][j];}
printf("%2d\n",s);s=0;}
return 0;}
24
2.12 NCP koji sa standardnog ulaza učitava 3x3 matricu i ispisuje je na standardni izlaz tako
da centralno polje a[1][1] bude jednako sumi gornjeg levog (a[0][0]) i donjeg desnog polja
(a[2][2]). Pre ucitavanja popuniti matricu proizvoljnim vrednostima.
#include <stdio.h>
void main()
{
int a[3][3] = {{0, 1, 2}, {10, 11, 12}, {20, 21, 22}}; /* deklaracija i inicijalizacija matrice a, može
se uraditi za konkretan primer date matrice*/
int i, j; /*brojaci u ciklusu */
/* unos elemenata matrice */
for(i=0; i<3; i++)
for(j=0; j<3; j++)
{
printf("\na[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
printf("\n*******************\n");
a[1][1] = a[0][0] + a[2][2]; /* 0 + 22 = 22 */
/*ispis matrice */
for(i=0; i<3; i++)
{
for(j=0; j<3; j++) printf("%d\t", a[i][j]);
printf("\n");
}
}
25
2.13 Neka je data kvadratna matrica u formatu:
a11 a12 a13
a 21 a 22 a 23
a31 a32 a33
Uneti članove matrice u program kao celobrojne veličine, a kao izlaz iz programa
predvideti štampanje takve matrice u pokazanom formatu kao i štampanje izračunate
vrednosti njene determinante urađene preko funkcije.
#include<stdio.h>
#include<math.h>
#include<iomanip.h>
main()
{static int mat[4][4];
int i,j;
float delta;
printf("Unesite proizvoljne elemente pravougle matrice:\n");
for(i=0;i<4;++i)
for(j=0;j<4;++j)
{printf("a[%d][%d]=",i,j);
scanf("%d",&mat[i][j]);printf("\n");}
printf("\nPolazna matrica je\n");
for(i=0;i<4;++i)
{for(j=0;j<4;++j)
printf("%3d ",mat[i][j]);printf("\n");}
printf("\nDeterminanta sistema je:\n");
delta=mat[0][0]*((mat[1][1]*mat[2][2]*mat[3][3]
26
+mat[1][2]*mat[2][3]*mat[3][1]
+mat[2][1]*mat[3][2]*mat[1][3])
-(mat[1][3]*mat[2][2]*mat[3][1]
+mat[1][1]*mat[2][3]*mat[3][2]
+mat[1][2]*mat[2][1]*mat[3][3]))-
mat[0][1]*((mat[1][0]*mat[2][2]*mat[3][3]
+mat[1][2]*mat[2][3]*mat[3][0]
+mat[2][0]*mat[3][2]*mat[1][3])
-(mat[1][3]*mat[2][2]*mat[3][0]
+mat[1][0]*mat[2][3]*mat[3][2]
+mat[1][2]*mat[2][0]*mat[3][3]))+
mat[0][2]*((mat[1][0]*mat[2][1]*mat[3][3]
+mat[1][3]*mat[2][0]*mat[3][1]
+mat[2][0]*mat[3][1]*mat[1][3])
-(mat[1][3]*mat[2][1]*mat[3][0]
+mat[3][1]*mat[2][3]*mat[1][0]
+mat[1][1]*mat[2][0]*mat[3][3]))-
mat[0][3]*((mat[1][0]*mat[2][1]*mat[3][2]
+mat[1][1]*mat[2][2]*mat[3][0]
+mat[2][0]*mat[3][1]*mat[1][2])
-(mat[1][2]*mat[2][1]*mat[3][0]
+mat[3][1]*mat[2][2]*mat[1][0]
+mat[1][1]*mat[2][0]*mat[3][2]));
printf("Vrednost determinante je :%f",delta);
return 0;}
27
Napomena: radi se o integer veličinama ali voditi računa da ne dođe do preopterećenja
memorije!
#include<stdio.h>
#include<math.h>
main()
{int i,n;
float F=1,S=1;
printf("Unesite verdnost za n\n n=");
scanf("%d",&n);
for(i=2;i<=n;i++)
{F=F*i;
S=S*F;};
printf("\nRezultat proizvoda i! je S=%lf\n",S);
return 0;}
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i,R;
long int P=1;
printf("Tri slucajna broja od 0 do 99 su:\n\n");
for(i=0; i<3; i++)
{R= rand()% 100;
printf("%d\n",R );
P=R*P;}
printf("Proizvod prva 3 slucajna broja je: %d\n", P);
return 0;
}
28
2.16 U sledećem primeru učitavaju se dva broja i jedan znak koji predstavlja izbor njihovog
odnosa (< manje, > veće, = jednako ). U zavisnosti od učitanog znaka ispituje se jedan
od tri odnosa za poređenje ova dva broja. Ako je odnos tačan štampati poruku "Izabrali smo
pravi odnos brojeva a i b", a ako nije "Izabrali smo pogresan odnos brojeva a i b". U
slučaju da se unese pogrešan znak za poređenje štampati poruku "Nedopusteni znak za odnos
brojeva!" .
#include <stdio.h>
int main(void)
{
float a,b;
char operacija;
printf("Upisati prvi broj: ");
scanf(" %f",&a);
printf("Upisati drugi broj: ");
scanf(" %f",&b);
printf("Upisati operaciju: zbir(z), oduzimanje(o),\n");
printf(" mnozenje(m),deljenje(d) :");
scanf(" %c",&operacija);
if(operacija=='z')
printf("%f\n",a+b);
else if(operacija=='o')
printf("%f\n",a-b);
else if(operacija=='m')
printf("%f\n",a*b);
else if(operacija=='d')
printf("%f\n",a/b);
else
printf("Nedopustena operacija!\n");
return 0;
}
#include<stdio.h>
#include <stdio.h>
#include <math.h>
float main(void)
{
float a,b,c,p,PTROUGLA;
29
printf("Upisati broj a: ");
scanf(" %f",&a);
printf("Upisati broj b: ");
scanf(" %f",&b);
printf("Upisati broj c: ");
scanf(" %f",&c);
p=(a+b+c)/2.;
printf("Vrednost prolazne promenljive je:%f\n",p);
PTROUGLA=sqrt(p*(p-a)*(p-b)*(p-c));
printf("Povrsina trougla izracunata datim obrascem je:%f\n",PTROUGLA);
return 0;
}
2.18 U sledećem primeru učitavaju se dva broja i jedan znak koji predstavlja izbor njihovog
odnosa (< manje, > veće, = jednako ). U zavisnosti od učitanog znaka ispituje se jedan
od tri odnosa za poređenje ova dva broja. Ako je odnos tačan štampati poruku "Izabrali smo
pravi odnos brojeva a i b", a ako nije "Izabrali smo pogresan odnos brojeva a i b". U
slučaju da se unese pogrešan znak za poređenje štampati poruku "Nedopusteni znak za odnos
brojeva!" .
#include<stdio.h>
#include <stdio.h>
int main(void)
{
float a,b;
char znak;
printf("Upisati prvi broj: ");
scanf(" %f",&a);
printf("Upisati drugi broj: ");
scanf(" %f",&b);
printf("Upisati znak poredjenja: manje <, vece >,\n");
printf(" jednako = :");
scanf(" %c",&znak);
if(znak=='<')
{if(a<b) printf("Izabrali smo pravi odnos brojeva a i b\n");
else printf("Izabrali smo pogresan odnos brojeva a i b\n");}
else if(znak=='>')
{if(a>b) printf("Izabrali smo pravi odnos brojeva a i b\n");
else printf("Izabrali smo pogresan odnos brojeva a i b\n");}
else if(znak=='=')
{if(a==b) printf("Izabrali smo pravi odnos brojeva a i b\n");
30
else printf("Izabrali smo pogresan odnos brojeva a i b\n");}
else
{printf("Nedopusteni znak za odnos brojeva!\n");}
return 0;
}
FUNKCIJE
1. Pokazati kako funkcioniše prototip funkcije.
#include<stdio.h>
myfunc();/*inicijalizacija funkcije bez argumenata*/
void main()
{
myfunc();/*pozivanje funkcije bez argumenata*/
}
myfunc()/*definisanje funkcije bez argumenata*/
{
printf("ZDRAVO, ovo je test\n");
return 0;}
31
#include<stdio.h>
napisi(int count);
void main()
{napisi(4);}
napisi(int count)
{
int c;
for(c=0;c<count;c++)
printf("\nZDRAVO");
return 0;}
3. Test funkcije
#include<stdio.h>
test();
void main()
{
printf("Ulazimo unutar test funkcije\n");
test();
printf("\nVracamo se iz test funkcije\n");
}
test()
{
int a,b;a=100;
b=a+100;
printf("a je %d i b je %d",a,b);
return 0;}
4. Naći minimum od dva cela broja. U glavnom programu obezbediti štampanje, a u funkciji
njihovo poređenje.
#include<stdio.h>
int imin(int n,int m);
void main()/* glavni program */
{ int broj1,broj2,vrati;
printf("Unesite dva cela broja\n");
32
vrati=scanf("%d %d",&broj1,&broj2);
if(vrati==2)
printf("Manji od %d i %d je %d\n",broj1,broj2,imin(broj1,broj2));}
#include<stdio.h>
int min(int a, int b);
main()
{
int m;
m=min(3,6);
printf("Minimum je %d\n",m);
return 0;
}
33
6. Formiranje zbira preko funkcije
#include <iostream.h>
7.Uraditi meni sa izborom operacija za sabiranje, oduzimanje i množenje dva cela realna
broja. U funkciji izvesti opisane računske radnje.
#include<stdio.h>
#include<stdlib.h>
add();
subtract();
multiply();
void main()
{
int choice;
while(1)
{
printf("\n\nMenu:\n");
34
printf("1- Add\n2- Subtract\n");
printf("3- Multiply\n4- Exit");
printf("\n\nYour choice -> ");
scanf("%d",&choice);
switch(choice)
{ case 1 : add();
break;
case 2 : subtract();
break;
case 3 : multiply();
break;
case 4 : printf("\nProgram Ends. !");
exit(0);
default:
printf("\nInvalid choice");
}
}
}
add()
{
float a,b;
printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
printf("a+b=%f",a+b);
return 0;}
subtract()
{
float a,b;
printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
printf("a-b=%f",a-b);
return 0;}
multiply()
{
float a,b;
printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
printf("a*b=%f",a*b);
return 0;}
35
8. Pozivanje funkcije po vrednosti
/*Pozivanje po vrednosti*/
#include<stdio.h>
void test(int a);
main()
{
int m;
m=2;
printf("\nM je %d",m);
test(m);
printf("\nM je %d",m);
return 0;
}
void test(int a)
{
a=5;}
#include<stdio.h>
#include<math.h>
mno();
sab();
36
void main()
{ mno();
sab();}
mno()
{float a,b;
printf("\nUnesite vrednosti za a i b\n");
scanf("%f%f",&a,&b);
printf("a*b=%f",a*b);
return 0;}
sab()
{float a,b;
printf("\nUnesite vrednosti za a i b\n");
scanf("%f%f",&a,&b);
printf("a+b=%f",a+b);
return 0;}
#include<stdio.h>
#include<math.h>
min();
void main()
{ min();}
min()
{int a,b,c,m;
printf("\nUnesite vrednosti za a , b i c\n");
scanf("%d%d%d",&a,&b,&c);
m=a;
if(b<m) m=b;
if(c<m) m=c;
printf("Minimum brojeva a=%d b=%d i c=%d je broj %d\n",a,b,c,m);
return 0;}
37
11.Poziv funkcije salje vrednost promenljive m funkciji a ne salje promenljivu samu sebi:
m=2, M=2
/*Pozivanje po referenci*/
#include<stdio.h>
void test(int *ptr);
main()
{
int m;
m=2;
printf("\nM je %d",m);
test(&m);
printf("\nM je %d",m);
return 0;
}
void main( )
{
38
suma_kvadrata(10);
suma_kvadrata(15);
suma_kvadrata(20);
}
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
void main()
{
float delta,a,b,c,x1,x2;
printf("Enter a : ");
scanf("%f",&a);
printf("Enter b : ");
scanf("%f",&b);
printf("Enter c : ");
scanf("%f",&c);
delta=b*b-(4*a*c);
if(delta<0)
{
printf("Jednacina NEMA resenja !\n");
exit(0);//Potrebna hederska funkcija stdlib
}
if(delta==0)
{
x1=-b/(2*a);
printf("Jednacina IMA dva ista resenja !\n");
printf("x1=x2=%f",x1);
exit(0);
}
39
x1=(-b+sqrt(delta))/(2*a);
x2=(-b-sqrt(delta))/(2*a);
printf("\nX1=%f",x1);
printf("\nX2=%f\n",x2);
}
#include <stdio.h>
#define IME "VTS"
#define ADRESA "Ul. Generala Medvedeva 20."
#define MESTO "18000 Nis"
#define LIMIT 65
40
void zvezde();
void main()
{ void zvezde(); /*deklaracija funkcije bez argumenata*/
zvezde(); /*poziv korisnicke funkcije */
printf("%s \n ", IME) ; /*poziv funkcije iz standardne biblioteke*/
printf("%s\n", ADRESA);
printf("%s\n", MESTO) ;
zvezde ( ) ; }
/*definicija korisnicke funkcije */
void zvezde() /*funkcija nema argumenata*/
{ int brojac;
for(brojac=1;brojac<=LIMIT;brojac++)
putchar ( '*' );
putchar ( '\n' ) ; }
void Hipotenuza(void)
{c=sqrt(a*a+b*b);}
void Ucitaj(void)
{printf("Prva kateta:");
scanf("%lf",&a);
printf("Druga kateta:");
scanf("%lf",&b);}
41
17. Primer za izracunavanje y=sin2(x)+cos2(x)
#include<stdio.h>
#include<math.h>
double Funkcija(double x);
void main()
{double x,y;/* deklaracija lokalnih promenljivih, posle pocetka programa*/
printf("Unesite vrednost za x:");
scanf("%lf",&x);
y=Funkcija(x);
printf("Vrednost funkcije je %f.",y);}
double Funkcija(double x)
{double y;
y=sin(x)*sin(x)+cos(x)*cos(x);
return y;}
42
19. Neka je data kvadratna matrica u formatu:
43
20.Četiri računske radnje preko funkcije choice i switch naredbi.
#include<stdio.h>
#include<stdlib.h>
void add(void);
void subtract(void);
void multiply(void);
void divide(void);
float a,b,rezultat;
void main()
{int choice;
while(1)
{
printf("\n\nMenu:\n");
printf("1- Add\n2- Subtract\n");
printf("3- Multiply\n4- Divide\n5-Exit");
printf("\n\nYour choice -> ");
scanf("%d",&choice);
switch(choice)
{ case 1 : add();printf("Rezultat operacije je:%f\n",rezultat);
break;
case 2 : subtract();printf("Rezultat operacije je:%f\n",rezultat);
break;
case 3 : multiply();printf("Rezultat operacije je:%f\n",rezultat);
break;
case 4 : divide();printf("Rezultat operacije je:%f\n",rezultat);
break;
case 5 : printf("\nProgram Ends. !");
exit(0);
default:
printf("\nInvalid choice");}
}}
void add(void)
{printf("\nEnter a:");
44
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
rezultat=(a+b);}
void subtract(void)
{printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
rezultat=(a-b);}
void multiply(void)
{printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
rezultat=(a*b);}
void divide(void)
{printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
rezultat=(a/b);}
45
PRIMERI PROGRAMA ZA PRIPREMU PRVOG
KOLOKVIJUMA
1
1. ULAZ - IZLAZ
2
Zadatak 4: Formatiranje ulaza u pokretnom zarezu
void main()
{
/* deklaracija podataka */
float f_pro;
double d_pro;
/*dodela vrednosti*/
f_pro=106.11;
d_pro=-0.0000654;
/*stampanje vrednosti promenljivih */
printf ("Promenljiva f_pro=%2f\n", f_pro);
printf ("Promenljiva d_pro=%.11f\n", d_pro);
printf ("Promenljiva f_pro=%e\n", f_pro);
printf ("Promenljiva d_pro=%G\n", d_pro) ;
}
3
2. OPERATORI
x = 10; y =10;
printf( "Vrednost izraza --x je %d\n", --x);
printf( "Vrednost izraza y-- je %d\n", y--) ;
printf( "Nakon dekrementiranja vrednost x je %d\n",x);
printf( "Nakon dekrementiranja vrednost y je %d\n", y);
}
#include<stdio.h>
void main()
{
int s, broj;
printf("Unesite broj za odredjivanje uslova:");
scanf("%d",&broj);
s=(broj < 0) ? -1 : ((broj==0) ? 0 : 1);
printf("Vrednost izraza za uneti broj %d je s = %d\n",broj,s);
}
4
3. IF NAREDBA
5
else if(choice==2)
printf("\nProgram finansija Runs. !");
else if(choice==3)
printf("\nProgram zabave Runs. !");
else if(choice==4)
{
printf("\nKraj programa!.\n");
exit(0);
}
else
printf("\nPogresan izbor");
}
Napisati program koji de unetu cifru ispisiati Morzeovom azbukom. Sldeda tablica prikazuje izgled cifre
prevedene na Morzeovu azbuku:
0 "-----"
1 (".----"
2 "..---"
3 "...--"
4 "....-"
5 "....."
6 "-...."
7 "--..."
8 "---.."
9 "----.")
int main()
{
int broj;
printf("Unesi jedan broj izmedju 0 i 9:");
scanf("%d",&broj);
if((broj<0)||(broj>9))
printf("Broj nije u opsegu izmedju 0 i 9\n");
else
{
printf("Broj %d prikazan Morzeovom azbukom je:",broj);
if(broj==0) printf("-----");
if(broj==1) printf(".----");
if(broj==2) printf("..---");
if(broj==3) printf("...--");
if(broj==4) printf("....-");
if(broj==5) printf(".....");
if(broj==6) printf("-....");
if(broj==7) printf("--...");
if(broj==8) printf("---..");
if(broj==9) printf("----.");
}
printf("\n\n");
}
Zadatak 12: U sledećem primeru učitavaju se dva broja i jedan znak koji predstavlja izbor
njihovog odnosa (< manje, > veće, = jednako ). U zavisnosti od učitanog znaka ispituje se
jedan od tri odnosa za poreĎenje ova dva broja. Ako je odnos tačan štampati poruku
"Izabrali smo pravi odnos brojeva a i b", a ako nije "Izabrali smo pogresan odnos brojeva a i
b". U slučaju da se unese pogrešan znak za poreĎenje štampati poruku "Nedopusteni znak za
odnos brojeva!" .
int main(void)
{
float a,b;
char znak;
printf("Upisati prvi broj: ");
6
scanf(" %f",&a);
printf("Upisati drugi broj: ");
scanf(" %f",&b);
printf("Upisati znak poredjenja: manje <, vece >,\n");
printf(" jednako = :");
scanf(" %c",&znak);
if(znak=='<')
{
if(a<b) printf("Izabrali smo pravi odnos brojeva a i b\n");
else printf("Izabrali smo pogresan odnos brojeva a i b\n");
}
else if(znak=='>')
{
if(a>b) printf("Izabrali smo pravi odnos brojeva a i b\n");
else printf("Izabrali smo pogresan odnos brojeva a i b\n");
}
else if(znak=='=')
{
if(a==b) printf("Izabrali smo pravi odnos brojeva a i b\n");
else printf("Izabrali smo pogresan odnos brojeva a i b\n");
}
else
printf("Nedopusteni znak za odnos brojeva!\n");
return 0;
}
Zadatak 13: U sledećem primeru učitavaju se dva broja i jedan znak koji predstavlja izbor
računske operacije (s za sabiranje, o za oduzimanje, m za množenje i d za deljenje). U
zavisnosti od učitanog znaka izvršava se jedna od četiri računske operacije i štampanje
rezultata.
int main(void)
{
float a,b;
char operacija;
printf("Upisati prvi broj: ");
scanf(" %f",&a);
printf("Upisati drugi broj: ");
scanf(" %f",&b);
printf("Upisati operaciju: zbir(z), oduzimanje(o),\n");
printf(" mnozenje(m),deljenje(d) :");
scanf(" %c",&operacija);
if(operacija=='z')
printf("%f\n",a+b);
else if(operacija=='o')
printf("%f\n",a-b);
else if(operacija=='m')
printf("%f\n",a*b);
else if(operacija=='d')
printf("%f\n",a/b);
else
printf("Nedopustena operacija!\n");
return 0;
}
7
Zadatak 14: Izračunavanje vrednosti funkcije
Sastaviti dijagram toka i napisati program kojim se izračunava vrednost funkcije:
x, x2
y 2, 2 x 3 .
x 1, x 3
if (x < 2)
y = x;
else if(x>=2 && x<3)
y = 2;
else
y = x-1;
8
4. POMOĆNE FUNKCIJE
Zadatak 15: Primeri korišćenja funkcija abs, exp, log, sin. sqrt
#include <math.h>
#include <stdio.h>
void main(void)
{
int number = -1234;
double x = 4.0, y = 8.6872, result, z = 0.5;
int main(void)
{
double x = 2.0, y = 3.0;
printf("%lf na stepen %lf je %lf\n", x, y, pow(x, y));
return 0;
}
int main(void)
{
double result;
double x = 100;
result = log10(x);
printf("LOGARITAM BROJA %lf JE %lf\n", x, result);
return 0;
}
9
Zadatak 19: rand funkcija za PRIMER GENERISANJA SLUCAJNIH BROJEVA
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(void)
{
int i;
/* initialize random seed: */
srand (time(NULL));
slucajan = rand();
dvostruki = slucajan*2;
x = rand() % 10; /*slucajan izmedju 0 i 9*/
y = rand() % 10 + 10; /*slucajan izmedju 10 i 19*/
printf("Slucajan broj je %d\n", slucajan);
printf("Dvostruki slucajan broj je %d\n", dvostruki);
printf("Jos neki slucajni brojevi %d, \t %d \n", x, y);
}
10
scanf("%lf%lf%lf", &a, &b, &c);
pom = sqrt(b*b-4*a*c);
x1 = ( (-b) + pom ) / 2 * a;
x2 = ( (-b) - pom ) / 2 * a;
printf("Vrednost prvog korena x1 = %f\n",x1);
printf("Vrednost drugog korena x2 = %f\n",x2);
}
float main(void)
{
float a,b,c,p,PTROUGLA;
printf("Upisati broj a: ");
scanf(" %f",&a);
printf("Upisati broj b: ");
scanf(" %f",&b);
printf("Upisati broj c: ");
scanf(" %f",&c);
p=(a+b+c)/2.;
printf("Vrednost prolazne promenljive je:%f\n",p);
PTROUGLA=sqrt(p*(p-a)*(p-b)*(p-c));
printf("Povrsina trougla izracunata datim obrascem je:%f\n",PTROUGLA);
return 0;
}
11
5. SWITCH – CASE NAREDBA
Zadatak 24: Naredba break sa naredbom switch. Uneti neki tekst. Unos teksta prekinuti
unošenjem znaka #. Izbrojati koliko kojih samoglasnika ima u unetom tekstu.
#include <stdio.h>
void main()
{
char ch;
int a_ct,e_ct,i_ct,o_ct,u_ct; a_ct=e_ct=i_ct=o_ct=u_ct=0;
printf("Unesi priozvoljan tekst; Unesi # za izlaz.\n");
while((ch=getchar())!= '#')
{
switch (ch)
{
case 'a' :
case 'A' : a_ct++;
break;
case 'e' :
case 'E' : e_ct++;
break;
case 'i' :
case 'I' : i_ct++;
break;
case 'o' :
case 'O' : o_ct++;
break;
case 'u' :
case 'U' : u_ct++;
break;
default: break;
} /* kraj switch */
} /* dok petlji nije kraj */
printf("Broj samoglasnika: \n A %d\n E %d\n I %d\n O %d\n U %d\n\n",
a_ct,e_ct,i_ct,o_ct,u_ct);
}
12
6. FOR PETLJA
Zadatak 26: Napisati program koji računa proizvod 5 slučajno izabranih jednocifrenih
brojeva.
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
int main(void)
{
int i,R;
long int P=1;
srand(time(NULL));
printf("Pet slucajnih brojeva izmedju 0 i 9 su: \n\n\n");
for(i=0; i<5; i++)
{
R= rand() % 10;
printf("%d\n",R );
P=R*P;
}
printf("Proizvod 5 slucajnih brojeva je: %d\n\n\n", P);
return 0;
}
Zadatak 27: Odštampati sve neparne brojeve manje od 200 koristeći for petlju:
#include <stdio.h>
void main()
{
int broj;
for (broj=1; broj<=200; broj=broj+2)
printf("\n%d",broj);
}
Zadatak 28:
1. Napisati program koji štampa tablicu množenja (od 1*1 do 9*9 tako da kao rezultat
dobijete tablicu koja ima 9 redova i 9 kolona).
#include<stdio.h>
void main()
{
int i,j;
for(i=1;i<10;i++)
{
for(j=1;j<10;j++)
printf("%3d",i*j);
printf("\n");
}
}
13
Zadatak 29: Napisati program koji računa faktorijel unetog broja (N! = 1*2*3*...* (N-1) *N)
void main()
{
int i, n;
long fak = 1;
printf("lzracunavanje n!\nUkucajte broj ? ");
scanf("%d", &n);
for ( i=1; i<=n; ++i)
fak *= i;
printf("%4d! = %ld\n", n, fak);
}
Zadatak 30: Napisati program koji računa aritmetičku sredinu za n proizvoljno unetih
realnih brojeva.
void main()
{
int n, brojac;
float suma = 0, x;
printf("Ukupno brojeva ?");
scanf("%d", &n);
for ( brojac=1; brojac<=n; ++brojac)
{
printf("Ukucajte %d broj ?", brojac);
scanf("%f",&x);
suma+=x;
}
printf("Srednja vrednost ovih brojeva je %4.2f\n", suma/n);
}
14
Zadatak 32: Štampanje vrednosti stepena Farenhajta i Celzijusa pocev od 0 do 300 sa
korakom 20
#include <stdio.h>
int main()
{
int fahr;
for (fahr = 300; fahr >= 0; fahr = fahr - 20)
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
return 0;
}
15
7. WHILE i DO WHILE PETLJE
Zadatak 33: Izračunajte zbira n proizvoljno unetih celih brojeva korišćenjem while petlje.
#include <stdio.h>
void main()
{
long sum = 0L;
int num;
printf("Unesite broj za sumiranje Ili 0 za izlaz\n");
scanf("%ld", &num);
while (num != 0)
{
sum = sum+num;
printf("Unesite naredni broj za sabiranj ili 0 za quite :::::::: %d
\n ", num);
scanf("%ld", &num);
}
printf("Zbir unetih brojeva je %ld.\n", sum);
}
Zadatak 35: Napisati program koji računa srednju vrednosti n realnih brojeva pomoću
while petlje.
void main()
{
int n, brojac = 0;
float suma = 0, x;
printf("Ukupno brojeva? ");
scanf("%d", &n);
while (brojac < n)
{
printf("Ukucajte %d. broj ? ", brojac+1);
scanf("%f", &x );
suma += x ;
brojac += 1;
}
printf("Srednja vrednost ovih brojeva je %f\n", suma/n);
}
Zadatak 36: Program za permutovanje cifara celog broja - while iskaz (npr. 54321 u 12345 )
Postupak: celi broj 54321 delimo po modulu 10 - rezultat je 1
celi broj 54321 delimo sa 10 - rezultat je 5432
celi broj 5432 delimo po modulu 10 - rezultat je 2
celi broj 5432 delimo sa 10 - rezultat je 543
celi broj 543 delimo po modulu 10 - rezultat je 3
16
celi broj 543 delimo sa 10 - rezultat je 54
celi broj 54 delimo po modulu 10 - rezultat je 4
celi broj 54 delimo sa 10 - rezultat je 5
celi broj 5 delimo po modulu 10 - rezultat je 5
Petlja se prekida jer broj postaje nula !!!
#include <stdio.h>
void main()
{
int broj;
printf("Ukucajte ceo broj ? ");
scanf("%d", &broj );
printf("Permutovani broj je ");
while ( broj )
{
printf("%d", broj % 10);
broj = broj/10;
}
printf("\n");
}
Zadatak 37: Napisati program na jeziku C koji za zadani prirodan broja treba da izračuna i
ispiše sve njegove delitelje.
int main(void)
{
long num; // broj koji proveravamo
long div; // potencijalni delitelj
unsigned flag = 1; // prost broj?
printf("Unesite celi broj: ");
scanf("%ld",&num);
printf("%d je deljiv sa 1 i %d\n", num, num);
for (div=2; div<=num/2; div++)
if(num % div == 0)
{
printf("%d je deljiv sa %d i %d\n", num, div, num/div);
flag = 0;
}
Zadatak 38: Napisati program na jeziku C koji proverava da li je uneti broj prost?
int main(void)
{
long num; // broj koji proveravamo
long div; // potencijalni delitelj
unsigned flag = 1; // prost broj?
printf("Unesite celi broj: ");
scanf("%ld",&num);
for (div=2; div<=num/2; div++)
if(num % div == 0)
flag = 0;
if(flag == 1)
printf("%ld je prost broj.\n",num);
else
printf("%ld je slozen.\n",num);
return 0;
}
17
#include <stdio.h>
void main() /* Program za izracunavanje faktorijela */
{
int i, fak;
long n ;
i = 1; n = 1;
printf("lzracunavanje n!\nUkucajte broj ? ");
scanf("%d", &fak);
do{
n *= i;
i++;
} while (i <= fak);
printf("%d! = %ld\n", fak,n);
}
Zadatak 40: Napisati program na jeziku C koji računa najvećeg zajedničkog delioca dva
nenegativna cela broja. Za izračunavanje koristiti Euklidovu metodu koja se sastoji iz
sledećih koraka:
Neka su a i b dva broj za koje važi da je a >= b
Izračunaj c = a MOD b
Ako je c = 0, b je najvedi zajednički delilac
Ako je c != 0, onda de a da uzme vrdnost b, a b de uzeti vrednost c.
Ponoviti postupak sve dok c ne bude jednako 0
#include<stdio.h>
void main()
{
int prvi, drugi, pomocni;
printf("Ukucajte dva nenegativna cela broja ?\n");
scanf("%d%d", &prvi, &drugi );
if (prvi < drugi)
{
pomocni = prvi;
prvi = drugi;
drugi = pomocni;
}
while (drugi != 0)
{
pomocni = prvi % drugi;
prvi = drugi;
drugi = pomocni;
}
printf("Najveci zajednicki delilac ovih brojeva je %d\n", prvi);
}
Zadatak 41: Napisati program za permutovanje cifara nenegativnog celog broja koristeći
do-while iskaz.
#include<math.h>
void main()
{
int broj;
printf("Ukucajte ceo broj ? ");
scanf("%d", &broj );
printf("Permutovani broj je ");
do
{
printf("%d", broj%10);
broj =broj/10;
}
while (broj);
printf("\n");
18
}
19
Zadaci za pripremu II kolokvijum iz predmeta
programski jezici I
Sadržaj
Zadaci za pripremu II kolokvijum iz predmeta programski jezici I .................................................... 1
Nizovi ................................................................................................................................................... 2
Funkcije i procedure............................................................................................................................. 4
Rad sa nizovima karaktera ................................................................................................................. 14
Matrice ............................................................................................................................................... 21
Opšti zadaci ........................................................................................................................................ 26
1
Nizovi
Zadatak 1: Napisati program za unos i izračunavanje zbira članova niza sa 5 elemenata.
void main(void)
{
float broj[5]; //deklaracija niza
double rez = 0; int i; //pomocne promenljive
void main()
{
double dip[VELICINA] = {20.0, 17.66, 8.2, 15.3, 22.22};
int i;
for(i = 0; i < VELICINA; i++)
dip[i] *= mnozi;
printf("\n");
for(i = 0; i < n; i++)
printf("%8.3f ", dip[i]);
printf ("\n");
}
Zadatak 3: Razmotriti rad programa pisanog u C programskom jeziku, koji sortira dati
vektor ar = {7,3,9,2,11,20,17,19,6,4} korišćenjem metode "bubble sort" algoritma.
Program se najpre sastoji u pisanju funkcije "swap" koja vrši zamenu vrednosti dve
promenljive i smešta ih u dve memorijske lokacije. Zatim tu funkciju koristimo da bi
izvršili sortiranje datog vektora. "Bubble sort" ispituje svake dve ćelije vektora i ako nisu
sortirane - svapuje ih. Ako se obezbedi upoređenje i svapovanje n-1 put nad svim ćelijama
vektora, on će biti kompletno sortiran.
#include <stdio.h>
void swap (int *a, int *b);
void main()
{
int ar[10] = {7, 3, 9, 2, 11, 20, 17, 19, 6, 4};
int i,j,n;
3
Funkcije i procedure
Zadatak 4: Pokazati kako funkcioniše prototip funkcije.
void myfunc();/*inicijalizacija funkcije bez argumenata*/
void main()
{
myfunc();/*pozivanje funkcije bez argumenata*/
}
Zadatak 6: Naći minimum od dva cela broja. U glavnom programu obezbediti štampanje, a
u funkciji njihovo poređenje.
int imin(int n,int m);
void main()/* glavni program */
{
int broj1,broj2,vrati;
printf("Unesite dva cela broja\n");
vrati=scanf("%d %d",&broj1,&broj2);
if(vrati == 2)
printf("Manji od %d i %d je %d\n",broj1,broj2,imin(broj1,broj2));
}
4
{
int min;
if (n<m)
min=n;
else
min=m;
return min;
}
void main()
{
int choice;
while(1)
{
printf("\n\nMenu:\n");
printf("1- Add\n2- Subtract\n");
printf("3- Multiply\n4- Exit");
printf("\n\nYour choice -> ");
scanf("%d",&choice);
switch(choice)
{ case 1 : add();
break;
case 2 : subtract();
break;
case 3 : multiply();
break;
case 4 : printf("\nProgram Ends. !");
exit(0);
default:
printf("\nInvalid choice");
}
}
}
void add()
{
float a,b;
printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
printf("a+b=%f",a+b);
}
void subtract()
{
5
float a,b;
printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
printf("a-b=%f",a-b);
}
void multiply()
{
float a,b;
printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
printf("a*b=%f",a*b);
}
void test3(int* a)
{
*a = 5;
}
int main()
{
int m;
m=2;
printf("\nM je %d",m);
test1(m);
printf("\nM je i dalje %d iako je vrednost promenjna u funkciji",m);
6
printf("\n\n\nM je %d",m);
test2(m);
printf("\nM je promenila vrednost i sada je %d\n",m);
printf("\n\n\nM je %d",m);
test3(&m);
printf("\nM je promenila vrednost i sada je %d\n",m);
return 0;
}
void min()
{
int a,b,c,m;
printf("\nUnesite vrednosti za a , b i c\n");
scanf("%d%d%d",&a,&b,&c);
m=a;
if(b<m) m=b;
if(c<m) m=c;
printf("Minimum brojeva a=%d b=%d i c=%d je broj %d\n",a,b,c,m);
}
7
Zadatak 11: Suma kvadrata celih brojeva od 1 do N preko funkcije
#include <stdio.h>
#include <math.h>
suma_kvadrata(int n);
void main( )
{
suma_kvadrata(10);
suma_kvadrata(15);
suma_kvadrata(20);
}
8
Zadatak 13: Poziv funkcije bez argumenta
void main()
{
void zvezde(); /*deklaracija funkcije bez argumenata*/
zvezde(); /*poziv korisnicke funkcije */
printf("%s \n ", IME) ; /*poziv funkcije iz standardne biblioteke*/
printf("%s\n", ADRESA);
printf("%s\n", MESTO) ;
zvezde ( ) ;
}
/*definicija korisnicke funkcije */
void zvezde() /*funkcija nema argumenata*/
{
int brojac;
for(brojac=1; brojac <= LIMIT; brojac++)
putchar ( '*' );
putchar ( '\n' ) ;
}
#include<stdio.h>
float hipotenuza( float n, float m); // Deklaracija funkcije
void unos( float &n, float &m);
10
float pt = Povrsina(a, b, c);
printf("\nPovrsina trougla je %f.",pt);
}
Zadatak 18: Četiri računske radnje preko funkcije choice i switch naredbi.
#include<stdio.h>
#include<stdlib.h>
float add(float aa, float bb);
float subtract(float aa, float bb);
float multiply(float aa, float bb);
float divide(float aa, float bb);
void main()
{
int choice;
float a, b, rezultat;
while(1)
{
printf("\n\nMenu:\n");
printf("1- Add\n2- Subtract\n");
printf("3- Multiply\n4- Divide\n5-Exit");
printf("\n\nYour choice -> ");
scanf("%d",&choice);
if (choice != 5)
{
printf("\nEnter a:");
scanf("%f",&a);
printf("\nEnter b:");
scanf("%f",&b);
}
switch(choice)
{
case 1: rezultat = add(a,b);
printf("Rezultat operacije je:%f\n",rezultat);
break;
case 2: rezultat = subtract(a,b);
printf("Rezultat operacije je:%f\n",rezultat);
11
break;
case 3: rezultat = multiply(a,b);
printf("Rezultat operacije je:%f\n",rezultat);
break;
case 4: rezultat = divide(a,b);
printf("Rezultat operacije je:%f\n",rezultat);
break;
case 5: printf("\nProgram Ends. !");
exit(0);
default: printf("\nInvalid choice");}
}
}
Zadatak 19: Primer prenosa niza kao parametra funkcije za realizaciju sabiranja članova
niza.
#include <stdio.h>
#define VELIC 10
long sump(int *pok, int vel);
void main()
{
12
static int niz[VELIC] = {20,10,5,39,4,16,19,26,31,20};
long odgovor;
odgovor = sump(niz, VELIC);
printf("Suma niza je: %ld.\n", odgovor);
}
Zadatak 20: Napisati program za štampanje niza i množenje elemenata niza konstantnom
vrednošću. Množenje i štmpanje niza impelemntirati pomoću potprograma.
void prikaz_niza(double niz[], int n);
void uvecaj_niz(double broj, double *pok, int vel);
void main()
{
static double dip[VELICINA] = {20.0, 17.66, 8.2, 15.3, 22.22};
prikaz_niza(dip, VELICINA);
uvecaj_niz(2.5, dip, VELICINA) ;
prikaz_niza(dip, VELICINA);
}
13
Rad sa nizovima karaktera
Zadatak 21: Primer rada sa funkcijama za rad sa stringovima (nizovima karaktera).
#include <cstring>
#include <stdio.h>
void main()
{
char rec1[20] = "lep";
char rec2[20] = "dan";
char rec3[20];
printf("%d\n", strlen(rec1));
printf("%d\n", strlen(rec2));
printf("%s\n", strcat(rec1, rec2));
printf("%d\n", strlen(rec1));
strcpy(rec3, rec1);
Zadatak 23: Razliciti primeri za unosenje i štampanje niza karaktera sa standardnog ulaza:
void main()
{
char recenica[80];
printf("Unesite niz proizvoljnih karaktera:");
gets(recenica);
printf("\nUneli ste niz karaktera:");
puts(recenica); //Stampanje unetih karaktera
printf("\n"); //Prelazak u novi red
14
Zadatak 24: Unos i štampanje jednog karaktera
#include<stdio.h>
void main( ) {
char c;
printf("Unesite jedan proizvoljni karakter:");
c = getchar( );
putchar('\n');//Prelazak u novi red
printf("Uneli ste karakter:");
putchar(c);//Stampanje unetog karaktera
putchar('\n');//Prelazak u novi red
}
15
Zadatak 26: - Program čita jedan karakter i ispisuje ga.
#include <stdio.h>
void main()
{
int c; /* Karakter - obratiti paznju na int */
printf("Unesite jedan proizvoljni karakter:");
c = getchar(); /* cita karakter sa standardnog ulaza */
printf("\nUneli ste karakter:");
putchar(c); /* pise karakter zapamćen u promenljivoj c na standardni izlaz */
putchar('\n'); /* prelazak u novi red */
printf("Ispisuje malo a:");
putchar('a'); /* ispisuje malo a */
printf("\nIspisuje ASCI 97:");
putchar(97); /* ekvivalentno prethodnom */
putchar('\n');/* prelazak u novi red */
}
Zadatak 27: Program učitava i broji karaktera sa ulaza sve dok se ne otkuca znak za kraj
unosa EOF. EOF se može generisati kucanjem Control /Z.
#include <stdio.h>
void main()
{
int ch, i = 0;
while((ch = getchar()) != EOF)
i ++;
printf("%d\n", i);
}
Zadatak 28: Program koristi getchar da učita liniju sa standardnog ulaza stdin, postavlja
takav ulaz u buffer, onda završava string terminacionim karakterom i zatim štampa
string na ekranu.
#include <stdio.h>
void main( void )
{
char buffer[81];
int i, ch;
printf( "Enter a line: " );
/* Read in single line from "stdin": */
for( i = 0; (i < 80) && ((ch = getchar()) != EOF)
&& (ch != '\n'); i++ )
buffer[i] = (char)ch;
/* Terminate string with null character: */
buffer[i] = '\0';
printf( "%s\n", buffer );
16
}
Zadatak 29: Program konvertuje ulazne karaktere u velika slova. Da bi ovo učinili moramo
dodati funkciju toupper iz biblioteke za konverziju karaktera ctype.h
#include <ctype.h> /* For definition of toupper */
#include <stdio.h> /* For definition of getchar, putchar, EOF */
void main()
{
int ch;
while((ch = getchar()) != EOF)
putchar(toupper(ch));
}
Zadatak 30: NCP koji će ispisati na standardni izlaz ukupan broj karaktera standardnog
ulaza do markera kraja, kao i broj prelazaka u novi red. Pretpostaviti da je za ukupan
broj karaktera (zajedno sa enter i blanko) i ukupan broj prelazaka u novi red dovoljan
opseg long promenljivih.
#include <stdio.h>
void main()
{
int znak; /*prihvata znak sa ulaza */
long linije=0 ; /*brojac linija */
long br_znak=0; /*brojac znakova na ulazu */
while ( (znak=getchar() ) != EOF)
{
br_znak++;
if (znak=='\n')
linije ++;
}
printf("Prelazaka u novi red: %ld, karaktera: %ld \n",linije,br_znak);
}
Zadatak 32: Napisati program koji nalazi najduzu unetu liniju sa standardnog ulaza. Nije
poznat ukupan broj linija, ali svaka linija nema vise od 80 karaktera a unos se prekida
unosom karaktera CTRL/Z.
#define MAX_DUZINA_LINIJE 80
void main()
{
char linija[MAX_DUZINA_LINIJE];
char najduza_linija[MAX_DUZINA_LINIJE];
int duzina_linije = 0;
int duzina_najduze_linije = 0;
najduza_linija[0] = '\0';
while( gets(linija) != NULL){
duzina_linije=strlen(linija);
if (duzina_linije > duzina_najduze_linije){
strcpy(najduza_linija, linija);
duzina_najduze_linije = duzina_linije;
}
}
printf("Najduza linija je : %s\n i ona ima %d karaktera
\n\n",najduza_linija, duzina_najduze_linije);
}
18
Zadatak 33: Uraditi program za unos niza karaktera ”Moram da položim drugi kolokvijum
iz Programskih jezika 1” u vektor Niz1. Odštampati ovaj niz karaktera u potpunoj formi,
i izračunati dužinu unetog niza. Iskopirati sadržaj vektora Niz1 u vektror Niz2 i utvrditi
dali su to isti nizovi. Prebrojati koliko praznina (blanko karaktera) ima u nizu Niz1.
void main()
{
int brojznak=0,i=0;
char Niz1[81],Niz2[81];
printf("Unesi clanove niza Niz1, za kraj Ctrl/z/");
while( gets(Niz1)!= NULL) /* Unos se prekida sa Ctrl/z */
continue;
while (Niz1[i]!='\n')
{
if(Niz1[i] == ' ')
brojznak++;
i=i+1;
}
printf("Broj blanko znakova u nizu Niz1 je:%ld \n",brojznak);
}
Zadatak 34: Sastaviti program koji iz skupa unetih karaktera (na primer: ’’Ja sam rodjen
1990. god u 12. mesecu, u petak!’’) izračunava broj unetih slova, brojeva i ostalih
karaktera. Tekst se unosi sa tastature, a program se prekida pritiskom na ctrl+Z
#include<conio.h>
void main( ){
int slovo, broj, ostalo, c;
slovo = broj = ostalo = 0;
while( (c=getchar( )) != EOF )
if( ('A'<=c && c<='Z') || ('a'<=c && c<='z') )
++ slovo;
else if( '0'<=c && c<='9' ) ++broj;
else ++ostalo;
printf("Uneli ste:%d slova, %d brojeva,%d ostalih\n\n", slovo, broj,
ostalo);
}
19
Zadatak 35: Napisati program konvertuje velika u mala slova. Recenica se unosi sa tastature
a program se prekid unošenjem karaktera %.
void main( ) {
char c;
while( (c=getchar( )) != '%' )
if( 'A'<=c && c<='Z' )
putchar(c+'a'-'A');
else
putchar(c);
}
Zadatak 36: Program broji karaktere, brojeve i praznine u tekstu. Završava se unosom %.
void main( )
{
int let, dig, other, c;
let = dig = other = 0;
while( (c=getchar( )) != '%' )
if( ('A'<=c && c<='Z') || ('a'<=c && c<='z') )
++let;
else if( '0'<=c && c<='9' ) ++dig;
else ++other;
printf("%d slova, %d broja, %d ostalih karaktera\n", let, dig,
other);
}
20
Matrice
Zadatak 37: Štampanje elemenata matrice
#include<stdio.h>
#include<math.h>
void main()
{
static int mat[3][3]={{0,1,2},{3,4,5},{6,7,8}};
int i,j;
for(i=0; i<3; ++i)
{
printf("\n");
for(j=0; j<3; ++j)
printf("%d\t",j,mat[i][j]);
}
printf("\n");
}
21
Zadatak 39: Neka je data kvadratna matrica u formatu:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Članove matrice uneti u program kao konstantne celobrojne veličine, a kao izlaz iz programa
predvideti štampanje ove matrice u pokazanom formatu kao polazne matrice i štampanje
nove matrice u istom obliku ali sada unazad od člana a44,a43,a42a41,......,a11.
void main()
{
int mat[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int i,j;
printf("\nPolazna matrica je\n");
for(i=0;i<4; i++)
{
for(j=0;j<4; j++)
printf("%2d ",mat[i][j]);
printf("\n");
}
Zadatak 40: Napisati program na C++ jeziku koji izračunava sumu svih elemenata u
svakom redu pojedinačno, pravougaone matrice [4x4].
22
1 2 3 4
5 6 7 8
A=
9 10 11 12
13 14 15 16
void main()
{
int mat[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int i,j,s=0;
for(i=0;i<4; i++)
{
printf("\nSuma %d reda je:",i+1);
for(j=0;j<4; j++)
s=s+mat[i][j];
printf("%2d\n",s);
s=0;
}
}
Zadatak 41: NCP koji sa standardnog ulaza učitava 3x3 matricu i ispisuje je na standardni
izlaz tako da centralno polje a[1][1] bude jednako sumi gornjeg levog (a[0][0]) i donjeg
desnog polja (a[2][2]). Pre učitavanja popuniti matricu proizvoljnim vrednostima.
#include <stdio.h>
void main()
{
int a[3][3]; /* deklaracija i inicijalizacija matrice a, može se uraditi
za konkretan primer date matrice*/
int i, j; /*brojaci u ciklusu */
/*ispis matrice */
for(i=0; i<3; i++)
{
for(j=0; j<3; j++) printf("%d\t", a[i][j]);
printf("\n");
}
}
void main()
{
int mat[4][4];
int i,j;
float dijagonala;
printf("Unesite proizvoljne elemente pravougle matrice:\n");
for(i=0;i<4;++i)
for(j=0;j<4;++j)
24
{
printf("a[%d][%d]=",i,j);
scanf("%d",&mat[i][j]);
printf("\n");
}
printf("\nPolazna matrica je\n");
for(i=0;i<4;++i)
{
for(j=0;j<4;++j)
printf("%3d ",mat[i][j]);
printf("\n");
}
25
Opšti zadaci
Zadatak 43: Program za odredjivanje da li je godina prestupna ili nije
#include<stdio.h>
#include<math.h>
void main()
{
int godina,ost_4,ost_100,ost_400;
printf("Ukucajte godinu ? ");
scanf("%d", &godina);
ost_4=godina%4;
ost_100=godina%100;
ost_400=godina%400;
if (ost_4 ==0 && ost_100 != 0 || ost_400== 0)
printf("Godina %d je prestupna\n", godina);
else
printf("Godina %d nije prestupna\n", godina);
}
Zadatak 44: Program za odredjivanje srednje vrednosti n celih pozitivnih brojeva -for iskaz
#include<stdio.h>
#include<math.h>
void main()
{
int n,brojac;
float suma =0, x ;
printf("Ukupno brojeva? ");
scanf("%d", &n);
for (brojac=1 ; brojac<=n; ++brojac, suma+=x )
{
printf("Ukucajte %d broj? ",brojac);
scanf("%f",&x);
}
printf("Srednja vrednost ovih brojeva je %f\n", suma/n);
}
Zadatak 47: Odredjivanje u ulaznom tekstu broja praznih karaktera, kao i broja znakova:
tacka, zarez, dvotacka i tacka-zarez (naredbe switch i break) za izlaz CTRL/Z.
#include <math.h>
#include <stdio.h>
void main( )
{
int c, prazno=0, interp=0;
while((c=getchar())!=EOF)
switch(c)
{
27
case ' ':
prazno++;
break;
case '.':
case ',':
case ':':
case ';':
interp++;
break;
default:
break;
}
printf("\nBroj praznina: %d", prazno);
printf("\nBroj znakova tacka, zarez, dvotacka i tacka-zarez: %d\n",
interp);
}
28