You are on page 1of 92

FAKULTET ELEKTROTEHNIKE, STROJARSTVA I BRODOGRADNJE SVEUILITE U SPLITU

(UVOD U) RAUNALA I PROGRAMIRANJE


Laboratorijske vjebe

Listopad, 2010.

KATEDRA ZA MODELIRANJE I INTELIGENTNE RAUNALNE SUSTAVE (KaMIS) Laboratorij za robotiku i inteligentne sustave (LaRIS)

Predavanja: dr. sc. Mirjana Bonkovi, red. prof. dr. sc. Ranko Goi, doc. mr. sc. Ana Kuzmani Skelin Laboratorijske vjebe: Maja Braovi, mag. ing. Bruno Batarelo, dipl. ing. Ante Deni, dipl. ing.

Dodatna literatura za kolegij (Uvod u) Raunala i programiranje: 1. Gottfried, B.: "Schaum's Outline Series: Programming with C", Second Edition, McGraw-Hill, 1996. 2. Vulin, R.: "Zbirka rijeenih zadataka iz C-a", kolska knjiga, Zagreb, 2003. 3. Parlante, N.: "Essential C", 2003, http://cslibrary.stanford.edu/101/EssentialC.pdf. 4. Materijali dostupni preko MIT OpenCourseWare projekta: http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/.

VJEBA 1 Povijest programskog jezika C Programski jezik C nastao je 1972. godine u Bell laboratorijima, kao rezultat rada raunalnog znanstvenika Dennisa Ritchiea. On je prvi kreirao i primijenio programski jezik C.

Slika 1.1. Raunalni znanstvenici Ken Thompson (lijevo) i Dennis Ritchie (desno) [1]. Veina bitnih ideja i koncepata koji su koriteni prilikom razvijanja programskog jezika C dolo je iz programskog jezika BCPL (engl. Basic Combined Programming Language), ali samo posredno, preko programskog jezika B kojega je razvio Ken Thompson 1970. godine za prvi UNIX sustav na DEC PDP raunalu (engl. Digital Equipment Corporation Programmed Data Processor). Dennis Ritchie i Ken Thompson su 1983. godine nagraeni Turingovom nagradom (za teoretski rad na podruju generikih operacijskih sustava te za implementaciju operacijskog sustava UNIX), to je jedna od najveih poasti koju raunalni znanstvenici mogu dobiti. Zato C? Programski jezik C je inicijalno dizajniran za implementaciju sistemskog softvera (jezgra UNIX sustava je gotovo u potpunosti napisana u C-u), ali danas se upotrebljava kao jezik ope namjene. To znai da se pomou njega mogu implementirati ne samo operacijski sustavi, ve i raunalne igre, driveri, razliite aplikacije i sl. Iako danas sve popularniji postaju objektno-orijentirani programski jezici (npr. Java ili C#), C se jo uvijek esto koristi jer programeru omoguuje veu kontrolu nad programom i obino se takvi programi izvravaju bre nego njihovi ekvivalenti napisani u nekom od objektno-orijentiranih jezika. C jezik bi se mogao nazvati jezikom nie razine sa stajalita objektno-orijentiranog programera, ali sa stajalita programera koji pie programe u Asembleru (engl. Assembly language) ili (teoretski) u strojnom jeziku (npr. 00010110 01010111 11111000 10000001), bio bi shvaen kao jezik vie 3

razine. Izrazi "jezik nie razine" te "jezik vie razine" su dosta relativni i obino jako vezani uz kontekst u kojemu se koriste. Kako do izvrne datoteke? Proces stvaranja izvrne datoteke sastoji se od 3 koraka: 1. Programer napie izvorni kod programa (engl. source code). Datoteke u kojima se nalazi izvorni kod imaju ekstenziju .c (ako su napisane u C-u), i moe ih biti vie od jedne. 2. Izvorni kod se prevodi u objektni kod pomou prevoditelja (engl. compiler). Prevoditelj u objektni kod posebno prevede svaku datoteku u kojoj se nalazi izvorni kod. Datoteke u kojima se nalazi objektni kod sadre kod razumljiv raunalu (strojni kod), te imaju ekstenziju .obj ili .o. 3. Datoteke u kojima se nalazi objektni kod i biblioteke koje su specificirane u njemu se povezuju u jedinstvenu datoteku pomou poveznika (engl. linker). Ta jedinstvena datoteka naziva se izvrna datoteka, i ima ekstenziju .exe. Slika 1.2. Proces kreiranja izvrne datoteke.

Vano je napomenuti da je prevoenje izvornog koda u strojni kod jednosmjeran proces, tj. strojni kod se gotovo nikad u potpunosti ne moe uspjeno prevesti natrag u izvorni kod.

Ukratko o C programima Opi oblik C programa izgleda ovako: #include <stdio.h> #include ... int main() { Naredbe napisane u C-u... return 0; } Sve naredbe koje zapoinju znakom # nazivaju se predprocesorske naredbe. Naredba #include se koristi kada se u programu koji se pie trebaju koristiti unaprijed isprogramirane funkcije (posebni dijelovi programskog koda o kojima e biti vie govora kasnije). Uz ovu naredbu mora stajati parametar oblika <ime_datoteke.h>. Taj parametar definira ime datoteke u kojoj se nalaze prototipovi ili deklaracije funkcija koje e se koristiti u programu. Takve datoteke imaju ekstenziju .h (engl. header file), i esto se nazivaju standardnim bibliotekama. U programima se najee koriste naredbe za ispis znakova na ekran, za unos znakova sa tipkovnice, za otvaranje i zatvaranje tekstualnih datoteka, itd. Deklaracije svih ovih (i mnogih drugih) funkcija nalaze se u datoteci standard input/output header, i zato se na poetku gotovo svakog C programa nalazi naredba #include <stdio.h>. Naravno, na poetku svakog C programa moe se nalaziti vie #include naredbi, a ne samo jedna. U programskim jezicima esto se nailazi na koncept funkcije. Funkcija je dio programa koji ima svoje ime, te koji moe primati odreene argumente i vratiti odreeni argument (ako funkcija vrati nulu, to obino znai da su sve naredbe u njoj uspjeno izvrene). Funkcije se koriste kako bi se poveala preglednost programa, te kako bi programeri mogli koristiti ve unaprijed isprogramirana rjeenja za uestale probleme. Funkcija main() je glavna funkcija u C jeziku. Jedina razlika izmeu ove funkcije i svih ostalih jest to e se funkcija main() uvijek izvesti prije svih ostalih funkcija. Ostale se funkcije moraju pozvati iz funkcije main() da bi se uope mogle izvriti. Linija koda int main() kae da funkcija main() vraa cijeli broj (engl. integer). Unutar vitiastih zagrada pie se kod programa. Na kraju programa se pomou naredbe return moe specificirati vrijednost koju e funkcija vratiti. U ovome sluaju funkcija main() vraa nulu. Nakon svake naredbe stavlja se toka zarez (';'). Ona oznaava kraj jedne naredbe i poetak druge. Prvi program u C-u Slijedei program je najmanji i najjednostavniji program koji se moe napisati u C-u. Program ne radi nita. 5

#include <stdio.h> int main() { return 0; } Ako nije potrebno da funkcija vraa neku vrijednost, onda bi se gornji program mogao napisati u slijedeem (ekvivalentnom) obliku: #include <stdio.h> void main() { } Program takoer ne radi nita. Hello World! Najjednostavniji program napisan u bilo kojem programskom jeziku (osim onih programa koji ne rade nita), bio bi program koji na ekran ispisuje nekakav tekst. U raunarstvu se tradicionalno za takav tekst uzima reenica "Hello World!". Slijedei program na ekran ispisuje "Hello World!": #include <stdio.h> int main() { printf("Hello World!\n"); return 0; } Naredba printf("Neki tekst..."); se koristi za ispis teksta na ekran raunala. Tekst se pie unutar navodnika, a ako se nakon teksta jo doda i znak '\n', to znai da e kursor nakon ispisa teksta na ekran prijei u novu liniju. Upotrebu naredbe printf() omoguuje predprocesorska naredba #include <stdio.h>. U biblioteci <stdio.h> se nalazi prototip naredbe printf(). Varijable Varijable su memorijske lokacije ija se vrijednost tijekom izvoenja programa moe promijeniti, tj. varijable su imena koja koristimo za memorijske lokacije na kojima se nalaze vrijednosti s kojima 6

radimo. Postoje razliiti tipovi varijabli: char (engl. character) znakovni tip int (engl. integer) cijeli broj short krai oblik cijelog broja long dui oblik cijelog broja float (engl. floating point) realni broj double realni broj dvostruke tonosti

Razliiti tipovi varijabli zauzimaju razliite koliine memorije. Varijable moraju biti prijavljene prije upotrebe, i to najee na poetku funkcije, prije bilo koje izvrne naredbe. Kae se da se varijable deklariraju. Deklaracijom se varijabli pridruuju ime i tip (npr. odreuje se da li e varijabla sadravati znak ili broj), te se deklarira potrebna koliina memorije (npr. 1 bajt za znak ili 4 bajta za cijeli broj). Na primjer, ovako se deklarira cjelobrojna varijabla a: int a; Ovo znai da je deklariran memorijski prostor (imena 'a') u koji e se spremiti cijeli broj. Primjeri deklaracije varijabli: int varijabla1, varijabla2; float varijabla3, varijabla4, varijabla5; char varijabla6; Za razliku od deklaracije varijable, definicija varijable bi varijabli pridruila i neku vrijednost. Na primjer: int varijabla1 = 5; float varijabla2 = 2.3; char varijabla3 = 'c'; int varijabla4 = varijabla1; int varijabla5, varijabla6; varijabla5 = varijabla6 = 7; char a = 'A'; char b = 65; // varijabla4 = 5 // varijabla5 = 7, varijabla6 = 7 // a = A // b = A --> u ASCII tablici, znak 'A' je predstavljen sa brojem 65

Imena varijabli sastoje se od slova i znamenki, pri emu prvi znak mora uvijek biti slovo. Znak podcrte '_' (engl. underscore) uvaava se kao slovo, to je bitna stvar ako se eli poveati itljivost 7

programa. Programeri varijablama obino daju imena u nekom od slijedeih formata: int varijabla; int druga_varijabla; int trecaVarijabla; Primjeri neispravnih imena varijabli: int 1varijabla; int prva varijabla; int $varijabla; int const; Operatori u C-u Aritmetiki operatori: +, -, *, /, te modul operator % (ostatak dijeljenja). Relacijski operatori: < (manje), > (vee), <= (manje ili jednako), >= (vee ili jednako), == (jednako), != (nije jednako). Relacijski operatori se koriste kod usporedbi. Logiki operatori: && (i) i || (ili). Operatori uveavanja (inkrementiranja) i umanjivanja (dekrementiranja): ++ i --. Njihova bitna karakteristika je da mogu biti koriteni kao sufiks operatori (npr. varijabla++) ili kao prefiks operatori (npr. ++varijabla). Operator konverzije tipova: cast. Ako u programskom kodu naiemo na operator iji su operandi razliitog tipa (npr. jedan je int, a drugi float), itav e izraz dobiti konanu vrijednost po tono odreenim pravilima. Cast operator pretvara izraz bilo kojeg tipa u eljeni tip. Openita formula glasi: (tip) izraz. Primjer: #include <stdio.h> void main() { int x; char y = 'A'; x = (int) y; printf("x = %d\n", y); } // prvi znak ne smije biti broj // nisu dozvoljeni razmaci // znak '$' nije dozvoljen samo slova, brojke ili '_' // const je kljuna rije (unaprijed rezervirana)

ISPIS PROGRAMA: x = 65 U gornjem primjeru, varijabli x se dodjeljuje ASCII vrijednost varijable y (odnosno znaka A), a to je 65. Operatori za manipulaciju bitovima (bitznaajni operatori): & binarno I (AND) | binarno ILI (OR) ^ binarno ekskluzivno ILI (XOR) ~ jedinini komplement (NOT) << pomak u lijevo (SHIFT LEFT) >> pomak u desno (SHIFT RIGHT) Operatori dodjele vrijednosti. Veina binarnih operatora ima odgovarajui operator dodjele vrijednosti po pravilu: izraz1 operator= izraz2. To je ekvivalentno izrazu: izraz1 = (izraz1) operator (izraz2). Na primjer, a *= b je ekvivalentno izrazu a = a * b. a *= b je samo krai nain zapisa izraza a = a * b. Napomena: obratite pozornost na operator dodjele vrijednosti (=) i operator usporeivanja dviju vrijednosti (==). Ovi operatori nisu jednaki! Mijeanje ovih dvaju operatora je jedna od najeih greaka u programiranju! Ovakva se greka naziva logika greka, i prevoditelj vas na nju nee upozoriti. Operator '=' nekoj varijabli dodjeljuje neku vrijednost, npr. a = 3. Operator '==' usporeuje dvije varijable i vraa nulu ili jedinicu, ovisno o tome jesu li te varijable jednake. Neke od najee koritenih funkcija u C-u Neke od najee koritenih funkcija u C-u su: printf("%d", argument) scanf("%d", &argument) getchar() putchar() toupper(c) tolower(c) ispisuje znak ili niz znakova na ekran prihvaa znak ili niz znakova unesenih sa tipkovnice prihvaa samo jedan znak sa tipkovnice ispisuje samo jedan znak na ekran pretvara mala slova u velika pretvara velika slova u mala

DODATAK Microsoft (MS) Visual Studio 2010 Express Svi programi opisani u vjebama iz kolegija (Uvod u) Raunala i programiranje mogu se izvravati u MS Visual Studio integriranoj razvojnoj okolini (engl. Integrated Development Environment ili IDE). IDE je razvojna okolina unutar koje programeri piu i testiraju svoje programe. Na linku http://www.microsoft.com/express/Downloads/ moe se pronai Microsoft Visual Studio 2010 Express. To je IDE koji se koristi u edukacijske i nekomercijalne svrhe. Da biste instalirali MS Visual Studio Express 2010, slijedite ove upute: 1. 2. 3. 4. Otiite na web stranicu http://www.microsoft.com/express/Downloads/. Odaberite Visual C++ 2010 Express. Odaberite engleski jezik. Otvoriti e se prozor koji vas pita elite li skinuti aplikaciju sa interneta. Kliknite OK. Napomena: program koji ste sauvali je samo aplikacija koja e pokrenuti skidanje MS Visual Studio 2010 Express sa interneta. 5. Pokrenite skinutu aplikaciju i slijedite postupak instalacije. 6. Priekajte dok se aplikacija ne instalira (ovo e malo potrajati...). Pokrenite aplikaciju. Pojaviti e se ovakav prozor:

10

Da biste mogli napisati i pokrenuti prvi program u C-u, slijedite ove upute: 1. Kliknite na File --> New --> Project. 2. Odaberite Win32 Console Application. 3. Odaberite ime novog projekta (npr. prviProjekt) i kliknite OK. 4. Otvoriti e se novi prozor imena Win32 Application Wizard. Pod Application Settings odaberite Console application i Empty project, te deselektirajte Precompiled header.

11

5. Kliknite Finish. Otvoriti e se ovakav prozor:

6. Sa lijeve strane moete vidjeti nekoliko datoteka. Desnim klikom mia kliknite na datoteku imena Source Files, te odaberite Add --> New Item. Odaberite C++ File (.cpp). Novoj datoteci dodijelite neko ime (npr. mojPrviProgram). Kliknite Add. Otvoriti e se upravo kreirana tekstualna datoteka.

12

7. U datoteku upiite slijedei programski kod: #include <stdio.h> void main() { printf("Hello World!\n"); getchar(); }

/* program eka unos znaka sa tipkovnice */

Na kraju programa nalazi se poziv funkcije getchar(). Ta funkcija eka na unos znaka sa tipkovnice. Da se u programu ne nalazi ova linija koda, prozor sa tekstom Hello World! bi se zatvorio im bi se program izvrio (gotovo trenutano), te ne biste uspjeli vidjeti rezultate programa. 8. Kliknite Debug --> Build Solution, pa zatim Debug --> Start Debugging. Alternativno moete pritisnuti F7 (Build Solution) i F5 (Start Debugging). 9. Va program e se izvriti. Otvoriti e se slijedei prozor:

10. Pritisnite Enter da bi zatvorili prozor.

13

VJEBA 2 Komentari u C-u #include <stdio.h> void main() { printf("Hello World!\n"); }

/* ispisuje "Hello World!" na ekran */

Prilikom prevoenja programa, prevoditelj zanemaruje sve to se nalazi unutar znakova '/*' i '*/'. Oni oznaavaju poetak i kraj komentara. /* ovo je komentar */ /* i ovo je komentar */ Ovakva vrsta komentara se danas sve rijee koristi. Popularnost im je pala nakon to su u programiranje uvedeni jednoredni komentari "uvezeni" iz programskog jezika C++. // komentar Gornji komentar je jednoredi komentar. Prednost ovakvih komentara je to programer ne mora paziti na zavretak komentara, a nedostatak je taj to su ogranieni na jedan redak. Komentari su posebno vani kod velikih programa (sa vie tisua linija koda), jer programski kod postaje pregledniji i razumljiviji. Escape nizovi Kombinacije znakova koje zapoinju sa znakom '\' (engl. backslash), te iza kojih slijedi neki drugi znak, slovo, ili niz brojeva (ako se koristi oktalni ili heksadecimalni zapis), nazivaju se escape nizovi. Njihova zadaa jest da promijene znaenje odreenih znakova ili simbola (Tablica 2.1). Na primjer, znak 'n' se tretira na jedan nain kada predstavlja ime varijable, a na drugi nain kada se ispred njega nalazi znak '\'. Escape nizovi koji se najee koriste u C-u: Tablica 2.1. Escape nizovi Znak zvono (upozorenje) Escape niz \a ASCII 007 14

(engl. bell code, audible alert) backspace vodoravni tabulator okomiti tabulator novi red ili LF (engl. Line Feed) nova stranica CR (engl. Carriage Return) navodnik jednostruki navodnik (apostrof) upitnik backslash null znak \b \t \v \n \f \r \" \' \? \\ \0 008 009 011 010 012 013 034 039 063 092 000

Znakovi pretvorbe #include <stdio.h> int main() { int a; a = 10; printf("%d\n", a); return 0; }

// deklariramo cjelobrojnu varijablu a // varijabli a pridruujemo vrijednost 10 // na ekran ispisujemo vrijednost varijable a // funkcija vraa nulu

U gornjem se primjeru koristi znak %d. Kada se ispred nekih odreenih slova (Tablica 2.2) nalazi znak '%', onda slovo predstavlja znak pretvorbe (engl. conversion character). On oznaava tip ili format znaka koji se ispisuje na ekran ili uitava sa tipkovnice (npr. int, float...). Tablica 2.2. Znakovi pretvorbe Znak pretvorbe c d e f g i podatak je znak podatak je decimalna cjelobrojna vrijednost s predznakom podatak je realna vrijednost u eksponencijalnoj formi podatak je realna vrijednost bez eksponencijalne forme podatak je realna vrijednost podatak se zapisuje u najkraoj moguoj formi (ili f ili e) podatak je decimalna cjelobrojna vrijednost s predznakom Znaenje

15

podatak moe biti zapisan u dekadskom, oktalnom ili heksadecimalnom brojevnom sustavu o s u x [. . .] podatak je oktalna vrijednost, bez vodee nule podatak je niz znakova (engl. string) null znak ('\0') se automatski dodaje na kraj stringa podatak je decimalna vrijednost bez predznaka podatak je heksadecimalna vrijednost, bez vodeeg 0x podatak je niz znakova koji moe sadravati razmake

Funkcija printf() Funkcija printf() se koristi za ispis znakova na ekran raunala. Primjer: #include <stdio.h> void main() { int a = 5; float b = 5.1; // na ekran ispisujemo vrijednost cjelobrojne varijable a printf("Vrijednost varijable a = %d\n", a); // na ekran ispisujemo vrijednost realne varijable b printf("Vrijednost varijable b = %f\n", b); // program eka na unos znaka sa tipkovnice getchar(); } Funkcija printf() dozvoljava koritenje ogranienja na minimalnu duljinu niza koji se upisuje (npr. niz brojeva). Ako je niz vei od minimalne duljine, onda ogranienje nema nikakvog utjecaja na ispis niza. U programerskim krugovima ta je situacija poznata pod imenom "override". Funkcija printf() takoer dozvoljava specifikaciju tonosti nekog broja (npr. zaokruivanje broja na odreeni broj decimala iza decimalne toke). Primjer: #include <stdio.h> void main() { 16

int a = 12345; float b = 345.678; printf("%3d\n", a); printf("%10d\n\n", a); printf("%6g\n", b); printf("%13g\n\n", b); printf("%13e\n", b); printf("%16e\n\n", b); printf("%.4f\n", b); printf("%.30e\n", b); } getchar();

