OSNOVE C JEZIKA 1./*Napisati program koji na ekranu ispisuje poruku Zdravo svete!*/ #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. scanf(“%d”,&x); - %d - broj koji se unosi je celobrojni. - %8.2f – ostavljanje mesta za zapis realnog broja Escape karakteri \b – povratnik \nnn – vrednost karaktera \f – from feed \\ - obrnuta kosa crta \n – nova linija \” – dvostuka navodnica \r – carriage return \’ – jednostruke navodnice \t – horizontalni tab \ - nastavak linije \v – vertikalni tab Konverzioni karakteri funkcije printf Konverz. kar. Konverzija izlaznog niza c Karakter (char) d ceo broj (int) f realan broj (float) s niz karaktera (string) e realan br. u naučnoj notaciji le double 1.2.2 Variables - Promenljive Promenljiva je objekt jezika koji ima ime i kome se mogu dodeljivati različite vrednosti u toku izvršavanja programa. 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.. Ime promenljive (indentifikator): skola y Ab63c auto_skola 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. Aritmetički izrazi i operatori Aritmetički operatori C jezika su +, -, *, / i % koji odgovaraju matematičkim operacijama sabiranja, oduzimanja, množenja, deljenja i deljenja po modulu, respektivno. Ovi operatori su binarni, jer zahtevaju dva operanda, sa izuzetkom operatora -, koji može biti i unaran. Operator deljenja po modulu (%) daje ostatak posle celobrojnog deljenja. 2 Tablica operatora. Operator Namena Primer Rezultat Sabiranje 5+6 11 + Oduzimanje 7 3 4 Množenje 4*4 16 * Deljenje 12 / 6 2 / Deljenje sa ostatkom 5%2 1 % % operator se naziva još i modulus operator . Aritmetički operatori jednako dobro rade sa negativnim brojevima kao i sa pozitivnim, sa izuzetkom modulus operatora, rade sa celim brojevima jednako dobro kao i sa realnim. Konstante (nepromenjive) - Varijable su promenjive dok su konstante izrazi sa fiksnim, nepromenjivim vrednostima. - Kostante su objekti koji dobijaju vrednost pre nego što počne izvršavanje programa i u toku rada programa se ne mogu menjati. Primer definisanja konstanti: #define PI 3.141592 #define POREZ 20 #define PI 3.141592 #define POREZ 20 main(){ ..... Obim=2*r*PI; ... } #define IME “VLADE DIVAC” #define BROJ 52 main() { printf(“Kosarkas %s ima br. Cip.%f”,IME, BROJ); } 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. Odnosni operatori: if ((a>b)&&(b>c)) || (b>d) Operator Značenje Primer && || ! logičko I logičko ILI logička negacija (i>1)&&(j<6) x=10||20; if(!b) brojac=0; 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). Operator inkrementiranja i dekrementiranja Operator inkrementiranja ++ i dekrementiranja -- su unarni operatori i javljaju se u prefiksnom i postfiksnom obliku. Operator inkrementiranja ++ promenljivoj p dodaje vrednost 1, dok operator dekrementiranja -- promeljivoj p oduzima vrednost 1, pa važi: p++ je ekvivalentno p=p+1 ++p je ekvivalentno p=p+1 p-- je ekvivalentno p=p-1 --p je ekvivalentno p=p-1 (postfiksni oblik) (prefiksni oblik) 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 Rezervisane reči - Keywords The following keywords are reserved and may not be used as an identifier for any other purpose. auto double int long break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while 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 zbir = a + b PRINT zbir END #include <stdio.h> void main () { 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 IF b <> 0 THEN PRINT a/b ELSE PRINT "Ne mogu deliti nulom" END #include<stdio.h> void main () { float a, b; scanf("%f%f", &a, &b); 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 INPUT b FOR a = 1 TO b zbir = zbir + a NEXT a PRINT zbir END #include <stdio.h> void main() { int a, b, zbir = 0; scanf("%d", &b); 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 Primjer u BASIC-u Kod provere istinitosti na ulazu u petlju postoji mogućnost da se ne izvrši ni jedno ponavljanje. Razlog je jednostavan, ako uslov nije ispunjen odmah se "preskače" na sledeću liniju izvan petlje. Za ovu vrstu petlje u većini programa se koristi ključna reč "WHILE" prilagođena sintaksi programskog jezika. Primjer u C-u zbir = 0 WHILE zbir < 200 INPUT a zbir = zbir + a WEND #include <stdio.h> void main() { int a, zbir = 0; while (zbir < 200) { scanf("%d", &a); zbir += a; } PRINT zbir END printf("%d\n", zbir); } Primer algoritma kada nije poznat konačan broj iteracija sa proverom na kraju petlje Primjer u BASIC-u Kod provere istinitosti na kraju petlje, ne postoji mogućnost da se ne izvrši ni jedno ponavljanje. Razlog je jednostavan, provera se vrši u posednjem redu bloka kôda, pe se mora proći barem jedanput kroz čitav blok. Za ovu vrstu petlje u većini programa se koristi ključna reč "DO..WHILE" prilagođena sintaksi programskog jezika. zbir = 0 DO INPUT a zbir = zbir + a WHILE (zbir < 200) PRINT zbir END Primjer u C-u #include <stdio.h> void main() { int a, zbir = 0; do { scanf("%d", &a); zbir += a; } while (zbir < 200); } printf("%d\n", zbir); 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; Međutim, ako postoji višestruko granjanje koristi se: if(izraz1) iskaz1; else if(izraz2) iskaz2; ..... else iskazn; If statements if ( statement is TRUE ) Execute this line of code Else if ( /* } else /* } TRUE ) { Execute these statements if TRUE */ { Execute these statements if FALSE */ *) Primer: #include <stdio.h> int main() { int age; /*Most important part of the program!*/ /* Need a variable... */ printf( "Please enter your age" ); /* Asks for age */ scanf( "%d", &age ); /* The input is put in age */ if ( age < 100 ) { /*If the age is less than 100*/ printf ("You are pretty young!\n" ); /*Just to show you it works.*/ } else if ( age == 100 ) { /*I use else just to show an example*/ printf( "You are old\n" ); } else { printf( "You are really old\n" ); /*Executed if no other statement is*/ } return 0; } 9 Osnovne bibliotečne funkcije <math.h> sin(x) cos(x) tan(x) exp(x) log(x) log10(x) sin(x) cos(x) tg(x) ex log e (x), x>0 - 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 6. /*Napisati program za izračunavanje apsolutne vrednosti celog broja*/ #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); } 7. /*Napisati program koji ispituje da li je karakter malo ili veliko slovo, cifra ili specijalni karakter - if else iskaz*/ #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); } 8./*Izračunati površinu trougla zadatog stranicama x, y i z po formuli za površinu p=sqrt(s*(s-x)*(s-y)*(s-z)), gde je s=(x+y+z)/2. */ #include<stdio.h> #include<math.h> void main() { double x,y,z,p,s; printf("Unesite stranice\n"); scanf("%lf%lf%lf",&x,&y,&z); if((x+y>z)&&(x+z>y)&&(y+z>x)) { s=(x+y+z)/2; p=sqrt(s*(s-x)*(s-y)*(s-z)); printf("Povrsina trougla je=%0.2f\n",p); } else printf("Ne moze se konstruisati trougao\n"); } 9. /*Napisati program koji za dati trocifreni prirodan broj n proverava da li je Armstrongov. Broj je Armstrongov ako je jednak zbiru kubova svojih cifara.*/ #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); } 10. /*Napisati program koji za dato x izračunava y po formuli.*/ 2 x,........ 2 x 2 3x 1,........5 x 7 y 1 / x,........za..ostale...slucajeve #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 ; printf("Unesite prvi broj:") ; scanf("%d", &prvibroj ) ; printf("Unesite drugi broj :" ) ; scanf("%d" , &drugibroj ) ; if ( ( prvibroj % 2 == 0) && ( drugibroj % 2 == 0 ) ) printf ("%d\n" , prvibroj + drugibroj ) ; else printf("%d\n" , prvibroj * drugibroj ) ; return 0 ; } 12. Napisati program koji broji razmake, tabulatore i nove redove. #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; } Operator višestrukog izbora SWITCH Omogućava grananje u programu izborom jednog između više operatora switch (izraz) { case konstanta1: operator1 ...... break; case konstanta2: operator2 ......... break; ..... default : operatorn break; } Naredba switch - Izraz u naredbi switch mora imati celobrojnu vrednost (char, int). Nakon ključne reči case pojavljuju se celobrojne konstante ili konstantni izrazi. Na početku izvršavanja naredbe switch prvo se testira izraz. Ako je vrednost izraza jednaka konstanta_i onda se izvršava naredba_i i sve naredbe koje dolaze nakon nje, sve do prve 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!"); } 14./*Napisati program koji će zamentiti u unetom tekstu . sa ! i slovo a sa A.*/ #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; printf("Unetite ceo broj a i realan broj x:"); scanf("%d%lf",&a, &x); 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 ako je a = 2 ako je a = 3 ako je a = 4 tada je y = |x| + |x-5|....................................................y = fabs(x)+fabs(x-5) tada je y najveći ceo broj koji nije veći od x..............y = floor(x) tada je y = sin(x+5)-e x ...............................................y = sin(x+5)+exp(x) 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); } i=1; while (i <= n) { S+=i; i++; } i=1; do { S+=i; i++; } while (i <= n); for (i=1; i <= n; i++) { S+=i; } 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> /* stampanje Fahrenheit-Celsius tabele za fahr = 0, 20, ..., 300 */ void main() { int fahr, celsius; int lower, upper, step; lower = 0; upper = 300; step = 20; fahr = lower; while (fahr <= upper) { celsius = 5 * (fahr-32) / 9; printf("%d\t%d\n", fahr, celsius); fahr = fahr + step; } } 19. /*Program za određivanje srednje vrednosti n celih pozitivnih brojeva*/ #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; U do-while iskazu prvo se izvršava do-iskaz. Zatim se izvršava uslov_petlje. Ako je istinit, petlja se nastavlja, inače se petlja završava i kontrola prenosi na sledeci_iskaz. Do-while iskaz se koristi za slučaj da je petlju neophodno izvršiti najmanje jedanput. 20. /*Program za permutovanje cifara celog broja*/ #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 for(pocetni_izraz; uslov_petlje; izraz_petlje) programski_iskaz; sledeci_iskaz; 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. - Beskonačna petlja koja ne radi ništa: for(;;); 21. /*Program za izračunavanje faktorijela*/ #include<stdio.h> void main() { int i,n; long fak=1; printf("Izracunavanje n!\nUkucajte broj (<33)?"); scanf("%d",&n); for(i=1;i<=n;i++) fak*=i; printf("%d!=%ld\n",n,fak); } 18 22. /*Program za odredjivanje srednje vrednosti n celih pozitivnih brojeva-for 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. Definicija funkcije ima oblik: tip_p ime_funkcije(tip_1 arg_1, ... ,tip_n arg_n) { telo funkcije } 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() { printf(“Zdravo!\n”); } /*Zaglavlje funkcije*/ /*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; } if naredba i uslovni operator Sedeće dve naredbe su ekvivalentne: 1) max = a>b ? a : b 2) if(a>b) max=a; else max=b; Funkcija tipa void: Kada funkcija ne vraća nikakvu vrednost onda se za tip vraćene vrednosti koristi ključna reč void: Primer: #include <stdio.h> void maximum(int x, int y) { int z; z=(x>=y) ? x : y; printf("\nMaksimalna vrednost =%d\n",z); return; } 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; } 23. /*Napisati program za izračunavanje sume kvadrata celih brojeva od 1 do n*/ #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); } Funkcija suma_kvadrata(n) je deklaracija funkcije, koja definiše ime funkcije (identifikator suma_kvadrata), broj argumenata funkcije i njihova imena, i predstavljaju formalne argumente. Ovde je definisan samo jedan argument n koji predstavlja formalni argument jer se koristi samo u definiciji funkcije. Na kraju funkcije se nalazi return promenljiva; 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 funkcije, u zagradi stoje stvarni argumenti 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); } 25./*Napisati program kojim se ispisuju parovi prijateljskih brojeva do n. Za dva broja kažemo da su prijateljski, ako je jedan broj jednak sumi delioca drugog broja. U sumu delioca ne ulazi sam taj broj. Sumu delioca računati korišćenjem funkcije Npr. prijateljski brojevi su: 220=1+2+4+71+142 284=1+2+4+5+10+11+20+22+44+55+110*/ #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); } } 26./*Napisati program za izračunavanje faktorijela zadatog broja n korišćenjem funkcije fakt().*/ #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; long broj; printf("Uneti broj ciji faktorijel trazimo\n"); scanf("%d",&n); broj=fakt(n); printf("Faktorijel broja %d je: %ld\n",n,broj); } 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); } } Funkcije getchar i putchar: (<stdio.h>) 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 goto naredba prekida sekvencijalno izvršavanje programa i nastavlja izvršavanje s naredbom koja je označena labelom koja se pojavljuje u goto. Oblik joj je goto labela; gdje je label identifkator koji služi za označavanje naredbe kojom se nastavlja program. Sintaksa je labela: naredba; Labela na koju se vrši skok mora biti unutar iste funkcije kao i goto naredba (pomoću goto se ne može izaći iz funkcije). 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: ; } Slično vredi i za continue unutar while i do-while petlje. 22./* Napisati program za rekurzivnu funkciju za izračunavanje n-tog stepena realnog broja x0, ako je n ceo broj.*/ n0 1, n 1 x x x , n 0 1 / x n , n 0 n može se izvršiti sledeća rekurzivna formula: n0 1, 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)); JEDNODIMENZIONALNI I VIŠEDIMENZIONALNI NIZOVI Nizovi predstavljaju skup homogenih podataka. Nizove treba razlikovati od struktura koje predstavljaju skup heterogenih podataka. Elementi niza su istog tipa, dok su elementi struktura različitih tipova. Niz se obeležava: 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’}; Primer: int broj[100]; 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. 12 4 10 .... .... 7 broj[0] (sadrži prvi broj, na primer 12) broj[1] (sadrži prvi broj, na primer 4) broj[2] (sadrži prvi broj, na primer 10) broj[99] (sadrži prvi broj, na primer 7) 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> void sort(double x[] , int n) { int i,j; for ( i = 0 ; i <n-1 ; i++) for ( j = i+1 ; j<n ; j++) if ( x[i] >= x[j] ) { double temp = x[i]; x[i] = x[j]; x[j] = temp; } } 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); 30. /*Napisati program za unos i stampanje 10 ocena ucenika*/ #include<stdio.h> void main() { int i,ocena[10]; printf("Uneti ocene ucenika\n"); for(i=0;i<10;i++) scanf("%d",&ocena[i]); printf("Unete ocene ucenika su:\n"); for(i=0;i<10;++i) printf("%c ocena[%2d]=%2d",(i%5==0)?'\n':' ',i,ocena[i]); printf("\n"); } 31. /*Program za sortiranje jednodimenzionalnih nizova realnih brojeva od najmanjeg do najveceg*/ #include<stdio.h> void main() { int n,i,j; float priv, x[100]; do { printf("Koliko brojeva za sortiranje?[<100]:"); scanf("%d",&n); } while(n>=100||n<=0); printf("\n"); /*Ucitavanje n brojeva*/ for(i=0;i<n;++i) { printf("? x[%2d]=",i); scanf("%f",&x[i]); } /*Sortiranje*/ for(j=0;j<n-1;++j) for(i=j+1;i<n;++i) if(x[i]<x[j]) { priv=x[j]; x[j]=x[i]; x[i]=priv; } /*Stampanje sortiranih brojeva*/ printf("\nSortiranji brojevi:\n"); for(i=0;i<n;++i) printf("x[%2d]=%15.6e\n",i,x[i]); } 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]); } } int BrojMax(float a[],int n) { float max; int i,k; max=a[0]; k=1; for(i=1;i<n;i++) if(a[i]>max) { max=a[i]; k=1; } else if(a[i]==max) k++; return k; } void main() { float a[100]; int n; printf("Uneti broj elemenata niza\n"); scanf("%d",&n); citaj(a,n); printf("U nizu ima %d maksimalnih clanova\n", BrojMax(a,n)); } 33. /*Dat je niz realnih brojeva. Napisati funkciju koja: a) izračunava sumu elemenata niza koji prethode prvoj nuli u nizu; b) određuje broj elemenata koji prethode prvom negativnom elementu u nizu; c) izračunava proizvod elemenata između prve i druge nule u nizu (niz ima bar dve nule);*/ #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]); } float suma(float a[],int n) { int i=0; float s=0; while(i<n&&a[i]) s+=a[i++]; return s; } 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.*/ Uradjen ceo program. 31 #include<stdio.h> #define DIM 100 void main(){ int A[DIM]; int i, n; int zbir=0; printf("Unesite broj elemenata niza:\n"); scanf("%d", &n); printf("Unesite elemenateniza:\n"); for(i=0; i<n; i++) scanf("%d", &A[i]); for(i=n-1; i>n-9; i--) zbir+=A[i]; printf("Zbir zadnjih osam elemenata niza je: %d\n", zbir); } ili kao funkcija: int zbirZadnjihOsam(int niz[], int n) { int i; int zbir=0; for(i=n-1; i>n-9; i--) zbir+=niz[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: static int M[4][3]={ {13,-18,21}, {36,101,0}, {-5,0,-9}, {3,1,9} }; 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. void funkcija(int z[][25][35]); 38. /*Program za skalarno množenje matrica*/ #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); } 40./*Program za množenje dve zadate matrice*/ #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); } 41./*Program za transponovanje matrice a dimenzije 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); } 42./*Napisati program koji u matrici realnih brojeva a određuje: a) maksimalni element; b) sumu elemenata ispod glavne dijagonale; c) sumu elemenata iznad sporedne dijagonale.*/ 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("Uneti dimenzije matrice: "); scanf("%d", &n); printf("Uneti elemente matrice:\n"); for(i=0; i<n; i++) for(j=0; j<n; j++) scanf("%d", &M[i][j]); /*Sumiranje elemenata matrice M po redovima i smestanje vrednosti u niz sumaRedova*/ for(i=0; i<n; i++) for(j=0; j<n; j++) sumaRedova[i]+=M[i][j]; /*Formiranje matrice C od prosecnih vrednosti vrsta matrice na glavnoj dijagonali, a ostali elementi su jedinice (van glavne dijagonale)*/ for(i=0; i<n; i++) for(j=0; j<n; j++) if(i==j) C[i][j]=sumaRedova[i]/n; else C[i][j]=1.; /*Stampanje matrice C na standardnom izlazu*/ printf("\n\nNovodobijena matrica C je:\n\n"); for(i=0; i<n; i++){ printf("\n"); for(j=0; j<n; j++){ printf(" %4.2f ", C[i][j]); } } printf("\n\n"); } POKAZIVAČI (POINTERI) Pokazivačka promenljiva je promenljiva koja “pokazuje “ na drugu promenljivu, odnosno sadrži adresu memorijske lokacije u kojoj se čuva ta promenljiva. Deklariše se tako što se u specifikaciji zada tip promenljive na koju ukazuje pokazivačka promenljiva. Ispred imena promenljive piše se * int *pi /*pokazivač na celobrojnu promenljivu */ 41 char *pc /*pokazivač na znakovnu promenljivu */ float *a, *b /*pokazivač na float promenljive */ x = *pi dodeljuje promenljivoj x celobrojnu vrednost koja se nalazi na adresi sadržanoj u promenljivoj pi. 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; } Prenos adrese argumenata int a; int *pok; a = 10; pok = &a; *pok = 100; a = 100; /* promenljiva tipa int */ /* pokazivač na int tip */ /* inicijalizacija promenljive a na 10 */ /* inicijalizacija pokazivač tako da pokazuje na promenljivu a */ /* promena sadržaja promenljive a na 100 preko pokazivača */ Pokazivači omogućavaju formiranje složenih dinamičkih struktura podataka (liste, magacini, stabla, redovi i dr.) i s tim u vezi dinamičko dodeljivanje memorije, prenos argumenata funkcije referisanjem, efikasniji rad sa vektorima i prenos funkcija kao argumenata u druge funkcije. Proizvoljna programska promenljiva memorisana je u određenom memorijskom bloku, na određenoj programskoj lokaciji ili adresi. Pokazivači omogućavaju indirektni način za pristupanje programskim promenljivim, korišćenjem i manipulacijom adresama promenljivih. U C jeziku možemo deklarisati promenljivu, prom: int *prom; koja omogućava da se indirektno pristupi vrednosti promenljive prom. Karakter zvezdica ‘*’ deklariše promenljivu kao pokazivač, a tip int da je promenljiiva prom pokazivač na celobrojnu promenljivu, što 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. Dinamičke strukture podataka Dinamičke strukture zahtevaju eksplicitno rezervisanje i oslobađanje memorije. U sistemskoj biblioteci svakog C prevodioca postoje funkcije malloc, calloc, realloc i free, kojima se rezerviše i oslobađa mimorijski blok. Za kreiranje dinamičkih objekata koriste se funkcije malloc() i calloc(), a za njihovo uništavanje funkcija free(). Pri korišćenju ovih funkcija treba priključiti zaglavlje <alloc.h>.Definicija ovih funkcija je sledeća: 1. char *malloc(size). Rezerviše memorijski blok veličine size bajtova, koji se inicijalizuje na 0. Argument size je unsigned. U slučaju uspešne rezervacije malloc vraća pokazivač na rezervisani memorijski blok. U protivnom, vraća 0. 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. 50./*Izračunati zbir i razliku dva broja koristeći pokazivače na funkciju*/ #include<stdio.h> int zbir(int *a,int *b) { return *a+*b; } int razlika(int *a,int *b) { return *a-*b; } 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); } 51./*Stranice a i b pravougaonika su prirodni brojevi. Odrediti, na koliko se kvadrata maksimalne površine može iseći dati pravougaonik. Ispisati dimenzije kvadrata. Na primer za a=12 i b=7 se ispisuje: 1 kvadrata stranice: 7 1 kvadrata stranice: 5 2 kvadrata stranice: 2 2 kvadrata stranice: 1 #include<stdio.h> void razmeni(int *a, int *b) { int t; t=*a; *a=*b; *b=t; } void main() { int a,b; printf("Uneti stranice pravougaonika\n"); scanf("%d%d",&a,&b); if(a==b) printf("Jedan kvadrat stranice %d\n",a); else while(a) { if(a<b) razmeni(&a,&b); printf("%d kvadrata stranice: %d\n",a/b,b); a=a%b; } } 52. /*Nizovi i pokazivaci*/ #include<stdio.h> void main() { 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; p_fniz=fniz; a=*p_fniz; b=*(p_fniz+2); p_fniz=&fniz[2]; c=*(p_fniz+2); printf("a=%f b=%f c=%f\n",a,b,c); for(i=0;tekst[i]!='\0';++i)putchar(tekst[i]); 44 for(p_tekst=tekst;*p_tekst!='\0';++p_tekst)putchar(*p_tekst); } 53. /*Program za odredjivanje duzine stringa*/ #include<stdio.h> int duzina(char *p_string); void main(int argc,char *argv[]) { char *p_text={"ovo je znakovni niz\n"}; int i; for(i=1;i<argc;i++) printf("argument%d%s\n",i,argv[i]); i=duzina(p_text); printf("duzina stringa je %d\n",i); } int duzina(char *p_string) { int l=0; char*p; p=p_string; while(*p!='\0') { ++l; ++p; } return l; } 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]); } void razmeni (int *x,int *y) { int p; p=*x; *x=*y; *y=p; } void f(int a[][10],int n, int k) { int i,j; for(i=0;i<k;i++) for(j=0;j<k-i;j++) razmeni(&a[i][j],&a[n-1-j][n-1-i]); } void pisi(int a[][10],int n) { int i,j; for(i=0;i<n;i++) 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); } 55./*Program za izračunavanje zbira kubova i kvadrata.*/ #include <stdio.h> main() { int m,n,k,l,p,q,r; void kavdrat_kub(); kavdrat_kub(2,4,&p,&q); /*deklaracija f-je*/ /*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"); printf("Najveci element niza je %d, a njegov indeks %d \n", max, ind_max); printf("Izgled vektora (niza) B:\n"); for(i=0;i<9;i++){ printf("%d ",B[i]); } printf("\n"); return 0; } Dodatak – Nizovi i pokazivači int x[4], *p; p=x; 56006 p p+1 p+2 p+3 x[0] x[1] x[2] x[3] 56007 56008 56009 56010 56011 56012 56013 x+2=&x[2] *(x+2)=x[2] *(x+i)=x[i] 1. Napisati program kojim se odredjuje koliko je ucesnika takmicenja iz programiranja imalo natprosecne rezultate. Problem se moze razloziti na sledece module: 1. Ucitavanje vrednosti elemenata niza. 2. Izracunavanje prosecnog rezultata: 3. Prebrojavanje natprosecnog rezultata. 4. Ispisivanje izvestaja (izlazni podaci) #include<stdio.h> void main() { int n,i,broj, ocena[50]; 47 float prosek(); /*deklaracija f-je prosek*/ printf("Uneti broj takmicara\n"); scanf("%d",&n); /*Ucitavanje elemenata niza*/ for(i=0;i<n;++i) { printf("ocena[%d]=",i); scanf("%d",&ocena[i]); } /*Prebrojavanje natprosecnih rezultata*/ broj=0; for(i=0;i<n;++i) if (ocena[i]>prosek(ocena,n)) broj++; printf("Prosecan rezultat je: %f.\n", prosek(ocena,n)); printf("Natprosecne rezultate je imalo: %d takmicara.\n",broj); } float prosek(int x[], int n) { int i, suma; suma=0; for(i=0; i<n; suma+=x[i], i++); return((float)suma/n); } /*definicija 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 ) x[4] je isto što i *(x+4) x[i] je isto što i *(x+i) float prosek(int *x, int n) { int pom, i; suma=0; for(i=0; i<n; suma+=*(x+i), i++); return((float)suma/n); } 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]. void levo_za_1(int a[], int n) { int pom, i; pom=a[0]; for(i=1; i<n; a[i-1]=a[i], i++); a[n-1]=pom; 48 } II način: Ako bi umesto deklaracije int a[]; stavili int *a; { a[i] je isto što i *(a+i) } void levo_za_1(int *a, int n) { int pom, i; pom=*a; for(i=1; i<n; *(a+i-1)=*(a+i), i++); *(a+n-1)=pom; } 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]; (uz obvezni malloc kasnije) char *niz; Ispis stringa : koristi se format %s, npr. printf("%s", niz) Primeri učitavanja stringa: gets(niz); scanf("%s", niz); scanf("%[^\n]", niz); Standardni fajlovi zaglavlja 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 Nizovi karaktera su jednodimenzionalni vektori tipa char. U standardnom zaglavlju stdio.h definisane su sledeće funkcije: - getchar() - čita sledeći znak, uključujući i bele znakove, preko tastature. Vrednost funkcije je kod pročitanog znaka ili simbolička konstanta EOF (end of file) ukoliko je pročitan signal za kraj datoteke kao i u slučaju greške u toku čitanja. 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 U standardnom zaglavlju string.h definisane su sledeće funkcije: - strlen(cs)-vraća duzinu stringa cs. strcmp(cs,ct)-upoređuje niz cs sa nizom ct; vraća <0 ako je cs<ct, 0 ako je cs=st ili >0 ako je cs>ct. strcpy(s, c)-kopira niz c u niz s. strcpy(s, c,n)-kopira niz c u niz s prvih n karaktera. srtcat(s, c)-povezuje niz karaktera c iza niza s srtcat(s, c,n)-povezuje niz karaktera c iza niza s počevši od n-tog karaktera srtcmp(s, c)-upoređuje niz karaktera s sa nizom c srtcmp(s, c,n)-upoređuje prvih n karaktera niza s sa nizom c strchr(s, c)-pokazivač na prvi karakter niza c u nizu s strrchr(s, c)-pokazivač na poslednji karakter niza c u nizu s memcpy(s, c, n)-kopira n karaktera iz niza c u niz s memmove(s, c, n)-kopira n karaktera iz niza c u niz s sa mogućnošću preklapanja memchr(s, c, n)-pozakizvač na prvi c u privih n karaktera u nizu s memset(s, c, n)-smešta c u prvih na karaktera niza s U standardnom zaglavlju ctype.h definisane su sledeće funkcije: - isalnum(c)-ispituje da li je c alfanumerički karakter (slovo ili broj) isalpha(c)-ispituje da li je c alfabetski karakter (slovo) iscntrl(c)-ispituje da li je c kontrolni karakter isdigit(c)-ispituje da li je c cifra isgraph(c)-ispituje da li je c štampani karakter (ne uključuje prazninu) islower(c)-ispituje da li je c malo slovo isprint(c)-ispituje da li je c karakter (samo da nije praznina) ispunct (c)- ispituje da li je c znak izuzimajući praznine, slovo ili broj isspace(c)-ispituje da li je c praznina, formfeed, nova linija, vertikalni, horizontalni karaker isupper(c)-ispituje da li je c veliko slovo isxdigit(c)-ispituje da li je c heksadecimalni broj tolower(c)-pretvara c u malo slovo toupper(c)-pretvara c u veliko slovo isblank(c)- ispituje da li je c razmak ili '\t' (TAB)? 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]; printf("Upisite rec: "); scanf("%s", rec); printf("a) rec: %s\n", rec); printf("b) rec bez prvog znaka: %s\n", &rec[1]); printf("c) treci znak: %c\n", rec[2]); return 0; } 58. /*Prikazivanje tablice ASCII kodova*/ #include<stdio.h> void 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'); } } 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); } 60. /*Program za odredjivanje duzine nizova karaktera*/ #include<stdio.h> unsigned strlen(s) char *s; 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)); } 61. /*Primer koji radi sa stringovima korišćenjem <string.h> zaglavlja*/ #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); /*Provera unetog stringa*/ printf("Uneta je recenica: %s\n", buffer); /*Funkcija strlen daje duzinu stringa, odnosno broj karaktera u stringu*/ brojSlova=strlen(buffer); printf("Broj slova u recenici je: %d\n", brojSlova); /*Funkcija strlwr menja sva slova u zadatom stringu u mala slova*/ strlwr(buffer); printf("Uneta je recenica: %s\n", buffer); /*Funkcija strupr menja sva slova u zadatom stringu u velika slova*/ strupr(buffer); printf("Uneta je recenica: %s\n", buffer); /*Funkcija strcmp poredi dva stringa (drugi sa prvim argumentom)*/ printf("Uneti lozinku: "); gets(lozinka); provera=strcmp(buffer, lozinka); if (provera==0) /*ili if(!provera)*/ printf("tacno uneta lozinka\n"); else printf("pogresno uneta lozinka\n"); printf("Uneta je recenica: %s\n", 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); } 63. /*Program za ilustraciju brojanja reci u nizu karaktera*/ #include<stdio.h> unsigned wc(s) char *s; { unsigned n=0; while(*s) { while(*s==' '||*s=='\n'||*s=='\t') ++s; if(*s) { ++n; while(*s!=' '&&s!='\n'&&*s!='\t'&&*s!='\0') ++s; } } return(n); } main() { static char string[]="Ilustracija procesiranja nizova\t karaktera\n\t\n"; printf("Broj reci je %u\n",wc(string)); } return l; } 64./*Napisati program za odredjivanje broja velikih i malih slova u unetom tekstu.*/ #include <stdio.h> void main() { int ch; 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); } 65./*Napisati program za odredjivanje ukupnog broja karaktera u unetom tekstu.*/ #include <stdio.h> int main(void) { int ch; int ct = 0; while ((ch = getchar()) != EOF) ct++; printf("\n"); printf("Uneto je %d karaktera\n", ct); } 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++; } k=0; q+=k; } 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++])); } 70. /*Program za konverziju niza ASCII cifara u celobrojnu vrednost*/ #include<stdio.h> int isspace(c) char c; { return(c==' '||c=='\t'||c=='\n'); } int isdigit(c) char c; { return(c>='0'&&c<='9'); } int atoi(s) char *s; { int value=0,sign=1; char c; if(*s=='-') { ++s; sign=-1; } else if(*s=='+') ++s; while(isspace(*s)) ++s; while(isdigit(c=*s++)) value=10*value+c-'0'; return(sign*value); } void main() { char niz[81]; printf("Ukucajte broj:\n"); scanf("%s",niz); printf("\"%s\"=%d\n",niz,atoi(niz)); } 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> void izbaci(char *s){ int i,j,br=0; for(i=0, j=0 ; s[i] != '\0' ; i++){ 56 if (! (isalpha(s[i]) && ++br % 3 == 0) ) s[j++] = s[i]; } s[j] = '\0'; } int main ( void) { char s[] = "Ovo je niz iz kojeg treba izbaciti svako 3. slovo."; izbaci(s); printf("%s\n", s); return 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.*/ Rešenje 2: – umesto indeksa i i j koristimo pomoćni pokazivač void izbaci(char *s){ char *p; int br=0; p = s; for(; *s ; s++){ if (! (isalpha(*s) && ++br % 3 == 0) ){ *p = *s; p++; } } *p = '\0'; } 73. /*Program koji ucitava 7 imena i prezimena studenata. Imena nisu duza od 15 karaktera, a prez. 25. Zatim formira novi tekst koji je oblika: Ime Prezime: za svakog studenta. Potom odredjuje koji od ovako novoformiranih tekstova je najduzi i stampa ga.*/ #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]; for(i=0; i<BR_ST; i++){ printf("Uneti ime sledeceg studenta: "); gets(ime[i]); printf("Uneti prezime sledeceg studenta: "); gets(prezime[i]); strcpy(rez[i], ime[i]); strcat(rez[i], " "); strcat(rez[i], prezime[i]); strcat(rez[i],":"); D[i]=strlen(rez[i]); 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.*/ int palindrom(char *s){ int i=0,j; for(j=0 ; s[j]!='\0'; j++); while(i < j){ if (!isalpha(s[i])){ i++; continue; } if (!isalpha(s[j])){ j--; continue; } if (tolower(s[i]) != tolower(s[j])) return 0; else{ i++;j--; } } return 1; } Dinamički alocirani stringovi 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'; } int main (void) { char s[17]; printf("Upisite string: "); scanf("%[^\n]", s); brisi_samoglasnike(s); printf("Rez: \"%s\"\n", s); 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 Inicijalizacija strukture je slična inicijalizaciji vektora. Inicijalizacione vrednosti se navode između vitičasti zagrada razdvojene zarezom. 76. /*Program koji za za zadato tekuće vreme određuje naredno vreme.*/ #include<stdio.h> void main() { struct vreme{ int sat; int minut; int sekund; }tekuce_vreme,naredno_vreme; printf("Unesite tekuce vreme?[cc:mm:ss]"); scanf("%d:%d:%d",&tekuce_vreme.sat, &tekuce_vreme.minut, &tekuce_vreme.sekund); naredno_vreme=tekuce_vreme; if(++naredno_vreme.sekund==60) { naredno_vreme.sekund=0; if(++naredno_vreme.minut==60) { naredno_vreme.minut=0; if(++naredno_vreme.sat==24) naredno_vreme.sat=0; } } printf("Naredno vreme je %02d:%02d:%02d\n", naredno_vreme.sat, naredno_vreme.minut, naredno_vreme.sekund); } 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); } } 78. /*Program za prevodjenje srpskih reci na engleske (srpsko-engleski recnik)*/ #include<stdio.h> struct element { char srpski[20]; char engleski[50]; }; int strcmp(char*s1,char*s2) { while(*s1==*s2) { if(!*s1) 61 return(0); ++s1; ++s2; } return(*s1-*s2); } int bin_search(struct element recnik[],char*ukaz_niz,unsigned n) { int low=0; int mid,high=n-1; int result; while(low<=high) { mid=(low+high)/2; result=strcmp(ukaz_niz,recnik[mid].srpski); if(result<0) high=mid-1; else if(result>0) low=mid+1; else return(mid+1); } return(0); } void main(){ static struct element recnik[100]= {{"baba","old woman,grandmother"}, {"babica","widwife"}, {"badem","almond"}, {"bager","dredge"}, {"bajka","fairytale"}, {"bakalin","grocer"}}; unsigned j; int n=10; char rec[20]; printf("Ukucajte rec:\n"); scanf("%s",rec); j=bin_search(recnik,rec,6); if(!j) printf("Zalim, rec %s nije u recniku\n",rec); else printf("%s\n",recnik[j-1].engleski); } 79./* Napisati program koji pravi rang listu studenata koji su polagali prijemni ispit. Sa standardnog ulaza se unose sledeci podaci: ime studenta, cetiri ocene iz prethodnog skolovanja i broj bodova na prijemnom ispitu.*/ #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); } 80. /*Definisati strukturu GRAD sa podacima clanovima: ime, broj_stanovnika, prosecan_dohodak_radnika. Napisati program kojim se unose podaci o gradovima u Srbiji i stampati na standardnom izlazu ime grada sa najvecim brojem stanovnika. Izracunati ukupan dohodak svih unetih gradova.*/ #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); } 81. /*Napisati program za formiranje strukture podataka telefonski_imenik sa poljima: prezime, broj i adresa. Napisati program za sortiranje imenika prema prezimenu pretplatnika.*/ #include<stdio.h> #define DIM 10 typedef struct telefonski_imenik{ char prezime[20]; char broj[10]; char adresa[20]; }; 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; j<n; j++) if(niz[i].prezime<niz[j].prezime) razmeni(&niz[i], &niz[j]); } void main(){ struct telefonski_imenik nizImenik[DIM]; int n, i; printf("Uneti broj telefonskih pretplatnika: "); scanf("%d", &n); for(i=0; i<n; i++){ printf("Uneti prezime pretplatnika: "); scanf("%s", &nizImenik[i].prezime); printf("Uneti broj telefona pretplatnika: "); scanf("%s", &nizImenik[i].broj); printf("Uneti adresu pretplatnika: "); scanf("%s", &nizImenik[i].adresa);; } sort(nizImenik, n); 64 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].broj, nizImenik[i].adresa); } RAD SA DATOTEKAMA Datotekama se pristupa korišćenjem pokazatelja na strukturu FILE, koja je definisana u include datoteci stdio.h. Datoteka stdio.h se uključuje u program iskazom #include. U stdio.h definisane su i konstante EOF i NULL. Konstanta EOF označava kraj datoteka i najčešće ima vrednost -1. Konstanta NULL ima vrednost 0, i vraća se kao rezultat nekih funkcija za upravljanje datotekama u slučaju neuspešnog izvršavanja funkcija. fopen vraća pokazatelj na strukturu FILE, koji se dodeljuje promenljivoj in_file istog tipa. U slučaju neuspešnog otvaranja fopen, vraća vrednost NULL. Iz tog razloga neophodno je ispitati vraćenu vrednost, odnosno, dodati iskaz 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. Zatvaranje datoteke vrši se funkcijom fclose čija je deklaracija: int fclose(FILE *dat); 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); Primer za čitanje niza od najviše n_max celobrojnih podataka iz datoteke podaci: n=fread(vektor, sizeof(int), n_max, podaci); int fwrite(const void *niz, int vel, int br, FILE *dat); Funkcije za štampanje i unos podataka: fprintf-za štampanje podataka u datoteci (fajlu) sprintf-za štampanje znakovnog niza fscanf-za unos podataka u datoteku sscanf-za unos znakovnog niza. Funkcija getc() učitava jedan karakter iz specificirane datoteke. Ova funkcija je vrlo slična već opisanoj funkciji getchar, s tom razlikom što se učitavanje ne obavlja sa terminala nego iz datoteke. getc vraća vrednost EOF, ako je dosegnut kraj datoteke. Funkcija putc upusuje karakter u specificiranu datoteku. Zaglavlje funkcije je int putc(c,file_pointer) char c; 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); 82. /*Odrediti broj linija u tekstualnom fajlu sa imenom knjiga.txt.*/ #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)); nizRastojanja[brojacTacaka]=rastojanje;/*Rastojanje svake tacke od referentne pamtimo u nizu*/ printf("Rastojanje od %d tacke je: %8.4le\n", brojacTacaka+1, nizRastojanja[brojacTacaka]); brojacTacaka++; } minimalnoRastojanje=nizRastojanja[0];/*Pretpostavimo da je minimalno rastojanje izmedju prve tacke*/ for(i=0; i<brojacTacaka; i++){ if(nizRastojanja[i]<minimalnoRastojanje) minimalnoRastojanje=nizRastojanja[i]; } printf("Rastojanje najblize tacke od referentne je: %8.4le\n", minimalnoRastojanje); fclose(in); return 0; } 91. /*Dodavanje novih zapisa u datoteku o stedisama*/ stednovi.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; Stedisa prazno={0}; unsigned int sifra; unsigned int veldat; /*Otvaranje datoteka o stedisama*/ 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