97
Programiranje 1 Beleˇ ske sa veˇ zbi ˇ Skolska 2007/2008 godina Matematiˇ cki fakultet, Beograd Jelena Tomaˇ sevi´ c January 23, 2008

Programiranje 1 - Emir Ugljaninemirugljanin.com/ap/Vezbe.pdf · Programiranje 1 Beleˇske sa veˇzbi Skolska 2007/2008 godinaˇ Matematiˇcki fakultet, Beograd Jelena Tomaˇsevi´c

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

  • Programiranje 1Beleš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 51.1 Identifikatori i ključne reči . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.2 Tipovi i veličina podataka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.3 Konstante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.4 Deklaracije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.5 Prvi primeri u C-u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    2 Programski jezik C 92.1 Funkcije printf i scanf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.2 Operatori i izrazi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

    2.2.1 Aritmetički operatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.2.2 Operatori dodele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.2.3 Operatori uvećana i umanjenja . . . . . . . . . . . . . . . . . . . . . . . . . 122.2.4 Relacioni i logički operatori . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

    2.3 Konverzija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.3.1 Automatska konverzija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.3.2 Eksplicitna konverzija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

    2.4 Kontrola toka — if, while, do - while, for . . . . . . . . . . . . . . . . . . . . . . . . 162.4.1 if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.4.2 Else-if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.4.3 Petlja while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.4.4 Petlja do-while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.4.5 Petlja for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.4.6 Naredbe break i continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

    3 Programski jezik C 253.1 Oblast važenja lokalnih promenljivih . . . . . . . . . . . . . . . . . . . . . . . . . . 253.2 Konverzija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

    3.2.1 Automatska konverzija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.2.2 Eksplicitna konverzija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

    3.3 Ugnježdena petlja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.4 Znakovni ulaz i izlaz - getchar i putchar . . . . . . . . . . . . . . . . . . . . . . . . 273.5 Priprema za kolokvijum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

    4 Programski jezik C 354.1 Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354.2 Uslovni izraz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364.3 Operator sizeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374.4 Operator zarez . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374.5 Nizovi — osnovni pojmovi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

  • 4 SADRŽAJ

    4.6 Funkcije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

    5 Programski jezik C 475.1 Statičke promenljive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475.2 Lenjo izračunavanje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495.3 Pokazivači . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505.4 Zadaci za vežbu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

    6 Programski jezik C 556.1 Prenos parametara po vrednosti i preko pokazivača . . . . . . . . . . . . . . . . . . 556.2 Prenos niza u f-ju . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576.3 Funkcije za rad sa niskama (stringovima) . . . . . . . . . . . . . . . . . . . . . . . 59

    7 Programski jezik C 637.1 Funkcije za rad sa niskama (stringovima) — nastavak . . . . . . . . . . . . . . . . 637.2 Funkcije koje vrše konverziju . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677.3 Sortiranje niza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697.4 Linearna i binarna pretraga niza . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717.5 Veza izmeu nizova i pokazivača . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737.6 Vraćanje nizova iz funkcije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

    8 Programski jezik C 778.1 Pokazivač na funkciju . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 778.2 Strukture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 788.3 Unije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

    9 Programski jezik C 879.1 Rad sa datotekama . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 879.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 ” ” sesmatra slovom (uglavnom se koristi kod dužih identifikatora). Identifikatori se koriste za imenapromenljivih, 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 imenatipova 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 intse mogu pridružiti oba pri čemu navoenje 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)

  • 6 Jelena Tomašević

    Postoje i kvalifikatori signed i unsigned koji se odnose na označene i neoznačene cele brojeve.Npr. promenljiva tipasigned char uzima vrednosti od -128 do 127dok promenljiva tipaunsigned char uzima vrednosti od 0 do 255.

    1.3 Konstante

    Razlikujemo:

    • Karakterske konstante— To su konstante tipa char. Navode se izmeu jednostrukih navod-nika;

    • Celobrojne konstante — To su konstante tipa int. Mogu biti dekadne, oktalne i hek-sadekadne. Oktalne počinju nulom a heksadekadne sekvencom 0x ili 0X. Mogu imati sufikseu ili U koji nagoveštavaju da se radi o neoznačenoj konstanti. Takoe mogu imati i sufikse lili 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 konstantesa 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 deklar-isati. 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 izmeu /* i */. Mogu se prostirati u vǐse linijai 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čioda 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!”.

    #include

    main(){

    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?

    #include

    main(){

    printf("Zdravo, ");printf("svete!");printf("\n");

    }

    Izlaz iz programa:Zdravo, svete!

    Primer 3 Uvoenje promenljivih u program.

    #include

    main(){/* Deklaracija vise promenljivih istog tipa */int rez,pom1,pom2;pom1=20;pom2=15;rez=pom1-pom2;

    /* Ispisivanje rezultata */printf("Rezultat je %d-%d=%d\n",pom1,pom2,rez);}

    Izlaz iz programa:Rezultat je 20-15=5

    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 svojomvisinom 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 ∗ x2 + 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 odreenom formatu. Primerkorǐsćenja funkcije printf je:

    printf("%d\t%d\n", broj1, broj2);

    Prvi argument ove funkcije je uvek izmedju ”” i odreuje format u kome će se podaci ispisati naizlaz. Ova funkcija vraća kao vrednosti broj upisanih znakova na izlazu. Sekvenca \n u okviruprvog argumenta funkcije printf je C oznaka za prelazak u novi red, \t je oznaka za tabulatordok %d označava da će na tom mestu biti ispisana celobrojna vrednost argumenta koji je sa njimu 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 funkcijeprintf 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 ispǐsemo realanbroj) 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. Naprimer 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žisledeće:%f — štampaj kao realan broj%6f — štampaj kao realan broj širok najvǐse 6 znakova%.2f — štampaj kao realan broj sa dve decimale%6.2f — štampaj kao realan broj širok najvǐse 6 znakova pri čemu su 2 iza decimalne tačke.

    Da bi se izvršilo levo poravnanje, izmeu % i odgovarajućeg karaktera dodaje se znak -.

    Primer 41Zasnovano 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ć

    #include main(){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 korǐsć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 dodeljenihulaznih vrednosti. Naredni poziv funkcije scanf nastavlja čitanje neposredno iza poslednjeg znakakoji je već pročitan.

    Primer 5 Program prikazuje unos celog broja koristeći funkciju scanf("%d", &x)

    #include

    main(){

    int x;printf("Unesi ceo broj : ");

    /* Obratiti paznju na znak &pre imena promenljive u funkciji scanf. */scanf("%d",&x);

    /* U funkciji printf nijepotrebno 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 isufiksni a binarni su po pravilu infiksni. Operatori imaju svoj prioritet i asocijativnost.

    Kombinovanjem promenljivih, konstanti i operatora dobijamo izraze. Svaki izraz ima svoj tipi vrednost.

    Tip izraza zavisi od tipova podizraza koji ga čine kao i od operatora kojim se ovi podizrazipovezuju. Ako su operandi neodgovarajućeg tipa onda se vrši implicitna konverzija, ako je tomoguće. Tip izraza se može eksplicitno promeniti tzv. cast operatorom (ispred izraza se u zagradinavede 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 jeizraz istog tipa kao i operandi. Ako operandi nisu istog tipa onda se vrši implicitna konverzijaužeg u širi tip. Posebno je zanimljiv operator /. On realizuje celobrojno deljenje ako su obaoperanda celi brojevi, a realno deljenje ako je bar jedan od operanada realan broj. Da li će seizvršiti celobrojno ili realno deljenje zavisi isključivo od tipa operanada a ne od tipa promenljive ukoju 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.

    #include main(){

    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 Unesi drugi broj : 3 Izlaz:Zbir a+b je : 5Razlika a-b je : -1Proizvod a*b je : 6Celobrojni kolicnik a/b je : 0Progresan pokusaj racunanja realnog kolicnika a/b je : 0.000000Realni kolicnik a/b je : 0.666667I ovo je realni kolicnik a/b: 0.666667Ostatak pri deljenju a/b je : 2

    Primer 7 Program ilustruje celobrojno i realno deljenje.#include

    main(){

    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.000000Uzrok problema : 5/2 = 2.000000Popravljeno : 5.0/2.0 = 2.500000Moze i : 5/2.0 = 2.500000 i 5.0/2 = 2.500000Za 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 vrednostse po potrebi konvertuje u tip promenljive na levoj strani i nakon toga se ta vrednost dodeljujepromenljivoj na levoj strani. Bitno je napomenuti da izraz dodele ima svoj tip (tip promenljive) ivrednost (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ćenomobliku 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 semogu 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 prenego što se njena vrednost koristi, dok n++ uvećava n nakon što se njena vrednost koristi. Takose x=++n; razlikuje od x=n++;.

    Primer 8 Ilustracija prefiksnog i postfiksnog operatora ++

  • 2.2 Operatori i izrazi 13

    #include main(){

    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 ipostfiksni operator se ne razlikuju */

    a++;++b;printf("Posle : a++; ++b; \na = %d\nb = %d\n", a, b);

    /* Prefiksni operator uvecava promenjivu, i rezultatje uvecana vrednost */

    x = ++a;

    /* Postfiksni operator uvecava promenjivu, i rezultat jestara (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 = 0b = 0Posle : a++; ++b;a = 1b = 1Posle : x = ++a;a = 2x = 2Posle : y = b++;b = 2y = 1

    2.2.4 Relacioni i logički operatori

    Relacioni operatori su: > >= <

  • 14 Jelena Tomašević

    Prioritet logičkih operatora je niži od prioriteta relacionih operatora i operatora jednakosti.Operator ! je vǐseg prioriteta u odnosu na && a on je vǐseg 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 izrazaako je a=10, b=5, c=1, d=15?

    Primer 9 Ilustracija logičkih vrednosti (0 - netačno, različito od 0 - tačno).

    #include

    main(){

    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 Izlaz:Logicka vrednost broja je : tacno

    Ulaz:Unesi ceo broj : 0 Izlaz:Logicka vrednost broja je : netacno

    Primer 10 Ilustracija logičkih i relacijskih operatora.

    #include

    main(){

    int a = 5

  • 2.3 Konverzija 15

    b = 5>3, /* vece */c = 3==5, /* jednako */d = 3!=5; /* razlicito */

    printf("53 - %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:53 - 13==5 - 03!=5 - 1Konjunkcija : 3>5 && 5>3 - 0Disjunkcija : 3>5 || 5>3 - 1Negacija : !(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 korǐsć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)

    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 izvrsenakonverzija broja 2.3 u 2 pa tek onda izvrsenomnozenje. */

    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 serealan rezultat c=2.5*/

    c = (0.0+a)/b; /* Implicitna konverzija: (0.0+a) je realanbroj pa priliko deljenja sa b dobija serealan 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

    elsenaredba2

    Naredba može biti prosta naredba a može biti i složena naredba (blok) koja se dobije kada sevǐse prostih naredbi grupǐsu navoenjem vitičastih zagrada.

    Primer 12 Program ilustruje if i ispisuje ukoliko je uneti ceo broj negativan.

    #include

    int main(){

    int b;printf("Unesi ceo broj:");scanf("%d", &b);if (b < 0)

    printf("Broj je negativan\n"); //prosta naredbareturn 0;

    }

    Ulaz:Unesi ceo broj:-5Izlaz:Broj je negativan

    Ulaz:

  • 2.4 Kontrola toka — if, while, do - while, for 17

    Unesi ceo broj:5Izlaz:

    Else se odnosi na prvi neuparen if. Ako želimo drugačije moramo da navedemo vitičaste zagrade.

    if (izraz) //prvo ifif (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 (a10)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.

    #include

    int main(){

    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");

    elseprintf("Broj je pozitivan\n");

    return 0;}

    Ulaz:Unesi ceo broj:-5Izlaz:Broj je negativan

    Ulaz:Unesi ceo broj:5Izlaz:Broj je pozitivan

    Primer 14 Pogresan program sa dodelom = umesto poredjenja ==.

    #include

    int main(){

    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:-5Izlaz:Broj je pozitivan

    Napomena: Voditi računa o tome da je = operator dodele a == je operator poreenja na jednakost.Ne mešati ta dva operatora!

    2.4.3 Petlja while

    while(izraz) naredbaUslov u zagradi se testira i ako je ispunjen telo petlje (naredba) se izvršava. Zatim se uslov ponovotestira 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! Akonema vitičastih zagrada onda se prva naredba iza while(uslov) tretira kao telo while petlje. Naprimer, u sledećem fragmentu koda

    while (i

  • 20 Jelena Tomašević

    int x;

    x = 1;do{

    printf("x = %d\n",x);x++; /* x++ je isto kao i x=x+1 */

    }while (x

  • 2.4 Kontrola toka — if, while, do - while, for 21

    x = 3x = 4x = 5x = 6x = 7x = 8x = 9

    Napomena: izraz1, izraz2, izraz3 i naredba mogu biti izostavljeni. Ako je izraz2 izostavl-jen podrazumeva se da je stalno tačan.for( ; ; ); pretstavlja ”beskonačnu” for petlju.

    Primer 18 Konverzija centimetara u inče - while petlja.

    #include

    /* 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 main(){

    int a;a = POCETAK;while (a

  • 22 Jelena Tomašević

    printf("%d cm = %f in\n", a, a/2.54);

    return 0;}

    Izlaz:0 cm = 0.000000 in10 cm = 3.937008 in20 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ćeiteracije u petlji i nastavak izvršenja petlje počev od sledeće iteracije.

    Primer 20 Ilustracija naredbe break

    #include

    int main(){

    int i;for(i=1; i

  • 2.4 Kontrola toka — if, while, do - while, for 23

    i = 2i = 4i = 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 stan-dardni 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 petogkvadrata 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 kojise 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− x33! + x5

    5! − . . . + (−1)n ∗ x2n−1

    (2n−1)!

    Primer 24 Napisati program koji računa sumu 1− x22! + x4

    4! − . . . + (−1)n x2n

    (2n)!

    Primer 25 Napisati program koji računa sumu x− x33∗1! + x5

    5∗2! − x7

    7∗3! + . . . + (−1)n x2n+1

    (2n+1)∗n!

  • 24 Jelena Tomašević

  • 3

    Programski jezik C

    1

    3.1 Oblast važenja lokalnih promenljivih

    Primer 26

    #include

    main(){

    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=1Pre izlaska iz unutrasnjeg bloka pom=50Nakon 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*/

    1Zasnovano 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)

    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 izvrsenakonverzija broja 2.3 u 2 pa tek onda izvrsenomnozenje. */

    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 serealan rezultat c=2.5*/

    c = (0.0+a)/b; /* Implicitna konverzija: (0.0+a) je realanbroj pa priliko deljenja sa b dobija serealan rezultat c=2.5*/

    c = (float)a/(float)b; /* Eksplicitna konverzija*/

    3.3 Ugnježdena petlja

    Primer 29 Ilustracija dve ugnježdene petlje.

    #include

    int main(){

    int i,j;for(i=1; i

  • 3.4 Znakovni ulaz i izlaz - getchar i putchar 27

    2 * 1 = 2 2 * 2 = 4 2 * 3 = 63 * 1 = 3 3 * 2 = 6 3 * 3 = 9

    Primer 30 Program koji ispisuje tablicu množenja

    #include

    main() {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 obezbeuje nekoliko funkcija za čitanje i pisanje po jednog znaka posebno,od kojih su getchar i putchar najprostije.

    Primer korǐsć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 korǐsć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 standardnomizlazu.

    Konstanta EOF je celobrojna vrednost definisana u biblioteci . Ovo je vrednost kojuvraća funkcija getchar() kada nema vǐse ni jednog znaka na ulazu, odnosno kada se stigne dokraja ulazne datoteke. Nazvana je EOF kao End Of File, engleski prevod za kraj datoteke. Ovavrednost mora da se razlikuje od svake vrednosti koja može da bude karakter. Zato promenljivac za koju se poziva c=getchar() treba da bude tipa dovoljno velikog da može da prihvati sve štomože da vrati poziv ove funkcije, dakle sve što je karakter i plus EOF. Zbog toga se za c koristi tipint 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.

    #include

    main(){

    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 = 98c1 = a, c2 = baba

    Primer 32 Program čita jedan karakter sa standardnog ulaza i ispisuje ga na standardnom izlazu.

    #include

    main(){

    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: sIzlaz iz programa:saa

    Primer 33 Program vrši prebrojavanje cifara unetih na ulazu.

    #include

    /* zbog isdigit */#include main(){

  • 3.4 Znakovni ulaz i izlaz - getchar i putchar 29

    int c;int br_cifara = 0;while ((c = getchar()) != EOF)

    if (c>=’0’ && c=’a’ && c=’A’ && c

  • 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 OGRADJENviticastim 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 backslash-ove vidljivim.

    #include main() {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 ) */

    } /*main() */

    3.5 Priprema za kolokvijum

    Primer 38 Šta će biti izlaz iz sledećeg programa?

    #include

    main(){

    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?

    #include

    main(){

    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

    #include main(){

    int vrednost;vrednost=’A’;printf("%s\nkarakter=%3c\nvrednost=%3d\n","Veliko slovo",vrednost,vrednost);vrednost=’a’;printf("%s\nkarakter=%3c\nvrednost=%3d\n","Malo",vrednost,vrednost);

    }

    Izlaz (u slucaju ASCII):Veliko slovokarakter= Avrednost= 65Malokarakter= avrednost= 97

    Primer 41 Napisati program koji ispisuje ascii tabelu.

    #include

    main(){

  • 32 Jelena Tomašević

    int c;for (c = 0; c

  • 3.5 Priprema za kolokvijum 33

    return 0;}

    Izlaz:Unesite broj1234Novi broj je 4321

    Zadatak 13 Šta će biti ispisano nakon izvršavanja sledećeg programa?

    #include main(){

    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

  • 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 vǐsestrukog grananja. Ovom naredbom se proverava dali je neki izraz jednak jednoj od vǐse konstantnih celobrojnih vrednosti i u zavisnosti od toga,preduzima se odgovarajuća akcija. Opšti oblik ove naredbe je:

    switch (izraz) {case konstantan_izraz1: naredbe1case konstantan_izraz2: naredbe2...default: naredbe

    }

    Svaki konstantni izraz pretstavlja odreeni 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 sadefault nije obavezan. Ako se ne navede i nijedan drugi slučaj ne odgovara vrednosti izraza ondase neće izvršiti nikakva akcija.

    Primer 44 Ilustracija switch konstrukcije.

    #include

    int main(){

    int n;printf("Unesi paran broj manji od 10\n");scanf("%d",&n);switch(n){

    case 0:printf("Uneli ste nulu\n");break;

    case 2:printf("Uneli ste dvojku\n");

    1Zasnovano 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 102Izlaz: Uneli ste dvojku

    Primer 45 Napisati program koji vrši brojanje pojavljivanja karaktera 0, 1 i 2 korǐsćenjem switchnaredbe.

    #include

    main() {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 obezbeuju alternativni način pisanja if-else konstrukcije. Tako seif(izraz1)

  • 4.3 Operator sizeof 37

    izraz2;else izraz3;

    može zapisati kaoizraz1 ? izraz2 : izraz3Primer korǐsćenja uslovnog izraza:

    min = (ab)? 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

    main(){

    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)=4sizeof(long)=4sizeof(short)=2sizeof(signed)=4sizeof(unsigned)=4sizeof(char)=1sizeof(float)=4sizeof(double)=8sizeof(i)=4sizeof(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

  • 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 #include main(){

    /* Niz brojaca za svaku od cifara */int br_cifara[10];int i, c;

    /* Resetovanje brojaca */for (i = 0; i < 10; i++)

    br_cifara[i] = 0;

    /* Citamo sa ulaza i povecavamo odgovarajuce brojace */while ((c = getchar()) != EOF)

    if (isdigit(c)) /* moze i if(c>=’0’&& c

  • 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 skrivajudetalje postupka od delova programa i time čine ceo program jasnijim i jednostavnijim za men-janje. Prilikom deklaracije funkcije navodi se tip povratne vrednosti funkcije (ako se ne navedepodrazumeva se int), ime funkcije, lista argumenata i telo funkcije. Funkcija se poziva navoenjemimena funkcije i liste stvarnih argumenata.

    Primer 50 Napisati funkciju koja vrši sabiranje dva cela broja i program koji testira rad ovefunkcije.

    /* Definicija funkcije */int zbir(int a, int b){

    return a+b;}

    main(){

    /* Poziv funkcije */printf("%d\n", zbir(3,5));

    }

    Deklaracija funkcije može da stoji nezavisno od definicije funkcije. Deklaracija je neophodna usituacijama 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() */

    main(){

    /* 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.

    #include

    /* 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

  • 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

  • 4.6 Funkcije 43

    }

    Izlaz:Zbir 2. stepena od 1 do 5 jeste 55Zbir 3. stepena od 1 do 5 jeste 225Zbir 4. stepena od 1 do 10 jeste 25333

    Primer 55 Napisati funkciju koja izračunava zbir kvadrata brojeva od 1 do date granice kao iprogram koji ilustruje korǐsćenje date funkcije.

    #include void Zbir_Kvad(int n); /*f-ja koja vrsi zeljeno izracunavanje */main(){

    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 gornja) /*obezbedjivanje relacije: 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 deliocemedju brojevima od 2 do n/2. Pri implementaciji se koristi tvrdjenje da jebroj prost ako je jednak 2, ili ako je neparan i ako nema delitelja medjuneparnim 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 medjuneparnim brojevima razlicitim od jedan */

    i=3;while ( (prost) && (i0){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 20Izlaz:191713

    Zadaci za vežbu:

    Zadatak 17 Sa tastature učitati elemente niza koji su celi brojevi i za koje se pretpostavlja da ihnema vǐse 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 bro-jeva.

    Zadatak 22 Ilustracija korǐsć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 korǐsć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: (ius-tracija redirekcije standardnog ulaza i izlaza)

    ./a.out tekst.txt

    ./a.out kopija.c

    #include

    main() {int c;/* Obratiti paznju na raspored zagrada */while ((c = getchar()) != EOF)

    putchar(c);}

    Zadatak 25 Napisati program koji prepisuje ulaz na izlaz pri čemu vǐse blanko znakova zamenjujejednim.

    Zadatak 26 Napisati program koji prepisuje ulaz na izlaz pri čemu velika slova pretvara u malaa mala u velika.

    Zadatak 27 Napisati funkciju koja izračunava broj redova u tekstu i program koji vrši njeno te-stiranje.

  • 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).

    #include

    /* 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);

    }

    1Zasnovano 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);

    }

    main(){

    /* Promenjive lokalne za funkciju main */int i;int x = 3;

    printf("main::x = %d\n", x);

    for (i = 0; i

  • 5.2 Lenjo izračunavanje 49

    increase::a = 1decrease::a = -1main::a = 1nonstatic::s=1nonstatic::s=1nonstatic::s=1static::s=1static::s=2static::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.

    #include

    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;

    }

    main(){

    /* 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);

    elseprintf("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);

    elseprintf("Uslov nije ispunjen : a = %d, b = %d\n", a, b);

    }

    Izlaz:

  • 50 Jelena Tomašević

    Pozvano izracunaj()Uslov ispunjen : a = 0, b = 1Uslov nije ispunjen : a = 1, b = 1Pozvano izracunaj()Uslov ispunjen : a = 2, b = 2Uslov nije ispunjen : a = 3, b = 2Pozvano izracunaj()Uslov ispunjen : a = 4, b = 3Uslov nije ispunjen : a = 5, b = 3Pozvano izracunaj()Uslov ispunjen : a = 6, b = 4Uslov nije ispunjen : a = 7, b = 4Pozvano izracunaj()Uslov ispunjen : a = 8, b = 5Uslov nije ispunjen : a = 9, b = 5----------------------------Uslov ispunjen : a = 0, b = 0Pozvano izracunaj()Uslov ispunjen : a = 1, b = 1Uslov ispunjen : a = 2, b = 1Pozvano izracunaj()Uslov ispunjen : a = 3, b = 2Uslov ispunjen : a = 4, b = 2Pozvano izracunaj()Uslov ispunjen : a = 5, b = 3Uslov ispunjen : a = 6, b = 3Pozvano izracunaj()Uslov ispunjen : a = 7, b = 4Uslov ispunjen : a = 8, b = 4Pozvano 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 prioritetaoperatora*/

    ip = &z[0]; /* ip sada pokazuje na z[0]*/

  • 5.3 Pokazivači 51

    Primer 59 Ilustracija rada sa pokazivačkim promenljivim.

    #include main() {

    int x = 3;

    /* Adresu promenjive x zapamticemo u novoj promeljivoj.Nova promenljiva je tipa pokazivaca na int (int*) */

    int* px;

    printf("Adresa promenljive x je : %p\n", &x);printf("Vrednost promenljive x je : %d\n", x);

    px = &x;printf("Vrednost promenljive px je (tj. px) : %p\n", px);printf("Vrednost promenljive na koju ukazuje px (tj. *px) je : %d\n", *px);

    /* Menjamo vrednost promenljive na koju ukazuje px */*px = 6;printf("Vrednost promenljive na koju ukazuje px (tj. *px) je : %d\n", *px);

    /* Posto px sadrzi adresu promenljive x, ona ukazuje na x tako da jeposredno promenjena i vrednost promenljive x */

    printf("Vrednost promenljive x je : %d\n", x);

    }

    Izlaz (u konkretnom slucaju):Adresa promenljive x je : 0012FF88Vrednost promenljive x je : 3Vrednost promenljive px je (tj. px) : 0012FF88Vrednost promenljive na koju ukazuje px (tj. *px) je : 3Vrednost promenljive na koju ukazuje px (tj. *px) je : 6Vrednost promenljive x je : 6

    Pored pokazivača na osnovne tipove, postoji i pokazivač na prazan tip (void).

    void *pp;

    Njemu može da se dodeli da pokazuje na int, ili na char ili na proizvoljan tip ali je to neophodnoeksplicitno naglasiti svaki put kada želimo da koristimo ono na šta on pokazuje.

    Primer 60 Upotreba pokazivača na prazan tip.

    #include

    main(){void *pp;int x=2;char c=’a’;

  • 52 Jelena Tomašević

    pp = &x;*(int *)pp = 17; /* x postaje 17*/printf("\n adresa od x je %p", &x);printf("\n%d i %p",*(int*)pp,(int * )pp);

    pp = &c;printf("\n adresa od c je %p", &c);printf("\n%c i %p",*(char*)pp,(char * )pp);

    }

    /*adresa od x je 0012FF7817 i 0012FF78adresa od c je 0012FF74a i 0012FF74

    */

    Posebna konstanta koja se koristi da se označi da pokazivač ne pokazuje na neko mesto umemoriji je NULL.

    5.4 Zadaci za vežbu

    Zadatak 28 Broj je Armstrongov ako je jednak sumi n-tih stepena svojih cifara. Ispitati da li jebroj koji se unosi sa standardnog ulaza Armstrongov.

    Zadatak 29 Za dati broj može se formirati niz tako da je svaki sledeći član niza dobijen kaosuma cifara prethodnog člana niza. Broj je srećan ako se dati niz završava sa jedinicom. Napisatiprogram koji za uneti broj odreuje da li je srećan.

    Zadatak 30 Sa ulaza se unosi broj u osnovi deset i osnova

  • 5.4 Zadaci za vežbu 53

    Zadaci za praktikum

    Zadatak 34 Napisati funkciju koja izračunava broj grafičkih karaktera u tekstu i program koji vršinjeno testiranje.

    Zadatak 35 Napisati funkciju koja izračunava zbir svih cifara koje su se pojavile u tekstu i programkoji vrši njeno testiranje.

    Zadatak 36 Napisati funkciju koja izračunava broj reči koje su se pojavile u tekstu i program kojivrši njeno testiranje. Smatrati da se reči sastoje iz proizvoljnog niza karaktera i da su razdvojeneprazninama, tabulatorima ili prelascima u novi red.

    Zadatak 37 Napisati funkciju koja izračunava broj reči u tekstu dužine n i program koji vrši njenotestiranje. Broj n se učitava sa ulaza.

  • 54 Jelena Tomašević

  • 6

    Programski jezik C

    1

    6.1 Prenos parametara po vrednosti i preko pokazivača

    Primer 61 Demonstracija prenosa parametara po vrednosti - preneti parametri se ne mogu men-jati!

    #include void f(int x){x++;}

    main(){int x=3;f(x);printf("%d\n", x);}Izlaz:3

    Ovaj problem se može prevazići na vǐse načina.Prvi način je da se promenljiva x ne prenese u funkciju f po vrednosti već preko pokazivača,

    odnosno da se prenese njena adresa.

    #include void f(int *x){(*x)++;}

    main(){int x=3;f(&x);

    1Zasnovano na primerima sa sajta http://www.matf.bg.ac.yu/∼filip

  • 56 Jelena Tomašević

    printf("%d\n", x);}Izlaz:4

    Drugi način je da se promenjena vrednost privremene promenljive x u okviru funkcije f vrati kaorezultat rada funkcije:

    #include int f(int x){return x++;}

    main(){int x=3;printf("%d\n", f(x));}Izlaz:4

    I treći način je preko globalne promenljive:

    #include int x=3;

    void f(){x++;}

    main(){f();printf("%d\n", x);}

    Izlaz:4

    Dakle, u programskom jeziku C argumenti se funkciji prosleuju po vrednosti. To znači da sledećafunkcija neće uraditi ono što želimo:

    void razmeni(int x, int y) /* POGRESNO!!!!!!!!*/{int pom;pom = x;x = y;y = pom;}

    Zbog prenosa parametara po vrednosti, funkcija razmeni ne može da utiče na argumente a i bu funkciji koja je pozvala ovu funkciju razmeni. Funkcija razmeni samo zamenjuje kopije od a ib.

    Da bi se dobio željeni efekat, potrebno je da se proslede adrese promenljivih a i b:

  • 6.2 Prenos niza u f-ju 57

    /* Zameni *px i *py */void razmeni(int *px, int *py){int pom;pom = *px;*px = *py;*py = pom;}

    a poziv funkcije razmeni izlgeda sada ovako

    razmeni(&a, &b);

    Primer 62 Demonstracija vǐse povratnih vrednosti funkcije koristeći prenos preko pokazivača.

    /* Funkcija istovremeno vraca dve vrednosti - kolicnik i ostatak dva data broja.Ovo se postize tako sto se funkciji predaju vrednosti dva broja (x i y) koji se delei adrese dve promenljive na koje ce se smestiti rezultati */

    void div_and_mod(int x, int y, int* div, int* mod){

    printf("Kolicnik postavljam na adresu : %p\n", div);printf("Ostatak postavljam na adresu : %p\n", mod);*div = x / y;*mod = x % y;

    }

    main() {int div, mod;printf("Adresa promenljive div je %p\n", &div);printf("Adresa promenljive mod je %p\n", &mod);

    /* Pozivamo funkciju tako sto joj saljemo vrednosti dva broja (5 i 2)i adrese promenljvih div i mod na koje ce se postaviti rezultati */

    div_and_mod(5, 2, &div, &mod);

    printf("Vrednost promenljive div je %d\n", div);printf("Vrednost promenljive mod je %d\n", mod);

    }

    Izlaz u konkretnom slucaju:Adresa promenljive div je 0012FF88Adresa promenljive mod je 0012FF84Kolicnik postavljam na adresu : 0012FF88Ostatak postavljam na adresu : 0012FF84Vrednost promenljive div je 2Vrednost promenljive mod je 1

    6.2 Prenos niza u f-ju

    Nizovi se prenose u funkciju tako što se prenese adresa njihovog početka. Iz tog razloga oni seMOGU MENJATI u okviru funkcije.

  • 58 Jelena Tomašević

    Napomena: Sve nizove osim niski karaktera (stringova) neophodno je prenositi zajedno sadimenzijom niza.

    Primer 63 Funkcija za ispis niza brojeva - demonstracija prenosa niza brojeva u funkciju.

    #include

    void print_array(int a[], int n){

    int i;for (i = 0; i < n; i++)

    printf("%d ",a[i]);putchar(’\n’);

    /* Obratite paznju na ovo : *//* Ispisace se broj bajtova koje zauzima promenljivatipa pokazivac na int */printf("sizeof(a) - u okviru fje : %d\n", sizeof(a));

    }

    main(){

    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    /* Ispisace se broj bajtova koje zauzima niz a */printf("sizeof(a) - u okviru main : %d\n", sizeof(a));print_array(a, sizeof(a)/sizeof(int));

    }

    Izlaz:sizeof(a) - u okviru main : 361 2 3 4 5 6 7 8 9sizeof(a) - u okviru fje : 4

    Primer 64 Skalarni proizvod dva niza brojeva

    #include

    long mnozi(int x[],int y[],int n);

    main(){int a[]={1,2,3,4,5,6}, b[]={8,7,6,5,4,3};printf("Skalarno a*b= %ld\n",mnozi(a,b,6));

    }long mnozi(int x[ ],int y[ ],int n){

    int i;long suma=0;for(i=0;i

  • 6.3 Funkcije za rad sa niskama (stringovima) 59

    Izlaz:Skalarno a*b= 98

    6.3 Funkcije za rad sa niskama (stringovima)

    Niska karaktera ili string je niz karaktera koji se završava karakterom ’\0’.Napomena: Karakter ’\0’ ima ASCII vrednost 0 pa se može tumačiti kao logička vrednost

    ”netačno”.Format za ispis niske pomoću funkcije printf je %s. Konstante tipa niska se navode izmeu

    znakova navodnika. Na primer, možemo napisati:

    char s[]="Primer stringa";

    Pri tome je s niska od 15 karaktera:

    {’P’, ’r’, ’i’, ’m’, ’e’, ’r’, ’ ’, ’s’, ’t’, ’r’, ’i’, ’n’, ’g’, ’a’, ’\0’}

    Primer 65 Kakva je razlika izmeu ’s’ i ”s”?

    ’s’ je karakter ”s” je string ili niz od dva karaktera ’s’ i ’\0’.

    Primer 66 Funkcija za ispis niske karaktera - demonstrira prenos niske karaktera u funkciju.

    #include

    /* Uz nisku karaktera nije potrebno prenositi dimenzijuukoliko se postuje dogovorda se svaka niska zavrsava karakterom ’\0’.*/

    void stampaj_nisku(char s[]){

    int i;for (i = 0; s[i]; i++)/* s[i] ce biti netacno samo kada bude jednako sa ’\0’ ciji je ASCII kod 0. *//* Ovo je isto kao da smo napisali for(i = 0; s[i]!=’\0’; i++) */

    putchar(s[i]);}

    main(){

    stampaj_nisku("Zdravo\n");}Izlaz:Zdravo

    Primer 67 Funkcija za učitavanje reči sa ulaza u nisku karaktera.

    #include #include /* Potrebno je zbog funkcije isspace */

    /* Funkcija ucitava rec sa standardnog ulaza i smesta je u niz karaktera s.Ovo uspeva zbog toga sto se po vrednosti prenosi adresa pocetka niza,

  • 60 Jelena Tomašević

    a ne ceo niz */void ucitaj_rec(char s[]){

    int c, i = 0;

    /* Funkcija isspace ispituje da li je karakter praznina(blanko, tabulator ili prelazak u novi red).Ona je definisana u okviru ctype.h */while (!isspace(c=getchar()))

    s[i++] = c;s[i] = ’\0’;

    }

    main(){

    /* Obavezno je alocirati memoriju za niz karaktera */char s[100];

    ucitaj_rec(s);/* Format za ispis stringa se zadaje kao %s */printf("%s\n", s);

    }

    Da li bi bio ispravan sledeći program:

    #include

    /* Funkcija ucitava ceo broj sa standardnog ulaza i smesta je u promenljivu x. */void ucitaj_broj(int x){

    scanf("%d", &x);}

    main(){

    int x;ucitaj_broj(x);printf("%d\n", x);

    }

    Ako ovo nije ispravno, zašto nije?

    Primer 68 obrni string - obrće nisku karaktera.

    #include

    /* Ova funkcija racuna duzinu date niske karaktera.Umesto nje, moguce je koristiti standardnu funkciju strlen .

    */int duzina_stringa(char s[]){

    int i;for (i = 0; s[i]; i++)

    ;

  • 6.3 Funkcije za rad sa niskama (stringovima) 61

    return i;}

    /* Funkcija obrce nisku karaktera */void obrni_string(char s[]){

    int i, j;for (i = 0, j = duzina_stringa(s)-1; i= 0; i--)

    if (s[i] != ’ ’ && s[i] != ’\t’ && s[i] != ’\n’)break;

    s[i+1] = ’\0’;return i;}

    Continue se ree koristi, on prouzrokuje da se pree na sledeću iteraciju u petlji.Primer 70for(i=0; i

  • 62 Jelena Tomašević

    Zadaci za vežbu

    Zadatak 38 Napisati funkciju koja izračunava zbir i razliku dva cela broja i program koji testirarad ove funkcije. Zbir vratiti preko liste argumenata.

    Zadatak 39 Napisati funkciju koja vraća prvu poziciju u niski s1 na kojoj se pojavljuje znak iz s2ili -1 ako s1 ne sadrži ni jedan znak iz s2. Ako je s1 pera a s2 navip onda funkcija treba da vratipoziciju 0. Ako je s1 zeleno a s2 nana onda funkcija treba da vrati poziciju 4.

    Zadatak 40 januar 2006.(II grupa)

    1. Napisati funkciju void brojanje(int a[], int brojac[], int N) čiji su argumenti a i brojaccelobrojni nizovi dimenzije N. Vrednosti elemenata niza a su izmeu 0 i N - 1. Funkcijaizračunava elemente niza brojac tako da je brojac[i] jednak broju pojavljivanja broja i unizu a.

    2. Kažemo da je celobrojni niz a dimenzije N permutacija ako sadrži svako i: 0

  • 7

    Programski jezik C

    1

    7.1 Funkcije za rad sa niskama (stringovima) — nastavak

    Primer 71 Izvršiti implementaciju funkcija strlen, strcpy, strcat, strcmp, strchr, strstr bibliotekestring.h

    #include

    /* Izracunava duzinu stringa */int duzina_stringa(char s[]){

    int i;for (i = 0; s[i]; i++)

    /* for (i = 0; s[i]!=’\0’; i++) */; /*Telo petlje je prazno*/

    return i;}

    /* Kopira string src u string dest.Pretpostavlja da u dest ima dovoljno prostora. */

    void kopiraj_string(char dest[], char src[]){

    int i;/* Kopira karakter po karakter, sve dok nije iskopiran karakter ’\0’ */for (i = 0; src[i]!=’\0’; i++)

    dest[i]=src[i];

    /* Ovo se moglo zapisati i kao:for (i = 0; (dest[i]=src[i]) != ’\0’; i++)

    ;*//* a ako se izostavi uslov != ’\0’, moze se zapisati kao:

    1Zasnovano na primerima sa sajta http://www.matf.bg.ac.yu/∼filip, http://www.matf.bg.ac.yu/∼milan.

  • 64 Jelena Tomašević

    for (i = 0; dest[i]=src[i]; i++);

    */}

    /* Nadovezuje string t na kraj stringa s.Pretpostavlja da u s ima dovoljno prostora. */

    void nadovezi_stringove(char s[], char t[]){

    int i, j;/* Pronalazimo kraj stringa s */for (i = 0; s[i]; i++)

    ;

    /* Vrsi se kopiranje, slicno funkciji kopiraj_string */for (j = 0; s[i] = t[j]; j++, i++)

    ;}

    /* Vrsi leksikografsko poredjenje dva stringa.Vraca :

    0 - ukoliko su stringovi jednaki0 - ukoliko je s leksikografski iza t

    */int uporedi_stringove(char s[], char t[]){

    /* Petlja tece sve dok ne naidjemo na prvi razliciti karakter */int i;for (i = 0; s[i]==t[i]; i++)

    if (s[i] == ’\0’) /* Naisli smo na kraj oba stringa,a nismo nasli razliku */

    return 0;

    /* s[i] i t[i] su prvi karakteri u kojima se niske razlikuju.Na osnovu njihovog odnosa, odredjuje se odnos stringova */

    return s[i] - t[i];}

    /* Pronalazi prvu poziciju karaktera c u stringu s, odnosno -1ukoliko s ne sadrzi c */

    int string_char(char s[], char c){

    int i;for (i = 0; s[i]; i++)

    if (s[i] == c)return i;

    /* nikakoelse

    return -1;*/

    /* Nije nadjeno */

  • 7.1 Funkcije za rad sa niskama (stringovima) — nastavak 65

    return -1;}

    /* Pronalazi poslednju poziciju karaktera c u stringu s, odnosno -1ukoliko s ne sadrzi c */

    int string_poslednji_char(char s[], char c){

    /* Pronalazimo kraj stringa s */int i;for (i = 0; s[i]; i++)

    ;

    /* Krecemo od kraja i trazimo c unazad */for (i--; i>=0; i--)

    if (s[i] == c)return i;

    /* Nije nadjeno */return -1;

    /*Koristeci duzina_stringa :

    for (i = duzina_stringa(s) - 1; i>0; i--)if (s[i] == c)

    return i;

    return -1;*/

    }

    /* Proverava da li string str sadrzi string sub.Vraca poziciju na kojoj sub pocinje, odnosno -1 ukoliko ga nema

    */int string_string(char str[], char sub[]){

    int i, j;/* Proveravamo da li sub pocinje na svakoj poziciji i */for (i = 0; str[i]; i++)

    /* Poredimo sub sa str pocevsi od poziciji isve dok ne naidjemo na razliku */

    for (j = 0; str[i+j] == sub[j]; j++)/* Nismo naisli na razliku a ispitali smo

    sve karaktere niske sub */if (sub[j+1]==’\0’)

    return i;/* Nije nadjeno */return -1;

    }

    main(){

  • 66 Jelena Tomašević

    char s[100];char t[] = "Zdravo";char u[] = " svima";

    kopiraj_string(s, t);printf("%s\n", s);

    nadovezi_stringove(s, u);printf("%s\n", s);

    printf("%d\n",string_char("racunari", ’n’));printf("%d\n",string_poslednji_char("racunari", ’a’));

    printf("%d\n",string_string("racunari", "rac"));printf("%d\n",string_string("racunari", "ari"));printf("%d\n",string_string("racunari", "cun"));printf("%d\n",string_string("racunari", "cna"));

    }

    Izlaz:ZdravoZdravo svima45052-1

    Primer 72 Funkcija koja uklanja znak c kad god se pojavi u stringu s.

    #include void sazimanje(char s[], char c){int i,j;for(i=j=0; s[i]!=’\0’;i++)

    if(s[i]!=c) s[j++]=s[i];s[j]=’\0’;}

    main() {char niz[20];char c;

    printf("Unesi karakter\n\n");scanf("%c", &c);

    scanf("%s", &niz);sazimanje(niz, c);printf("%s\n", niz);

    }

  • 7.2 Funkcije koje vrše konverziju 67

    Izlaz:Unesi karakteriUnesi stringprimerprmer

    7.2 Funkcije koje vrše konverziju

    Primer 73 Funkcija koja konvertuje velika slova u mala slova.

    #include

    /* Konvertuje karakter iz velikog u malo slovo */char lower(char c){if (c >= ’A’ && c = ’0’) && (s[i]

  • 68 Jelena Tomašević

    printf("\nN je : %d\n",n);}

    Izlaz:

    N je : 234

    Primer 75 btoi - konverzija iz datog brojnog sistema u dekadni.

    #include #include

    /* Pomocna funkcija koja izracunava vrednost koju predstavlja karakter u datoj osnoviFunkcija vraca -1 ukoliko cifra nije validna.

    Npr.cifra ’B’ u osnovi 16 ima vrednost 11cifra ’8’ nije validna u osnovi 6

    */

    int digit_value(char c, int base){

    /* Proveravamo obicne cifre */if (isdigit(c) && c < ’0’+base)

    return c-’0’;

    /* Proveravamo slovne cifre za mala slova */if (’a’

  • 7.3 Sortiranje niza 69

    }

    main(){

    char bin[] = "11110000";char hex[] = "FF";

    printf("Dekadna vrednost binarnog broja %s je %d\n", bin, btoi(bin, 2));printf("Dekadna vrednost heksadekadnog broja %s je %d\n", hex, btoi(hex, 16));

    }

    Izlaz:Dekadna vrednost binarnog broja 11110000 je 240Dekadna vrednost heksadekadnog broja FF je 255

    Primer 76 Program vrši konverziju iz dekadnog brojnog sistema u datu osnovu.

    #include#define OSNOVA 16main(){

    int x; /* Broj cija se konverzija vrsi */int ostaci[32]; /* Niz ostataka pri deljenju sa osnovom */int i = 0;

    /* Unosi se dekadni broj */scanf("%d",&x);

    /* Srz algoritma konverzije */while(x>0){

    /* novi ostatak se dodaje u pomocni niz */ostaci[i++] = x%OSNOVA;x/=OSNOVA;

    }

    /* Niz se ispisuje unatrag */for (i--; i>=0; i--)if (ostaci[i]

  • 70 Jelena Tomašević

    važi da je niz[0] >= niz[1] >= ... niz[n]. Jednostavnom modifikacijom ovog algoritma nizse može sortirati i u opadajućem, rastućem ili neopadajućem poretku.

    Primer 77 Selection sortU prvom prolazu se razmenjuju vrednosti a[0] sa onim članovima ostatka niza koji su vev́i od njega.Na taj način će se posle prvog prolaza kroz niz a[0] postaviti na najveći element niza.

    #include#define MAXDUZ 100

    int main(){

    /* Niz od maksimalno MAXDUZ elemenata*/int a[MAXDUZ];

    /* Dimenzija niza, pomocna i brojacke promenljive */int n,pom,i,j;

    printf("Unsite dimenziju niza\n");scanf("%d",&n);

    if (n>MAXDUZ){

    printf("Nedozvoljena vrednost za n\n");exit(1);

    }

    /* Unos clanova niza */for(i=0; i

  • 7.4 Linearna i binarna pretraga niza 71

    }

    7.4 Linearna i binarna pretraga niza

    Primer 78 Linearno pretraživanje

    #include /* Funkcija proverava da li se dati element x nalaziu datom nizu celih brojeva.Funkcija vraca poziciju u nizu nakojoj je x pronadjenodnosno -1 ukoliko elementa nema.*/int linearna_pretraga(int niz[], int br_elem, int x){

    int i;for (i = 0; i

  • 72 Jelena Tomašević

    Funkcija vraca poziciju na kojoj je element nadjen odnosno-1 ako ga nema.!!!!! VAZNO !!!!!Pretpostavka je da je niz a uredjen po velicini. U ovom primeruniz je uredjen u rastucem ili neopadajucem poretku.*/int binarna_pretraga(int a[], int n, int x){

    /* Pretrazujemo interval [l, d] */int l = 0;int d = n-1;/* Sve dok interval [l, d] nije prazan */while (l

  • 7.5 Veza izmeu nizova i pokazivača 73

    7.5 Veza izmeu nizova i pokazivačaU C-u postoji jaka veza izmeu pokazivača i nizova. Deklaracija

    int a[10];

    definǐse niz a veičine 10, odnosno blok od 10 susednih objekata u memoriji sa imenima a[0], a[1],a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]. Zapis a[i] ukazuje na i-ti element niza a. Akoje pa pokazivač na neki ceo broj deklarisan pomoću

    int *pa;

    tada dodeljivanje

    pa = &a[0];

    podešava pa da pokazuje na nulti element niza a, to jest, pa sadrži adresu od a[0]. Kako je imeniza sinonim za adresu početnog elementa niza, dodela

    pa = &a[0];

    se može napisati i kao

    pa = a;

    Ako pa pokazuje na odreeni element nekog niza, tada pa+1 pokazuje na naredni element (ne nanaredni bajt) pa tako pa+i pokazuje i elemenata iza pa, a pa-i na i elemenata ispred pa. Dakle,ako pa pokazuje na a[0] onda je

    *(pa+i)

    zapravo sadržaj i-tog elementa niza to jest isto je što i a[i]. A pa+i je isto što i &pa[i].

    Primer 80 Ilustracija veze izmeu nizova i pokazivača.

    #include

    main(){int a[10]={0,1,2,3,4,5,6,7,8,9};int *pa, i;pa=a;printf("Vrednost od a je %p\n", a);printf("Vrednost od pa je %p\n", pa);printf("Vrednost od a[0] je %d\n", a[0]);printf("Vrednost od *a je %d\n", *a);printf("Vrednost od pa[0] je %d\n", pa[0]);printf("Vrednost od *pa je %d\n", *pa);printf("Vrednost od *(pa+3) je %d\n", *(pa+3));printf("Vrednost od pa[3] je %d\n", pa[3]);printf("Vrednost od *(a+3) je %d\n", *(a+3));printf("Vrednost od a[3] je %d\n", a[3]);

    /*Vraca se kao rezultat *pa a nakon toga se pa uveca za jedan*//* Ovo moze...*/printf("Vrednost od *pa++ je %d\n", *pa++);

  • 74 Jelena Tomašević

    /* ...a ovo bi prijavilo greskuprintf("Vrednost od *a++ je %d\n", *a++); */printf("Vrednost od *pa je %d\n", *pa);

    /*Ono na sta pokazuje pa (*pa) se uveca za jedan*/printf("Vrednost od ++*pa je %d\n", ++*pa);

    printf("Pocetni niz sada izgleda ovako:\n");for(i=0;i

  • 7.6 Vraćanje nizova iz funkcije 75

    Pokazivacka aritmetika:int duzina_niske(char *s){int i;for(i=0; *s != ’\0’; i++)s++;

    return i;}

    7.6 Vraćanje nizova iz funkcije

    Sledeći primer je u C-u sintaksno neispravan zato što ne može funkcija kao rezultat svog rada davrati podatak koji je tipa int[]:

    Primer 82 int[]funkcija(){int a[10],i;/*Napunimo niz nekim vrednostima*/for(i=0; i

  • 76 Jelena Tomašević

    1. Napisati funkciju koja ispituje da li dve niske (koje se prenose kao parametri funkcije) suanagrami. Anagrami su niske koje se sastoje od istih karaktera. Npr. vetar, trave, verat suanagrami.

    2. Napisati program koji testira funkciju iz prvog dela.

    Zadatak 48 I kolokvijum, februar 2005. Napisati program koji učitava sa standardnog ulazadve niske sa ne vǐse od 80 karaktera u svakoj i prirodan broj k i ispisuje na standardni izlaz porukuda li se prva niska dobila cikličnim pomeranjem druge niske za k mesta. Na primer za k=3, niskaCDEAB”” se dobila cikličnim pomeranjem niske ”ABCDE”

    Zadatak 49 Jun, 2004. Napisati funkciju koja koja kao argumente prihvata dve niske i prover-ava da li se prva od zadatih niski može dobiti cikličnim pomeranjem karaktera druge niske.

    Zadaci za praktikum:Napomena: Ove zadatke na praktikumu rade samo studenti kod prof. Vitasa. Studenti

    prof. Pavlović-Lažetić rade zadatke za vežbu. Kao tekst za testiranje ovih zadataka, uzeti svojseminarski rad.

    Zadatak 50 Napisati funkciju koja izračunava broj rečenica u tekstu. Rečenice se završavajukarakterima ’.’, ’?’ ili ’!’ iza kojih sledi ’ ’ a nakon toga veliko slovo.

    Zadatak 51 Napisati funkciju koja izračunava broj vlastitih imena ili reči izvedenih iz nekog vlasti-tog imena i broj broj brojeva bez obzira da li su zapisani slovima ili ciframa. Broj vlastitih imenavratiti preko liste argumenata. Napisati program koji testira rad ove funkcije.

    Zadatak 52 Napisati program koji ispisuje redne brojeve rečenica u kojima se pojavljuje tačnojedno vlastito ime ili reč izvedena iz nekog vlastitog imena. Rečenice se završavaju karakterima’.’, ’?’ ili ’!’ iza kojih sledi ’ ’ a nakon toga veliko slovo.

  • 8

    Programski jezik C

    1

    8.1 Pokazivač na funkciju

    Primer 85 Napisati funkciju koja izračunava sumu kvadrata, kubova i parnih brojeva na interbalu[a,b] sa korakom k.

    #include int kvadrat(int n) { return n*n; }int kub(int n) { return n*n*n; }int parni_broj(int n) { if (n%2==0) return n; else return 0; }

    /* Funkcija izracunava sumu od 1 do n f(i), gde je f data funkcija.*/

    int sumiraj(int (*f) (int), int a, int b, int k) {

    /* U argumentu funkcije sumiraj, int (*f) (int) je pokazivac na funkciju sa imenom f,koja kao argument prima promenljivu tipa int i vraca kao rezultat vrednost tipa int */

    int i, suma=0;for (i=a; i

  • 78 Jelena Tomašević

    Suma parnih brojeva od 3 do 9 sa korakom 1 je 18*/

    8.2 Strukture

    Struktura je kolekcija nekoliko promenljivih, potencijalno različitih tipova, koje su grupisane podjednim imenom radi lakšeg rada sa njima.

    Primer 86 Napisati program koji izračunava obim i površinu trougla i kvadrata.

    /* Program uvodi strukture - geometrijske figure */#include

    /* Zbog funkcije sqrt */#include /* Upozorenje : pod linux-om je potrebno program prevoditi sa

    gcc -lm primer.ckada god se koristi

    */

    /* Tacke su predstavljene sa dve koordinate. Strukturom gradimo novi tip podataka. */struct point{

    int x;int y;

    };

    /* Izracunava duzinu duzi zadatu sa dve tacke */float segment_length(struct point A, struct point B){

    int dx = A.x - B.x;int dy = A.y - B.y;return sqrt(dx*dx + dy*dy);

    }

    /* Izracunava povrsinu trougla Heronovim obrascem.Argumenti funkcije su tri tacke koje predstavljaju temena trougla */

    float Heron(struct point A, struct point B, struct point C){

    /* Duzine stranica */float a = segment_length(B, C);float b = segment_length(A, C);float c = segment_length(A, B);

    /* Poluobim */float s = (a+b+c)/2;

    return sqrt(s*(s-a)*(s-b)*(s-c));}

    /* Izracunava obim poligona. Argumenti funkcije su niz tacaka

  • 8.2 Strukture 79

    koje predstavljaju temena poligona kao i njihov broj */float circumference(struct point polygon[], int num){

    int i;float o = 0.0;

    /* Dodajemo duzine stranica koje spajaju susedna temena */for (i = 0; i

  • 80 Jelena Tomašević

    triangle[2].x = 1; triangle[2].y = 0;

    /* Ispisujemo velicinu strukture tacka */printf("sizeof(struct point) = %d\n", sizeof(struct point));

    /* Ispisujemo vrednosti koordinata tacaka */printf("x koordinata tacke a je %d\n", a.x);printf("y koordinata tacke a je %d\n", a.y);printf("x koordinata tacke b je %d\n", b.x);printf("y koordinata tacke b je %d\n", b.y);

    printf("Obim trougla je %f\n",circumference(triangle, 3));

    printf("Obim kvadrata je %f\n",circumference(square, 4));

    printf("Povrsina trougla je %f\n",Heron(triangle[0], triangle[1], triangle[2]));

    /* Broj tacaka je moguce odrediti i putem sizeof */printf("Povrsina kvadrata je %f\n",

    area(square, sizeof(square)/sizeof(struct point)));

    }

    Izlaz:sizeof(struct point) = 8x koordinata tacke a je 0y koordinata tacke a je 0x koordinata tacke b je 1y koordinata tacke b je 2Obim trougla je 3.414214Obim kvadrata je 4.000000Povrsina trougla je 0.500000Povrsina kvadrata je 1.000000

    Primer 87 Ilustracija korisšćenja typedef.

    /* Koriscenje typedef radi lakseg rada */#include

    #include /* Ovim se omogucava da se nadalje u programu umesto int moze

    koristiti ceo_broj */typedef int ceo_broj ;

    /* Ovim se omogucuje da se nadalje u programu umesto struct pointmoze koristiti POINT */

    typedef struct point POINT;

    struct point{

    int x;int y;

  • 8.2 Strukture 81

    };

    /* Moze se zapisati itypedef struct point{

    int x;int y;

    } POINT;*/

    main(){

    /* Umesto int mozemo koristiti ceo_broj */ceo_broj x = 3;

    /* Definisemo promenljivu tipa tacke.Umesto struct point mozemo koristiti POINT */

    POINT a;

    printf("x = %d\n", x);

    /* Postavljamo vrednosti koordinata tacke a*/a.x = 1; a.y = 2;/* Ispisujemo velicinu strukture tacka */printf("sizeof(struct point) = %d\n", sizeof(POINT));

    /* Ispisujemo vrednosti koordinata tacaka */printf("x koordinata tacke a je %d\n", a.x);printf("y koordinata tacke a je %d\n", a.y);

    }

    Izlaz:x = 3sizeof(struct point) = 8x koordinata tacke a je 1y koordinata tacke a je 2

    Primer 88 Strukture se u funkcije prenose po vrednosti. Moguće je koristiti pokazivače na struk-ture.

    #include

    typedef struct point{

    int x, y;} POINT;

    /* Zbog prenosa po vrednosti tacka ne moze biti ucitana */void get_point_wrong(POINT p){

    printf("x = ");scanf("%d", &p.x);

  • 82 Jelena Tomašević

    printf("y = ");scanf("%d", &p.y);

    }

    /* Koriscenjem prenosa preko pokazivaca, uspevamo */void get_point(POINT* p){

    /* p->x je skraceni zapis za (*p).x */

    printf("x = ");scanf("%d", &p->x);printf("y = ");scanf("%d", &p->y);

    }

    main(){

    POINT a = {0, 0};

    printf("get_point_wrong\n");get_point_wrong(a);printf("a: x = %d, y = %d\n", a.x, a.y);

    printf("get_point\n");get_point(&a);printf("a: x = %d, y = %d\n", a.x, a.y);

    }

    Napomena: Ako je tacka ime promenljive tipa POINT (POINT tacka;) onda se x i y clanupristupa kao tacka.x i tacka.y. Ako je ptacka ime promenljive tipa pokazivač na POINT (POINT*ptacka;) onda se x i y članu pristupa kao ptacka->x i ptacka->y.

    Primer 89 Napisati funkciju koja sabira dva kompleksna broja i rezultat vraća kao povratnu vred-nost. Napisati funkciju koja oduzima dva kompleksna broja i rezultat vraća preko liste argumentata.Napisati program koji testira rad ovih funkcija.

    #includetypedef struct complex{float Re,Im;} COMPLEX;

    COMPLEX saberi(COMPLEX prvi, COMPLEX drugi){COMPLEX rezultat;rezultat.Re = prvi.Re + drugi.Re;rezultat.Im = prvi.Im + drugi.Im;return rezultat;}

    void oduzmi(COMPLEX prvi, COMPLEX drugi, COMPLEX *rezultat)

  • 8.2 Strukture 83

    {rezultat->Re = prvi.Re - drugi.Re;rezultat->Im = prvi.Im - drugi.Im;}

    main(){COMPLEX k1,k2,k3;printf("Unesi realni i imaginarni deo prvog kompleksnog broja:\n");scanf("%f %f", &k1.Re, &k1.Im);printf("Unesi realni i imaginarni deo drugog kompleksnog broja:\n");scanf("%f %f", &k2.Re, &k2.Im);k3=saberi(k1,k2);printf("(%.2f + %.2f *i) + (%.2f + %.2f *i) = (%.2f + %.2f *i) ",

    k1.Re, k1.Im, k2.Re, k2.Im, k3.Re, k3.Im);oduzmi(k1,k2,&k3);printf("(%.2f + %.2f *i) - (%.2f + %.2f *i) = (%.2f + %.2f *i) ",

    k1.Re, k1.Im, k2.Re, k2.Im, k3.Re, k3.Im);}

    Primer 90 Uneti niz osoba, koje se karakterǐsu svojim imenom i brojem godina, sortirati po imenua unutar istog imena, po starosti.

    #include#include /*Zbog funkcija za rad sa stringovima*/#define MAXIME 15

    typedef struct osoba{char ime[MAXIME]; /*Mora se ograniciti duzina niza!*/int starost;} OSOBA;

    main(){OSOBA nizOsoba[100];OSOBA pom;int n, i, j;printf("Unesi broj osoba manji od 100\n");scanf("%d", &n);printf("Unesi %d osoba:\n", n);for(i=0; i

  • 84 Jelena Tomašević

    /*...razmeni mesta i-toj i j-toj osobi.*/{strcpy(pom.ime, nizOsoba[j].ime);pom.starost = nizOsoba[j].starost;strcpy(nizOsoba[j].ime, nizOsoba[i].ime);/* Ne bi smelo nizOsoba[j].ime=nizOsoba[i].ime; !!!*/nizOsoba[j].starost = nizOsoba[i].starost;strcpy(nizOsoba[i].ime, pom.ime);nizOsoba[i].starost = pom.starost;

    }printf("Sortiran niz je:\n");for(i=0; inizOsoba[j].ime; kada se porede dveniske već mora da poreenje obavi pozivom funkcije strcmp. Kod dodele se poziva funkcijastrcpy!!!

    8.3 Unije

    Unija je struktura koja može čuvati (u različito vreme) objekte različitih tipova i veličina. Timese obezbeuje manipulisanje različitim vrstama podataka u istom memorijskom području.

    Primer 91 Ilustracija koriscenja unije.

    #include typedef union u{

    int i;float f;char c;} u;

    main(){u unija;unija.c=’A’;unija.i=5;/* Dozvoljen je pristup samo poslednje dodeljenom clanu unije */printf("Trenutna vrednost unije je %d\n",unija.i); /* U redu je *//* Pogresno bi bilo da se napiseprintf("Trenutna vrednost unije je %c\n",unija.c);*/}

    Unija se dakle može shvatiti kao struktura u kojoj svi članovi imaju relativnu poziciju 0 odnjenog početka. Struktura je dovoljno velika kako bi mogla da čuva ”najvećeg” člana.

    Zadaci za vežbu:

    Zadatak 53 Datoteka čije se ime unosi sa standardnog ulaza sadri podatke o uspehu studenata nakolokvijumima iz osnova programiranja. Prva linija datoteke sadrži broj studenata, a zatim svakasledeća linija sadrži ime i prezime odredjenog studenta, njegov broj indeksa (u obliku korisničkogimena na alas-u npr. mr07888) i broj poena na prvom i na drugom kolokvijumu.

  • 8.3 Unije 85

    a) Definisati strukturu podataka za čuvanje podataka o studentimab) Učitati iz datoteke studente i smestiti ih u niz struktura. Ispisati taj niz studenata na

    standardni izlaz radi provere ispravnosti učitavanja niza.c) Sortirati niz studenata u u opadajućem poretku prema broju poena.d) U datoteku RezultatIspita.txt uneti spisak studenata koji su položili ispit sortiran u opadajućem

    poretku prema broju poena.Ispit su položili samo oni kojima je zbir poena na prvom i drugom kolokvijumu bar pedeset.

    Napomena: Zadatak uraditi sa preusmeravanjem!

    Zadatak 54 Napisati program koji iz datoteke čije se ime unosi sa standardnog ulaza, učitavaniz struktura tačaka, izračunava obim poligona odreen učitanim nizom tačaka i ispisuje njegovuvrednost na standardni izlaz. Smatrati da u datoteci nema vǐse od 100 tačaka. Zadatak uraditi sapreusmeravanjem!

    Zadaci za praktikum:

    Zadatak 55 Napisati program kojim se izdvajaju sekvence od n karaktera iz seminarskog rada.Broj n se učitava sa ulaza.

    Zadatak 56 Napisati program kojim se izdvaja najduža sekvenca karaktera bez ponovljenih kon-sonanata.

    Zadatak 57 Napisati funkciju koja datoteci brKljucRec.c vrši prebrojavanje pojave ključnih rečiif, while i for i rezultat vraća preko liste argumenata. Napisati program koji vrši testiranje radaove funkcije i sačuvati ga u datoteci sa imenom brKljucRec.c.

  • 86 Jelena Tomašević

  • 9

    Programski jezik C

    1

    9.1 Rad sa datotekama

    Svi dosadašnji primeri su čutali podatke sa standardnog ulaza i pisali rezultat na standardniizlaz. Sledeći korak je pisanje programa koji pristupa datoteci koja nije unapred povezana saprogramom. Pravila su jednostavna. Pre nego što se može čitati ili pisati, datoteka mora bitiotvorena bibliotečkom funkcijom fopen. Ova funkcija kao argument uzima ime datoteke kojuotvara, obavlja neke pripremne radnje (detalji toga nam nisu potrebni) i vraća pokazivač koji semože koristiti u narednim operacijama čitanja ili pisanja datoteke. Ovaj pokazivač pokazuje nastrukturu FILE koja sadrži informacije o datoteci. Sve ovo sadržano je u . Prototip ovepromenljive i funkcije je:

    FILE *fp;FILE *fopen(char *ime, char *mode);

    Poziv funkcije fopen u programu je:

    fp = fopen(ime, mode);

    Prvi argument funkcije je ime datoteke koja se otvara a drugi je režim rada. Dozvoljeni režimi radasu ”r” za čitanje, ”w” za pisanje i ”a” za dodavanje na kraj datoteke. Uvek pri otvaranju trebaproveriti da li je otvaranje uspelo to jest da li je vrednost koja se vratila kao rezultat poziva funkcijerazličita od NULL. Ako otvaranje nije uspelo potrebno je prijaviti grešku i nasilno završiti radprograma (funkcijom exit definisanom u ). Greška se može prijaviti na standardnomizlazu ili na standardnom izlazu za greške (stderr).

    Prilikom otvaranja datoteke, automatski se otvaraju tri datoteke i obezbeuju pokazivači tihdatoteka: to su standardni ulaz (pokazivac je stdin), standardni izlaz (stdout) i standardna greška(stderr).

    Prototip funkcije za formatirani ulaz je:

    int fscanf(FILE *fp, char *format,...)

    Funkcija fscanf vraća kao rezultat broj učitanih parametara.Prototip funkcije za formatirani izlaz je:

    int fprintf(FILE *fp, char *format,...)

    1Zasnovano na primerima sa sajtova http://www.matf.bg.ac.yu/∼filip.

  • 88 Jelena Tomašević

    Ove funkcije su identične funkcijama scanf i printf samo što je prvi argument pokazivač datotekekoji odreuje u koju se datoteku nešto upisuje ili iz koje datoteke se nešto čita.Pomenimo još i funkciju

    int sscanf(const char *s, const char *format...)

    Ona je identična sa scanf samo što ne učitava sa ulaza nego iz niske s.Funkcije za ulaz i izlaz znakova su:

    int fgetc(FILE *fp)

    Vraća jedan znak iz datoteke fp ili EOF u slučaju kraja datoteke ili greške

    char *fgets(char *s, int n, FILE *fp)

    Čita najvǐse n-1 znak u niz s prekidajući čitanje ako naie na znak za novi red. Taj znak se neupisuje u niz već se niz završava sa ’\0’. Ova funkcija vraća s a u slučaju kraja datoteke ili greškevraća NULL.

    int fputc(int c, FILE *fp)

    Upisuje znak c u datoteku fp. Vraća upisani znak ili EOF u slučaju greške.

    int fputs(const char *s, FILE *fp)

    Upisuje string s (koji ne mora da sadrži znak ’\n’) u datoteku fp. Ona vraća nenegativnu vred-nost ili EOF u slučaju greške.

    int ungetc(int c, FILE *fp)

    Dodaje znak c nazad u datoteku fp kako bi se pročitao pri sledećem pozivu funkcije za čitanje.Vraća kao rezultata znak koji je dodat nazad ili EOF u slučaju greške.Kada se završ rad sa datotekom, potrebno je zatvoriti datoteku funkcijom fclose(FILE *fp).

    Primer 92 U datoteku ”podaci.txt” upisati prvih 10 prirodnih brojeva, a zatim iz iste datotekeučitati brojeve dok se ne stigne do kraja i ispisati ih na standardni izlaz.

    #include

    /* Zbog funkcije exit */#include

    main(){

    int i;int br;

    /* Otvaramo datoteku sa imenom "podaci.txt" za pisanje */FILE* f = fopen("podaci.txt", "w");

    /* Ukoliko otvaranje nije uspelo, fopen vraca NULL. U tom slucaju,prijavljujemo gresku i zavrsavamo program */

    if (f == NULL)

  • 9.1 Rad sa datotekama 89

    {printf("Greska prilikom otvaranja datoteke podaci.txt za pisanje\n");exit(1);

    }

    /* Upisujemo u datoteku prvih 10 prirodnih brojeva (svaki u posebnom redu) */for (i = 0; i

  • 90 Jelena Tomašević

    printf("Greska prilikom otvaranja datoteke podaci.txt za citanje\n");exit(1);kao u prethodnom primeru. Nema sustinske razlike.*/

    }

    /* Upisujemo sadrzaj u datoteku */fprintf(datoteka,"Zdravo svima\n");

    /* Zatvaramo datoteku */fclose(datoteka);

    }

    Primer 94 Kopirati datoteku ”ulaz.txt” u datoteku ”izlaz.txt”. Uz svaku liniju zapisati i njen broj.

    #include

    #define MAX_LINE 256

    /* Funkcija getline iz K&R jednostavno realizovana preko funkcije fgetsint getline(char s[], int lim){

    char* c = fgets(s, lim, stdin);return c==NULL ? 0 : strlen(s);

    }Ovu funkciju necemo koristiti u programu.*/main(){

    char line[MAX_LINE];FILE *in, *out;int line_num;

    if ((in = fopen("ulaz.txt","r")) == NULL){

    fprintf(stderr, "Neuspesno otvaranje datoteke %s\n", "ulaz.txt");return 1;

    }

    if ((out = fopen("izlaz.txt","w")) == NULL){

    fprintf(stderr, "Neuspesno otvaranje datoteke %s\n","izlaz.txt");return 1;

    }

    /* Prepisivanje karakter po karakter je moguce ostvariti preko:int c;while ((c=fgetc(in)) != EOF)

    putc(c,out);*/

    line_num = 1;/* Citamo liniju po liniju sa ulaza*/

  • 9.1 Rad sa datotekama 91

    while (fgets(line, MAX_LINE, in) != NULL){

    /* Ispisujemo broj linije i sadrzaj linije na izlaz */fprintf(out, "%-3d :\t", line_num++);fputs(line, out);

    }

    /* Zatvaramo datoteke */fclose(in);fclose(out);

    }

    Primer 95 Ilustracija čitanja niza struktura iz tekstualne datoteke.

    Datoteka cije se ime unosi sa standardnog ulaza sadrzi podatke oproizvodima koji se prodaju u okviru odredjene prodavnice.Svaki proizvod se odlikuje sledecim podacima :

    bar-kod - petocifreni pozitivan