ISPIS PROGRAMA:

Funkcija scanf() Funkcija scanf() se koristi za uitavanje znakova sa tipkovnice. Primjer: #include <stdio.h> void main() { int a; float b; // sa tipkovnice se uitava cijeli broj i sprema se u varijablu a scanf("%d", &a); // sa tipkovnice se uitava realni broj i sprema se u varijablu b 17

scanf("%f", &b); } getchar();

Kada se ispred imena varijable nalazi znak &, onda &ime_varijable predstavlja adresu te varijable. Da bi funkcija scanf() mogla nekoj varijabli promijeniti vrijednost, najprije mora znati na kojoj se memorijskoj adresi ta varijabla nalazi. Kao i funkcija printf(), funkcija scanf() omoguava postavljanje ogranienja na duljinu niza koji se uitava sa tipkovnice. Primjer: #include <stdio.h> void main() { int a, b, c; scanf("%3d %3d %3d", &a, &b, &c); printf("a = %d b = %d c = %d\n", a, b, c); } Unos: 1 2 3 Ispis: a = 1 b = 2 c = 3 Unos: 123 456 789 Ispis: a = 123 b = 456 c = 789 Unos: 123456789 Ispis: a = 123 b = 456 c = 789 Unos: 1234 5678 9 Ispis: a = 123 b = 4 c = 567 Napomena: preostala dva znaka e biti ignorirana, osim ako ih ne pokupi neka druga scanf() funkcija.

18

ZADACI Zadatak 2.1. Napiite program koji ispisuje zauzee memorije u bajtovima (engl. byte) za sve standardne tipove programskog jezika C (char, int, short, long, float, double, unsigned short, unsigned int, unsigned long). Koristite funkciju sizeof(). Rjeenje: #include <stdio.h> void main () { printf("Sizeof(char) = %d", sizeof(char)); printf("\nSizeof(int) = %d", sizeof(int)); printf("\nSizeof(short) = %d", sizeof(short)); printf("\nSizeof(long) = %d", sizeof(long)); printf("\nSizeof(float) = %d", sizeof(float)); printf("\nSizeof(double) = %d", sizeof(double)); printf("\nSizeof(unsigned short) = %d", sizeof(unsigned short)); printf("\nSizeof(unsigned int) = %d", sizeof(unsigned int)); printf("\nSizeof(unsigned long) = %d\n", sizeof(unsigned long)); getchar(); } ISPIS PROGRAMA:

Zadatak 2.2. Napiite program u kojem deklarirate integer i char varijablu. Objema pridijelite vrijednost znakovne konstante (primjerice 'c'). Ispiite vrijednosti varijabli i veliinu memorije koju zauzimaju. Kako komentirate rezultate? Rjeenje: #include <stdio.h> void main() 19

int i = 'c'; char n = 'c' ; printf("sizeof(int) = %d\n", sizeof(int)); printf("sizeof(char) = %d\n", sizeof(char)); printf("vrijednost (i) = %d\n", i); printf("vrijednost (n) = %d\n", n); printf("vrijednost (n) = %c\n", i); printf("vrijednost (n) = %c\n", n);

getchar();

ISPIS PROGRAMA:

