Programiranje 1 Beleške sa vežbi Školska 2007/2008 godina Matematički fakultet, Beograd Jelena Tomašević January 23, 2008
2
Sadržaj 1 Programski jezik C 5 1.1 Identifikatori i ključne reči................................ 5 1.2 Tipovi i veličina podataka................................ 5 1.3 Konstante......................................... 6 1.4 Deklaracije........................................ 6 1.5 Prvi primeri u C-u.................................... 6 2 Programski jezik C 9 2.1 Funkcije printf i scanf.................................. 9 2.2 Operatori i izrazi..................................... 10 2.2.1 Aritmetički operatori............................... 11 2.2.2 Operatori dodele................................. 12 2.2.3 Operatori uvećana i umanjenja......................... 12 2.2.4 Relacioni i logički operatori........................... 13 2.3 Konverzija......................................... 15 2.3.1 Automatska konverzija.............................. 15 2.3.2 Eksplicitna konverzija.............................. 15 2.4 Kontrola toka if, while, do - while, for........................ 16 2.4.1 if.......................................... 16 2.4.2 Else-if....................................... 17 2.4.3 Petlja while.................................... 18 2.4.4 Petlja do-while.................................. 19 2.4.5 Petlja for..................................... 20 2.4.6 Naredbe break i continue............................ 22 3 Programski jezik C 25 3.1 Oblast važenja lokalnih promenljivih.......................... 25 3.2 Konverzija......................................... 25 3.2.1 Automatska konverzija.............................. 25 3.2.2 Eksplicitna konverzija.............................. 26 3.3 Ugnježdena petlja.................................... 26 3.4 Znakovni ulaz i izlaz - getchar i putchar........................ 27 3.5 Priprema za kolokvijum................................. 30 4 Programski jezik C 35 4.1 Switch........................................... 35 4.2 Uslovni izraz....................................... 36 4.3 Operator sizeof...................................... 37 4.4 Operator zarez...................................... 37 4.5 Nizovi osnovni pojmovi................................ 38
4 SADRŽAJ 4.6 Funkcije.......................................... 40 5 Programski jezik C 47 5.1 Statičke promenljive................................... 47 5.2 Lenjo izračunavanje................................... 49 5.3 Pokazivači......................................... 50 5.4 Zadaci za vežbu...................................... 52 6 Programski jezik C 55 6.1 Prenos parametara po vrednosti i preko pokazivača.................. 55 6.2 Prenos niza u f-ju..................................... 57 6.3 Funkcije za rad sa niskama (stringovima)....................... 59 7 Programski jezik C 63 7.1 Funkcije za rad sa niskama (stringovima) nastavak................ 63 7.2 Funkcije koje vrše konverziju.............................. 67 7.3 Sortiranje niza...................................... 69 7.4 Linearna i binarna pretraga niza............................ 71 7.5 Veza izmežu nizova i pokazivača............................ 73 7.6 Vraćanje nizova iz funkcije................................ 75 8 Programski jezik C 77 8.1 Pokazivač na funkciju.................................. 77 8.2 Strukture......................................... 78 8.3 Unije............................................ 84 9 Programski jezik C 87 9.1 Rad sa datotekama.................................... 87 9.2 Formiranje HTML dokumenta.............................. 96
1 Programski jezik C 1 1.1 Identifikatori i ključne reči Identifikator se može sastojati iz slova i cifara pri čemu ne sme počinjati cifrom. Potcrta se smatra slovom (uglavnom se koristi kod dužih identifikatora). Identifikatori se koriste za imena promenljivih, imena funkcija itd. Velika i mala slova se u C-u razlikuju. int x, X; /*To su dve razlicite promenljive!!!*/ Ključne reči se koriste za definisanje jezičkih konstrukcija kao što su if, else, for, while ili imena tipova kao što su int, double, float, char. Ključne reči se ne mogu koristiti za imena promenljivih. 1.2 Tipovi i veličina podataka Osnovni tipovi podataka: int celobrojna vrednost, najčešće 4 bajta (može i 2 bajta zavisi od računara), char jedan znak (celobrojna vrednost), jedan bajt, float realan broj jednostruke tacnosti, najčešće 4 bajta, double realan broj dvostruke tacnosti, najčešće 8 bajtova. Postoje modifikatori koje možemo pridružiti osnovnim tipovima a to su short i long. Tipu int se mogu pridružiti oba pri čemu navoženje ključne reči int nije obavezno: short int kratak_broj; long int dugacak_broj; short kratak; long dugacak; Na svakom računaru važi: broj bajtova(short) <= broj bajtova(int) <= broj bajtova(long) Tipu double se može pridružiti long dok se tipu float ne može pridružiti ni jedan modifikator. Postoje još i modifikatori signed i unsigned koji se mogu pridružiti celobrojnim tipovima (int, char, short i long). 1 Zasnovano na primerima sa sajtova http://www.matf.bg.ac.yu/ milan, http://www.matf.bg.ac.yu/ filip, http://www.matf.bg.ac.yu/ milena.
6 Jelena Tomašević Postoje i kvalifikatori signed i unsigned koji se odnose na označene i neoznačene cele brojeve. Npr. promenljiva tipa signed char uzima vrednosti od -128 do 127 dok promenljiva tipa unsigned char uzima vrednosti od 0 do 255. 1.3 Konstante Razlikujemo: Karakterske konstante To su konstante tipa char. Navode se izmežu jednostrukih navodnika; Celobrojne konstante To su konstante tipa int. Mogu biti dekadne, oktalne i heksadekadne. Oktalne počinju nulom a heksadekadne sekvencom 0x ili 0X. Mogu imati sufikse u ili U koji nagoveštavaju da se radi o neoznačenoj konstanti. Takože mogu imati i sufikse l ili L koji nagoveštavaju da se radi o konstanti tipa long; Realne konstante To su konstante tipa double i mogu biti sa ili bez eksponencijalnog dela. Mogu imati sufiks f ili F i on označava da se radi o konstanti tipa float. Realne konstante sa sufiksom l ili L su tipa long double. 1.4 Deklaracije Da bi se promenljiva mogla upotrebljavati u programu ona se mora na početku programa deklarisati. Prilikom deklaracije može se izvršiti i početna inicijalizacija. int broj; /* Deklaracija celog broja */ int vrednost=5; /* Deklaracija i inicijalizacija celog broja */ U programskom jeziku C komentari se navode izmežu /* i */. Mogu se prostirati u više linija i ne mogu biti ugnježdeni. Komentari u jednoj liniji se obeležavaju sa //. Postoji i kvalifikator const koji može biti dodeljen deklaraciji bilo koje promenljive da bi označio da se ona neće menjati const double e=2.71828182845905 1.5 Prvi primeri u C-u Primer 1 Napisati program koji na standardnom izlazu štampa Zdravo, svete!. printf("zdravo, svete!\n"); Izlaz iz programa: Zdravo, svete!
1.5 Prvi primeri u C-u 7 Primer 2 Šta je izlaz iz sledećeg programa? printf("zdravo, "); printf("svete!"); printf("\n"); Izlaz iz programa: Zdravo, svete! Primer 3 Uvoženje promenljivih u program. /* Deklaracija vise promenljivih istog tipa */ int rez,pom1,pom2; pom1=20; pom2=15; rez=pom1-pom2; /* Ispisivanje rezultata */ printf("rezultat je %d-%d=%d\n",pom1,pom2,rez); Izlaz iz programa: Rezultat je 20-15=5 Svaka prosta naredba u C-u završava se sa ;. Zadaci za praktikum: Zadatak 1 Napisati program koji sabira dva cela broja sa ulaza. Zadatak 2 Napisati program koji izračunava broj koji se dobija kada se 110 umanji za 10% (rešenje je 99). Zadatak 3 Napisati program za razmenu vrednosti dva cela broja. Zadatak 4 Napisati program za izračunavanje površine i zapremine pravog valjka zadatog svojom visinom H i poluprečnikom osnove r. Zadatak 5 Napisati program koji izračunava maksimum i minimum 3 cela broja sa ulaza. Zadatak 6 Napisati program koji izračunava rešenje proizvoljne kvadratne jednačine a x 2 + b x + c.
8 Jelena Tomašević
2 Programski jezik C 1 2.1 Funkcije printf i scanf Funkcija printf je bibliotečka funkcija koja prikazuje izlazne podatke u odreženom formatu. Primer korišćenja funkcije printf je: printf("%d\t%d\n", broj1, broj2); Prvi argument ove funkcije je uvek izmedju i odrežuje format u kome će se podaci ispisati na izlaz. Ova funkcija vraća kao vrednosti broj upisanih znakova na izlazu. Sekvenca \n u okviru prvog argumenta funkcije printf je C oznaka za prelazak u novi red, \t je oznaka za tabulator dok %d označava da će na tom mestu biti ispisana celobrojna vrednost argumenta koji je sa njim u paru. Svaka % konstrukcija je u paru sa odgovarajućim argumentom koji sledi. Da bi se ispisala vrednost promenljive koja je tipa char, u okviru prvog argumenta funkcije printf na odgovarajućem mestu se navodi sekvenca %c. %o se koristi za ispis oktalnog broja, %x za ispis heksadekadnog broja, %u za ispis neoznačenog dekadnog broja, %f, %e ili %g koristi se za ispis realnog broja (zavisi od toga na koji način želimo da ispišemo realan broj) i na kraju: %% koristi se za ispis znaka %, \\ koristi se za ispis znaka \, \ koristi se za ispis znaka. Postoji mogućnost da se precizira i širina polja u kome će se ispisati odgovarajuće vrednosti. Na primer koristimo %3c za štampanje karaktera na tri pozicije poravnato sdesna. Isto tako, koristimo %3d za štampanje broja na tri pozicije ili %6d za štampanje broja na 6 pozicija. Isto tako važi sledeće: %f štampaj kao realan broj %6f štampaj kao realan broj širok najviše 6 znakova %.2f štampaj kao realan broj sa dve decimale %6.2f štampaj kao realan broj širok najviše 6 znakova pri čemu su 2 iza decimalne tačke. Da bi se izvršilo levo poravnanje, izmežu % i odgovarajućeg karaktera dodaje se znak -. Primer 4 1 Zasnovano na primerima sa sajtova http://www.matf.bg.ac.yu/ milan, http://www.matf.bg.ac.yu/ filip, http://www.matf.bg.ac.yu/ milena.
10 Jelena Tomašević printf("slova:\n%3c\n%5c\n", z, Z ); Izlaz iz programa: Slova: z Z Formatizovan izlaz se ostvaruje pomoću funkcije scanf i ona je ulazna analogija funkcije printf. Primer korišćenja ove funkcije je: scanf("%d %d", &broj1, &broj2); Ova funkcija čita sa ulaza dva cela broja i smešta ih na adresu promenljivih broj1 i broj2, redom. (karakterom & se označava adresa). Kao rezultat, ova funkcija vraća broj uspešno dodeljenih ulaznih vrednosti. Naredni poziv funkcije scanf nastavlja čitanje neposredno iza poslednjeg znaka koji je već pročitan. Primer 5 Program prikazuje unos celog broja koristeći funkciju scanf("%d", &x) int x; printf("unesi ceo broj : "); /* Obratiti paznju na znak & pre imena promenljive u funkciji scanf. */ scanf("%d",&x); /* U funkciji printf nije potrebno stavljati &. */ printf("uneli ste broj %d\n", x); 2.2 Operatori i izrazi U C-u postoji veliki broj operatora i oni mogu biti unarni i binarni. Unarni mogu biti prefiksni i sufiksni a binarni su po pravilu infiksni. Operatori imaju svoj prioritet i asocijativnost. Kombinovanjem promenljivih, konstanti i operatora dobijamo izraze. Svaki izraz ima svoj tip i vrednost. Tip izraza zavisi od tipova podizraza koji ga čine kao i od operatora kojim se ovi podizrazi povezuju. Ako su operandi neodgovarajućeg tipa onda se vrši implicitna konverzija, ako je to moguće. Tip izraza se može eksplicitno promeniti tzv. cast operatorom (ispred izraza se u zagradi navede ime tipa u koji želimo da konvertujemo izraz).
2.2 Operatori i izrazi 11 2.2.1 Aritmetički operatori Operatori +, -, *, / i % nazivaju se aritmetički operatori. Rezultat aritmetičkih operacija je izraz istog tipa kao i operandi. Ako operandi nisu istog tipa onda se vrši implicitna konverzija užeg u širi tip. Posebno je zanimljiv operator /. On realizuje celobrojno deljenje ako su oba operanda celi brojevi, a realno deljenje ako je bar jedan od operanada realan broj. Da li će se izvršiti celobrojno ili realno deljenje zavisi isključivo od tipa operanada a ne od tipa promenljive u koju se rezultat smešta. Operator % se primenjuje samo na cele brojeve i daje ostatak pri deljenju. Primer 6 Program ilustruje neke od aritmetičkih operacija. int a, b; printf("unesi prvi broj : "); scanf("%d",&a); printf("unesi drugi broj : "); scanf("%d",&b); printf("zbir a+b je : %d\n",a+b); printf("razlika a-b je : %d\n",a-b); printf("proizvod a*b je : %d\n",a*b); printf("celobrojni kolicnik a/b je : %d\n", a/b); printf("pogresan pokusaj racunanja realnog kolicnika a/b je : %f\n", a/b); printf("realni kolicnik a/b je : %f\n", (float)a/(float)b); printf("i ovo je realni kolicnik a/b: %f\n", (float)a/b); printf("ostatak pri deljenju a/b je : %d\n", a%b); Ulaz: Unesi prvi broj : 2 <enter> Unesi drugi broj : 3 <enter> Izlaz: Zbir a+b je : 5 Razlika a-b je : -1 Proizvod a*b je : 6 Celobrojni kolicnik a/b je : 0 Progresan pokusaj racunanja realnog kolicnika a/b je : 0.000000 Realni kolicnik a/b je : 0.666667 I ovo je realni kolicnik a/b: 0.666667 Ostatak pri deljenju a/b je : 2 Primer 7 Program ilustruje celobrojno i realno deljenje. int a = 5;
12 Jelena Tomašević int b = 2; int d = 5/2; /* Celobrojno deljenje - rezultat je 2 */ float c = a/b; /* Iako je c float, vrsi se celobrojno deljenje jer su i a i b celi */ /* Neocekivani rezultat 2.000000 */ printf("c = %f\n",c); printf("uzrok problema : 5/2 = %f\n", 5/2); printf("popravljeno : 5.0/2.0 = %f\n", 5.0/2.0); printf("moze i : 5/2.0 = %f i 5.0/2 = %f \n", 5/2.0, 5.0/2); printf("za promenjive mora kastovanje : %f\n", (float)a/(float)b); Izlaz iz programa: c = 2.000000 Uzrok problema : 5/2 = 2.000000 Popravljeno : 5.0/2.0 = 2.500000 Moze i : 5/2.0 = 2.500000 i 5.0/2 = 2.500000 Za promenljive mora kastovanje : 2.500000 2.2.2 Operatori dodele Operator proste dodele je operator =. Levi operand ovog operatora je leva vrednost (ime promenljive) a desni operand je proizvoljan izraz. Najpre se izračuna izraz na desnoj strani, njegova vrednost se po potrebi konvertuje u tip promenljive na levoj strani i nakon toga se ta vrednost dodeljuje promenljivoj na levoj strani. Bitno je napomenuti da izraz dodele ima svoj tip (tip promenljive) i vrednost (vrednost dodeljena promenljivoj). Izrazrazi kao što je i = i + 2; u kojima se promenljiva na levoj strani odmah ponavlja na desnoj, mogu se pisati u skraćenom obliku kao i+ = 2; Operator += se naziva operator složene dodele. Ovo važi za većinu binarnih operatora (+ - * / %). Dakle, izraz1 op = izraz2 je ekvivalnetno sa izraz1 = (izraz1) op (izraz2). Na primer x = y + 1 je ekvivalento sa x = x (y + 1). 2.2.3 Operatori uvećana i umanjenja Operator ++ dodaje vrednost 1 svom operandu a -- oduzima 1. Ovo su unarni operatori i oni se mogu koristiti kao prefiksni (ispred promenljive, npr. ++n) i kao postfiksni (iza promenljive, npr. n++). U oba slučaja vrši se uvećanje promenljive za 1 ali izraz ++n uvećava promenljivu n pre nego što se njena vrednost koristi, dok n++ uvećava n nakon što se njena vrednost koristi. Tako se x=++n; razlikuje od x=n++;. Primer 8 Ilustracija prefiksnog i postfiksnog operatora ++
2.2 Operatori i izrazi 13 int x, y; int a = 0, b = 0; printf("na pocetku : \na = %d\nb = %d\n", a, b); /* Ukoliko se vrednost izraza ne koristi, prefiksni i postfiksni operator se ne razlikuju */ a++; ++b; printf("posle : a++; ++b; \na = %d\nb = %d\n", a, b); /* Prefiksni operator uvecava promenjivu, i rezultat je uvecana vrednost */ x = ++a; /* Postfiksni operator uvecava promenjivu, i rezultat je stara (neuvecana) vrednost */ y = b++; printf("posle : x = ++a; \na = %d\nx = %d\n", a, x); printf("posle : y = b++; \nb = %d\ny = %d\n", b, y); Izlaz iz programa: Na pocetku: a = 0 b = 0 Posle : a++; ++b; a = 1 b = 1 Posle : x = ++a; a = 2 x = 2 Posle : y = b++; b = 2 y = 1 2.2.4 Relacioni i logički operatori Relacioni operatori su: > >= < <=. Svi oni imaju isti prioritet. Niži prioritet imaju operatori poreženja na jednakost ==!=. Tako je a < 5!= 1 ekvivalentno sa (a < 5)!=1. Svi relacioni operatori imaju niži prioritet od aritmetičkih operatora. Tako je i < n-1 ekvivalentno sa i < (n-1). Logički operatori su:! unarna negacija, && logičko i, logičko ili.
14 Jelena Tomašević Prioritet logičkih operatora je niži od prioriteta relacionih operatora i operatora jednakosti. Operator! je višeg prioriteta u odnosu na && a on je višeg u odnosu na. Izrazi povezani logičkim operatorima izračunavaju se sleva na desno. Napomena: U C-u ne postoji logički tip! U tu svrhu se koristi celobrojni tip pri čemu se svaki ceo broj različit od nule smatra da ima logičku vrednost tačno, a nula ima vrednost netačno. Primeri: 5 && 4 vrednost je tačno, 10 0 vrednost je tačno, 0 && 5 vrednost je 0,!1 vrednost je 0,!9 vrednost je 0,!0 vrednost je 1,!(2>3) vrednost je 1. a>b && b>c b>d je isto što i ((a>b) && (b>c)) (b>d). Koja je vrednost ovog izraza ako je a=10, b=5, c=1, d=15? Primer 9 Ilustracija logičkih vrednosti (0 - netačno, različito od 0 - tačno). int a; printf("unesi ceo broj : "); scanf("%d", &a); if (a) printf("logicka vrednost broja je : tacno\n"); else printf("logicka vrednost broja je : netacno\n"); Ulaz: Unesi ceo broj : 3 <enter> Izlaz: Logicka vrednost broja je : tacno Ulaz: Unesi ceo broj : 0 <enter> Izlaz: Logicka vrednost broja je : netacno Primer 10 Ilustracija logičkih i relacijskih operatora. int a = 5<3, /* manje */
2.3 Konverzija 15 b = 5>3, /* vece */ c = 3==5, /* jednako */ d = 3!=5; /* razlicito */ printf("5<3 - %d\n5>3 - %d\n3==5 - %d\n3!=5 - %d\n", a, b, c, d); printf("konjunkcija : 3>5 && 5>3 - %d\n", a && b); printf("disjunkcija : 3>5 5>3 - %d\n", a b); printf("negacija :!(3>5) - %d\n",!a); Izlaz iz programa: 5<3-0 5>3-1 3==5-0 3!=5-1 Konjunkcija : 3>5 && 5>3-0 Disjunkcija : 3>5 5>3-1 Negacija :!(3>5) - 1 Operatori dodele su najnižeg prioriteta. Ako dva operatora imaju isti prioritet onda se u obzir uzima asocijativnost koja može biti s leva na desno ili s desna na levo. Prioritet operatora može se promeniti korišćenjem zagrada. 2.3 Konverzija 2.3.1 Automatska konverzija Ako je jedan od operanada razližličit vrši se konverzija, uvek u smeru manjeg ka većem tipu. Naredba dodele: int i=5; float f=2.3; f=i; /* f ce imati vrednost 5.0*/ obrnuto: int i=5; float f=2.3; i=f; /* i ce imati vrednost 2*/ 2.3.2 Eksplicitna konverzija (tip)<izraz> float x; x=2.3+4.2; /* x ce imati vrednost 6.5 */ x=(int)2.3+(int)4.2; /* x ce imati vrednost 6 */ x=(int)2.3*4.5; /* x ce imati vrednost 9.0 jer zbog prioriteta
16 Jelena Tomašević operatora konverzije prvo ce biti izvrsena konverzija broja 2.3 u 2 pa tek onda izvrseno mnozenje. */ x=(int)(2.3*4.5) /* x ce imati vrednost 10.0 */ Primer 11 Kako izbeći celobrojno deljenje int a,b; float c; a = 5; b = 2; c = a/b; /* Celobrojno deljenje, c=2*/ c = (1.0*a)/b; /* Implicitna konverzija: 1.0*a je realan broj pa priliko deljenja sa b dobija se realan rezultat c=2.5*/ c = (0.0+a)/b; /* Implicitna konverzija: (0.0+a) je realan broj pa priliko deljenja sa b dobija se realan rezultat c=2.5*/ c = (float)a/(float)b; /* Eksplicitna konverzija*/ 2.4 Kontrola toka if, while, do - while, for 2.4.1 if if (izraz) naredba1 else naredba2 Naredba može biti prosta naredba a može biti i složena naredba (blok) koja se dobije kada se više prostih naredbi grupišu navoženjem vitičastih zagrada. Primer 12 Program ilustruje if i ispisuje ukoliko je uneti ceo broj negativan. int int b; printf("unesi ceo broj:"); scanf("%d", &b); if (b < 0) printf("broj je negativan\n"); //prosta naredba return 0; Ulaz: Unesi ceo broj:-5 Izlaz: Broj je negativan Ulaz:
2.4 Kontrola toka if, while, do - while, for 17 Unesi ceo broj:5 Izlaz: Else se odnosi na prvi neuparen if. Ako želimo drugačije moramo da navedemo vitičaste zagrade. if (izraz) //prvo if if (izraz1) naredba1 //drugo if else naredba2 Ovo else se odnosi na drugo if a ne na prvo if! if (izraz) if (izraz1) naredba1 else naredba2 Tek sada se else odnosi na prvo if!!! 2.4.2 Else-if if (izraz1) iskaz1 else if (izraz2) iskaz2 else if (izraz3) iskaz3 else if (izraz4) iskaz4 else iskaz npr if (a<5) printf("a je manje od 5\n"); else if (a==5) printf("a je jednako 5\n"); else if (a>10) printf("a je vece od 10\n"); else if (a==10) printf("a je jednako 10\n"); else printf("a je vece od pet i manje od 10\n"); Primer 13 Program ilustruje if-else konstrukciju i ispituje znak broja. int int b; printf("unesi ceo broj : "); scanf("%d", &b); if (b < 0) printf("broj je negativan\n");
18 Jelena Tomašević else if (b == 0) printf("broj je nula\n"); else printf("broj je pozitivan\n"); return 0; Ulaz: Unesi ceo broj:-5 Izlaz: Broj je negativan Ulaz: Unesi ceo broj:5 Izlaz: Broj je pozitivan Primer 14 Pogresan program sa dodelom = umesto poredjenja ==. int int b; printf("unesi ceo broj : "); scanf("%d", &b); /* Obratiti paznju na = umesto == Analizirati rad programa*/ if (b = 0) printf("broj je nula\n"); else if (b < 0) printf("broj je negativan\n"); else printf("broj je pozitivan\n"); return 0; Ulaz: Unesi ceo broj:-5 Izlaz: Broj je pozitivan Napomena: Voditi računa o tome da je = operator dodele a == je operator poreženja na jednakost. Ne mešati ta dva operatora! 2.4.3 Petlja while while(izraz) naredba Uslov u zagradi se testira i ako je ispunjen telo petlje (naredba) se izvršava. Zatim se uslov ponovo testira i ako je ispunjen ponovo se izvršava telo petlje. I tako sve dok uslov ne postane neispunjen. Tada se izlazi iz petlje i nastavlja sa prvom sledećom naredbom u programu.
2.4 Kontrola toka if, while, do - while, for 19 Napomena: Voditi računa o tome da li je naredba koja čini telo petlje prosta ili složena! Ako nema vitičastih zagrada onda se prva naredba iza while(uslov) tretira kao telo while petlje. Na primer, u sledećem fragmentu koda while (i<j) i=2*i; j++; samo naredba i=2*i; se ponavlja u okviru while petlje dok se naredba j++; izvršava tek nakon izlaženja iz while petlje. Primer 15 Program ilustruje petlju - while. int int x; Izlaz: x = 1 x = 2 x = 3 x = 4 x = 5 x = 6 x = 7 x = 8 x = 9 x = 1; while (x<10) printf("x = %d\n",x); x++; /* x++ je isto kao i x=x+1 */ 2.4.4 Petlja do-while Ovo je slično repeat-until izrazu u Pascal-u. do naredba while (izraz); Primer 16 Program ilustruje petlju do-while. int
20 Jelena Tomašević Izlaz: x = 1 x = 2 x = 3 x = 4 x = 5 x = 6 x = 7 x = 8 x = 9 int x; x = 1; do printf("x = %d\n",x); x++; /* x++ je isto kao i x=x+1 */ while (x<10); 2.4.5 Petlja for for (izraz1; izraz2; izraz3) naredba Ovo je ekvivalentno kodu: izraz1; while (izraz2) naredba izraz3; Primer 17 Program ilustruje for petlju. int int x; Izlaz: x = 1 x = 2 for (x = 1; x < 10; x++) printf("x = %d\n",x);
2.4 Kontrola toka if, while, do - while, for 21 x = 3 x = 4 x = 5 x = 6 x = 7 x = 8 x = 9 Napomena: izraz1, izraz2, izraz3 i naredba mogu biti izostavljeni. Ako je izraz2 izostavljen podrazumeva se da je stalno tačan. for( ; ; ); pretstavlja beskonačnu for petlju. Primer 18 Konverzija centimetara u inče - while petlja. /* Definicija simbolickih konstanti preko #define direktiva */ /* U fazi pretprocesiranja se vrsi doslovna zamena konstanti njihovim vrednostima */ #define POCETAK 0 #define KRAJ 20 #define KORAK 10 int int a; a = POCETAK; while (a <= KRAJ) printf("%d cm = %f in\n", a, a/2.54); a += KORAK; /* isto sto i a = a + KORAK; */ return 0; Izlaz: 0 cm = 0.000000 in 10 cm = 3.937008 in 20 cm = 7.874016 in Primer 19 Konverzija centimetara u inče - for petlja. #define POCETAK 0 #define KRAJ 20 #define KORAK 10 int int a; for (a = POCETAK; a <= KRAJ; a += KORAK)
22 Jelena Tomašević printf("%d cm = %f in\n", a, a/2.54); return 0; Izlaz: 0 cm = 0.000000 in 10 cm = 3.937008 in 20 cm = 7.874016 in 2.4.6 Naredbe break i continue Naredba break omogućava prevremeni izlazak iz petlje a continue omogućava izlazak iz tekuće iteracije u petlji i nastavak izvršenja petlje počev od sledeće iteracije. Primer 20 Ilustracija naredbe break int int i; for(i=1; i<=5; i++) if(i==3) break; printf("i = %d\n", i); return 0; Izlaz: i = 1 i = 2 Primer 21 Ilustracija naredbe continue int int i; for(i=1; i<=5; i++) if(i==3) continue; printf("i = %d\n", i); return 0; Izlaz: i = 1
2.4 Kontrola toka if, while, do - while, for 23 i = 2 i = 4 i = 5 Zadaci za praktikum: Zadatak 7 Napisati program koji izračunava zbir recipročnih vrednosti prvih 10 brojeva. Zadatak 8 Izvršiti štampanje parnih brojeva od 1 do 100 (for, while i do-while). Zadatak 9 Napisati program koji izračunava sumu i maksimum brojeva koji se unose na standardni ulaz pri čemu je poslednji uneti broj 0 (for, while). Zadatak 10 Napisati program koji ispisuje kvadrate svih brojeva od 5 do 35. Nakon svakog petog kvadrata odštampati znak za novi red (for, while). Zadatak 11 Napisati program koji izračunava koliki je realni deo kompleksnog broja (1 + i) 21 (rešenje je -1024). Zadatak 12 Napisati program koji sabira pozitivne brojeve niza cifara koji završava nulom i koji se unose sa standardnog ulaza. Primer 22 Napisati program koji računa zbir 1 + x + x2 2 +... + xn n! Primer 23 Napisati program koji računa sumu x x3 3! + x5 5!... + ( 1) n x2n 1 (2n 1)! Primer 24 Napisati program koji računa sumu 1 x2 2! + x4 4!... + ( 1) n x2n (2n)! Primer 25 Napisati program koji računa sumu x x3 3 1! + x5 5 2! x7 x2n+1 7 3! +... + ( 1)n (2n+1) n!
24 Jelena Tomašević
3 Programski jezik C 1 3.1 Oblast važenja lokalnih promenljivih Primer 26 int pom=1; printf("pre ulaska u unutrasnji blok pom=%d\n",pom); int pom=50; printf("pre izlaska iz unutrasnjeg bloka pom=%d\n",pom); printf("nakon izlaska iz unutrasnjeg bloka pom=%d\n",pom); Izlaz: Pre ulaska u unutrasnji blok pom=1 Pre izlaska iz unutrasnjeg bloka pom=50 Nakon izlaska iz unutrasnjeg bloka pom=1 Primer 27 Program koji ispisuje prvih n prostih brojeva 3.2 Konverzija 3.2.1 Automatska konverzija Ako je jedan od operanada razližličit vrši se konverzija, uvek u smeru manjeg ka većem tipu Naredba dodele: int i=5; float f=2.3; f=i; /* f ce imati vrednost 5.0*/ 1 Zasnovano na primerima sa sajtova http://www.matf.bg.ac.yu/ filip,http://www.matf.bg.ac.yu/ milena.
26 Jelena Tomašević obrnuto: int i=5; float f=2.3; i=f; /* i ce imati vrednost 2*/ 3.2.2 Eksplicitna konverzija (tip)<izraz> float x; x=2.3+4.2; /* x ce imati vrednost 6.5 */ x=(int)2.3+(int)4.2; /* x ce imati vrednost 6 */ x=(int)2.3*4.5; /* x ce imati vrednost 9.0 jer zbog prioriteta operatora konverzije prvo ce biti izvrsena konverzija broja 2.3 u 2 pa tek onda izvrseno mnozenje. */ x=(int)(2.3*4.5) /* x ce imati vrednost 10.0 */ Primer 28 Kako izbeći celobrojno deljenje int a,b; float c; a = 5; b = 2; c = a/b; /* Celobrojno deljenje, c=2*/ c = (1.0*a)/b; /* Implicitna konverzija: 1.0*a je realan broj pa priliko deljenja sa b dobija se realan rezultat c=2.5*/ c = (0.0+a)/b; /* Implicitna konverzija: (0.0+a) je realan broj pa priliko deljenja sa b dobija se realan rezultat c=2.5*/ c = (float)a/(float)b; /* Eksplicitna konverzija*/ 3.3 Ugnježdena petlja Primer 29 Ilustracija dve ugnježdene petlje. #include<stdio.h> int int i,j; for(i=1; i<=3; i++) for(j=1; j<=3; j++) printf("%d * %d = %d\t", i, j, i*j); printf("\n"); Izlaz: 1 * 1 = 1 1 * 2 = 2 1 * 3 = 3
3.4 Znakovni ulaz i izlaz - getchar i putchar 27 2 * 1 = 2 2 * 2 = 4 2 * 3 = 6 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9 Primer 30 Program koji ispisuje tablicu množenja #include<stdio.h> int n, m; /* Dimenzije tablice */ int i, j; /* Brojaci */ scanf("%d", &n); scanf("%d", &m); /* Petlja po redovima... */ for(i = 0; i < n; i++) /* unutrasnja petlja */ for(j = 0; j < m; j++) printf("%d * %d = %d\t", i, j, i*j); /* na kraju prelazimo u sledeci red */ printf("\n"); 3.4 Znakovni ulaz i izlaz - getchar i putchar Standardna biblioteka obezbežuje nekoliko funkcija za čitanje i pisanje po jednog znaka posebno, od kojih su getchar i putchar najprostije. Primer korišćenja funkcije za čitanje jednog znaka sa ulaza je: c = getchar();. Nakon izvršetka ove naredbe, promenljiva c će sadržati jedan znak sa standardnog ulaza. Primer korišćenja funkcije za štampanje jednog znaka na izlazu je: putchar(c); Nakon izvršetka ove naredbe, štampa se karakter koji je sadržaj promenljive c na standardnom izlazu. Konstanta EOF je celobrojna vrednost definisana u biblioteci <stdio.h>. Ovo je vrednost koju vraća funkcija getchar() kada nema više ni jednog znaka na ulazu, odnosno kada se stigne do kraja ulazne datoteke. Nazvana je EOF kao End Of File, engleski prevod za kraj datoteke. Ova vrednost mora da se razlikuje od svake vrednosti koja može da bude karakter. Zato promenljiva c za koju se poziva c=getchar() treba da bude tipa dovoljno velikog da može da prihvati sve što može da vrati poziv ove funkcije, dakle sve što je karakter i plus EOF. Zbog toga se za c koristi tip int a ne char. Napomena: EOF se pod Linux-om označava karakterom ctrl-d a pod Windows-om u Dev- C++ sa enter ctrl-z enter. Primer 31 Program vrši demonstraciju poziva funkcija putchar i getchar. int c1, c2;
28 Jelena Tomašević c1 = getchar(); printf("------------\n"); c2 = getchar(); printf("c1 = %d, c2 = %d\n",c1, c2); printf("c1 = %c, c2 = %c\n",c1, c2); putchar(c1); /* isto je kao i printf("%c",c1); */ putchar(c2); /* isto je kao i printf("%c",c2); */ putchar( \n ); /* Za ispisivanje karaktera a */ putchar( a ); /* dozvoljeno je : printf("abc"); printf("a"); */ /* nedozvoljeno je : printf( a ); putchar( abc ); putchar("abc"); */ Ulaz: ab Izlaz: ------------ c1 = 97, c2 = 98 c1 = a, c2 = b ab a Primer 32 Program čita jedan karakter sa standardnog ulaza i ispisuje ga na standardnom izlazu. int c; /* Karakter - obratiti paznju na int */ c = getchar(); /* cita karakter sa standardnog ulaza */ putchar(c); /* pise karakter c na standardni izlaz */ putchar( \n ); /* prelazak u novi red */ putchar( a ); /* ispisuje malo a */ putchar(97); /* ekvivalentno prethodnom */ Ulaz: s Izlaz iz programa: s aa Primer 33 Program vrši prebrojavanje cifara unetih na ulazu. /* zbog isdigit */ #include <ctype.h>
3.4 Znakovni ulaz i izlaz - getchar i putchar 29 int c; int br_cifara = 0; while ((c = getchar())!= EOF) if (c>= 0 && c<= 9 ) /* moze i if (isdigit(c)) */ br_cifara++; printf("broj cifara je : %d\n", br_cifara); Napomena: Obratiti pažnju na zagrade u okviru while ( (znak=getchar() )!= EOF). Ako bi se izostavile onda bi se prvo ispitalo da li je getchar()!= EOF pa bi se vrednost (1 ii 0) dodelila promenljivoj znak, što nije željeni efekat. Primer 34 Napisati program koji prepisuje ulaz na izlaz tako što mala slova pretvara u velika, velika u mala, a ostale karaktere prepisuje nepromenjene. int c; while ((c = getchar())!= EOF) if (c>= a && c<= z ) putchar(c- a + A ); else if (c>= A && c<= Z ) putchar(c+ a - A ); else putchar(c); Primer 35 Program broji linije i znakove na ulazu. int znak; /* Prihvata znak sa ulaza */ long br_linija=0 ; /* Brojac linija */ long br_znakova=0; /* Brojac znakova na ulazu */ while ( (znak=getchar() )!= EOF) br_znakova++; if (znak== \n ) br_linija ++; printf("prelazaka u novi red: %ld, karaktera: %ld \n",br_linija,br_znakova); Primer 36 Program broji blankove, horizontalne tabulatore.
30 Jelena Tomašević int znak; /* Prihvata znak sa ulaza */ int br_blankova=0; /* Brojac blankova */ int br_tabulatora=0; /* Brojac horizontalnih tabulatora */ /* UOCITI: blok naredbi while ciklusa NIJE OGRADJEN viticastim zagradama jer postoji samo jedna if naredba! */ while( (znak=getchar())!=eof ) if( znak== ) ++br_blankova; /* brojimo blanko simbole */ else if( znak== \t ) ++br_tabulatora; /* brojimo tab-ove */ /* Izdavanje rezultata na standardnom izlazu */ printf("broj blankova je %d a tabulatora %d.\n", br_blankova, br_tabulatora); Primer 37 Napisati program koji prepisuje ulaz na izlaz čineći tabulatore, nove linije i backslashove vidljivim. int znak; znak=getchar(); while( znak!=eof ) if( znak== \t ) /*uciniti tab vidljivim */ putchar( \\ ); putchar( t ); else if( znak== \n ) /*uciniti new line vidljiv */ putchar( \\ ); putchar( n ); putchar( \n ); else if( znak== \\ ) /*backslash udvojiti */ putchar( \\ ); putchar( \\ ); else putchar(znak); /* */ znak=getchar(); /* while( znak!=eof ) */ 3.5 Priprema za kolokvijum Primer 38 Šta će biti izlaz iz sledećeg programa? printf("\"zdravo, svima\"\n"); printf("\\n\tprelazak u novi red\n"); printf("\\t\ttabulator\n"); printf("\\\\\tkosa crta\n"); printf("%%%%\tprocenat\n"); Izlaz iz programa:
3.5 Priprema za kolokvijum 31 "Zdravo, svima" \n prelazak u novi red \t tabulator \\ kosa crta %% procenat Primer 39 A šta iz ovog? putchar( \\ ); putchar( t ); putchar( \t ); printf("za %d ispisujem %c", \\, \\ ); printf("\n\n\\n\\\n\\\\n\n"); Izlaz iz programa: \t Za 92 ispisujem \ \n\ \\n Primer 40 int vrednost; vrednost= A ; printf("%s\nkarakter=%3c\nvrednost=%3d\n", "Veliko slovo",vrednost,vrednost); vrednost= a ; printf("%s\nkarakter=%3c\nvrednost=%3d\n", "Malo",vrednost,vrednost); Izlaz (u slucaju ASCII): Veliko slovo karakter= A vrednost= 65 Malo karakter= a vrednost= 97 Primer 41 Napisati program koji ispisuje ascii tabelu.
32 Jelena Tomašević int c; for (c = 0; c<128; c++) printf("%d - %c\n",c,c); Primer 42 Napisati program za razmenu vrednosti dva cela broja. Prvi nacin: int a = 10; int b = 15; int tmp; tmp = a; a = b; b = tmp; printf ("a=%d, b=%d\n", a, b); Drugi nacin: int a = 10; int b = 15; b = a+b; /* a = 10; b = 25; */ a = b-a; /* a = 15; b = 25; */ b = b-a; /* a = 15; b = 10; */ printf ("a=%d, b=%d\n", a, b); Primer 43 Napisati program koji menja mesta cifara u broju. int n,t=0; printf("unesite broj\n"); scanf("%d",&n); while(n) t=t*10+n%10; n/=10; printf("novi broj je %d\n", t);
3.5 Priprema za kolokvijum 33 return 0; Izlaz: Unesite broj 1234 Novi broj je 4321 Zadatak 13 Šta će biti ispisano nakon izvršavanja sledećeg programa? int x=506, y=3, z=21, t=2; printf("x=%d y=%d\n",x,y); printf("z - t=%d\n", z-t); printf("z / t =%d\n",z / t); printf("-x=%d\n",- x); printf("x %% y=%d\n", x%y); Zadatak 14 Dat je fragment C programa: i=1; j=1; while (i+j<10) ++j; i+=2; suma=i+j; a) Koliko puta će se ponoviti while ciklus? b) Koje su vrednosti promenljivih i, j, suma nakon izvršenja fragmenta? c) Napisati ekvivalentan for ciklus. Rešenje: a) 3 puta b)i=7, j=4, suma=11 c)for(i=1,j=1; i+j<10; ++j, i+=2); suma=i+j; Zadatak 15 Dat je fragment C programa: i=1; j=1; while (i+j<10) ++j; i+=2; suma=i+j; a) Koliko puta će se ponoviti while ciklus? b) Koje su vrednosti promenljivih i, j, suma nakon izvršenja fragmenta? c) Napisati ekvivalentan for ciklus. Rešenje: a) 8 puta b)i=3, j=9, suma=12 c)for(i=1,j=1; i+j<10; ++j); i+=2; suma=i+j;
34 Jelena Tomašević Zadaci za praktikum: Zadatak 16 Uraditi zadatke sa kolokvijuma.
4 Programski jezik C 1 4.1 Switch Naredba switch se naziva još i naredba višestrukog grananja. Ovom naredbom se proverava da li je neki izraz jednak jednoj od više konstantnih celobrojnih vrednosti i u zavisnosti od toga, preduzima se odgovarajuća akcija. Opšti oblik ove naredbe je: switch (izraz) case konstantan_izraz1: naredbe1 case konstantan_izraz2: naredbe2... default: naredbe Svaki konstantni izraz pretstavlja odreženi slučaj. Ako neki slučaj odgovara vrednosti izraza, izvršavanje počinje od tog slučaja. Svi izrazi slučajeva moraju biti različiti. Slučaj označen sa default nije obavezan. Ako se ne navede i nijedan drugi slučaj ne odgovara vrednosti izraza onda se neće izvršiti nikakva akcija. Primer 44 Ilustracija switch konstrukcije. #include<stdio.h> int int n; printf("unesi paran broj manji od 10\n"); scanf("%d",&n); switch(n) case 0: printf("uneli ste nulu\n"); break; case 2: printf("uneli ste dvojku\n"); 1 Zasnovano na primerima sa sajta http://www.matf.bg.ac.yu/ filip.
36 Jelena Tomašević break; case 4: printf("uneli ste cetvorku\n"); break; case 6: printf("uneli ste sesticu\n"); break; case 8: printf("uneli ste osmicu\n"); break; defalut: printf("uneli ste nesto sto nije paran broj\n"); return 0; Ulaz: Unesi paran broj manji od 10 2 Izlaz: Uneli ste dvojku Primer 45 Napisati program koji vrši brojanje pojavljivanja karaktera 0, 1 i 2 korišćenjem switch naredbe. int c; int br_0=0, br_1=0, br_2=0; while ((c = getchar())!= EOF) switch(c) /* Obratiti paznju da nije case 0: niti case 0 ; */ case 0 : br_0++; break; /* Isprobati veziju bez break */ case 1 : br_1++; break; case 2 : br_2++; break; printf("br 0 : %d\nbr 1 : %d\nbr 2 : %d\n",br_0, br_1, br_2); 4.2 Uslovni izraz Uslovni izrazi obezbežuju alternativni način pisanja if-else konstrukcije. Tako se if(izraz1)
4.3 Operator sizeof 37 izraz2; else izraz3; može zapisati kao izraz1? izraz2 : izraz3 Primer korišćenja uslovnog izraza: min = (a<b)? a : b; max = (a>b)? a : b; 4.3 Operator sizeof Operator sizeof izračunava veličinu tipa (ili promenljive) u broju bajtova koji zauzima u memoriji. Primer 46 Demonstracija sizeof operatora. #include<stdio.h> int i; float f; printf("sizeof(int)=%d\n", sizeof(int)); printf("sizeof(long)=%d\n", sizeof(long)); printf("sizeof(short)=%d\n", sizeof(short)); printf("sizeof(signed)=%d\n", sizeof(signed)); printf("sizeof(unsigned)=%d\n", sizeof(unsigned)); printf("sizeof(char)=%d\n", sizeof(char)); printf("sizeof(float)=%d\n", sizeof(float)); printf("sizeof(double)=%d\n", sizeof(double)); printf("sizeof(i)=%d\n", sizeof(i)); printf("sizeof(f)=%d\n", sizeof(f)); Izlaz iz programa(u konkretnom slucaju): sizeof(int)=4 sizeof(long)=4 sizeof(short)=2 sizeof(signed)=4 sizeof(unsigned)=4 sizeof(char)=1 sizeof(float)=4 sizeof(double)=8 sizeof(i)=4 sizeof(f)=4 4.4 Operator zarez Dva izraza razdvojena zarezom se izračunavaju sleva na desno, ali se vrednost levog izraza odbacuje. Tip i vrednost rezultata su tip i vrednost desnog operanda. Najčešće se koristi u okviru for petlje.
38 Jelena Tomašević Tako se na primer sledeći fragment programa: s=0; for(i=0; i<=3; i++) s+=i; korišćenjem operatora zarez može zapisati na sledeći način: for(s=0, i=0; i<=3; s+=i, i++); 4.5 Nizovi osnovni pojmovi Niz pretstavlja kolekciju elemenata istog tipa. Primer deklaracije niza je: int niz[5]; /* niz od 5 elemenata tipa int*/ Pristupanje elementima niza se ostvaruje na sledeći način: niz[0] = 4; niz[1] = 2 * niz[0]; /*niz[1] = 8*/ niz[2] = niz[0] * niz[1]; /*niz[2] = 32*/ niz[3] = 5; niz[4] = 7; Napomena: Prvi element u nizu se označava sa indeksom 0 a ne 1! Indeks niza može da bude proizvoljan izraz celobrojne vrednosti. Na primer može se napisati niz[i*2]=5. Primer unosa vrednosti elemenata niza sa standardnog ulaza: for(i=0; i<5; i++) scanf("%d ", &a[i]); Stampanje elemenata niza na standardni izlaz. for(i=0; i<5; i++) printf("%d ", a[i]); Primer 47 Program ilustruje korišćenje statičkih nizova. Ispisuje 10 unetih brojeva unazad. int a[10]; int i; for (i = 0; i<10; i++) printf("a[%d]=",i); scanf("%d",&a[i]); printf("unazad : \n"); for (i = 9; i>=0; i--) printf("a[%d]=%d\n",i,a[i]);
4.5 Nizovi osnovni pojmovi 39 Primer 48 Napisati program koji vrši brojanje pojavljivanja svake od cifara na standardnom ulazu. Koristiti niz brojača. #include <ctype.h> /* Niz brojaca za svaku od cifara */ int br_cifara[10]; int i, c; /* Resetovanje brojaca */ for (i = 0; i < 10; i++) br_cifara[i] = 0; /* Citamo sa ulaza i povecavamo odgovarajuce brojace */ while ((c = getchar())!= EOF) if (isdigit(c)) /* moze i if(c>= 0 && c<= 9 ) */ br_cifara[c- 0 ]++; /* Ispis rezultata */ for (i = 0; i < 10; i++) printf("cifra %d se pojavila %d put%s\n",i, br_cifara[i], br_cifara[i]==1?"":"a"); Primer 49 Program ilustruje inicijalizaciju nizova. /* Niz inicijalizujemo tako sto mu navodimo vrednosti u viticasnim zagradama. Dimenzija niza se odredjuje na osnovu broja inicijalizatora */ int a[] = 1, 2, 3, 4, 5, 6; /* Isto vazi i za niske karaktera */ char s[] = a, b, c ; /* Ekvivalentno prethodnom bi bilo char s[] = 97, 98, 99; */ /* Broj elemenata niza */ int a_br_elem = sizeof(a)/sizeof(int); int s_br_elem = sizeof(s)/sizeof(char); /* Ispisujemo nizove */ int i; for (i = 0; i < a_br_elem; i++) printf("a[%d]=%d\n",i, a[i]);
40 Jelena Tomašević for (i = 0; i < s_br_elem; i++) printf("s[%d]=%c\n",i, s[i]); 4.6 Funkcije Veliki računski zadaci mogu se razbiti u manje delove i time se omogućava ljudima da iskoriste ono što su neki drugi već uradili, umesto da počinju sve od početka. Odgovarajuće funkcije skrivaju detalje postupka od delova programa i time čine ceo program jasnijim i jednostavnijim za menjanje. Prilikom deklaracije funkcije navodi se tip povratne vrednosti funkcije (ako se ne navede podrazumeva se int), ime funkcije, lista argumenata i telo funkcije. Funkcija se poziva navoženjem imena funkcije i liste stvarnih argumenata. Primer 50 Napisati funkciju koja vrši sabiranje dva cela broja i program koji testira rad ove funkcije. /* Definicija funkcije */ int zbir(int a, int b) return a+b; /* Poziv funkcije */ printf("%d\n", zbir(3,5)); Deklaracija funkcije može da stoji nezavisno od definicije funkcije. Deklaracija je neophodna u situacijama kada se definicija funkcije navodi nakon upotrebe date funkcije u kodu. Primer 51 Funkcija koja sabira dva broja (deklaracija stoji nezavisno od definicije). int zbir(int, int); /* Deklaracija funkcije zbir() */ /* Poziv funkcije */ printf("%d\n", zbir(3,5)); /* Definicija funkcije */ int zbir(int a, int b) return a+b; Primer 52 power - funkcija koja stepenuje realan broj na celobrojni izlozilac. /* stepenuje x^k tako sto k puta pomnozi x */
4.6 Funkcije 41 float power(float x, int k) int i; float s = 1; for (i = 0; i<k; i++) s*=x; return s; /* Poziv funkcije */ float s = power(2.0,8); printf("%f\n", s); Primer 53 Verzija funkcije power koja radi i za negativne izlozioce. float power_n(float x, int k) int i; int negative = k<0; if (negative) k = -k; float s = 1; for (i = 0; i<k; i++) s*=x; return negative? 1.0/s : s; /* Poziv funkcije */ float s = power(2.0,-1); printf("%f\n", s); Primer 54 Napisati funkciju koja izračunava zbir n-tih stepena brojeva od 1 do granice i program koji ilustruje rad ove funkcije. long Zbir_stepena (int n, int granica); printf(" Zbir 2. stepena od 1 do 5 jeste %ld\n",zbir_stepena(2,5)); printf(" Zbir 3. stepena od 1 do 5 jeste %ld\n",zbir_stepena(3,5)); printf(" Zbir 4. stepena od 1 do 10 jeste %ld\n",zbir_stepena(4,10));
42 Jelena Tomašević return 0; long Zbir_stepena (int n, int granica) int i,j; /*brojaci u for petljama */ long Zbir=0, stepenovan ; /*spoljasnji for ciklus obavlja sumiranja*/ for (i=1; i<=granica; Zbir +=stepenovan, ++i) /*unutrasnji for ciklus obavlja stepenovanje */ for( stepenovan=1,j=1; j<=n; stepenovan*=i, ++j) ; return Zbir; Ako izuzmemo korišćenje operatora zarez, ova funkcija može da se napiše jednostavnije na sledeći način: long Zbir_stepena (int n, int granica) int i,j; /*brojaci u for petljama */ long Zbir=0, stepenovan ; /*spoljasnji for ciklus obavlja sumiranja*/ for (i=1; i<=granica; ++i) stepenovan=1; /*unutrasnji for ciklus obavlja stepenovanje */ for(j=1; j<=n; ++j) stepenovan*=i; Zbir +=stepenovan; return Zbir; Ako iskoristimo funkciju power iz prethodnog primera, ova funkcija može da se napiše još jednostavnije: long Zbir_stepena (int n, int granica) int i,j; /*brojaci u for petljama */ long Zbir=0; /*spoljasnji for ciklus obavlja sumiranja*/ for (i=1; i<=granica; ++i) Zbir +=power(i,n); return Zbir;
4.6 Funkcije 43 Izlaz: Zbir 2. stepena od 1 do 5 jeste 55 Zbir 3. stepena od 1 do 5 jeste 225 Zbir 4. stepena od 1 do 10 jeste 25333 Primer 55 Napisati funkciju koja izračunava zbir kvadrata brojeva od 1 do date granice kao i program koji ilustruje korišćenje date funkcije. void Zbir_Kvad(int n); /*f-ja koja vrsi zeljeno izracunavanje */ Zbir_Kvad( 5); Zbir_Kvad( 23); void Zbir_Kvad(int n) int br; /* lokalna promenljiva funkcije, brojac u ciklusu */ long Zbir=0; /* lokalna promenljiva funkcije, suma kvadrata brojeva od 1..n */ for (br=1; br<=n; Zbir+=br*br, ++br) ; printf(" Zbir kvadrata brojeva od 1 do %d jese %ld\n", n,zbir); Izlaz: Zbir kvadrata brojeva od 1 do 5 jese 55 Zbir kvadrata brojeva od 1 do 23 jese 4324 Primer 56 Napisati program u C-u koji prikazuje sve proste brojeve u datom intervalu kojima je zbir cifara složen broj. Interval se zadaje učitavanjem gornje i donje granice (dva prirodna broja). Brojeve prikazati u opadajućem poretku. #include <stdlib.h> int prost (int n); /*testira da li je broj n prost broj */ /* Svi prirodni brojevi (sem 1) imaju najmanje dva delioca: jedinicu i samog sebe. Brojevi koji nemaju drugih delioca, sem ova dva, nazivaju se prostim brojevima. */ int zbircifara (int n); /* vraca zbir cifara broja n */ int donja,gornja; /*granice intervala */ int i; /*brojac u petlji */ int pom; /*posrednik u eventualnoj zameni */ /*ucitavanja granice intervala */ scanf("%d%d", &donja, &gornja); if (donja > gornja) /*obezbedjivanje relacije: donja <=gornja */ pom=donja;
44 Jelena Tomašević donja=gornja; gornja=pom; for(i=gornja;i>=donja; i--) if (prost (i) &&!prost(zbircifara(i) ) ) printf("%d\n",i); int prost(int n) /*Ispituje se da li je broj n prost tako sto se proverava da li ima delioce medju brojevima od 2 do n/2. Pri implementaciji se koristi tvrdjenje da je broj prost ako je jednak 2, ili ako je neparan i ako nema delitelja medju neparnim brojevima od 3 do n/2 */ int prost; /*indikator slozenosti broja n */ int i; /*potencijalni delitelj broja n */ if (n==1) return 0; /*parni brojevi razliciti od od dva nisu prosti brojevi */ prost= (n%2!=0) (n==2); /*najmanji potencijalni kandidat za delitelje medju neparnim brojevima razlicitim od jedan */ i=3; while ( (prost) && (i<=n/2) ) prost=n%i!= 0; i=i+2; /*proveravamo kandidate za delitelje samo medju neparnim brojevma */ return prost; int zbircifara (int n) int Suma=0; while (n>0) Suma+= n%10; /*dodavanje cifre tekuceg razreda,pocev od razreda jedinica, a iduci ka visim razredima cifara */ n=n/10; /*prelaz ka visem razredu */ return Suma; Ulaz: 1 20 Izlaz: 19 17 13 Zadaci za vežbu: Zadatak 17 Sa tastature učitati elemente niza koji su celi brojevi i za koje se pretpostavlja da ih nema više od 100. Pronaći maksimalan elemenat niza i ispisati ga na izlaz.
4.6 Funkcije 45 Zadatak 18 Sa tastature se unosi 15 karaktera u niz. Ispitati da li uneti niz predstavlja palindrom (primer palindroma je anavolimilovana ). Zadatak 19 Ispisati prvih 15 članova Fibonačijevog niza. Zadatak 20 Napisati program koji ispituje da li dva niza imaju barem jedan zajednički element. Zadatak 21 Napisati f-ju koja za uneti broj n izračunava zbir recipročnih vrednosti prvih n brojeva. Zadatak 22 Ilustracija korišćenja funkcije za izračunavanje faktorijela celog broja. (a) Napisati funkciju koja izračunava faktorijel celog broja. (b) Napisati program koji izračunava faktorijel unetog broja koristeći prethodno definisanu funkciju. Zadatak 23 Ilustracija korišćenja funkcije za proveru da li je broj prost. (a) Napisati funkciju koja za ceo broj proverava da li je prost. (b) Napisati program koji štampa prvih 100 prostih brojeva. Zadaci za praktikum: Zadatak 24 Sledeći program koji prepisuje standardni ulaz na standardni izlaz pokrenuti sa: (iustracija redirekcije standardnog ulaza i izlaza)./a.out <zadatak.c./a.out >tekst.txt./a.out <zadatak.c >kopija.c int c; /* Obratiti paznju na raspored zagrada */ while ((c = getchar())!= EOF) putchar(c); Zadatak 25 Napisati program koji prepisuje ulaz na izlaz pri čemu više blanko znakova zamenjuje jednim. Zadatak 26 Napisati program koji prepisuje ulaz na izlaz pri čemu velika slova pretvara u mala a mala u velika. Zadatak 27 Napisati funkciju koja izračunava broj redova u tekstu i program koji vrši njeno testiranje.
46 Jelena Tomašević
5 Programski jezik C 1 5.1 Statičke promenljive Primer 57 Demonstracija životnog veka i oblasti važenja promenjivih (scope). /* Globalna promenjiva */ int a = 0; /* Uvecava se globalna promenjiva a */ void increase() a++; printf("increase::a = %d\n", a); /* Umanjuje se lokalna promenjiva a. Globalna promenjiva zadrzava svoju vrednost. */ void decrease() /* Ovo a je nezavisna promenjiva u odnosu na globalno a */ int a = 0; a--; printf("decrease::a = %d\n", a); void nonstatic_var() /* Nestaticke promenjive ne cuvaju vrednosti kroz pozive funkcije */ int s=0; s++; printf("nonstatic::s=%d\n",s); 1 Zasnovano na primerima sa sajtova http://www.matf.bg.ac.yu/ filip,http://www.matf.bg.ac.yu/ milena.
48 Jelena Tomašević void static_var() /* Staticke promenjive cuvaju vrednosti kroz pozive funkcije. Inicijalizacija se odvija samo u okviru prvog poziva. */ static int s=0; s++; printf("static::s=%d\n",s); /* Promenjive lokalne za funkciju main */ int i; int x = 3; printf("main::x = %d\n", x); for (i = 0; i<3; i++) /* Promenjiva u okviru bloka je nezavisna od spoljne promenjive. Ovde se koristi promenjiva x lokalna za blok petlje koja ima vrednost 5, dok originalno x i dalje ima vrednost 3*/ int x = 5; printf("for::x = %d\n", x); /* U ovom bloku x ima vrednost 3 */ printf("main::x = %d\n", x); increase(); decrease(); /* Globalna promenjiva a */ printf("main::a = %d\n", a); /* Demonstracija nestatickih promenjivih */ for (i = 0; i<3; i++) nonstatic_var(); /* Demonstracija statickih promenjivih */ for (i = 0; i<3; i++) static_var(); Izlaz iz programa: main::x = 3 for::x = 5 for::x = 5 for::x = 5 main::x = 3
5.2 Lenjo izračunavanje 49 increase::a = 1 decrease::a = -1 main::a = 1 nonstatic::s=1 nonstatic::s=1 nonstatic::s=1 static::s=1 static::s=2 static::s=3 5.2 Lenjo izračunavanje Primer 58 Ilustracija lenjog izračunavanja logičkih operatora. Prilikom izračunavanja izraza - A && B, ukoliko je A netačno, izraz B se ne izračunava. Prilikom izračunavanja izraza - A B, ukoliko je A tačno, izraz B se ne izračunava. int b = 0; /* Funkcija ispisuje da je pozvana i uvecava promenjivu b. Funkcija uvek vraca vrednost 1 (tacno) */ int izracunaj() printf("pozvano izracunaj()\n"); b++; return 1; /* Funkcija izracunaj() ce se pozivati samo za parne vrednosti a */ int a; for (a = 0; a < 10; a++) if (a%2 == 0 && izracunaj()) printf("uslov ispunjen : a = %d, b = %d\n", a, b); else printf("uslov nije ispunjen : a = %d, b = %d\n", a, b); printf("----------------------------\n"); /* Funkcija izracunaj() ce se pozivati samo za neparne vrednosti a */ b = 0; for (a = 0; a < 10; a++) if (a%2 == 0 izracunaj()) printf("uslov ispunjen : a = %d, b = %d\n", a, b); else printf("uslov nije ispunjen : a = %d, b = %d\n", a, b); Izlaz:
50 Jelena Tomašević Pozvano izracunaj() Uslov ispunjen : a = 0, b = 1 Uslov nije ispunjen : a = 1, b = 1 Pozvano izracunaj() Uslov ispunjen : a = 2, b = 2 Uslov nije ispunjen : a = 3, b = 2 Pozvano izracunaj() Uslov ispunjen : a = 4, b = 3 Uslov nije ispunjen : a = 5, b = 3 Pozvano izracunaj() Uslov ispunjen : a = 6, b = 4 Uslov nije ispunjen : a = 7, b = 4 Pozvano izracunaj() Uslov ispunjen : a = 8, b = 5 Uslov nije ispunjen : a = 9, b = 5 ---------------------------- Uslov ispunjen : a = 0, b = 0 Pozvano izracunaj() Uslov ispunjen : a = 1, b = 1 Uslov ispunjen : a = 2, b = 1 Pozvano izracunaj() Uslov ispunjen : a = 3, b = 2 Uslov ispunjen : a = 4, b = 2 Pozvano izracunaj() Uslov ispunjen : a = 5, b = 3 Uslov ispunjen : a = 6, b = 3 Pozvano izracunaj() Uslov ispunjen : a = 7, b = 4 Uslov ispunjen : a = 8, b = 4 Pozvano izracunaj() Uslov ispunjen : a = 9, b = 5 5.3 Pokazivači Pokazivač je promenljiva koja sadrži adresu neke druge promenljive. int x=1, y=1, z[10]; int *ip; /* ip je pokazivac na int, odnosno *ip je tipa int */ ip = &x; /* ip sada pokazuje na x */ y=*ip; /* y je sada 1 */ *ip = 0; /* x je sada 0 */ *ip+=10; /* x je sada 10*/ ++*ip; /* x je sada 11*/ (*ip)++; /* x je sada 12, zagrada neophodna zbog prioriteta operatora*/ ip = &z[0]; /* ip sada pokazuje na z[0]*/