programiranje 2 - racunarstvo550.xyz. semestar/programiranje... · 1 i. općenito o c-u programski...

Download Programiranje 2 - racunarstvo550.xyz. semestar/Programiranje... · 1 I. Općenito o C-u Programski jezik C spada u proceduralne programske jezike kojeg su razvili Dennis Ritchie i

If you can't read please download the document

Upload: trankhue

Post on 06-Feb-2018

233 views

Category:

Documents


0 download

TRANSCRIPT

  • Izradili: Duje Senta Antonio Prcela 9. oujka 2015.

    Sveuilite u Splitu Fakultet elektrotehnike, strojarstva i brodogradnje

    Programiranje 2

    Prirunik za laboratorijske

    vjebe

  • Sadraj

    I. Openito o C-u ............................................................................................................................................ 1

    II. Uvod u leksiki pretprocesor ...................................................................................................................... 1

    III. Usporedba sintaksi C-a i VB.Net-a .......................................................................................................... 3

    Vjeba 1. ............................................................................................................................................................. 5

    Vjeba 2. ............................................................................................................................................................. 8

    Vjeba 3. ...........................................................................................................................................................11

    Vjeba 4. ...........................................................................................................................................................13

    Vjeba 5. ...........................................................................................................................................................15

    Vjeba 6. ...........................................................................................................................................................20

    Vjeba 7. ...........................................................................................................................................................21

    Vjeba 8. ...........................................................................................................................................................24

    Vjeba 9. ...........................................................................................................................................................26

    Vjeba 10. .........................................................................................................................................................28

    Vjeba 11. .........................................................................................................................................................30

    Vjeba 12. .........................................................................................................................................................33

  • 1

    I. Openito o C-u

    Programski jezik C spada u proceduralne programske jezike kojeg su razvili Dennis Ritchie i Ken Thompson u

    Bellovim laboratorijima 1976.g. C je jezik ope namjene, to znai da se u njemu moe napraviti apsolutno sve:

    od rjeavanja zadataka, do pisanja pogonskih programa (engl. driver), operacijskih sustava, tekst procesora ili

    igara. C, kao jezik, ni u emu ne ograniava. Omoguuje i ukljuivanje naredbi pisanih strojnim jezikom (engl.

    assembler), zbog ega je zajedno s mogunou direktnog pristupa pojedinim bitovima, bajtovima ili cijelim

    blokovima memorije, pogodan za pisanje sistemskih programa. Zbog tih karakteristika C je meu popularnijim

    programskim jezicima i rabe ga mnogi programeri. Kao jedan od najvanijih jezika u povijesti komercijalne

    raunalne industrije, C je do danas ostao jedini programski jezik prilagoen za sve raunalne platforme, od malih

    sustava pa do mrenih superraunala. Programi napisani u njemu vrlo su bliski nainu rada hardvera te u naelu

    zahtijevaju od programera dobro razumijevanje rada procesora, memorije te ulazno-izlaznih sklopova. Koritenje

    C-a je odreeno standardom, a trenutni standard koji se koristi je C11.

    II. Uvod u leksiki pretprocesor

    Pojam "pretprocesor" se koristi za oznaku prve faze obrade izvornog koda. On vri leksiku obradu izvornog koda

    na tri naina:

    1. Umee u izvorni kod datoteke koje su navedene u direktivi #include

    2. Vri supstituciju teksta prema direktivi #define

    3. Vri selekciju koda, koji e se prevesti, pomou direktiva #if, #elif, #else i #endif

    Koriste se dvije varijante direktive #include:

    #include //primjer 1

    U gornjem primjeru (primjer 1) je prikazano kada se datoteka trai u direktoriju u kojem su smjetene datoteke s

    deklaracijama standardnih funkcija. Dok se u donjem primjeru (primjer 2) ukljuuje datoteka koja se nalazi u

    direktoriju gdje je izvorni kod (u direktoriju programa gdje se nalazi datoteka *.c).

    #include "ime_datoteke" //primjer 2

    Leksika supstitucija teksta, makro (engl. macro), se definira pomou direktive #define na dva naina:

    #define identifikator tekst_za_supstituciju

    Neki primjeri supstitucije:

    #define GODINA 20

    #define ANTE "Ante"

    #define NEW_LINE printf("\n");

    #define ISPIS printf

    #define ZBROJ(arg1, arg2) arg1 + arg2

  • 2

    Primjer koda sa supstitucijom: Ispis:

    #include

    #define GOD 20 #define ANTE "Ante" #define NEW_LINE printf("\n"); #define ISPISI printf #define POST(a,b) (float)((a)*(100))/(b)

    int main(int argc, char *argv[]) { ISPISI("%s ima %d godina.\n", ANTE, GOD); NEW_LINE ISPISI("Imao je na ispitu %f posto.", POST(3,5)); return 0;

    }

    Ante ima 20 godina.

    Imao je na ispitu 60 posto.

    Tablica T1 Primjer supstitucije

    Leksika definicija Izvorni kod Supstitucija

    #define MNOZI(a,b) ((a)*(b)) y = MNOZI(2+5,broj); y = ((2+5)*(broj));

    #define MNOZI(a,b) a*b y = MNOZI(2+5,broj); y = 2+5*broj;

    Tablica T2 Primjer makroa

    Razlog zagrada u prvoj definiciji (Tablica T2) je zbog prioriteta operatora, jer da je makro napisan na nain kao u

    drugoj definiciji zbog prioriteta operatora * nad +, makro ne bi vratio oekivani rezultat.

  • 3

    III. Usporedba sintaksi C-a i VB.Net-a

    Osnovna razlika koda napisanog u C-u s onim napisanim u VB.NET-u je taj to je C vrlo osjetljiv na velika i mala

    slova (case-sensitive). Nije isto je li napisano pozivFunkcije(); ili PozivFunkcije();, u ovom sluaju bi se

    pozvale dvije razliite funkcije.

    C programski jezik: Visual Basic .NET

    #include

    int main(int argc, char *argv[]) { int cijeli_broj = 0; char znak = 0; printf("Hello world!"); printf("\n");

    /*komentar u C-u*/ return 0; }

    Module Module1

    Sub Main()

    Dim cijeli_broj As Integer Dim znak as Char Console.Write("Hello world!") Console.WriteLine()

    'komentar u VB.Net-u End Sub End Module

    Tablica T3 Usporedba sintakse C i VB.net

    Kao to se moe vidjeti iz priloene tablice (Tablica T3), postoje znaajne razlike sintaksi. Prvo se moe uoiti da

    se u C-u imena kljunih rijei piu malim slovima. Sljedee je to to se svaka naredba mora zatvoriti s toka-

    zarezom ; inae se javlja greka pri prevoenju koda. Varijable prilikom deklaracije moraju imati pridruenu

    inicijalnu vrijednost, inae sadri nedefiniranu vrijednost. Pristup sadraju neinicijalizirane varijable je strogo

    zabranjen te moe dovesti do greke u prevoenju ili izvravanju programa.

    U C-u ne postoje procedure, samo funkcije. U gornjem primjeru se moe vidjeti funkcija main. Kao i kod VB.NET-

    a, main je poetna funkcija svakog programa, od nje program zapoinje s radom. Funkcija main() po

    standardima ANSI C te ISO/IEC C11 ima povratnu vrijednost iskljuivo tipa int, dok ostale funkcije mogu imati

    povratnu vrijednost bilo kojeg tipa. Poeljno je da main() vraa vrijednost nula (return 0;) ako je program

    uspjeno zavrio s radom, te bilo koju drugu vrijednost u sluaju da je dolo do greke prilikom izvravanja

    programa.

    int main(int argc, char *argv[])

    int main(void)

    int prije main-a, a i bilo koje druge funkcije, govori da funkcija vraa cijelobrojnu vrijednost, dok void unutar

    zagrada govori da funkcija ne prima nikakve argumente. U varijabli argc je zapisano broj argumenata koji se

    nalaze u nizu stringova u argv. Program moe imati minimalno jedan argument, to reprezentira naziv programa.

  • 4

    Funkcije vraaju vrijednost na sljedei nain:

    int inkrement(int x) { x++; return x; //x je varijabla tipa int }

    Funkcija printf()

    - funkcija koja se koristi za formatirani ispis teksta i/ili varijabli na ekranu.

    printf("Pozdrav! "); // ispis teksta

    printf("\n"); // prelazak u novi red

    printf("%d", x); // ispis vrijednosti varijable x tipa int

    postoji jo:

    %s ispis stringa (niza znakova)

    %c ispis varijable tipa char

    %e ispis tipa double

    %f ispis varijable tipa float

    Adresni operator &

    - Slui da bi se pristupilo adresi neke varijable. Navodi se ispred imena varijable.

    Funkcija scanf() & scanf_s()

    - koristi se za formatirani unos podataka s standardnog ulaza (stdin), te se koriste isti specifikatori formata

    kao kod printf-a (%d, %e, %c). Poto se radi o unosu, mora se koristiti adresni operator & da bi se

    vrijednost spremila na memorijsku adresu koja je dodijeljena varijabli.

    Primjer koritenja:

    scanf(" %d", &x); //spremi unos s tastature na adresu varijable x

    Za unos stringa preko scanf() se ne koristi adresni operator:

    scanf(" %s", txt); //txt je adresa poetnog elementa niza znakova

    Gore navedena funkcija ima nedostatak to na standardnom ulazu moe biti unesena vea koliina teksta nego

    to varijabla moe spremiti pa se program srui (prelijevanje meuspreminka). Da bi se sprijeilo ruenje

    programa u takvim uvjetima uvedena je funkcija scanf_s(), koja nije dio ANSI C-a i podrana je samo u

    Windows OS-u. Primjer koritenja:

    char txt[N] = {0}; // deklariran je niz znakova txt od N elemenata scanf_s(" %s", txt, N); /* unos se sprema u txt ako je unos krai od N

    znakova */

    Komentari u C-u se mogu pisati na dva naina:

    // komentar koda - koritenjem dvostruke kose crte, za samo jedan red komentara.

    /* tekst se nalazi

    u dvije linije */ - unutar oznaka za komentar koji se eli pisati u vie redaka.

  • 5

    Vjeba 1.

    U programskom jeziku C postoje etiri vrste osnovnih primitivnih varijabli (tablica 1.1). Osnovni operatori koji

    postoje u C-u su preteno isti kao i kod ostalih programskih jezika (tablica 1.2).

    Razred varijabli Oznaka Veliina Raspon vrijednosti

    Cjelobrojni tip podataka

    int

    short

    long

    4 byte

    2 byte

    8 byte

    Znakovni tip podataka char 1 byte

    Realni tip podataka

    float

    double

    4 byte

    8 byte

    Kardinalni tip podataka (mogu biti cjelobrojni i znakovni

    tipovi)

    unsigned char

    unsigned int

    unsigned long

    1 byte

    4 byte

    8 byte

    Tablica 1.1 Primitivne varijable u C-u

    Razredi operatora Oznaka Naziv Napomena

    Matematiki operatori

    + - * / = % ++ --

    zbrajanje oduzimanje mnoenje dijeljenje operator pridruivanja modulus inkrement dekrement

    - s desna na lijevo pridruuje vrijednost - ostatak cjelobrojnog dijeljenja

    Operatori za rad s bitovima

    & | ^ !

    logiko AND logiko OR logiko XOR logiko NOT

    Operatori indirekcije & *

    adresni operator pokazivaki operator

    Uvjetni operatori

    > <

    == != >=

  • 6

    Ime varijable ujedno oznaava i adresu varijable. Koja je to adresa? Brigu o tome vodi prevoditelj. Adresa

    varijable se moe odrediti pomou posebnog operatora & koji se naziva adresni operator. Koristi se kao unarni

    operator koji se zapisuje ispred imena varijable.

    Primjer koda: Ispis:

    #include

    int main(void) { int cijeli_broj = 5; printf("Adresa varijable je: %d\n", &cijeli_broj); printf("Vrijednost varijable je: %d", cijeli_broj); return 0; }

    Adresa varijable je: 24883681

    Vrijednost varijable je: 5

    Tablica 1.3 Primjer ispisa vrijednosti i adrese varijable

    Varijable je mogue prebaciti u drugi tip pomou eksplicitne pretvorbe (poznato kao cast operator).

    Primjenjuje se tako da se ispred varijable koja se pretvara napie novi tip. Sljedei primjer (tablica 1.4.) e

    pretvoriti cijeli broj y u broj s pominim zarezom i spremiti u varijablu x:

    Primjer koda: Ispis:

    int y = 12; float x = (float)y; printf("%f", x);

    12.000000

    Tablica 1.4 Primjer eksplicitne pretvorbe varijable

    for petlja

    For petlja se upotrebljava kada se kod unutar te petlje treba ponoviti odreeni broj puta. Prva treina zagrade

    (do prvog toka-zareza ;) govori koju varijablu uzeti i odakle krenuti. Druga treina zagrade je uvjet koji treba

    bit zadovoljen da bi krenulo u iduu iteraciju petlje. Zadnji dio zagrade je operacija kojom se mijenja varijabla,

    najee korak kojim se mijenja varijabla. Napomena: nije potrebno pisati sva tri dijela zagrade. Moe se npr.

    korak poveavati unutar petlje.

    Primjer koda: Ispis:

    for(int i=0; i

  • 7

    ZADACI

    1. Napisati program koji definira etiri varijable (char, int, float, double). Ispisati sve etiri varijable, zajedno s

    njihovim adresama i izraunati koliko su bajtova u memoriji sve te varijable zajedno zauzele.

    2. Napisati program koji definira tri varijable tipa znak. Prvoj dodijeliti znak 0, drugoj dodijeliti znak 9, a treu

    izraunati kao sumu prve dvije. Ispisati sva tri znaka kao znak i kao ASCII vrijednosti.

    3. Napisati program koji rauna sumu, produkt, razliku i kvocijent dva cijela broja. Ispisati sve rezultate na ekran.

    4. Napisati program koji rauna sumu prvih 50 brojeva.

    5. Napisati program koji na ekran ispisuje:

    E E E E E

    D D D D

    C C C

    B B

    A

    U programu je dozvoljeno koristiti najvie dvije printf() naredbe.

  • 8

    Vjeba 2.

    Cilj ove vjebe je upoznavanje s naredbom selekcije "if" koja slui za uvjetno izvravanje dijela koda. Provjera

    uvjeta se skoro pa uvijek koristi u programima (gotovo je nemogue zamislit program bez ijedne provjere nekog

    uvjeta).

    Razlikuje se:

    1. uvjetna naredba: if

    2. uvjetno grananje: if->else

    3. viestruko grananje: if -> else if -> else if -> -> else

    switch -> case

    Sintaksa if naredbe s primjerima je prikazana u tablici 2.1.

    Sintaksa za if->else...if->else:

    if (/*uvjet*/) { /* naredbe koje se izvravaju ukoliko je uvjet zadovoljen */

    }

    else if (/*drugi uvjet*/) { /* naredbe ukoliko NE proe prvi uvjet, a drugi bude zadovoljen */

    } else { /* naredbe ukoliko nije zadovoljen ni prvi ni drugi uvjet */ }

    Sintaksa za switch->case->..->default:

    switch (X) //varijabla koja e se provjeravati { case const: /* umjesto const se pie konstanta s kojom e se usporediti varijabla X */ /* dio koda koji se izvodi ako je uvjet zadovoljen */ break; /* nakon to se odradi kod, prekida se switch. Ako nema break, program e nastaviti provjeriti ostale case-eve */ case... ... default: /* ako nije nijedan case ispunjen, odradit e se naredbe unutar default-a */ break; }

    Tablica 2.1 Sintaksa if-a i switch-case

    U tablici 2.2 su prikazana dva primjera za zadatka koji provjerava varijablu I. Lijevi primjer je s if a desni s

    switch-case. Ako je I jednak 1 tada e nova vrijednost od I biti 20, ako I nije jednak 1 tada provjeri je li

  • 9

    jednak 2 te ako je promijeni mu vrijednost u 20. U sluaju da nijedan uvjet nije ispunjen ne mijenja se vrijednost

    od varijable I.

    if -> else if -> else switch -> case

    if (broj == 1) { broj = 20; } else if (broj == 2) { broj = 10; } else break;

    switch (broj) { case 1: broj = 20; break; case 2: broj = 10; break; default: break; }

    Tablica 2.2 Primjer zadatka s if...else-if & switch-case

    Opis za if:

    1. Ako je broj jednak 1 onda varijabli broj pridrui broj 20,

    2. Ako je broj jednak 2 onda varijabli broj pridrui broj 10,

    3. Ako ni to nije ispunjeno, odlazi na else. Zadnji else nema nikakav uvjet, pa e se izvriti ako nisu

    ispunjeni uvjeti prethodnih blokova.

    Opis za switch: Provjerava se uvjet za varijablu I. Ukoliko nije udovoljen nijedan uvjet prelazi se na default

    (koji je jednak kao i else).

    1. Ako je broj jednak 1 onda pridrui varijabli broj broj 20,

    2. Ako je broj jednak 2 onda pridrui varijabli broj broj 10,

    3. Jo ostaje default koji govori ono isto kao i else: ako broj nije bio ispunio prethodne uvjete onda

    prekini s radom programa (break).

    Kod switch-a nema provjere s logikim operandima, niti je mogua usporedba dviju ili vie varijabli. Mogua je

    jedino usporedba varijable s konstantom. Unutar svakog case-a ili default-a, iza naredbi se nalazi break koji

    prekida daljnje provjere. Taj break, koji odreuje da se zavri s bilo kakvom daljnjom provjerom, preskae sve

    preostale case-eve pa i tako preskoi default. Ako ne postoji break na kraju case-a, tada e switch nastavit

    s provjerom sljedeeg uvjeta, u ovom primjeru case 2.

  • 10

    Ugnijeeni uvjeti:

    Mogue je postavljati nove uvjete unutar uvjeta, tako da unutar jednog if naredbenog bloka moe bit drugi if

    naredbeni blok.

    Primjer:

    if(broj > 0 && broj < 50)

    {

    if (broj%2 == 0)

    printf("Broj je izmedju 1 i 49, te je paran.\n");

    else

    printf("Broj je izmedju 1 i 49, te nije paran.\n");

    }

    ZADACI

    1. Napisati program koji pretvara uneseni realni broj u cijeli na nain da ako je prva znamenka iza

    decimalne toke >= 5 zaokruuje se na prvi vei. Program mora raditi i za pozitivne i za negativne

    brojeve.

    2. Napisati program koji unosi 10 brojeva ali na ekran ispisuje samo neparne. Broj se ispisuje im je unesen.

    3. Napisati program koji unosi 10 brojeva i rauna koliko ih je djeljivo s 3.

    4. Napisati program koji unosi 10 znakova i rauna koliko ih je uneseno:

    a) malim slovima;

    b) koliko ih je = H.

    5. Napisati program koji unosi bodove kolokvija za 5 uenika (izmeu 0 i 100) te rauna koliko je uenika

    prolo (vie od 50) i koliki je prosjeni broj bodova.

  • 11

    Vjeba 3.

    Kod programiranja se esto javlja potreba da se odreeni dio koda ponavlja vie puta, s time da taj broj

    ponavljanja nije unaprijed poznat. U takvom sluaju se koristi while ili do->while petlja. Razlika izmeu ove

    dvije petlje je u tome to while najprije provjerava je li uvjet zadovoljen, te onda kree s izvravanjem koda i

    tako se vrti sve dok nije uvjet zadovoljen. Dok do->while petlja radi na nain da se uvijek ue jednom u petlju,

    izvri kod unutar petlje, pa tek nakon toga provjeri je li uvjet zadovoljen i ovisno o tome se ulazi u sljedeu

    iteraciju ili se zavrava rad petlje. Kod obje vrste while petlji mora se obratiti pozornost da se negdje unutar

    while petlje mijenja vrijednost varijable koja se provjerava u uvjetu, inae doi do realizacije beskonane petlje

    (primjeri obiju vrsta petlji se nalaze u tablici 3.1).

    while primjeri: do->while primjeri:

    int broj = 5; while (broj != 0) { printf("%d, ", broj); broj--; } //ispisuje: 5, 4, 3, 2, 1,

    int broj = 5; do { printf("%d, ", broj); broj--; } while(broj!= 0); //ispisuje: 5, 4, 3, 2, 1,

    int broj = -5; while(broj != 0) { printf("%d, ", broj); broj++; } //ispisuje: -5, -4, -3, -2, -1,

    int broj = -5; do { printf("%d, ", broj); broj++; }while(I != 0); //ispisuje: -5, -4, -3, -2, -1,

    Tablica 3.1 Primjeri while i do while petlji

    Sljedea while petlja prikazana u tablici 3.1 ne ispisuje nita, jer uvjet mora biti razliit od nule (true).

    int broj = 0; while(broj) { printf("%d, ", broj); broj--; }

    Tablica 3.2 Uvjet while petlje

    Da se na poetku inicijalizira broj = 3, petlja bi se izvrila tri puta jer sve to je razliito od nule, pa i negativni

    brojevi, u uvjetu se tretira kao istina.

    Naredbe za upravljanje petljama

    Postoje dvije naredbe koje se mogu koristiti unutar programa, a slue za prekid petlje (break) ili za direktan skok

    u sljedeu iteraciju petlje (continue).

  • 12

    Generiranje sluajnih brojeva

    Da bi raunalo nasumino generiralo brojeve, koristi se rand()funkcija definirana u zaglavlju .

    Meutim ako se koristi samo funkcija rand() ona e uvijek generirati iste sluajne brojeve zbog ega se

    najee koristi u kombinaciji s srand(). Funkcija srand() mijenja brojevnu bazu iz koje se generiraju brojevi,

    pa su brojevi generirani pomou funkcije rand() zbilja sluajni. Primjer generiranja sluajnih brojeva je prikazan

    u tablici 3.3.

    int broj = 5; srand((unsigned)time(NULL)); broj = rand();

    U ovom primjeru, srand() uzima trenutno vrijeme te na osnovu njega generira bazu od koje e krenuti generiranje sluajnih brojeva. Funkcija time(NULL) vraa trenutno vrijeme u UNIX/POSIX obliku, koje rauna ukupan broj sekundi koje su prole od 1.1.1970 (Koordinirano svjetsko vrijeme UTC).

    int i = 0, randBr = 0, min = 11, max = 100; srand((unsigned)time(NULL)); for(i=0; i ili < od generiranog. Pogaanje traje sve dok se broj ne pogodi. Potrebno je ispisati iz

    kojeg je puta broj pogoen.

    4. Napisati program koji ispisuje sve primitivne brojeve od 0 100.

  • 13

    Vjeba 4.

    Niz je imenovana i numerirana kolekcija istovrsnih objekata koji se nazivaju elementi niza. Elementi niza mogu

    biti prosti skalarni tipovi i korisniki definirani tipovi podataka. Oznaavaju se imenom niza i cjelobrojnom

    izrazom indeksom koji oznaava poziciju elementa u nizu. Indeks niza se zapisuje u uglatim zagradama iza

    imena niza. Primjerice, x[3] oznaava element niza x indeksa 3.

    Sintaksa deklaracije elementa jednodimenzionalnog niza je:

    Tip_podatka ime_Niza [ brojElemenata ];

    Prvi element niza ima indeks 0, a n-ti element ima indeks n-1. Prema tome, x[3] oznaava etvrti element niza. S

    elementima niza se manipulira kao s obinim skalarnim varijablama, uz uvjet da je prethodno deklariran tip

    elemenata niza. Primjerice, deklaracijom:

    int A[10];

    definira se A kao niz od 10 elementa tipa int.

    Inicijalizacija nizova

    Za globalno i statiki deklarirane nizove automatski se svi elementi postavljaju na vrijednost nula. Kod lokalno

    deklariranih nizova ne vri se inicijalizacija poetnih vrijednosti elemenata niza. To mora obaviti programer. Za

    inicijalizaciju elemenata niza na neku vrijednost esto se koristi for petlja, primjerice kod:

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

    A[i] = 1;

    sve elemente niza A postavlja na vrijednost 1.

    Niz se moe inicijalizirati listom konstanti, napisanom unutar vitiastih zagrada, koje redom odreuje poetnu

    vrijednost elemenata niza.

    int A[10]= {1,2,23,4,32,5,7,9,6};

    Ako se inicijaliziraju svi potrebni elementi niza, tada nije nuno u deklaraciji navesti dimenziju niza ve to obavlja

    sam prevodilac.

    int A[]= {1,2,23,4,32,5,7,9,6,3};

    Ovaj izraz je potpuno ekvivalentan prethodnoj deklaraciji.

    Niz se moe i parcijalno inicijalizirati. U deklaraciji int A[10]= {1,2,23}; prva tri elementa imaju vrijednost

    1, 2 i 23, a ostale elemente prevodilac postavlja na vrijednost nula.

  • 14

    ZADACI

    1. Napisati program koji s tastature unosi dva cijela broja i matematiku operaciju (+, -, * ili /). Ovisno o operaciji je potrebno izraunati i ispisati rezultat. 2. Napisati program koji unosi 20 rezultata ocjena s kolokvija (sprema ih u niz). Ocjene mogu biti od 1-5 i ako se

    unese krivi broj unos se ponavlja. Kada su ocjene unesene program rauna histogram ocjena u 5 grupa (koliko je

    bilo kojih ocjena) i ispisuje ga na ekran.

    3. Napisati program koji za uneseni niz od 10 cijelih brojeva:

    a) trai najmanji element niza;

    b) trai najvei element niza;

    c) sortira niz od najmanjeg prema najveem elementu.

    Napomena: najmanji i najvei element niza se ne smiju samo ispisati nakon sortiranja. Potrebno ih je pronai

    prije sortiranja.

  • 15

    Vjeba 5.

    U C-u ne postoji varijabla tipa string koja sprema tekst, nego se koristi niz znakova char varijable. Deklaracija i

    inicijalizacija je mogua na vie naina, a specifikator formata za ispis i unos je %s. Poto se radi o nizu znakova,

    potrebno je na kraju svakog stringa imati '\0' koji oznaava kraj stringa, inae e najvjerojatnije doi do ruenja

    programa ili ispisa nepoeljnih znakova.

    char znakovi1[] = "test" ;

    char znakovi2[] = {'t', 'e', 's', 't', '\0'};

    char znakovi3[5] = {0};

    scanf(" %s", znakovi3);

    printf("%s\n", znakovi1);

    printf("%s\n", znakovi2);

    printf("%s\n", znakovi3);

    Prva deklaracija i inicijalizacija automatski odreuje veliinu niza i na kraj niza dodaje '\0', dok je kod drugog

    naina potrebno runo dodati '\0'. Kod treeg naina se kreira niz s 5 elemenata, kod kojeg svaki element ima

    ASCII vrijednost -52, to je znak s brojem 204 iz proirene ASCII tablice. Tek nakon scanf() mijenja se vrijednost

    var. znakovi3 s onim to se unese s tastature te se na kraju unesenog stringa automatski doda '\0'. Pri tome se

    unos u niz znakova radi bez koritenja adresnog operatora &. Razlog tome je to varijabla znakovi3 pokazuje na

    adresu poetka niza.

    Napomena: U ostatku teksta koristiti e se naziv "string" umjesto "niz znakova".

    Unos stringa s tastature

    Stringove je mogue unijeti na sljedee naine:

    scanf(" %s", tekst);

    gets(tekst);

    Obratite pozornost na razliku izmeu koritenja razmaka u scanf i bez koritenja razmaka:

    /*prvi slucaj s razmakom*/ int broj = 0; char tekst[50] = {0}; scanf("%d ", &broj); //ima razmak! gets(tekst); printf("%d\n", broj); printf("%s\n", tekst);

    /*drugi slucaj bez razmaka*/ int broj = 0; char tekst[50] = {0}; scanf("%d", &broj); //nema razmak! gets(tekst); printf("%d\n", broj); printf("%s\n", tekst);

    Nakon unosa 123 pa abc se ispisuje:

    123 abc

    Nakon unosa 123 odmah se ispisuje:

    123

    Tablica 5.1 Primjeri unosa s razmakom i bez razmaka

  • 16

    Ako se u oba sluaja unese 123 pa pritisne enter, u prvom sluaju e biti mogue unijeti neku vrijednost u

    varijablu tekst, dok e u drugom sluaju preskoiti unos u tekst te e odmah ispisati vrijednost varijable tekst

    koja je samo nova linija (enter).

    U ostatku teksta e se spomenuti samo nekoliko vanijih funkcija za rad za stringovima. One su ugraene u

    datoteci zaglavlja , za detalje kako koja radi mogu se pogledi primjeri s prezentacija, potrait primjere

    na internetu ili u Pomoi (CTRL+F1) Visual Studia (ili nekog drugog razvojnog okruenja).

    Neke vanije funkcije unutar

    1) strlen(znakovi1);

    Funkcija strlen() vraa duinu stringa znakovi1. Duinu rauna od prvog elementa do '\0' (koji se ne rauna).

    Budui da funkcija vraa neku vrijednost, poeljno je da se ta vrijednost ispie ili spremi u neku varijablu jer je

    puno efikasnije pristupati varijabli nego pozivati funkciju.

    char neki_string[] = "abcdefg987" ;

    x = strlen(neki_string);

    printf("Duzina stringa neki_string je: %d \n" , x);

    ili:

    printf("Duzina stringa neki_string je: %d \n" , strlen(neki_string));

    ISPIS:

    Duzina stringa neki_string je: 10

    2) strcpy(destinacija, izvor);

    Funkcija strcpy() uzima sve znakove iz jednog stringa te ih sprema u novi (ukljuujui i '\0'). Lijevi argument je

    odredina varijabla u koju se kopira string, a desna je izvorina iz koje e se uzimati svi elementi.

    3) strcmp(prvi_string, drugi_string);

    Funkcija strcmp() usporeuje dva stringa te vraa:

    - 0 ako su oba stringa identina

    - pozitivni broj ako je prvi_string vei od drugi_string (vei ASCII vrijednost prvog razliitog slova je

    vea u prvi_string nego u drugi_string)

    - negativni broj ako je prvi_string manji od drugi_string (manji ASCII vrijednost prvog razliitog slova

    je manja u prvi_string nego u drugi_string)

    Funkcija strcmpi() radi na slian nain, ali ne razlikuje velika i mala slova, to znai da e vratiti 0 za usporedbu

    stringova abcd i ABCD.

  • 17

    Jo neke funkcije iz .

    strlwr Pretvara sva slova iz stringa u mala slova

    strupr Pretvara sva slova iz stringa u velika slova

    strrev Obre znakove u stringu (npr.: abcde pretvara u edcba)

    strchr Pronalazi prvo pojavljivanje odreenog znaka u stringu

    strrchr Pronalazi zadnje pojavljivanje odreenog znaka u stringu

    strncat Dodaje odreeni broj znakova iz jednog stringa u na kraj drugog stringa.

    strncmp Usporeuje n znakova od dva stringa, povratna vrijednost je ista kao kod strcmp.

    Tablica 5.2 funkcije iz zaglavlja string.h

    Funkcije za unos znaka s tastature

    Deklarirane su u zaglavlju .

    getch() uzima jedan znak s tastature, ali ga ne prikazuje na ekranu (ako koristite putty, onda vam je ovo

    poznato kod unosa ifre).

    getche() uzima jedan znak s tastature te ga odmah i prikae na ekranu.

    getchar() uzima jedan znak s tastature - bez obzira koliko se unese, isto kao i gore navedena

    funkcija getche() prikae unos, ali "eka" dok se pritisne enter nakon ega program nastavlja s radom. Obje

    funkcije uzimaju znak odmah prilikom unosa.

    Primjer:

    char a, b, c;

    a = getch();

    b = getche();

    c = getchar();

    printf("%c %c %c \n", a,b,c);

    Tijekom unosa abcde na konzolnom prozoru e se prikazati bcde, a funkcija printf e ispisati: a b c.

    Tablica 5.3. prikazuje jo neke od funkcija za rad sa znakovima. Kod svake od ovih funkcija vrijedi pravilo da vraa

    vrijednost 0 ako uvjet nije zadovoljen, a broj razliit od 0 ako je uvjet zadovoljen. Primjeri s ovim funkcijama su

    prikazani u tablici 5.4.

    Funkcije za rad s znakovima: isalnum testira je li neki znak dekadska znamenka ili slovo. isalpha testira je li neki znak slovo. islower testira je li znak malo slovo. isupper testira je li znak veliko slovo. isdigit testira je li neki znak dekadska znamenka ili slovo. isascii testira je li znak definiran u ASCII tablici. toascii vraa ASCII vrijednost nekog znaka tolower vraa ASCII vrijednost malog slova za zadano slovo toupper vraa ASCII vrijednost velikog slova za zadano slovo

    Tablica 5.3 Funkcije iz zaglavlja ctype.h

  • 18

    Primjer: Ispisuje:

    char a = 'a', b = 'B', c = '1', d = 'f';

    printf("isalnum 'a': %d \n", isalnum(a)); printf("isalpha 'B': %d \n", isalpha(b)); printf("isnum '1': %d \n", isdigit(c)); printf("isupper 'f': %d \n", isupper(d));

    isalnum 'a': 2

    isalpha 'B': 1

    isnum '1': 4

    isupper 'f': 0

    Tablica 5.4 Primjeri ispisa

    Pretvaranje tipova podataka

    Za pretvorbu jednog tipa podataka u drugi mogu se koristiti sljedee funkcije:

    atof() pretvara niz znakova (ascii) u realan broj;

    atoi() pretvara niz znakova (ascii) u cijeli broj;

    itoa() pretvara cijeli broj u niz znakova.

    Deklaracije funkcija:

    double atof(const char *string);

    int atoi(const char *string);

    char *itoa(int x, char *string, int baza);

    string - adresa niza znakova u koji se spremaju znamenke broja

    x - broj koji se pretvara u string

    baza - brojevna baza (heksadecimalno: 16; decimalno: 10;) po kojoj se vri pretvorba (u opsegu od 2-36) povratna vrijednost je pokaziva na string.

    Primjer:

    char tekst[] = "12ab34cd56";

    int broj;

    broj = atoi(tekst);

    printf("Tekst pretvoren u broj: %d \n" , broj);

    Ispisuje:

    Tekst pretvoren u broj: 12

  • 19

    ZADACI

    1. Napravi program koji uzima znakove s tastature (sa ili bez prikaza tih znakova na ekranu) sve dok se ne unese

    znak ESC. Tada se izlazi iz programa.

    2. Napravit program koji iz unesenog stringa stvara novi (u novoj varijabli), na nain da iz prvog prebaci sve

    znakove osim brojeva.

    3. Napraviti program koji uneseni string mijenja u 3 koraka i rezultat svakog ispisati. Smije se koristiti samo jedan

    string.

    a) U stringu trebaju ostati samo slova.

    b) Iz tog stringa treba izbaciti sve samoglasnike (velika i mala slova).

    c) Sva velika slova pretvoriti u mala i obrnuto.

    4. Napravi program koji unesenu dekadsku vrijednost pretvara u heksadecimalnu, s tim da je znamenke potrebno

    ispisati svaku u svom redu i to u pravom rasporedu.

  • 20

    Vjeba 6.

    Viedimenzionalnim nizovima se pristupa preko dva ili vie indeksa. Primjerice,deklaracijom int x[3][4]; definira

    se dvodimenzionalni niz koji ima 3 x 4 = 12 elemenata. Deklaraciju se moe itati i ovako: definirana su 3 niza od

    kojih svaki ima po 4 integer elementa. Dvodimenzionalni nizovi se esto koriste za rad s matricama. U tom

    sluaju nije potrebno razmiljati o tome kako je niz sloen u memoriji, jer se elementima pristupa preko dva

    indeksa: prvi je oznaka retka, a drugi je oznaka stupca matrice.

    Matrini prikaz niza je:

    x[0][0] x[0][1] x[0][2] x[0][3]

    x[1][0] x[1][1] x[1][2] x[1][3]

    x[2][0] x[2][1] x[2][2] x[2][3]

    Memorijski raspored elemenata dvodimenzionalnog niza, koji opisuju neku matricu, je takvi da su elementi

    sloeni po redovima matrice; najprije prvi redak, zatim drugi, itd. Viedimenzionalni niz se moe inicijalizirani ve

    u samoj deklaraciji, primjerom:

    int x[3][4] = {{1, 21, 14, 8},{12, 7, 41, 2},{1, 2, 4, 3}};

    Navoenje unutarnjih vitiastih zagrada je opcijski, pa se moe pisati i sljedea deklaracija:

    int x[3][4] = {1, 21, 14, 8, 12, 7, 41, 2, 1, 2, 4, 3};

    Ovaj drugi nain inicijalizacije se ne preporuuje, jer je tee uoiti raspored elemenata.

    ZADACI

    1. Napisati program koji unosi jednu matricu (A dimenzija 3x3) i iz te matrice rauna matricu B = 5*A. Matricu B

    je potrebno ispisati.

    2. Napisati program koji unosi jednu matricu (A dimenzija 3x3) i iz te matrice stvara matricu B = AT. Matricu B je

    potrebno ispisati.

    3. Napisati program koji unosi dvije matrice (A i B dimenzija 3x3), a zatim rauna matricu C = A + B i matricu D =

    A * B. Matrice C i D je potrebno ispisati.

    4. Napisati program koji unosi 5 imena i zatim:

    a) pronalazi indeks imena prvog po abecedi, te ispisuje indeks i ime;

    b) pronalazi indeks imena zadnjeg po abecedi, te ispisuje indeks i ime;

    c) sortira imena po abecedi i ispisuje ih.

    Pri tome rezultati pretraivanja ne smiju razlikovati velika i mala slova, tj. bez obzira je li ime uneseno velikim ili

    malim slovom treba biti na ispravnom mjestu po abecedi.

  • 21

    Vjeba 7.

    U C-u varijabla moe biti deklarirana na globalnoj i lokalnoj razini. Razlika izmeu ove dvije razine je to to je

    globalna varijabla dostupna "cijelom programu" tj. svim funkcijama, a lokalna samo u funkciji ili petlji u kojem je

    deklarirana. Primjer deklaracije varijabli na globalnoj i lokalnoj razini nalazi se u tablici 7.1.

    GLOBALNA LOKALNA

    #include

    int x = 11; //Globalna varijabla

    int main(void) { printf("x je jednak: %d\n", x); return 0; }

    #include

    int main(void) { int i = 5;

    for(int j = i; j > 0; j--) printf("j je: %d\n", j );

    printf("i je: %d \n", i); printf("konacni j je: %d", j); return 0; }

    Tablica 7.1 Deklaracija varijabli na globalnoj i lokalnoj razini

    U gornjem primjeru za deklariranje lokalne varijable, varijabla 'i' je lokalna i dostupna samo unutar main-a, dok

    je varijabla 'j' vidljiva samo unutar for petlje pa e prevodilac javiti greku "undeclared identifier" za zadnji printf.

    Varijable unutar funkcije se briu nakon to funkcija zavri s radom, te se opet kreiraju pri ponovnom pozivanju

    funkcije. Funkcije se najee koriste za odreenu radnju koja se esto koristi, pa se ne mora iznova pisati nego

    samo pozvati.

    Funkcija se kreira u tri koraka:

    1. Deklaracija ime funkcije, broj i tip argumenata koji se prosljeuju u funkciju te povratna vrijednost

    funkcije.

    2. Definicija funkcije - uz ime, argumente i povratnu vrijednost sadri kod s naredbama.

    3. Poziv funkcije - mjesto u kodu gdje se poziva funkcija.

  • 22

    DIO KODA OPIS

    #include

    int pravokut(int, int);

    Deklaracija funkcije pravokut iznad main-a.

    int main(void) { int kv = 0, x = 2, y = 3; kv = pravokut(x, y); printf("x*y je: %d \n", kv); return 0; }

    Varijabla kv prima povratnu vrijednost funkcije.

    Ispisuje se: x*y je: 6

    int pravokut(int a, int b) { return a * b; }

    Definicija funkcije povratnog tipa integer, prima argumente tipa integer i vraa njihov umnoak.

    Takav pristup je posebno vaan ukoliko funkcija poziva druge funkcije. Kad se ne bi kod pisao na ovaj nain,

    trebalo bi se voditi rauna o rasporedu funkcija u kodu. Poeljno je da se najprije deklariraju funkcije, te se iza

    main funkcije napiu njihove definicije . Postoje funkcije koje mogu vratiti vrijednost (int, double, char, itd.),

    te one koje ne vraaju vrijednost (void). Ukoliko funkcija vraa vrijednost, potrebno je tu vrijednost vratiti

    naredbom return. Na mjestu gdje je return funkcija se prekida, a sav kod koji se eventualno nalazi iza

    return nee izvriti.

    Ukoliko je funkcija void tada se poziva na sljedei nain:

    ime_funkcije(arg1, arg2);

    Ukoliko funkcija vraa vrijednost rada tada se vrijednost moe ili spremiti u varijablu ili direktno koristiti:

    x = ime_funkcije(arg1, arg2); //spremanje vrijednosti u varijablu

    printf("%[neki format ispisa]", ime_funkcije(arg1, arg2)); /*direktno

    koritenje vrijednosti za ispis */

    Nakon to se izae iz funkcije sve lokalne varijable se briu. Tako da kada se ponovo ue u funkciju, varijable

    poprimaju poetne vrijednosti. Ukoliko je potrebno da varijabla sadri svoju vrijednost i nakon to izae iz

    funkcije, to se moe napraviti koritenjem kljune rijei static. Ona omoguuje da kada se opet pozove

    funkcija zadrava prethodnu vrijednost.

    static int x = 0;

    Osim static postoji i kljuna rije const koja se koristi za deklaraciju konstanti.

    const broj = 123;

  • 23

    Neke funkcije iz zaglavlja Datoteka zaglavlja sadri matematike funkcije, kao npr.: potenciranje, korjenovanje, logaritmi, trigonometrija, itd. Neke od najee koritenih su definirane funkcije:

    double exp(double X); //koristi se za raunanje eX

    double sqrt(double X); //koristi se za raunanje double pow(double X, double Y); //koristi se za raunanje XY

    Kao to se moe vidjeti, u zagradama se alju vrijednosti koje su tipa razliitog od int. Zbog toga, u sluaju da je X varijabla tipa int, potrebno je koristiti cast operator, npr.:(double)X, pa e poziv jednoj od gornjih funkcija izgledati ovako:

    sqrt((double)varijabla); Takoer ne smije se zaboraviti da svaka od matematikih funkcija ima povratnu vrijednost, pa tu vrijednost treba negdje spremiti ili ispisati. Pri tome treba voditi rauna o tipu argumenta i povratnoj vrijednosti.

    double rezultat = 0; int parametar = 25; rezultat = sqrt((double)parametar);

    Povratna vrijednost je tipa double pa se mora spremiti u varijablu istog tipa.

    ZADACI

    1.Napisati program koji unese 3 broja i zatim po elji korisnika (ovisno o tome koje se slovo unese) rauna:

    a) = + + b) = c) = +

    d) =

    Svi rezultati se raunaju preko f-ija (jedna za svaki primjer), s tim da je za primjer pod d potrebno provjeriti je li izraz ispod korijena >= 0, i ako nije treba javiti greku. 2. Napisati program koji sadri dvije varijable: globalnu varijablu X i lokalnu varijablu Y(lokalna za f-ju main) i dodijeliti im neke vrijednosti. Iz glavnog programa treba pozvati f-ju koja ispisuje vrijednosti obije varijable.

    3. Napraviti program koji u obinoj f-ji rauna faktorijele. Rezultat je potrebno ispisati u glavnom programu i nije dozvoljeno koritenje globalnih varijabli.

    4. Napisati f-ju kojom se priblino odreuje vrijednost ex (e = 2.718282), i rezultat usporediti s vrijednou koja se dobije pomou standardne funkcije exp() deklarirane u math.h. U rjeavanju problema koristiti razvoj u red:

    = 1 +

    1!+

    2

    2!+

    3

    3!+

    4

    4!

    Npr. za x = 5, ispisati izraunate rezultate za 5, 10 i 50 ponavljanja. Zato se program ponaa "udno" za 50 ponavljanja?

  • 24

    Vjeba 8.

    U programiranju i matematici esto se koriste rekurzivne funkcije. Direktna rekurzija nastaje kada se u definiciji

    funkcije poziva ta ista funkcija, a indirektna rekurzija nastaje kada jedna funkcija poziva drugu funkciju, a ova

    ponovo poziva funkciju iz koje je pozvana. Definicija rekurzivne funkcije u pravilu se sastoji od dva dijela:

    temeljnog sluaja i pravila rekurzije. Jedan od najeih problema koji se koristi za opis rekurzivne funkcije su

    faktorijeli. Pri rjeavanju problema pomou rekurzivne funkcije treba voditi rauna o dvije stvari:

    1. Prvo treba provjerit temeljni sluaj rekurzije.

    2. Odradi pravilo rekurzivnog poziva.

    unsigned int my_fact(unsigned int x)

    {

    if(x < 2) // Temeljni sluaj za brojeve manje od 2

    return 1; // jer je: 0! == 1! == 1

    else

    return x * my_fact(x-1); /* Pravilo rekurzivnog poziva pr.: 3! =

    3 * 2! */

    }

    1. Pozivanja rekurzije

    my_fact(3); { return 3 * my_fact(2); { return 2 * my_fact(1); { return 1; //x je manji od 2 } } } 2. Vraanje iznosa

    //1. POVRAT

    my_fact(3); { return 3 * my_fact(2); { return 2 * 1; //vracena jedinica i mnoi se s 2. } }

    //2. POVRAT

    my_fact(3); { return 3 * 2; //vraa iznos 6 u glavni program }

    Tablica 8.1 Simulacija rada rekurzivne funkcije faktorijela za izraun 3!.

  • 25

    ZADACI

    1. Napisati program koji trai je li neki broj element niza. U programu treba napraviti f-ju trai koja uzima tri

    argumenta (niz, broj elemenata niza i vrijednost koja se trai), a treba vratiti 1 ako broj postoji ili 0 ako broj ne

    postoji.

    2. Napisati program koji rauna produkt svih elemenata matrice dimenzija 3x3. Program ne smije sadravati ni

    jednu globalnu varijablu, unos i proraun napraviti u odvojenim funkcijama.

    3. Napisati program koji sadri f-je my_strlen i my_strcpy, koje rade isto to i f-je strlen i strcpy. Ispravnost

    funkcija provjeriti usporedbom sa stvarnim f-jama strlen i strcpy.

    4. Napisati program koji pomou rekurzivne f-je rauna faktorijele.

    5. Napisati program koji koritenjem rekurzivnih funkcija trai minimalni, odnosno maksimalni element niza

    brojeva.

    6. Napraviti program koji uneseni dekadski broj pretvara u binarni, oktalni ili heksadecimalni. Dekadski broj, kao i

    brojevna baza (2, 8, 16) u koju se radi pretvorba se unose u programu, a pretvorbu je potrebno realizirati pomou

    rekurzivne f-je. Rezultat se ispisuje u mainu.

  • 26

    Vjeba 9.

    Struktura je skup jedne ili vie varijabli, grupiranih zajedno pod jednim imenom radi lakeg rukovanja. Varijable

    strukture su lanovi ili polja strukture koje definira korisnik. Kao i ostale varijable, strukture mogu biti povratna

    vrijednost neke funkcije. U daljnjem tekstu e se koristit prvo veliko slovo za ime strukture, dok se u programu

    mogu, kao i kod obinih varijabli, koristiti drugi naini imenovanja.

    struct Osoba {

    int dan, mjesec, godina, niz[10];

    char ime[15], prezime[15], spol;

    };

    Potrebno je naglasiti da se nakon zatvarajue vitiaste zagrade stavlja toka-zarez. Definiranjem strukture se ne

    kreira nova varijabla, niti se rezervira prostor u memoriji. Tek kada se deklariraju varijable tipa neke strukture

    rezervira se prostor u memoriji. Primjer s gornjom strukturom:

    struct Osoba Marko; /* U memoriji je rezervirano mjesto za varijablu tipa struct Osoba, a varijabla se zove Marko */

    Pristup pojedinim elementima strukture se vri pomou toka operatora:

    scanf(" %d", &Marko.dan);

    printf("%d\n", Marko.dan);

    Kod deklaracije strukture mogue je odmah deklarirati i varijable tipa te strukture, tako da se nakon zagrade

    napiu varijable:

    struct Osoba {

    int dan, mjesec, godina;

    char ime[15], prezime[15], spol;

    } Marko, Ana, Petra, Josip; /* Moe se deklarirati, ali nije preporuljivo.

    Nije dozvoljena deklaracija globalnih varijabli i koritenje istih na kolegiju! */

    Strukture se mogu deklarirati unutar neke funkcije (npr. main) ili pak izvan funkcija, razlika je u tome to u prvom

    sluaju deklarirana struktura nije vidljiva ostalim funkcijama (sjetiti se dijela o lokalnim i globalnim varijablama!).

  • 27

    Niz struktura

    struct Osoba nizOsoba[10];

    Kreiran je niz od 10 varijabli tipa strukture Osoba. Pristup pojedinoj varijabli se vri na sljedei nain npr.:

    nizOsoba[2].dan //Pristupa se treem elementu niza i to varijabli 'dan'.

    Struktura unutar strukture

    Definiranje strukture Motor Def. strukture Motor unutar strukture Auto.

    struct Motor { int kubik, snagaKw; };

    struct Auto { int godina; char proizvodac[15], model[15]; struct Motor motorizacija; };

    //Deklaracija i pristupanje motoru

    struct Auto Lancia; Lancia.Motor.snagaKw = 1750;

    Tablica 9.1 Primjeri definicija struktura

    ZADACI

    1. Napisati program koji unosi dva proizvoljna vremena (sat, minute, sekunde) i zbraja ih. Za pohranu

    vremena koristiti strukturu, a zbrajanje i ispis napraviti u odvojenim funkcijama.

    2. Napisati program koji za uneseni datum rauna koji je datum bio dan prije i koji e datum biti dan poslije.

    Za pohranu datuma koristiti strukturu datum (dan, mjesec, godina). Proraun i ispis dana prije/poslije

    napraviti u funkciji dan_prije / dan_poslije.

    3. Napisati program koji unosi podatke o 5 osoba (ime, prezime, datum i sat roenja). U programu napraviti

    funkciju koja pronalazi najstariju osobu, te funkciju koja pronalazi osobu prvu po abecedi.

  • 28

    Vjeba 10. Jedan od glavnih razloga zbog ega se C jezik smatra jezikom niske razine je taj to omoguuje indirektno

    manipuliranje s podacima i izvrenjem programa. Kako bi se pristupilo adresi varijabli koriste se posebni

    operatori - adresni operator & i operator indirekcije *, te specijalni tip varijabli koje se nazivaju pokazivake

    varijable ili pokazivai (engl. pointer).

    Adresni operator &

    Adresa varijable se moe odrediti pomou posebnog operatora & koji se naziva adresni operator. Koristi se kao

    unarni operator koji se zapisuje ispred imena varijable.

    #include int main(void) { int y = 777; printf("\n Vrijednost y je %d", y); printf("\n Adresa y je %#p", &y); //# je za ispisivanje u heks. obliku return 0; }

    Ispis programa moe izgledati ovako:

    Vrijednost y je 777

    Adresa y je 0x0063FDF4

    Tablica 10.1 Koritenje adresnog operatora

    Ispis adrese je izvren u heksadecimalnom obliku s osam znamenki, jer je koriteno 32-bitno raunalo na kojem

    je adresa odreena 32-bitnim kardinalnim brojem. Napomena: pri sljedeem izvravanju programa ispis adrese

    ne mora biti isti jer operacijski sustav ne uitava program uvijek na isto mjesto u memoriji (time se mijenja i

    adresa na kojoj se nalazi varijabla x).

    Pokazivai

    Varijable kojima je vrijednost adresa neke druge varijable ili funkcije nazivaju se pokazivai ili pointeri. Vrlo je

    vano definirati na koji tip varijable pokazuje jer C prevoditelj mora znati kakav e tip podatka biti na adresi koju

    oni sadre.

    Deklaracija pokazivaa vri se slino deklaraciji varijable, s razlikom to ispred imena varijable (imena pokazivaa)

    obvezno zapisuje znak indirekcije '*'. Primjerice,

    int *p = NULL; /* p je pokazivac na objekt tipa int */

    unsigned *q = NULL; /* q je pokazivac na objekt tipa unsigned */

    Ovim deklaracijama definirane su dvije pokazivake varijable. Njihova vrijednost je neodreena, jer im nije

    pridijeljena adresa neke varijable. Vano je znati da pokazivae prije upotrebe treba inicijalizirati, odnosno mora

    im se pridijeliti vrijednost adrese postojee varijable. Pri tome, tip pokazivaa mora biti jednak tipu varijable. To

    se ostvaruje adresnim operatorom '&'.

    int suma = 777; /* deklaracija i inicijalizacija varijable suma */

    int *p = NULL; /* deklaracija pokazivaca na objekt tipa int */

    p = &suma; /* p inicijaliziran na adresu varijable suma */

  • 29

    Pokaziva p je inicijaliziran da pokazuje na varijablu suma. Daljnje koritenje

    printf("%d", suma);

    printf("%d", *p);

    daje isti ispis, jer se indirekcijom pokazivaa dobiva vrijednost na koju on pokazuje, a to je vrijednost varijable

    suma.

    ZADACI

    1. Napisati program koji prvo unosi, a zatim ispisuje elemente nekog polja brojeva i polja znakova zajedno s

    adresom svakog elementa. Sve unose i ispise je potrebno napraviti preko pokazivaa i ne smiju se koristiti [].

    2. Napisati program koji u jednoj funkciji rauna sumu, produkt i razliku dva broja, a svi se rezultati ispisuju u

    glavnom programu.

    3. Zadatak s raunanjem dana prije i poslije rijeiti preko funkcija na nain da se sva tri datuma deklariraju u

    mainu, a unos, i proraun dana prije i poslije u f-ji. Rezultate je potrebno ispisati u mainu, a ne u funkciji.

    4. Napisati program koji za zadani string trai koliko se puta podstring pojavljuje u stringu. Podstring je potrebno

    unijeti u f-ji. F-ja za pretraivanje treba vratiti broj ponavljanja. U funkciji za pretraivanje se moe koristiti f-ja

    strncmp iz string.h.

  • 30

    Vjeba 11. U standardnoj biblioteci implementiran je niz funkcija koje se koriste za sve ulazno izlazne

    operacije: unos s tipkovnice, ispis na ekran te itanje i pisanje informacija koje se pohranjuju na magnetskim i

    optikim medijima. Komuniciranje s ureajima koji obavljaju ove operacije vri se sekvencijalno bajt po bajt, a

    programski mehanizam kojim se vri ovakvi prijenos informacije naziva se tok (engl. stream). U jednom se

    programu moe raditi s vie tokova. Svakom toku se pridjeljuje jedna struktura podataka imena FILE, koja je

    definirana u . Temeljna namjena te strukture je da slui kao memorijski ulazno/izlazni

    meuspremnik (engl. I/O buffer) pri prijenosu podataka.

    Tokovi se dijele u etiri grupe:

    standardni ulaz (vri unos znakova s tipkovnice),

    standardni izlaz (vri ispis na ekran),

    standardna dojava greke (obino se vri ispis na ekran),

    datoteni tok (vri itanje ili pisanje podataka u datoteku).

    1. Funkcije fopen() i fopen_s()

    Da bi se moglo koristiti neku datoteku potrebno je od operacijskog sustava zatraiti dozvolu pristupa toj

    datoteci. Taj proces se zove otvaranje datoteke. Isto tako se za kreiranje nove datoteke mora zatraiti dozvola od

    operacijskog sustava. Tu funkciju obavlja standardna funkcija fopen(). Ona pored komunikacije s operacijskim

    sustavom kreira datoteni tok koji sadri memorijski meuspremnik za efikasno itanje ili spremanje podataka

    na disk.

    Prototip funkcije fopen() je:

    FILE *fopen(const char *ime_datoteke, const char *mod);

    Moe se koristiti i sigurna verzija fopen_s()

    errno_t fopen_s(FILE **fp, const char *ime_datoteke, const char *mod);

    koja vraa poruku o greci u strukturu tipa errno_t umjesto vrijednosti NULL ukoliko doe do greke otvaranja datoteke. Modovi otvaranja datoteke su opisani u tablici 11.1.

    Mod Opis

    "r" Otvori datoteku za itanje, ako datoteka ne postoji fopen() vraa NULL.

    "w" Otvori datoteku za pisanje, ako ne postoji datoteka zadanog imena, kreira se nova.

    "a" Otvori datoteku za dopunu sadraja, ako ne postoji datoteka zadanog imena, kreira se nova.

    "r+" Otvori datoteku za itanje i pisanje . Ako ne postoji datoteka zadanog imena, kreira se nova.

    "w+" Isto kao "r+"

    "a+" Otvori datoteku za itanje i dopunu. Ako ne postoji datoteka zadanog imena, kreira se nova.

    "b" Ako se iza slova w, r ili a jo zapie slovo 'b' to oznaava da se datoteku treba otvoriti u binarnom modu.

    Tablica 11.1 Modovi za nain otvaranja datoteke.

  • 31

    Dobra je praksa da se uvijek provjeri je li datoteka otvorena bez greke. Primjerice, za otvoriti datoteku imena "hello.txt" u koju e se neto upisati koriste se sljedee naredbe:

    FILE *fp;

    fp = fopen("hello.txt", "w");

    if(fp == NULL)

    printf("Greska pri otvaranju datoteke");

    2. fclose() funkcija Zatvaranje datoteke se vri funkcijom fclose() iji je prototip:

    int fclose(FILE *fp);

    U koliko se ne pozove funkcija fclose() datoteka se automatski zatvara kada se doe do kraja programskog bloka u kojem je otvorena.

    3. feof() funkcija Za detektiranje kraja datoteke predviena je posebna funkcija:

    int feof(FILE *fp);

    koja vraa vrijednost razliitu od nule ako je dosegnut kraj datoteke. Nakon toga vie nije mogue itanje iz datoteke. 4. Funkcije za rad s datotekama

    getc() , putc() upravljaju sa znakovima fscanf(), fprintf() upravljaju sa formatirano zapisanim znakovima fgets(), fputs() upravljaju sa nizom znakova na razini retka

    5. fprintf() funkcija

    Kada je datoteka otvorena, koristi je se kao tok. Primjerice, naredbama

    fprintf(fp, "Hello World!\n"); fprintf(fp, "Hello World drugi put!");

    u prethodno otvorenoj datoteci "hello.txt" biti e zapisane dvije linije teksta:

    Hello World! Hello World drugi put!

  • 32

    6. fscanf() funkcija

    Za formatirano itanje sadraja datoteke koristi se fscanf() funkcija, koja je poopeni oblik scanf() funkcije za dobavu podataka iz ulaznih tokova. Prototip fscanf() funkcije je:

    int fscanf(FILE *fp, const char *fmt, ...);

    Parametar fp je pokaziva ulaznog toka, koji moe biti standardni ili datoteni tok koji se dobije kada se datoteka otvori s atributom "r", "r+" ili "w+". String 'fmt' slui za specifikaciju formata po kojem se uitava vrijednost varijabli, ije adrese se koriste kao argumenti funkcije. Tri toke oznaavaju proizvoljan broj argumenata, uz uvjet da svakom argumentu mora pripadati po jedan specifikator formata u stringu 'fmt'.

    7. fscanf_s() funkcija

    int fscanf_s(FILE *fp, const char *fmt, ...);

    Funkcija slina fscanf(), samo sa dodatnom kontrolom sigurnosti.

    ZADACI

    1. Napisati program koji kopira jednu datoteku u drugu. Nazivi obije datoteke se unose u glavnom programu, a

    kopiranje se radi u funkciji.

    2. Napisati program koji iz datoteke znak, po znak ita znamenke sve dok ne proita neto to nije broj ili se

    dostigne kraj datoteke. Te znamenke je potrebno pretvoriti u broj koji je bio zapisan u datoteci i ispisati ga na

    ekran.

    3. Napisati program koji iz datoteke ita maks. 100 podataka o osobama (ime, prezime i godinu roenja) i trai

    koliko se osoba zove Ana. itanje datoteke i brojenje je potrebno napraviti u odvojenim f-jama.

    4. Napisati program koji iz datoteke proita 1 cijeli redak i onda ga rije po rije ispisuje na ekran, a svaka je rije

    u svom retku.

    - Datoteke potrebne za ove zadatke je potrebno napraviti u nekom tekst. editoru (npr. Notepad, ).

  • 33

    Vjeba 12.

    Programski jezik C omoguuje da se pri potrebi za vrijeme izvravanja programa rezervira dodatna memorija za

    pohranu varijabli. Taj postupak se naziva alokacija, a koristan je npr. ukoliko prije pokretanja programa nije

    poznata veliina niza. Dinamiko alociranje memorije omoguuje da se tijekom rada programa rezervira

    odreeni dio memorije za odreenu varijablu.

    Dinamika alokacija se radi sa sljedeim naredbama koje su definirane u :

    malloc() - alocira odreeni broj bajtova u memoriji.

    calloc() - alocira odreeni broj bajtova u memoriji, te svaki bajt postavi na nulu.

    realloc() - koristi se za promjenu veliine ranije alociranog prostora u memoriji.

    free() - oslobodi rezervirani dio memorije.

    Za alociranje je potrebno koristiti pokazivae. Din. alociranje memorije za niz brojeva s 10 elemenata:

    int *nizBrojeva = (int *)malloc(10 * sizeof(int));

    Ako pokaziva ima vrijednost NULL znai da alokacija nije uspjela, pa je poeljno da se nakon svake alokacije

    provjeri je li uspjela ili ne. Isto ne smije se zaboraviti koristiti funkciju free() na kraju programa, inae e nakon

    zatvaranja programa ostati alociran blok memorije kojem operacijski sustav, a ni program, vie ne mogu

    pristupiti, te jedino preostaje ponovno pokretanje raunala da bi se taj blok memorije oslobodio.

    int *nizBrojeva = (int *)malloc(x * sizeof(int));

    if(nizBrojeva == NULL)

    {

    printf("Alokacija memorije nije uspjela!\n");

    return -1;

    }

    Pristup elementima je isto kao i kod nizova!

    for(int i = 0; i

  • 34

    ZADACI

    1. Napisati program koji unosi bodove kolokvija svih studenata i rauna prosjeni broj bodova, nakon to su

    ocjene unesene, uz uvjet da unaprijed nije poznato koliko je bilo studenata.

    2. Napisati program koji neki dekadski broj pretvara u string koji se sastoji od znamenki tog broja. String se

    dinamiki alocira ovisno o tome koliko znamenki ima broj.

    3. Napisati program koji ita imena N (unosi se u programu) studenata iz datoteke, a zatim za svakog studenta

    pita koliko je bodova dobio iz svakog od kolokvija(ukupno 3) i zatim rauna ukupni broj bodova i ocjenu, prema

    tablici:

    Bodovi Ocjena

    50 - 60% => 2

    61 74% => 3

    75 87% => 4

    88 -100% => 5

    4.Napisati program koji pomou nizova simulira rad reda (podaci se skidaju spoetka, a stiu na kraj). Red mora

    biti cirkularan, a dimenzija se unosi s tastature.

  • 35

    Reference:

    [1] Ivo Mateljan: Programiranje C jezikom, Sveuilite u Splitu, 2005.

    [2] Predavanja i prezentacije kolegija Programiranje 2:

    - doc. dr. sc. Linda Vickovi

    - dipl. ing. Ivica Crnjac