Zadatak 2.3. Napiite program koji ispisuje znakove 'z' i 'Z', s tim da su za prvi znak rezervirana 3 mjesta za ispis na ekran, a za drugi 5 mjesta. Rjeenje: #include <stdio.h> void main() { printf("Slova:\n%3c\n%5c\n", 'z', 'Z'); getchar(); } Zadatak 2.4. Primjer cjelobrojnog i realnog dijeljenja. Kako komentirate rezultate programa? #include <stdio.h> void main() { int a = 5; int b = 2; 20

int d = 5/2; float c = a/b;

// cjelobrojno dijeljenje rezultat je 2 // Iako je c float, vri se cjelobrojno dijeljenje jer su i a i b cijeli brojevi

printf("c = %f\n",c); printf("Uzrok problema : 5/2 = %f\n", 5/2); printf("Popravljeno : 5.0/2.0 = %f\n", 5.0/2.0); printf("Moze i : 5/2.0 = %f i 5.0/2 = %f \n", 5/2.0, 5.0/2); printf("Za varijable moramo uvesti cast-ing : %f\n", (float)a/(float)b); getchar();

ISPIS PROGRAMA:

Zadatak 2.5. Napiite program za unos cijelog broja sa tipkovnice. Rjeenje: #include <stdio.h> void main() { int x; printf("Unesite cijeli broj: "); scanf("%d", &x); printf("Unijeli ste broj: %d\n", x); getchar(); getchar();

Zadatak 2.6. Napiite program za unos cijelog broja sa tipkovnice. Neka program ispie kvadrat tog broja. Rjeenje: #include <stdio.h> 21

void main() { int a, b; printf("Unesite varijablu a.\n"); scanf("%d", &a); b = a * a; printf("Kvadrat broja a je %d.\n", b); getchar(); getchar(); // sa tipkovnice se uitava varijabla a // u varijablu b ide vrijednost kvadrata broja a

22

DOMAI RAD Zadatak 2.7. Napiite program za unos dva realna broja. Neka program ispie rezultat njihovog zbrajanja, oduzimanja, mnoenja i dijeljenja. Zadatak 2.8. Napiite program za unos realnog broja. Neka program ispie kvadrat i korijen tog broja. Napomena: funkcija za raunanje korijena je sqrt() (engl. square root) i definirana je u biblioteci <math.h>. Zadatak 2.9. Napiite program koji za proizvoljni radijus rauna opseg kruga.

23

DODATAK ASCII tablica Tablica 2.3. ASCII tablica

24

VJEBA 3 Naredbe kontrole toka Naredbe kontrole toka svoje djelovanje zasnivaju na logikim izrazima. Najee se koriste u svrhu grananja programa, tj. odabira jedne od nekoliko moguih radnji. Jedna od najee koritenih naredbi za kontrolu toka je if-else konstrukcija. If-else konstrukcija openito ima slijedeu sintaksu: if (logiki izraz) naredba1 if (logiki izraz) naredba 1 else naredba2

Slika 3.1. Grafiki prikaz grananja Primjer (if-else konstrukcija): Programsko rjeenje za grananje prikazano na slici 3.1: #include <stdio.h> void main() { int a = 7; int b = 3; if (a > b) printf("Vrijednost varijable a = %d.\n", a); else printf("Vrijednost varijable b = %d.\n", b); getchar(); 25

} ISPIS PROGRAMA: Vrijednost varijable a = 7. Umjesto if-else konstrukcije ponekad se moe koristiti uvjetni operator. Uvjetni operator je ternarni operator, jer ima tri elementa. Opi oblik: logiki_izraz ? izraz_1 : izraz_2; Program bi u ovom sluaju ispitao vrijednost logikog izraza, te ako je ta vrijednost jednaka jedinici izvrio bi se izraz 1, a ako je jednaka nuli izvrio bi se izraz 2. Primjer (uvjetni operator): Program provjerava da li je varijabla a vea od nule. Ako jest, postavlja varijablu b na jedinicu, a ako nije, postavlja varijablu b na nulu. Zatim ispisuje vrijednost varijable b. #include <stdio.h> void main() { int a = 7; int b; (a > 0) ? b = 1 : b = 0; printf("b = %d \n", b); getchar(); } ISPIS PROGRAMA: b=1 Programske petlje Programske petlje se koriste kada se vie puta eli ponoviti ista naredba ili blok naredbi. U programskom jeziku C postoje tri petlje: for, while i do-while. Opi oblik programske petlje for: for (inicijalizacija; uvjet; promjena vrijednosti) { blok naredbi } 26

Primjer (for petlja): Program ispisuje brojeve od 0 do 9. #include <stdio.h> void main() { int a; for (a = 0; a < 10; a++) printf("%d\n", a); } getchar();

Opi oblik programske petlje while: while (uvjet) { blok naredbi } Primjer (while petlja): Program ispisuje brojeve od 9 do 0. #include <stdio.h> void main() { int a = 9; while (a > -1) { printf("%d\n", a); a--; } } getchar();

Opi oblik programske petlje do-while: do { blok naredbi } while (uvjet);

27

Primjer (do-while petlja): Program ispisuje brojeve od 0-9. #include <stdio.h> void main() { int a = 0; do { printf("%d\n", a); a++; } while (a < 10); getchar(); } Petlje for i while se ne moraju uope izvriti (ako uvjet nije ispunjen), ali petlja do-while je specifina po tome to se ona uvijek izvri barem jedan put, pa tek nakon prvog izvravanja provjerava uvjet.

28

ZADACI Zadatak 3.1. Napiite program koji prihvaa i usporeuje bilo koja dva cijela broja unesena sa tipkovnice. Neka se na ekran ispie rezultat usporedbe tih brojeva. Rjeenje: #include <stdio.h> void main() { int a; int b; printf("Unesite prvi broj: "); scanf("%d", &a); printf("Unesite drugi broj: "); scanf("%d", &b); if (a > b) printf("%d > %d \n", a, b); else if (a < b) printf("%d > %d \n", b, a); else printf("%d = %d \n", a, b); getchar(); getchar(); } Zadatak 3.2. Napiite program koji ispisuje sumu svih brojeva od 1 do 10. Rjeenje: #include<stdio.h> void main() { int i; int suma = 0; for (i = 1; i <= 10; i++) suma = suma + i;

29

printf("Suma je %d.\n", suma); } getchar();

Zadatak 3.3. Napiite program koji od korisnika trai da unese dvije varijable (tipa int), s tim da druga varijabla mora biti manja od prve. Zahtjev za unos druge varijable se ponavlja (koristite while petlju) sve dok korisnik ne unese cijeli broj koji je manji od prvog broja. Program zatim treba ispisati: "Prva varijabla je (ispisati vrijednost), a druga je (ispisati vrijednost). Druga varijabla je manja od prve." Rjeenje: #include<stdio.h> void main() { int a; int b; int uvjet = 1; printf("Upisite vrijednost prve varijable: "); scanf("%d", &a); while (uvjet) // ponavlja se sve dok je uvjet jednak jedinici { printf("Upisite vrijednost druge varijable tako da bude MANJA od prve: "); scanf("%d", &b); if (b < a) uvjet=0; } printf("Prva varijabla je %d, a druga je %d. Druga varijabla je manja od prve.\n", a, b); getchar(); getchar(); }

30

Zadatak 3.4. to je rezultat izvoenja slijedeih programa? Ispiite sve meurezultate do cilja! a) #include <stdio.h> void main() { int i; for (i = 0; i < 5; i++) printf("%d\n",i); } d) #include <stdio.h> void main() { int i = 5; i = i + 2; if (i < 5) printf ("Izlaz A\n"); else printf("Izlaz B\n"); } b) #include <stdio.h> void main() { int i = 5; while (i) printf("%d\n", --i); } e) #include <stdio.h> void main() { int i = 5; if (--i > 4) i = i + 3; printf("%d\n", i); c) #include <stdio.h> void main() { int i = 5; while (i) printf("%d\n", i--); } f) #include <stdio.h> void main() { int i = 5; int uvjet = 1; int suma = 0; while (uvjet) { if (i-- > 2) uvjet = 0; suma = suma + i; } } Rjeenja: a) 0 1 2 3 4 d) Izlaz B b) 4 3 2 1 0 e) 4 c) 5 4 3 2 1 f) 4 31 printf("%d\n", suma);

DODATNI ZADACI Zadatak 3.5. Napiite program koji generira i ispisuje deset sluajnih brojeva. Napomena: koristite standardne biblioteke <stdlib.h> i <time.h>, te funkcije srand() i rand(). Zadatak 3.6. Napiite program za pogaanje broja generiranog od strane raunala. Broji se broj pokuaja, a pri svakom pokuaju raunalo daje informaciju da li je broj vei, manji ili pogoen. Ako je broj pogoen, izlazi se iz programa, uz ispis pogoenog broja te ukupnog broja pokuaja. Napomena vezana uz zadatke 3.5 i 3.6: U programiranju ne postoje stvarno sluajni brojevi, ve samo pseudosluajni. Generator pseudosluajnih brojeva e za istu ulaznu vrijednost uvijek generirati iste pseudosluajne brojeve. Funkcija srand() postavlja inicijalnu vrijednost za generator sluajnih brojeva koji je implementiran u funkciji rand(). Ako se ne koristi srand(), rand() e izgenerirati uvijek isti niz pseudosluajnih brojeva [2]. DOMAI RAD Zadatak 3.7. Napiite program koji pomou for petlje ispisuje kvadrate, kubove i korijene prvih 20 prirodnih brojeva. Napomena: funkcija za raunanje korijena je sqrt (engl. square root) i nalazi se u standardnoj biblioteci <math.h>. Zadatak 3.8. Napiite program koji ispisuje rjeenja kvadratne jednadbe. Neka korisnik unese koeficijente kvadratne jednadbe. Podsjetnik:
ax bxc=0
2

x=

b b2 4ac 2a

32

VJEBA 4 Naredba switch-case Ako u izvornom kodu postoji posebno dugaak lanac if-else naredbi, dobra je praksa takve naredbe zamijeniti sa naredbom switch-case. Naredba switch-case je preglednije zapisana if-else naredba. Najee se koristi za stvaranje izbornika (engl. menu) [3]. Na primjer, ako korisnik unese broj '1', izvri se jedna naredba, a ako unese '2', izvri se neka druga naredba. Opi oblik naredbe switch-case: switch (izraz) { case 'vrijednost izraza 1': ... break; case 'vrijednost izraza 2': ... break; ... default: ... }

// izvrava se ako nijedan drugi uvjet nije zadovoljen

Primjer (switch-case naredba): Program dozvoljava unos jednoznamenkastog cijelog broja sa tipkovnice, te obavijetava korisnika o tome je li uneseni broj paran, neparan ili jednak nuli. #include <stdio.h> void main() { int a; printf("Unesite cijeli broj: "); scanf("%d", &a); switch (a) { case 0: case 1: case 3: case 5: case 7: case 9:

printf("Uneseni broj je jednak nuli.\n"); break;

printf("Uneseni broj je neparan.\n"); 33

case 2: case 4: case 6: case 8:

break;

printf("Uneseni broj je paran.\n"); break; default: printf("Dozvoljen je unos samo jednoznamenkastih brojeva.\n"); break; } getchar(); getchar(); } Primijetite da je nakon vie case naredbi izostavljena naredba break. To znai da e se za sve te case naredbe izvriti isti blok programskog koda (prvi na koji program naie tijekom izvoenja). Ovakva je situacija poznata pod imenom "propadanje" kroz switch-case naredbu (engl. fallthrough). Napomena: naredba break se koristi za prekid izvravanja neke petlje. Slino, naredba continue se koristi za prekid jedne iteracije neke petlje, te skok na iduu iteraciju. Naredba goto Naredba goto je naredba bezuvjetnog skoka. Izvravanjem naredbe goto program se grana na zadanu programsku liniju [3]. Opi oblik: #include <stdio.h> void main() { ime_labele: ...programski kod... goto ime_labele; } Primjer (goto naredba): #include <stdio.h> void main() 34

int i = 0; start: printf("Beam me up, Scotty!\n"); if (i == 0) { i = 1; goto start; } getchar(); // start je ime labele

// program skae na labelu start

} ISPIS PROGRAMA: Beam me up, Scotty! Beam me up, Scotty! Veina programera izbjegava koritenje goto naredbe, budui da ona najee smanjuje preglednost i razumljivost programskog koda. U programskim jezicima vie razine ova se naredba gotovo nikad ne koristi, a neki je jezici ak i zabranjuju. Sve to se moe napraviti sa naredbom goto, moe se napraviti i sa standardnim petljama u C-u.

35

ZADACI Zadatak 4.1. Napiite program koji oponaa rad jednostavnog kalkulatora koji podrava operacije zbrajanja, oduzimanja, mnoenja i dijeljenja. Korisnik programu zadaje izraz, primjerice 9 * 5, a program ispisuje rezultat tog izraza. Koristite naredbu switch-case. Rjeenje: #include <stdio.h> void main() {

int broj1 = 0, broj2 = 0; float rezultat; char operator1; printf("Unesite izraz: \n"); scanf("%d %c %d", &broj1, &operator1, &broj2); switch (operator1) { case '+': rezultat = broj1 + broj2; printf("%d %c %d = %.4f\n", broj1, operator1, broj2, rezultat); break; case '-': rezultat = broj1 - broj2; printf("%d %c %d = %.4f\n", broj1, operator1, broj2, rezultat); break; case '*': rezultat = broj1 * broj2; printf("%d %c %d = %.4f\n", broj1, operator1, broj2, rezultat); break; case '/': if (broj2 == 0) { printf("Greska: dijeljenje sa nulom!\n"); break; } else { rezultat = (float)broj1 / broj2; 36

printf("%d %c %d = %.4f\n", broj1, operator1, broj2, rezultat); break; } default: printf("Nepoznata operacija!\n"); break; } getchar(); getchar();

Zadatak 4.2. Napiite program koji od korisnika trai da unese dva cijela broja, te zatim ispisuje tri broja koja se nalaze izmeu njih. Ako je udaljenost brojeva manja od tri, program treba ispisati odgovarajuu poruku. Rjeenje: #include <stdio.h> void main () { int x, y, i; printf("Unesite dva cijela broja: "); scanf("%d %d", &x, &y); oznaka: if (y >= x) { if ((y - x) < 4) { printf("Brojevi su nedovoljno udaljeni!\n"); } else {

printf("Brojevi unutar zadanih granica: "); for (i = x + 1; i < x + 4; i++) printf("%d ", i);

} else {

37

// ako je y > x zamijenimo im vrijednosti int t = x; x = y; y = t; goto oznaka; } getchar(); getchar(); } Zadatak 4.3. Napiite program u kojem korisnik unosi deset cijelih brojeva (koristite for petlju), a program vraa njihovu aritmetiku sredinu. Rjeenje: #include <stdio.h> void main() { int broj = 0; int brojac = 10; int suma = 0; int i; float prosjek = 0; for (i = 0; i < brojac; i++) { printf("Unesite broj: "); scanf ("%d", &broj); suma += broj; } prosjek = (float)suma/brojac; printf("Prosjecna vrijednost ovih deset unesenih brojeva iznosi: %f\n", prosjek); getchar(); getchar();

Zadatak 4.4. Napiite program koji rauna n-tu faktorijelu. Napomena: n se unosi pomou scanf() funkcije, i ne moe biti vei od 12.

38

Rjeenje: #include <stdio.h> void main() { int a, i; int faktorijela = 1; printf("Unesite pozitivni cijeli broj manji od 13: "); scanf("%d", &a); if ((a > 12) || (a < 0)) printf("Niste unijeli ispravan broj.\n"); else if (a == 0) printf("0! = 1\n"); else { for (i = 1; i <= a; i++) faktorijela = faktorijela * i; } printf("%d! = %d\n", a, faktorijela);

getchar(); getchar();

Zadatak 4.5. Napiite program koji ispisuje cijelu ASCII tablicu. Rjeenje: #include <stdio.h> void main() { int c; for(c = 0; c < 128; c++) printf("%d - %c\n", c, c); getchar(); }

39

DODATNI ZADACI Zadatak 4.6. Napiite program koji, uz pomo petlji, na ekran ispisuje: * ** *** **** Zadatak 4.7. Napiite program koji ispisuje sve vrijednosti funkcije y = 15 * x + 76, za sve cijele parne brojeve x iz intervala [-7, 7]. DOMAI RAD Zadatak 4.8. Napiite program koji zadanu vrijednost duljine u centimetrima pretvara u inche. (x(in) = x(cm) / 2,54). Zadatak 4.9. Napiite program koji za uitanu ocjenu ispisuje njezin opis. Na primjer, ako korisnik unese 5, program ispisuje "Izvrstan". Ako korisnik unese broj izvan intervala [1,5], program treba ispisati odgovarajuu poruku. Koristite switch-case naredbu. Zadatak 4.10. Napiite program koji ispisuje sve parne brojeve iz intervala od 0 do 100.

40

VJEBA 5 Polja Kolekcija varijabli istog tipa i zajednikog imena zove se polje ili niz (engl. array). Polje u memoriji zauzima kontinuirani niz memorijskih lokacija [2], a deklaracijom polja rezervira se memorija potrebna za njegove lanove. Polja mogu biti viedimenzionalna, a ime bilo kojeg polja predstavlja adresu prvog elementa u nizu. Opi oblik glasi: tip ime_polja[izraz], gdje je izraz pozitivni cijeli broj. Primjer deklaracije polja: int x[100]; char text[80]; float n[12]; Primjer inicijalizacije polja: int znamenke[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; float x[6] = {0, 0.25, 0, -0.50, 0, 0}; char boja[5] = {'P', 'L', 'A', 'V', 'A'}; Polja ili nizovi u programiranju su slini vektorima i matricama u matematici. Ako se eli pristupiti lanu nekog niza, to se radi pomou indeksiranja. Primjer: #include <stdio.h> void main() { int a[] = {1, 4, 7, 8, 17}; printf("%d ", a[0]); printf("%d", a[4]); } getchar(); // ispisujemo vrijednost prvog lana niza // ispisujemo vrijednost posljednjeg lana niza // niz od 100 cijelih brojeva // niz od 80 znakova // niz od 12 realnih brojeva

ISPIS PROGRAMA: 1 17

41

Polja znakova Polje znakova (engl. string) je polje koje se sastoji od niza znakova i koje zavrava oznakom kraja niza '\0' (engl. string terminator). Primjer (polje znakova): Program pohranjuje znakovni niz "Dalmacija" u jednodimenzionalno znakovno polje X. Budui da rije "Dalmacija" ima devet slova, znakovni niz mora imati mjesta za deset znakova. Oznaka kraja niza se rauna kao jedan znak. Ovako to izgleda u memoriji: D X[0] = 'D' X[1] = 'a' X[2] = 'l' X[3] = 'm' X[4] = 'a' X[5] = 'c' X[6] = 'i' X[7] = 'j' X[8] = 'a' X[9] = '\0' Programski kod: #include <stdio.h> void main() { char X[10] = "Dalmacija"; printf("Znakovni niz glasi: %s.\n", X); getchar(); } ISPIS PROGRAMA: Znakovni niz glasi: Dalmacija. a l m a c i j a \0

42

Viedimenzionalna polja Viedimenzionalna polja su skupovi jednodimenzionalnih polja. Primjer nekog viedimenzionalnog polja bila bi matrica. Grafiki prikaz dvodimenzionalnog polja: Tablica 5.1. Grafiki prikaz dvodimenzionalnog polja X redak 0 redak 1 redak 2 redak 3 stupac 0 X[0][0] X[1][0] X[2][0] X[3][0] stupac 1 X[0][1] X[1][1] X[2][1] X[3][1] stupac 2 X[0][2] X[1][2] X[2][2] X[3][2] stupac 3 X[0][3] X[1][3] X[2][3] X[3][3] stupac 4 X[0][4] X[1][4] X[2][4] X[3][4] stupac 5 X[0][5] X[1][5] X[2][5] X[3][5] stupac 6 X[0][6] X[1][6] X[2][6] X[3][6]

Opi oblik: tip_polja ime_polja [dimenzija_1] [dimenzija_2] ... [dimenzija_n] tip_polja ime_polja [broj_redaka] [broj_stupaca] ... [dodatne_dimenzije] Primjer deklaracije polja: float tablica[50][50]; char stranica[24][80]; static double zapisi [x][y][z]; Primjer inicijalizacije polja: int a[2][3] = {{1, 2, 3}, {4, 5, 6}}; Primjer (dvodimenzionalno polje): Program ispisuje dvodimenzionalno polje od tri retka i etiri stupca. #include <stdio.h> void main() { int polje[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; int i, j; for (i = 0; i < 3; i++) for (j = 0; j < 4; j++) printf("Polje [%d][%d] = %d\n", i, j, polje[i][j]); 43

getchar();

ISPIS PROGRAMA:

44

ZADACI Zadatak 5.1. Napiite program koji jednodimenzionalno polje od sedam lanova inicijalizira na nulu. Rjeenje: #include <stdio.h> void main() { int i; int polje[7]; for (i = 0; i < 7; i++) { polje[i] = 0; printf("polje[%d] = %d\n", i, polje[i]); } getchar(); } Zadatak 5.2. Napiite program koji uitava niz od deset cijelih brojeva, te ih ispisuje na ekran koritenjem for petlje. Rjeenje: #include <stdio.h> void main() { int i = 0; int a; int niz[10]; for (i = 0; i < 10; i++) { printf("Unesite %d. broj: ", i+1); scanf("%d", &a); niz[i] = a; } printf("\n");

45

for (i = 0; i < 10; i++) printf("%d. broj: %d\n", i+1, niz[i]); getchar(); getchar();

Zadatak 5.3. Napiite program koji uitava znakovni niz sa tipkovnice i zatim ga ispisuje na ekran. Rjeenje: #include <stdio.h> void main() { char niz[80]; printf("Unesite znakovni niz: "); scanf("%s", niz); printf("Upisali ste niz: %s.\n", niz); getchar(); getchar(); // alternativno: gets(niz);

Zadatak 5.4. Napiite program za zbrajanje matrica dimenzija 3x3. Matrice inicijalizirajte na proizvoljne vrijednosti unutar programskog koda. Primjer zbrajanja matrica [4]:

Rjeenje: #include <stdio.h> void main() { int A[3][3] = {{1, 3, 2}, {1, 0, 0}, {1, 2, 2}}; int B[3][3] = {{0, 0, 5}, {7, 5, 0}, {2, 1, 1}}; int C[3][3]; 46

int i, j; // zbrajanje matrica for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) C[i][j] = A[i][j] + B[i][j]; printf("Rezultat zbrajanja matrica:\n"); for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) { printf("[%d][%d] = %d", i, j, C[i][j]); printf("\n"); } getchar(); getchar(); } ISPIS PROGRAMA:

47

DODATNI ZADACI Zadatak 5.5. Napiite program koji uitava dva niza znakova i ispituje da li su ti nizovi jednaki. Kraj uitavanja niza odreen je oznakom za prijelaz u novi redak ('\n'). Zadatak 5.6. Napiite program koji uitava redak teksta i pretvara mala slova u velika. Redak mora biti ogranien na 80 znakova. Napomena: za pretvaranje malih slova u velika koristite funkciju toupper() iz biblioteke <ctype.h>, a za unoenje retka funkciju gets(). DOMAI RAD Zadatak 5.7. Napiite program koji uitava ime i prezime korisnika, dob i godinu roenja, te ispisuje te informacije na ekran. Zadatak 5.8. Napiite program u kojem korisnik unosi niz od deset cijelih brojeva, a program ispisuje njihovu aritmetiku sredinu. Zadatak 5.9. Napiite program za zbrajanje matrica. Elemente matrice unosi korisnik, a svaka matrica moe imati najvie 20 redaka i stupaca. Napomena: zbrajati se mogu samo matrice istih dimenzija.

48

VJEBA 6 Bubble sort algoritam Bubble sort algoritam je algoritam za sortiranje lanova nekog niza. Ovo je jedan od najjednostavnijih, ali ujedno i najsporijih, algoritama za sortiranje. U slijedeem primjeru prikazan je nain rada bubble sort algoritma. Algoritam u svakom koraku usporeuje dva susjedna broja, i u sluaju da je prvi broj vei od drugog, zamjenjuje im mjesta. Napomena: podebljani brojevi su oni koji se trenutno usporeuju. Ulazni niz brojeva: (0 8 1 3 2). 1. prolaz algoritma: (0 8 1 3 2) --> (0 8 1 3 2) (0 8 1 3 2) --> (0 1 8 3 2) (0 1 8 3 2) --> (0 1 3 8 2) (0 1 3 8 2) --> (0 1 3 2 8) // 0 < 8 --> nema zamjene // 8 > 1 --> zamjena // 8 > 3 --> zamjena // 8 > 2 --> zamjena

2. prolaz algoritma: (0 1 3 2 8) --> (0 1 3 2 8) (0 1 3 2 8) --> (0 1 3 2 8) (0 1 3 2 8) --> (0 1 2 3 8) (0 1 2 3 8) --> (0 1 2 3 8) // 0 < 1 --> nema zamjene // 1 < 3 --> nema zamjene // 3 > 2 --> zamjena // 3 < 8 --> nema zamjene

3. prolaz algoritma: (0 1 2 3 8) --> (0 1 2 3 8) (0 1 2 3 8) --> (0 1 2 3 8) (0 1 2 3 8) --> (0 1 2 3 8) (0 1 2 3 8) --> (0 1 2 3 8) // 0 < 1 --> nema zamjene // 1 < 2 --> nema zamjene // 2 < 3 --> nema zamjene // 3 < 8 --> nema zamjene

Iako je niz bio sortiran na kraju drugog prolaza algoritma, algoritam se je morao jo jednom izvriti da bi "znao" da je niz sortiran. Drugim rijeima, algoritmu je potreban jedan prolaz bez ijedne zamjene da bi bio siguran da je algoritam sortiran. Analiza bubble sort algoritma Pod analizom algoritma podrazumijeva se procjena vremena izvravanja tog algoritma. Vrijeme se poistovjeuje s brojem operacija koje odgovarajui program treba obaviti [5], i izraava se kao funkcija oblika O(n) (engl. Order(n)). Na primjer, za ulazni niz brojeva (0 8 1 3 2), n bi bio jednak pet. Da bi bubble sort algoritam uspio sortirati taj niz, u najboljem sluaju bi mu bilo potrebno O(n) operacija (u ovom sluaju 5), a u najgorem sluaju O(n2) operacija (u ovom sluaju 25). Kako se n poveava, najgore vrijeme izvravanja algoritma eksponencijalno raste. Upravo zbog ovog 49

problema, bubble sort algoritam nije dobar za sortiranje nizova sa velikim brojem podataka. Drugi algoritmi kao to su heap sort i mergesort imaju puno bolje vrijeme izvravanja u najboljem sluaju O(n), u najgorem sluaju O(nlogn) ali su ipak neto kompliciraniji.

50

ZADACI Zadatak 6.1. Napiite program koji u niz sprema maksimalno 20 cijelih brojeva koje unosi korisnik. Program sortira brojeve po veliini i ispisuje sortirani niz. Koristite bubble sort algoritam. Rjeenje: #include <stdio.h> void main () { int niz[20]; int n; int temp; int i, j; printf("Koliko brojeva zelite unijeti? "); scanf("%d", &n); if ((n <= 0) || (n > 20)) printf("Morate unijeti broj u rasponu od 1 do 20.\n"); else if (n == 1) printf("Nije potrebno sortirati niz od samo jednog clana.\n"); else { printf("\nUpisite clanove niza:\t "); for (i = 0; i < n; i++) scanf("%d", &niz[i]); for (i = 0; i < n-1; i++) for (j = i+1; j < n; j++) { if (niz[i] > niz[j]) { temp = niz[i]; niz[i] = niz[j]; niz[j] = temp; } } printf("\nSortirani niz:\t "); for (i = 0; i < n; i++) printf("%d ", niz[i]); } 51

printf("\n"); getchar(); getchar(); } ISPIS PROGRAMA:

Zadatak 6.2. Pomou for petlje unesite prosjene mjesene temperature za jednu godinu. Ispiite maksimalnu, minimalnu i prosjenu godinju temperaturu. Rjeenje: #include <stdio.h> void main() { float godina[12]; int i; float prosjecnaTemperatura = 0; float max, min; for (i = 0; i < 12; i++) { printf("Temperatura za mjesec broj %d: \t", i+1); scanf("%f", &godina[i]); } printf("\n"); for (i = 0; i < 12; i++) { printf("Temperatura za mjesec broj %d: \t %.2f\n", i, godina[i]); } for (i = 0; i < 12; i++) prosjecnaTemperatura = prosjecnaTemperatura + godina[i];

52

prosjecnaTemperatura = prosjecnaTemperatura / 12; printf("Prosjecna temperatura: \t %.2f\n", prosjecnaTemperatura); max = godina[0]; for (i = 1; i < 12; i++) { if (max < godina[i]) max = godina[i]; } min = godina[0]; for (i = 1; i < 12; i++) { if (min > godina[i]) min = godina[i]; } printf("Maksimalna temperatura: \t %.2f\n", max); printf("Minimalna temperatura: \t %.2f\n", min); getchar(); getchar();

Zadatak 6.3. Napiite program koji uitava proizvoljni broj znakova, te ispisuje koliko ima slova, brojeva i ostalih znakova. Kraj uitavanja niza odreen je oznakom za prijelaz u novi redak ('\n'). Za unos znakova koristite funkciju getchar(). Rjeenje: #include <stdio.h> void main() { int slova = 0; int brojevi = 0; int ostaliZnakovi = 0; int znak; puts("Unesite neki niz znakova:"); while ((znak = getchar()) != '\n') { 53

if ((znak >= 'a' && znak <= 'z') || (znak >= 'A' && znak <= 'Z')) slova++; else if (znak >= '0' && znak <= '9') brojevi++; else ostaliZnakovi++; } printf("Slova: %d\n", slova); printf("Brojevi: %d\n", brojevi); printf("Ostali znakovi: %d\n", ostaliZnakovi); } getchar();

Zadatak 6.4. Zadatak je slian prethodnome. Napiite program koji uitava proizvoljni broj znakova, te ispisuje koliko ima slova, brojeva i ostalih znakova. Koristite funkcije getchar(), isdigit(), isupper() i islower(). Ukljuite biblioteku <ctype.h>. Rjeenje: #include <stdio.h> #include <ctype.h> void main() { int slova = 0; int brojevi = 0; int ostaliZnakovi = 0; int znak; puts("Unesite neki niz znakova:"); while ((znak = getchar()) != '\n') { if ((islower(znak)) || (isupper(znak))) slova++; else if (isdigit(znak)) brojevi++; else ostaliZnakovi++; } printf("Slova: %d\n", slova); printf("Brojevi: %d\n", brojevi); printf("Ostali znakovi: %d\n", ostaliZnakovi); 54

getchar();

55

DODATNI ZADACI Zadatak 6.5. Napiite program koji za neku predefiniranu rije broji koliko ona ima samoglasnika, te tu informaciju ispisuje na ekran. Zadatak 6.6. Napiite program koji dozvoljava unos proizvoljnog broja znakova (koristite while petlju i funkciju getchar() za unos znakova). Kraj unosa odreen je oznakom za prijelaz u novi redak ('\n'). Program treba ispisati ukupan broj unesenih znakova. Napomena: prazna mjesta se takoer broje kao znakovi. DOMAI RAD Zadatak 6.7. Napiite program koji uitava niz od deset cijelih brojeva, te ih u obrnutom redoslijedu sprema u novi niz. Program treba ispisati taj novi niz. Zadatak 6.8. Napiite program koji uitava niz od deset cijelih brojeva, te ispisuje samo one koji su parni. Ako u nizu ne postoji nijedan parni broj, program treba ispisati odgovarajuu poruku.

56

VJEBA 7 Funkcije Funkcija je programski modul koji obavlja neke specifine, tono definirane zadae. Svaki C program sastoji se od jedne ili vie funkcija, pri emu se jedna mora zvati main(). Od main() funkcije program poinje obradu. Sve se ostale funkcije, posredno ili neposredno, pozivaju iz funkcije main(). Funkcija izvede programiranu radnju svaki put kad je "pozvana" iz bilo kojeg dijela programa. Po povratku iz funkcije programski tok nastavlja se tamo odakle je funkcija bila pozvana. U pravilu, funkcija prihvaa skup argumenata (jedan ili vie), a vraa samo jednu vrijednost. Opi oblik: tip_povratne_informacije ime_funkcije (tip1 argument1, tip2 argument2, ...) { ... } Napomena: lista argumenata moe biti i prazna, a tip povratne informacije moe biti void. Argumenti se unutar funkcije nazivaju i formalnim argumentima, jer predstavljaju samo preslike podataka koji su u funkciju poslani iz pozivnog dijela programa. Takoer, koristi se i naziv parametri. Argumente koji su u funkciju poslani nazivamo stvarnim argumentima ili parametrima. Informacija se iz funkcije vraa u pozivni dio programa preko naredbe return. Ta naredba takoer vraa programski tok na mjesto odakle je funkcija pozvana. Ako se iz funkcije main() poziva neka druga funkcija, onda se ta funkcija mora ili definirati prije funkcije main(), ili se prije funkcije main() mora nalaziti prototip te funkcije (tijelo funkcije se onda moe nalaziti poslije funkcije main()). Kako funkcija prenosi podatke? Kada se pozove neka funkcija, ona e napraviti kopije argumenata koji su joj predani, tj. od stvarnih argumenata (parametara) e napraviti formalne. U isto vrijeme funkcija e osigurati memorijski prostor za eventualnu povratnu vrijednost. Prijenos argumenata u funkciju Kada se alje neka varijabla kao stvarni argument u funkciju, njena vrijednost se preslika u formalni argument u pozvanoj funkciji. Takav nain proslijeivanja argumenata funkciji nazivamo proslijeivanjem preko vrijednosti (engl. call by value). Ovakav nain proslijeivanja ima svoje prednosti i nedostatke. Prednost je u tome to argument kroz funkciju ne mijenja svoju vrijednost, 57

a nedostatak je u tome to se na ovaj nain preko argumenata ne moe prenijeti informacija natrag iz funkcije. Kada se alje polje kao stvarni argument u funkciju, njegova vrijednost se preslika u formalni argument u pozvanoj funkciji. Kako je polje predstavljeno poetnom adresom polja, preslikana vrijednost poetne adrese pristupa istim podacima. Ovakav nain proslijeivanja argumenta funkciji nazivamo proslijeivanjem preko adrese (engl. call by reference). Ovakav nain proslijeivanja podrazumijeva da je svaka promjena argumenta u funkciji vidljiva i u dijelu programa koji je funkciju pozvao. Ukratko, ako se koristi proslijeivanje preko vrijednosti, stvarni argumenti ostaju nepromijenjeni. Ako se pak koristi proslijeivanje preko adrese, stvarni argumenti mogu biti promijenjeni.

Slika 7.1. Grafiki prikaz prijenosa argumenata u funkciju.

58

ZADACI Zadatak 7.1. Napiite program koji iz funkcije main() poziva funkciju zbroji() i prosljeuje joj dva proizvoljna cijela broja. Funkcija zbroji() mora vratiti rezultat zbrajanja ta dva broja. Rjeenje (1. nain): #include <stdio.h> int zbroji (int, int); void main() { int a; int b; int rezultat; printf("Unesite 1. broj: "); scanf("%d", &a); printf("Unesite 2. broj: "); scanf("%d", &b); rezultat = zbroji(a, b); printf("%d + %d = %d\n", a, b, rezultat); getchar(); getchar(); } int zbroji (int x, int y) { int z; z = x + y; return z; } Rjeenje (2. nain): #include <stdio.h> int zbroji (int x, int y) { int z; z = x + y; return z; // definicija funkcije zbroji() // prototip funkcije zbroji()

59

} void main() { int a; int b; int rezultat; printf("Unesite 1. broj: "); scanf("%d", &a); printf("Unesite 2. broj: "); scanf("%d", &b); rezultat = zbroji(a, b); printf("%d + %d = %d\n", a, b, rezultat); getchar(); getchar();

Zadatak 7.2. Napiite program koji uitava niz od deset cijelih brojeva, te zatim proslijeuje taj niz funkciji koja vraa aritmetiku sredinu lanova niza. Rjeenje: #include <stdio.h> float aritmetickaSredina(int a[]) { float aritmeticka_sredina = 0; int brojac; for (brojac = 0; brojac < 10; brojac++) aritmeticka_sredina = aritmeticka_sredina + a[brojac]; aritmeticka_sredina = aritmeticka_sredina / 10; return aritmeticka_sredina; } void main() { int niz[10], i; float rezultat;

60

for (i = 0; i < 10; i++) { printf("Unesite %d. clan niza: \t", i+1); scanf("%d", &niz[i]); } printf("\n"); rezultat = aritmetickaSredina(niz); printf("Aritmeticka sredina clanova niza je %.4f.\n", rezultat); getchar(); getchar(); } Zadatak 7.3. Napiite program koji uitava malo slovo, te ga pretvara u veliko slovo pomou funkcije malo_u_veliko(). Rjeenje: #include <stdio.h> int malo_u_veliko (char x) { int rezultat; // velika i mala slova su u ASCII tablici udaljeni za 32 znaka rezultat = x - 32; return rezultat; } void main() { char maloSlovo, velikoSlovo; printf("Unesite neko malo slovo: "); scanf("%c", &maloSlovo); if ((maloSlovo >= 'a') && (maloSlovo <= 'z')) { velikoSlovo = malo_u_veliko(maloSlovo); printf("Veliko slovo: %c\n", velikoSlovo); }

61

else

printf("Niste unijeli malo slovo.\n");

getchar(); getchar();

62

DODATNI ZADACI Zadatak 7.4. Napiite program u koji korisnik unosi ocjene ispita, sve dok se ne unese 0. Ocjene izvan doputenog raspona ocjena od 1 do 5 se zanemaruju. Program treba ispisati koliko je na ispitu bilo pozitivnih (prolaznih), a koliko negativnih (nedovoljnih) ocjena, te kolika je bila prosjena ocjena ispita. Zadatak 7.5. Napiite program u kojem korisnik unosi broj sekundi, a program preraunave sekunde u sate, minute i sekunde. Na primjer, ako korisnik unese 3670, program treba ispisati: 1 sat, 1 minuta i 10 sekundi. DOMAI RAD Zadatak 7.6. Napiite program u kojem korisnik unosi brojani iznos u kunama, a program preraunava kune u eure (1 euro = 7.26 kuna). Preraunavanje se mora obaviti u posebnoj funkciji. Zadatak 7.7. Napiite program koji za deset predefiniranih brojeva rauna aritmetiku sredinu, te trai najvei broj u nizu.

63

VJEBA 8 Doseg funkcije Kada govorimo o dosegu funkcije, govorimo o imenima varijabli koje koristimo. Doseg je dio programa unutar kojeg se neka varijabla moe koristiti. Varijable se mogu podijeliti na: lokalne (automatske) globalne (vanjske) statike registarske

Lokalne (automatske) varijable Lokalne (automatske) varijable su prijavljene unutar neke funkcije i vidljive su jedino u toj funkciji. Ako im se pokua pristupiti iz neke druge funkcije, program e javiti greku. Dvije lokalne varijable u razliitim funkcijama s istim imenima nezavisne su jedna od druge. Sve varijable su lokalne ako se to drugaije ne navede. Lokalne varijable ne zadravaju vrijednost nakon to programski tok ode iz funkcije u kojoj je varijabla definirana. Globalne (vanjske) varijable Suprotno lokalnim varijablama, globalne varijable nisu vezane za neku funkciju. Njihov doseg see od mjesta definicije kroz ostatak programa. ak tovie, katkad povezuju ne samo funkcije nego i cjelokupni program. Promjena globalne varijable u bilo kojoj funkciji biti e vidljiva u svakom dijelu programa. Inicijalizacija globalne varijable mora biti inicijalizirana konstantom, a nikako izrazom. Statike varijable Doseg statikih varijabli, kao i doseg lokalnih varijabli, see samo unutar funkcije u kojoj su definirane. Ako programski tok izae iz funkcije, pa se opet vrati u nju, statika e varijabla dobiti onu vrijednost koju je imala na izlazu iz funkcije. To znai da se statike varijable ne unitavaju nakon izlaska programskog toka iz neke funkcije, ve ostaju sauvane u memoriji. Statike varijable se oznaavaju sa kljunom rijei static. Registarske varijable Registarske varijable se najee koriste za ubrzavanje programskog koda. To su varijable koje se ne 64

moraju spremati i itati iz memorije, ve tijekom itavog izvoenja programa ostaju u registrima. Oznaavaju se sa kljunom rijei register. Lokalne varijable definirane unutar programskog bloka Ako se lokalne varijable definiraju unutar nekog programskog pod-bloka, biti e dostupne samo u tome pod-bloku. Pokuaj pristupa nekoj od njih izvan tog programskog bloka uzrokovati e greku. Primjer 1. #include <stdio.h> void main() { int a = 0; do {

int b = 1; ...programski kod... } while(...); // da pokuamo ovdje ispisati vrijednost varijable b, program bi javio greku // varijabla b ovdje vie ne postoji

Primjer 2. #include <stdio.h> void main () { int brojac1 = 1; do {

// deklariran u VANJSKOM bloku

int brojac2 = 0; ++brojac2; printf("\nbrojac1 = %d } while (++brojac1 <= 8); // brojac2 vise ne postoji

// deklariran u UNUTARNJEM bloku brojac2 = %d", brojac1, brojac2);

printf("\nbrojac1 = %d\n", brojac1); getchar(); 65

} ISPIS PROGRAMA:

Primjer 3. #include <stdio.h> void main() { int brojac = 0; do { int brojac = 0; ++brojac; printf("brojac = %d\n", brojac); } while (++brojac <= 8); printf("brojac = %d\n", brojac); getchar(); } ISPIS PROGRAMA: // ovo je druga varijabla nazvana brojac // ovo se odnosi na UNUTARNJI brojac // ovo mijenja VANJSKI brojac

// deklariran u VANJSKOM bloku

66

ZADACI Zadatak 8.1. (Lokalne varijable) Prouite i objasnite kako radi slijedei program: #include <stdio.h> void test() { // funkcija test() ne vidi varijablu a // ako se varijabla a pokua koristiti u ovoj funkciji, program e javiti greku } printf("Funkcija test(): ovdje ne postoji varijabla a\n");

void main() { int a; a = 2; printf("Funkcija main(): %d\n", a); test(); getchar(); } ISPIS PROGRAMA: Funkcija main(): 2 Funkcija test(): ovdje ne postoji varijabla a

// a je lokalna varijabla u funkciji main()

Zadatak 8.2. (Globalne varijable) Prouite i objasnite kako radi slijedei program: #include <stdio.h> int x = 7; void test() { printf("Funkcija test(): %d\n", x); } void main() { printf("Funkcija main(): %d\n", x); test(); getchar(); } // x je globalna varijabla, vidljiva u svim funkcijama

67

ISPIS PROGRAMA: Funkcija main(): 7 Funkcija test(): 7 Zadatak 8.3. (Statike varijable) Prouite i objasnite kako radi slijedei program: #include <stdio.h> int brojac = 1; // globalna varijabla brojac

void test() { static int a = 0; // statika varijabla a a = a + 2; printf("%d. poziv funkcije test(). \t a = %d\n", brojac, a); brojac++; } void main() { int i; for (i = 0; i < 10; i++) test(); getchar(); } ISPIS PROGRAMA:

// lokalna varijabla i

68

DODATNI ZADACI Zadatak 8.4. Napiite program koji ispisuje prvih 10 znamenki Fibonaccijevog niza (koristite while ili for petlju). Napomena: Fibonaccijev niz je niz brojeva koji zapoinje sa nulom i jedinicom, a svaki slijedei broj je zbroj prethodna dva. Prvih nekoliko znamenki Fibonaccijevog niza: 0 1 1 2 3 5 8 13 21 34 55 89 144 ... Zadatak 8.5. Napiite program koji, pomou petlji, generira i ispisuje: 1 232 34543 4567654 567898765 67890109876 7890123210987 890123454321098 90123456765432109 DOMAI RAD Zadatak 8.6. Napiite program u kojem korisnik unosi dva cijela broja, a program ispisuje sve proste brojeve koji se nalaze unutar zadanog intervala. Napomena: prosti brojevi ili prim-brojevi su svi prirodni brojevi djeljivi bez ostatka samo s brojem 1 i sami sa sobom, a vei od broja 1. Zadatak 8.7. Napiite program koji rauna sumu svih brojeva od 1 do 100 koji su djeljivi sa 5.

69

VJEBA 9 Bitznaajni operatori Bit je najmanja jedinica informacije, ili 0 ili 1, a bitznaajni operatori (engl. bitwise operators) se koriste za manipulaciju bitovima (odnosno za programiranje na najnioj moguoj razini). Bitznaajni operatori se najee koriste u kriptografiji i u saimanju podataka. Bitznaajni operatori: & | ^ ~ << >> binarno I (AND) binarno ILI (OR) binarno ekskluzivno ILI (XOR) jedinini komplement (NOT) pomak u lijevo (SHIFT LEFT) pomak u desno (SHIFT RIGHT) Tablica 9.1. Tablica istine za &, ^ i | operatore a 0 0 1 1 b 0 1 0 1 a&b 0 0 0 1 a^b 0 1 1 0 a|b 0 1 1 1

Tablica 9.2. Tablica istine za ~ operator a 0 1 ~a 1 0

Tablica 9.3. Primjeri primjene AND, OR i XOR operatora Primjer (AND): 0010 & 1010 0010 Primjer (OR): 0010 | 1010 1010 Primjer (XOR): 0010 ^ 1010 1000

Jedinini komplement (~) je unarni operator koji se koristi za inverziju bitova nekog operanda (jedinice postaju nule, a nule jedinice). Operand se najee predstavlja u oktalnoj ili u heksadecimalnoj formi, iako ovo nije formalno pravilo [6]. 70

Primjer: a = 0110 1101 1011 0111 ~a = 1001 0010 0100 1000 (dekadski brojevni sustav 28087) (dekadski brojevni sustav 37448)

Bitznaajni pomak u lijevo odgovara mnoenju operanda sa potencijama broja dva. Na primjer, ako operand pomaknemo za jedno mjesto u lijevo dobiti emo isti rezultat kao da smo ga pomnoili sa 2. Primjeri: a = 0110 1101 1011 0111 a << 6 = 0110 1101 1100 0000 a = 0000 a << 1 = 0000 a << 2 = 0000 a << 3 = 0001 a << 4 = 0010 0010 0100 1000 0000 0000 (dekadski brojevni sustav 28087) (dekadski brojevni sustav 28096)

(dekadski brojevni sustav 2) (dekadski brojevni sustav 4) (dekadski brojevni sustav 8) (dekadski brojevni sustav 16) (dekadski brojevni sustav 32)

Bitznaajni pomak u desno odgovara cjelobrojnom dijeljenju operanda sa potencijama broja dva. Na primjer, ako operand pomaknemo za jedno mjesto u desno dobiti emo isti rezultat kao da smo ga podijelili sa 2. Primjeri: a = 0110 1101 1011 0111 a >> 6 = 0000 0001 1011 0110 a = 0100 a >> 1 = 0010 a >> 2 = 0001 a >> 3 = 0000 a >> 4 = 0000 Maskiranje bitova Bitznaajni operator I (AND) se najee koristi za maskiranje bitova. Maskiranje bitova je proces vaan za raunalnu sigurnost, grafiku i kriptografiju. Primjer: a = 0110 1101 1011 0111 maska = 0000 0000 0000 1111 rezultat = 0000 0000 0000 0111 (dekadski brojevni sustav 28087) (dekadski brojevni sustav 15) (dekadski brojevni sustav 7) 0000 0000 0000 1000 0100 (dekadski brojevni sustav 28087) (dekadski brojevni sustav 438)

(dekadski brojevni sustav 64) (dekadski brojevni sustav 32) (dekadski brojevni sustav 16) (dekadski brojevni sustav 8) (dekadski brojevni sustav 4)

71

#include <stdio.h> void main() { unsigned n = 0x6db7; unsigned maska = 0xF;

// dekadski brojevni sustav - 28087 // dekadski brojevni sustav 15

// koritenje znaka '#' uzrokuje pojavu znakova '0x' ispred keksadecimalnog broja printf("Vrijednost od n (n = %#x), maskirana sa %#x, je: %#x\n", n, maska, n & maska); } getchar();

72

ZADACI Zadatak 9.1. Napiite program u kojem korisnik unosi neki cijeli broj, a program ispisuje njegov binarni ekvivalent. Rjeenje: #include <stdio.h> void main() { int x, i, n, b; printf ("Unesite jedan cijeli broj: "); scanf ("%d", &x); // sizeof(int) vraa broj bajtova koje zauzima int // 8 * sizeof(int) vraa broj bitova koje zauzima int n = 8 * sizeof(x); printf ("Binarni kod je: "); for (i = n-1; i >= 0; i--) { b = (x & (01 << i)) != 0; printf ("%d", b); } printf("\n"); getchar(); getchar(); // od MSB do LSB (od 31. do 0. bita)

Pretpostavimo da korisnik unese broj 2 (binarno 00000000 00000000 00000000 00000010). Promotrimo to tono radi linija koda: b = (x & (01 << i)) != 0; U prvom prolazu for petlje, i = 31. Dakle: b = (00000000 00000000 00000000 00000010 & (01 << 31)) != 0; Kada se broj 01 pomakne za 31 mjesto ulijevo, ostaje samo 00. Dakle: b = (00000000 00000000 00000000 00000010 & (00)) != 0; 73

Ako je bilo koji od operanada jednak nuli, rezultat logike operacije AND je takoer jednak nuli: 00000000 00000000 00000000 00000010 & 00 = 0. Dakle: b = (0) != 0; 0 != 0 nije tono, pa je itav izraz jednak logikoj nuli. MSB bit ima vrijednost nula. Napomena: != ima vei prioritet od =. Zato se u izrazu "b = (0) != 0;" prvo izvri usporedba (0) != 0, pa se tek onda rezultat usporedbe dodijeli varijabli b. U predzadnjem prolazu for petlje, i = 1. Dakle: b = (00000000 00000000 00000000 00000010 & (01 << 1)) != 0; Kada se broj 01 pomakne za 1 mjesto ulijevo, ostane 10. Dakle: b = (00000000 00000000 00000000 00000010 & (10)) != 0; Budui da je izraz (00000000 00000000 00000000 00000010 & (10)) != 0 istinit, bit sa teinskom vrijednou jedan jednak je jedinici. Zadatak 9.2. Napiite program u kojemu su definirana dva cjelobrojna niza. Elementi nizova mogu biti samo binarne znamenke, tako da itavo polje zapravo predstavlja neki binarni broj. Pokaite djelovanje AND, OR i XOR operatora nad lanovima tih nizova. Rjeenje: #include <stdio.h> void main() { int a[4] = {1,1,0,1}; int b[4] = {1,0,1,0}; int rezultat[4]; int i;

// 13 // 10

// AND for (i = 0; i < 4; i++) rezultat[i] = a[i] & b[i]; // ispisujemo rezultat logickog AND printf("Rezultat AND operacije: "); for (i = 0; i < 4; i++) printf("%d", rezultat[i]); // OR 74

for (i = 0; i < 4; i++) rezultat[i] = a[i] | b[i]; // ispisujemo rezultat logickog OR printf("\nRezultat OR operacije: "); for (i = 0; i < 4; i++) printf("%d", rezultat[i]); // XOR for (i = 0; i < 4; i++) rezultat[i] = a[i] ^ b[i]; // ispisujemo rezultat logickog XOR printf("\nRezultat XOR operacije: "); for (i = 0; i < 4; i++) printf("%d", rezultat[i]); getchar(); getchar(); } Zadatak 9.3. Napiite program i definirajte neki cijeli broj u heksadecimalnom obliku. Korisnik unosi redni broj bita iju vrijednost eli saznati, i program vraa nulu ili jedinicu, ovisno o tome koji se bit nalazi na mjestu kojeg je specificirao korisnik. Rjeenje: #include <stdio.h> void main () { int x = 0x2; int n;

// dekadski isto 2

printf("Unesite oznaku bita ciju vrijednost zelite procitati: \n"); scanf ("%d", &n); if ((n < 0) || (n >= 32)) printf("Odabrali ste nepostojeci bit!!!\n"); else printf("Bit na %d. mjestu ima vrijednost: %d \n", n, ((x & (01 << n)) != 0)); getchar(); getchar(); } 75

DODATNI ZADACI Zadatak 9.4. Napiite program u kojem korisnik unosi neki cijeli broj, a program ispisuje njegov binarni ekvivalent. Binarni ekvivalent se sprema u niz binarni_ekvivalent[32]. Postavite sve bitove binarnog ekvivalenta na nulu (koristite XOR operaciju). DOMAI RAD Zadatak 9.5. Napiite program koji za predefinirani cijeli broj ispisuje teinsku vrijednost svakog bita koji je jednak jedinici. Na primjer, za cijeli broj 11 (binarno 1011), program bi trebao ispisati 1, 2 i 8. 1 23=8
2

0
2 =4

1
2 =2
1

1
2 =1
0

76

DODATAK Pretvaranje iz dekadskog brojevnog sustava u binarni brojevni sustav 15610=? 2 Prvi nain (broj u dekadskom brojevnom sustavu se dijeli sa 2, a ostatak dijeljenja se zapisuje u poseban stupac): 156 : 2 = 78 78 : 2 = 39 39 : 2 = 19 19 : 2 = 9 9:2=4 4:2=2 2:2=1 1:2=0 0 0 1 1 1 0 0 1

Rjeenje se dobije tako da se ostaci dijeljenja sa 2 napiu obrnutim redoslijedom. Rjeenje bi bilo: 1001 1100. Drugi nain (promatraju se potencije broja 2): 156 128 = 28 28 64 = -36 28 32 = -4 28 16 = 12 12 8 = 4 44=0 0 2 = -2 0 1 = -1 1 0 0 1 1 1 0 0 (128 je najvea potencija broja 2 koja "stane" u broj 156) (64 je idua nia potencija broja 2, ali 64 ne "stane" u 28) (32 je idua nia potencija broja 2, ali 32 ne "stane" u 28) (16 je idua nia potencija broja 2) (8 je idua nia potencija broja 2) (4 je idua nia potencija broja 2) (2 je idua nia potencija broja 2) (1 je idua nia potencija broja 2)

Napomena: ako je rezultat oduzimanja negativan, za binarnu znamenku se uzima nula. Ako je rezultat pozitivan, uzima se jedinica. Pretvaranje iz binarnog brojevnog sustava u dekadski brojevni sustav 100111002 =?10 MSB 1 2 =128
7 6

LSB 0 2 =64
5

0 2 =32
4

1 2 =16

1 2 =8
3

1 2 =4
2 1

0 2 =2

0 2 0=1

112806403211618140201=1281684=156
77

Pretvaranje iz dekadskog brojevnog sustava u oktalni brojevni sustav 15610=? 8 156 najprije podijelimo sa najveom potencijom broja 8 koja "stane" u broj 156 (a to je 64). 156 : 64 = 2 28 : 8 = 3 4:1=4 Rezultat: 234. Pretvaranje iz oktalnog brojevnog sustava u dekadski brojevni sustav 234 8=? 10
28 38 48 =128244=156
2 1 0

(ostatak 28) (ostatak 4) (ostatak 0)

64=8 8=81 0 1=8

Pretvaranje iz dekadskog brojevnog sustava u heksadecimalni brojevni sustav 15610=? 16 156 najprije podijelimo sa najveom potencijom broja 16 koja "stane" u broj 156 (a to je 16). 156 : 16 = 9 12 : 1 = 12 (C) Rezultat: 9C. Pretvaranje iz heksadecimalnog brojevnog sustava u dekadski brojevni sustav 9C16=? 10 916 1216 =14412=156
1 0

(ostatak 12) (ostatak 0)

16=16 0 1=16

78

VJEBA 10 MATLAB MATLAB (engl. MATrix LABoratory) je aplikacija i programski jezik (slian C-u) za znanstvena istraivanja. MATLAB korisniku prua velik broj funkcija, grupiranih tematski u toolbox-ove, te namijenjenih rjeavanju problema vezanih za kontrolu i optimizaciju sustava, kao i za obradu signala. Neki od MATLAB-ovih toolbox-ova: Partial Differential Equation Toolbox Statistics Toolbox Neural Network Toolbox Aerospace Toolbox Image Processing Toolbox Fuzzy Logic Toolbox ...

Pokretanje MATLAB-a Na Windows Desktop-u kliknite na Start --> All Programs --> Matlab --> Matlab. Otvoriti e se osnovni prozor MATLAB-a (Slika 10.1) koji po default-u sadri naredbeni prozor (engl. Command Window), prozor povijesti naredbi (engl. Command History), prozora tekuih datoteka (engl. Current Directory) i prozor sa sadrajem radnog prostora (engl. Workspace). Osnovne operacije MATLAB koristi jednostavnu sintaksu. Naredbe u MATLABu se upisuju u posljednju, aktivnu liniju naredbenog prozora koja poinje sa oznakom '>>'. Nardbe (i operacije) koje se upisuju u komandnu liniju izvravaju se nakon pritiska na <enter>. Na primjer: >> (3^2+4*5)/ (9/2-8^3) <enter> izraunava vrijednost izraza 3245 9 3 . 8 2 Pretraivanje i preureivanje prethodno izvrenih izraza radimo sa 'tipkama-strelicama': gore, dolje, lijevo i desno. Na primjer, prethodni izraz pozivamo tipkom gore. 79

Slika 10.1. Osnovni prozor MATLAB-a Primijetili ste da se rezultat ispisuje na pod nazivom ans (engl. answer). Ukoliko elimo vrijednosti dodijeliti ime (ime konstante), ispred izraza napiemo ime i stavljamo znak jednakosti. Primjer: pozovimo prethodni izraz i dodijelimo ga konstanti k: >> k = (3^2+4*5)/ (9/2-8^3) <enter> >> k = -0.0571 Ukoliko ne elimo konstantu ispisati na ekran, na kraju izraza upisujemo toka-zarez ;. >> k = (3^2+4*5)/ (9/2-8^3); >> Na taj nain konstanta k se ne ispisuje na ekranu, ali ostaje definirana u programu dok joj se ne dodijeli nova vrijednost, odnosno izraz.

80

Matrice i operacije sa matricama Rjeavanje nekih problema (pogotovo onih vezanih za matrice i openito za matematiku), puno je jednostavnije i bre u Matlabu nego u nekim drugom programskim jezicima (npr. C-u). Matrica je dvodimenzionalno polje brojeva, i usput osnovni podatak za rad u MATLAB-u. Matrica dimenzija [1,1] naziva se skalar, a matrica koja sadri samo jedan stupac ili samo jedan redak naziva se vektor. Matrica se definira navoenjem njezinih redaka. Elementi redaka se razdvajaju zarezom ili praznim mjestom. Dva retka se razdvajaju simbolom ; na kraju retka. Primjer definiranja matrice u MATLAB-u: A = [16 3 2 13; 5 10 11 8; 9 6 7 12; 4 15 14 1]; ili A = [16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1]; Ovime smo definirali matricu:

16 3 2 13 5 10 11 8 A= 9 6 7 12 4 15 14 1
Napomena: matrice je uobiajeno oznaavati velikim slovima. Matrine operacije i funkcije Nad matricama se primjenjuju matematike operacije kao to su zbrajanje (oznaka je +), oduzimanje (-), mnoenje (*) i dijeljenje (mnoenje jedne matrice sa inverznom drugom matricom) (/). Napomena: prilikom mnoenja ili dijeljenja matrica treba voditi rauna o uzajamnoj usklaenosti veliine matrica. MATLAB poznaje standardne matrine operacije i funkcije kao to su transponiranje, potenciranje, nalaenje inverzne matrice i odreivanje determinante. Na primjer, slijedee naredbe >> B' >> B^2 >> inv(B) >> det(B) odreuju odgovarajuu transponiranu matricu B, kvadrat matrice B, inverznu matricu B (inverzna matrica se moe odrediti i sa B^(-1)) i determinantu matrice B, respektivno. 81

Posebne operacije sa matricama Ako su matrice A i B istih dimenzija, i ukoliko je binarna operacija, tada je . posebna operacija koja se moe primijeniti na matrice. Karakteristine posebne operacije (element sa elementom) su: mnoenje redaka (.*), dijeljenje redaka (./) i potenciranje redaka (.^). Primjer: >> A = [2 4 6; 1 2 3]; >> B = [1 1 1; 2 2 2]; >> A.*B

% A * B bi generiralo greku

U gornjem smo primjeru definirali matrice A i B, te izraunali njihov umnoak. Izdvajanje stupaca (redaka) matrice Indeksiranje matrica, odnosno izdvajanje vektora redka ili vektora stupca ili pojedinih elemenata vri se koritenjem simbola dvotoke ':'. Prvi indeks se odnosi na redak, a drugi indeks na stupac. Primjer: >> D = [9 8 7; 6 5 4; 3 2 1]; >> e = D(:, 3) >> f = D(1, :) >> g = D(1:2, 2) >> h = D(3, 2:3) Napomene MATLAB razlikuje velika i mala slova. Bilo koja linija napisana iza znaka '%' predstavlja komentar. Informacije o pojedinim naredbama se mogu dobiti primjenom naredbe help. Na primjer: >> help zeros prikazuje opis naredbe zeros. Varijable se iz MATLAB-ove memorije briu naredbama clear ime_varijable ili clear all. Naredbom clc se isprazni komandni ekran. % definiramo matricu D % izdvajamo trei stupac matrice D % izdvajamo prvi redak matrice D % izdvajamo prva dva elementa drugog stupca % izdvajamo drugi i trei element treeg retka

82

Vektori Matrica sa jednim retkom ili stupcem predstavlja vektor. Na primjer: >> v1 = [1 2 3 4]; >> v2 = [1; 2; 3; 4]; % matrica sa jednim retkom % matrica sa jednim stupcem

MATLAB omoguava definiranje vektora iji elementi imaju konstantan meusoban razmak. Na primjer, definirajmo vektor na intervalu [0, 100] sa korakom 10. >> x = 0 : 10 : 100; Dakle, rezultat je [0 10 20 30 40 50 60 70 80 90 100] i u konkretnom primjeru, 0 je poetni element vektora, 10 je srednji element koji predstavlja korak izmeu dva elementa vektora, dok je 100 zadnji element. Pa moemo zakljuiti da je sintaksa ovakvog definiranja vektora: ime_vektora = prvi_element : korak : zadnji_element; Ako se korak eksplicitno ne navede, po defaultu iznosi jedan. Polinomi Polinomi se definiraju preko vektora koeficijenata polinoma, od koeficijenta ispred najvieg stupnja polinoma do slobodnog elementa. Na primjer, polinom 2x3 x 23 se u MATLAB-u definira na slijedei nain: >> a = [2 -1 0 3] Napomena: primijetite da u zadanom polinomu koeficijent uz x ima iznos 0. Korijeni polinoma se mogu odrediti primjenom naredbe roots. Na primjer: >> roots([1 5 6]) pronalazi korijene polinoma x 2 5x6. Inverzna naredba roots naredbe je poly. Naime, ukoliko znamo korijene polinoma, primjenom naredbe poly, dobivamo koeficijente polinoma. Na primjer: >> poly([-2 -3]) ime iz zadanih korijena x1 = -2 i x2 = -3 dobivamo polinom x 2 5x6.

83

Rjeavanje sustava linearnih jednadbi Rjeavanje sustava jednadbi obavlja se preko operacija sa matricama. Pretpostavimo da traimo rjeenje Ax=B sustava.

Ax=B se moe zapisati i na slijedei nain:

Rjeenje sustava Ax=B bilo bi jednako x =A1 B . Na primjer, rjeenje sustava jednadbi x + 3y = 7 i 2x 5y = 8 bilo bi: >> A = [1 3; 2 -5] >> B = [7; -8] >> X = inv(A)*B Crtanje funkcija MATLAB posjeduje razliite funkcije za grafiki prikaz dobivenih rezultata. Najee koritena naredba za grafiki prikaz funkcija je plot, sa sintaksom: plot(x, y, 'opcije') Na primjer: >> x = -1 : 0.01 : 1; >> plot(x, exp(x)+1) crta funkciju e x 1 za 1 x 1 u posebnom prozoru. Korak u definiranju vektora elemenata je u ovom konkretnom sluaju 0.01, i s ovim odreujemo finou i preciznost prikaza funkcije. Alternative MATLAB-u Besplatne alternative MATLAB-u su Octave (http://sourceforge.net/projects/octave/files/) i Scilab (http://www.scilab.org/products/scilab/download).

84

ZADACI Zadatak 10.1. Definirajte matrice:

Izdvojite: a) b) c) d) e) Rjeenje: >> M = [-2 3 1; 1 5 6; 7 4 1]; >> N = [2 4 8; -1 2 9; 2 3 2]; >> O = [1 1 1; 2 2 2; 3 3 3]; >> a = M(:, 3); >> b = N(2, 1:2); >> c = O(2:3, 1); >> d = M(2, :); >> E = M + N; >> e = E(1:2, 3); Zadatak 10.2. Rijeite sustav jednadbi: 1. x 2y=3 2. x y4z=7 3. 2x3yz=5 Rjeenje: A = [1 2 0; -1 1 4; 2 3 -1]; B = [3; 7; 5]; x = inv(A) * B ISPIS PROGRAMA: 15 -6 7 posljednji stupac matrice M, prva dva elementa drugog reda matrice N drugi i trei element prvog stupca matrice O drugi redak matrice M prva dva elementa treeg stupca zbroja matrica M + N

85

Zadatak 10.3. Rijeite sustav jednadbi: 4. 5. 6. 7. Rjeenje: A = [-1 0 1 0; 1 -1 0 0; 0 1 1 0; 1 0 0 1]; B = [1; -1; 1; 3]; x = inv(A) * B ISPIS PROGRAMA: -0.50000 0.50000 0.50000 3.50000 Zadatak 10.4. Pronaite korijene polinoma y=3x 44x3 x3. Rjeenje: y = [-3 4 0 -1 3]; roots(y) ISPIS PROGRAMA (Octave): 1.48680 + 0.00000i 0.34243 + 0.82767i 0.34243 0.82767i -0.83832 + 0.00000i Zadatak 10.5. Na istoj slici iscrtati grafove funkcija y 1=x 32x 24 i y 2=5x 23, na intervalu (5,5), sa korakom 0.01. Neka graf funkcije y 1 bude iscrtan utom bojom, a graf funkcije y 2 zelenom bojom. Rjeenje: x = -5 : 0.01 : 5; y1 = x.^3 + 2.*x 4; y2 = -5.*x.^2 + 3; plot(x, y1, 'y', x, y2, 'g') x 1x 3=1 x 1 x 2=1 x 2 x 3=1 x 1 x 4=3

86

Zadatak 10.6. Nacrtajte graf funkcije y= Rjeenje: x = -5 : 0.02 : 5; y = exp(x)./(1 + exp(1./(1 + x))); plot(y)

ex 1e
1 1 x

, na intervalu (-5,5), sa korakom 0.02.

Zadatak 10.7. Nacrtajte graf funkcije y=

1 , na intervalu (-5,5), sa korakom 0.5. Neka graf 1e 1 x bude zelene boje, i neka sve toke na grafu budu oznaeve kruiima. Napomena: dodatne opcije za crtanje grafa funkcije objanjene su u dodatku.

ex

Rjeenje: x = -5 : 0.5 : 5; y = exp(x)./(1 + exp(1./(1 + x))); plot(y, '-og')

87

DOMAI RAD Zadatak 10.8. Pronaite korijene polinoma y=7x 4 4x 26x3. sinx cosx i y 2= , na intervalu (0,10), sa x x korakom 0.01. Neka graf funkcije y 1 bude iscrtan utom bojom, a graf funkcije y 2 zelenom bojom. Zadatak 10.9. Na istoj slici iscrtati grafove funkcija y 1=

88

DODATAK VJEBI 10 Grafovi U MATLAB-u se moe specificirati tip linije kojom se iscrtava graf, te se mogu prikazati oznake za eljene toke na grafu. Tablica 10.1. Tipovi linija u MATLAB-u [7] Oznaka u MATLAB-u '-' '--' ':' '-.' 'none' Tip linije solid line (default) dashed line dotted line dash-dot line no line

Tablica 10.2. Oznake toaka na grafovima u MATLAB-u [7] Oznaka u MATLAB-u '+' 'o' '*' '.' 'x' 'square' ili 's' 'diamond' ili 'd' '^' 'v' '>' '<' 'pentagram' ili 'p' 'hexagram' ili 'h''' 'none' Tip toke plus sign circle asterisk point cross square diamond upward-pointing triangle downward-pointing triangle right-pointing triangle left-pointing triangle five-pointed star (pentagram) six-pointed star (hexagram) no marker (default)

89

Boje grafova U MATLAB-u postoji osam predefiniranih boja za grafove. Sve su prikazane u tablici 10.3. Tablica 10.3. Predefinirane boje grafova u MATLAB-u [7] Oznaka u MATLAB-u r g b c m y k w Boja red green blue cyan magenta yellow black white

Na primjer, naredbom plot(x, y, '-.or') bi se iscrtao graf sa linijom tipa '-.' (engl. dash-dot line), a toke na grafu bi bile oznaeve kruiima ('o'). I graf i kruii bi bili crvene boje ('r') [7].

90

POPIS OZNAKA I KRATICA ASCII American Standard Code for Information Interchange BCPL - Basic Combined Programming Language CR Carriage Return DEC - Digital Equipment Corporation LF Line Feed LSB Least Significant Bit MATLAB MATrix LABoratory MIT Massachusetts Institute of Technology MSB Most Significant Bit PDP - Programmed Data Processor

91

LITERATURA [1] "Dennis Ritchie", http://en.wikipedia.org/wiki/Dennis_Ritchie, web stranica posjeena 15. rujna 2010. [2] Lavicki-atovi, N.; Vrba, .: "Library funkcije za sluajne brojeve", 2004, http://zvrba.net/writings/C-srand.pdf, web stranica posjeena 18. rujna 2010. [3] Vulin, R.: "Zbirka rijeenih zadataka iz C-a", kolska knjiga, Zagreb, 2003. [4] "Matrica (matematika)", http://hr.wikipedia.org/wiki/Matrica_(matematika), web stranica posjeena 19. rujna 2010. [5] Manger, R.; Marui, M.: "Strukture podataka i algoritmi", skripta, tree izdanje, Prirodoslovno matematiki fakultet, Sveuilite u Zagrebu, Zagreb, 2007, http://web.math.hr/nastava/spa/files/skripta.pdf, web stranica posjeena 20. rujna 2010. [6] Gottfried, B.: "Schaum's Outline Series: Programming with C", Second Edition, McGraw-Hill, 1996. [7] "LineSpec (Line Specification)", http://www.mathworks.com/help/techdoc/ref/linespec.html, web stranica posjeena 23. rujna 2010.

92

You might also like