selma krajnović - programiranje 3, skripta

95
ETŠ Tuzla, Selma Krajinović 1 PROGRAMIRANJE 3 Modul 1: Dvodimenzionalni niz

Upload: ahmed-sagdati

Post on 27-Nov-2015

455 views

Category:

Documents


32 download

DESCRIPTION

Skripta za internu upotrebu

TRANSCRIPT

Page 1: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

1

PROGRAMIRANJE 3

Modul 1: Dvodimenzionalni niz

Page 2: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

2

Uvod, Matrice

U matematici, matrica je pravougaona tabela brojeva, ili općenito, tabela koja se sastoji od apstraktnih objekata koji se mogu sabirati i množiti.

Matrice se koriste za opisivanje linearnih jednačina, za praćenje koeficijenata linearnih transformacija, kao i za čuvanje podataka koji ovise od dva parametra. Matrice se mogu sabirati, množiti i razlagati na razne načine, što ih čini ključnim konceptom u linearnoj algebri i teoriji matrica.

Matrice omogućuju jednostavan zapis i rješavanje sistema linearnih jednačina.

Definicija Pravougaona tablica brojeva

zove se matrica tipa mxn. Tablica se stavlja u uglaste ili oble zagrade. Brojevi

su elementi matrice ili komponente matrice. Svaki element matrice odjeđen je indeksom reda u kojem se nalazi (i) i indeksom kolone (j). Tako je element a2,8 onaj koji se nalazi u drugom redu i 8. koloni. Brojevi

formiraju -ti red, brojevi

tvore j-tu kolonu, a brojevi

formiraju dijagonalu matrice .

Ako je kažemo da je kvadratna matrica reda . Kod kvadratne matrice brojevi A1,1, A2,2, A3,3,…. An,n,

formiraju glavnu dijagonalu matrice . Brojevi A1,n, A2,n-1, A3,n-2,…. An,1,

Page 3: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

3

formiraju sporednu dijagonalu.

Ako je kažemo da je retčana matrica (ima samo jedan redak), a ako je

kažemo da je stupčana matrica. Retčane i stupčane matrice se još zovu vektori.

Matrice obično označavamo velikim pisanim slovima, A,B,X,Y…Koriste se i oznake

Vektore možemo označavati i s malim štampanim slovima a,b,x, ili s masnim slovima, a,b,x.

Na primjer, je matrica tipa 3x4, s označenim drugim retkom,

i su primjeri retčane odnosno stupčane matrice,

dok su i kvadratne matrice reda , a ujedno i stupčane i retčane matrice

Matrice i su jednake ako su istog tipa i ako je

za sve parove indeksa

Page 4: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

4

C++ : Dvodimenzionalni niz

Matrica se u C++ predstavlja kao dvodimenizionalni niz. Kao i kod matrice, svaki element određen je indeksom

reda i kolone u kojoj se nalazi, s tim što je indeks prvog reda i indeks prve kolone 0.

Na primjer, dvodimenzionalni niz A formata 3x5, sadrži slijedeće elemente: Kolona 1 (indeks 0) Kolona 2 (indeks 1) Kolona 3 (indeks 2) Kolona 4 (indeks 3) Kolona 5 (indeks 4)

Red 1 (indeks 0) a00 a01 a02 a03 a04 Red 2 (indeks 1) a10 a11 a12 a13 a14 Red 3 (indeks 2) a20 a21 a22 a23 a24

Dakle, indeks prvog reda je 0, a poslednjeg 2. Indeks prve kolone je 0, a poslednje 4.

Deklaracija dvodimenzionalnog niza

Dvodimenzionalni niz deklariše se tako što ste najprije navede tip elemenata niza, zatim naziv niza, a onda, u

uglastim zagradama, broj redova i broj kolona.

Tip_elemenata naziv_niza [broj redova] [broj kolona]

Primjer:

float X [4] [3]

Ovom naredbom deklarisali smo niz koji će sadržati maksimalno 4x3 realna broja.

Učitavanje dvodimenizionalnog niza

Elemente niza učitavamo tako što najprije učitamo broj redova (N) i broj kolona (M), a zatim pomoću dva

brojača, unutar dvije for petlje, učitavamo red po red niza. Brojač i kontroliše red a brojač j vrstu (ili kolonu) u

koju će učitani element biti upisan. Kod sadrži i kontrolu dimenzija koje korisnik upiše.

Page 5: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

5

Ispisivanje dvodimenzionalnog niza

Kao i kod učitavanja, dvodimenzionalni niz ispisujemo pomoću dva brojača.

Ako testiramo kodi zadamo dimenizije niza 3x3, dobijemo

Page 6: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

6

Ako želimo urediti ispis niza možemo koristiti funkciju setw iz biblioteke iomanip. Modifikovani kod za ispis je

Ovaj kod daje

Manipulator setw(n) je manipulator koji služi za formatiranje izlaza . Određuje minimalni broj kolona (n) za ispis broja koji slijedi. Tako u naredbi cout <<setw(6)<<X[i][j]; određujemo da je najmanji broj kolona u kojima će se ispisati element niza. Podrazumijevano poravnanje broja koji slijedi je udesno. To se može promijeniti pomoću manipulatora left i right, koji se mogu navesti poslije manipilatora setw. Npr. ako u kodu za ispis niza modifikujemo naredba cout za ispis elementa niza na slijedeći način cout <<setw(6)<<left<<X[i][j];

onda ispis izgleda ovako

Inicijalizacija niza

Elemente niza možemo inicijalizovati prilikom deklaracije. Npr.

Ako izostavimo zadnji red u inicijalizaciji, elementima niza u zadnjem redu biće dodijeljene nule

Page 7: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

7

Primjer 1.

Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te naći i ispisati sumu elemenata drugog reda i proizvod elemenata treće kolone. Elementi niza su cijeli brojevi, najmanji broj kolona je 3, najmanji broj redova je 2.

S

Promjenljiva suma2 se inicijalizuje na 0. Koristit će za formiranje sume elemenata reda.

Promjenljiva proizvod2 se inicijalizuje na 1. Koristit će se za formiranje proizvoda elemenata kolone.

Učitavanje M i N se ponavlja sve dok nije u dozvojenim granicama, i to:

2<=N<=10 i 3<=M<=10

Nakon učitavanja i ispisivanja elemenata niza, formiraju se tražena suma i proizvod, kako slijedi:

Indeks i elemenata drugog reda je 1, pa je u prvoj petlji fiksiran. Pomoću petlje po j dodaju se elementi reda.

Indeks j elemenata treće kolone je 2, pa je u drugoj petlji fiksiran. Pomoću petlje po i množe se elementi treće kolone.

i/j 0 1 2

0 1 2 3

1 4 5 6

2 7 8 9

Primjer izvršavanja programa

Page 8: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

8

Množenje matrice skalarom

Matrica se množi s nekim skalarom (brojem) tako da se svaki element matrice pomnoži s tim brojem.

c*A = c*A[i, j]

Na primjer:

Primjer 2

Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), i realni broj x, te naći proizvod matrice i broja x. Novodobivenu matricu treba ispisati u obliku tabele.

Rješenje 1

Množenje elemenata matrice možemo izvršiti prilikom ispisa, kako slijedi:

Page 9: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

9

Rješenje 2

Formira se novi dvodimenzionalni niz Y prema formuli:

Y = broj * X, tj. Y[i,j]= broj * X[i,j]

Page 10: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

10

Sabiranje matrica

Ako su zadane matrice A i B, dimenzija mxn, njihov zbir A + B je nova matrica C, dimenzija mxn, čiji su elementi izračunati sabiranjem odgovarajućih elemenata matrica A i B, t.j.

C=A+B, C[i, j] = A[i, j] + B[i, j]

Na primjer:

Primjer 3

Učitati dva dvodimenzionalna niza sa maksimalno 10x10 elemenata i formirajte i ispišite matricu koja predstavlja

zbir učitanih matrica.

Page 11: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

11

Množenje matrica

Matrice A i B možemo pomnožiti samo ako su ulančane, odnosno ako A ima onoliko kolona koliko B ima redova. Matrica C=A*B ima redova koliko ima matrica A i onoliko kolona koliko ima matrica B.

Neka je, dakle, A dimenzija nxk i B dimenzija kxm. Tada je matrica C dimenzija nxm i vrijedi

Anxk * Bkxm = Cnxm

Npr. neka je zadana matrica A formata 3x4 i B formata 4x5 sa elementima kao na slici

A3x4 * B4x5 = C3x5

Rezultujuća matrica C biće formata 3x5, sa elementima:

c11 c12 c13 c14 c15

c21 c22 c23 c24 c25 c31 c32 c33 c34 c35 Npr. element c23 računa se kao

Elementi prvog reda nove matrice računaju se prema formulama: c11=a11*b11 + a12*b21 + a13*b31 + a14*b41 c12=a11*b12 + a12*b22 + a13*b32 + a14*b42 c13=a11*b13 + a12*b23 + a13*b33 + a14*b43 c14=a11*b14 + a12*b24 + a13*b34 + a14*b44 c15=a11*b15 + a12*b25 + a13*b35 + a14*b45

Dakle, elementi prvog reda matrice A množe se odgovarajućim elementima pojedinih kolona u matrici B. c1,j =a11*b1j + a12*b2j + a13*b3j + a14*b4j, gdje j uzima vrijednosti od 1 do 5 i predstavlja indeks kolone sa kojom se množi.

Elementi drugog reda nove matrice računaju se prema formulama: C21=a21*b11 + a22*b22 + a23*b31 + a24*b41 C22=a21*b12 + a22*b22 + a23*b32 + a24*b42 C23=a21*b13 + a22*b23 + a23*b33 + a24*b43 C24=a21*b14 + a22*b24 + a23*b34 + a24*b44 C25=a21*b15 + a22*b25 + a23*b35 + a24*b45

Dakle, drugog reda matrice A množe se odgovarajućim elementima pojedinih kolona u matrici B. C2,j =a21*b1j + a22*b2j + a23*b3j + a24*b4j

Elementi trećeg reda nove matrice računaju se prema formulama: C31=a31*b11 + a32*b22 + a33*b31 + a34*b41 C32=a31*b12 + a32*b22 + a33*b32 + a34*b42 C33=a31*b13 + a32*b23 + a33*b33 + a34*b43 C34=a31*b14 + a32*b24 + a33*b34 + a34*b44 C35=a31*b15 + a32*b25 + a33*b35 + a34*b45

Dakle, drugog reda matrice A množe se odgovarajućim elementima pojedinih kolona u matrici B.

Page 12: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

12

C2,j =a21*b1j + a22*b2j + a23*b3j + a24*b4j

Na primjer,

Primjer 4

Napisati program koji ucitava matricu X formata nxk i matricu Y formata kxm, te izracunava i ispisuje matricu C koja je proizvod

matrica A i B.

Formiranje elemenata rezultujućeg niza realizuje se u okviru tri petlje:

Petlja i kontroliše red u kome je element niza Z; petlja j kontroliše kolonu. Pošto se rezultujući element računa kao suma,

postavlja se početna vrijednost – netralni element za sabiranje. Zatim se množe elementi i-tog reda prve matrice sa elementima

i-te kolone druge matrice. Ima ih K, pa brojač l uzima vrijednosti od 1 do K.

Page 13: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

13

Transponovana matrica

Transponovana matrica matrice A je matrica AT kod koje su kolone i redovi zamijenili mjesta.

Dakle, ako je A dimenzija nxm, tada je AT tipa mxn. Na primjer,

Primjer 5

Učitati matricu, a zatim ispisati transponovanu matricu.

Element transponovane matrice sa indeksom i,j dobiva vrijednost

elementa sa indeksom j,i polazne matrice.

Page 14: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

14

Primjer 6

Učitati kvadratnu matricu i ispisati elemente na glavnoj i elemente na sporednoj dijagonali.

Kvadratna matrica ima jednak broj redova i kolona, te oba

brojača imaju isti opseg.

Za elemente na glavnoj dijagonali vrijedi i=j, tj. na glavnoj

dijagonali su oni elementi koji imaju isti indeks reda i kolone.

Sporedna dijagonala sadrži elemente kod kojih je indeks

kolone određen kao N-i-1

Primjer 7

Napisati program koji formira kvadratnu matricu formata nmax =20 čiji elementi su *. Npr. za n=5, matrica

izgleda ovako:

* * * * * * * * * * * * * * * * * * * * * * * * * Ispisati kreiranu matricu. Zatim formirati i ispisatimatrice kako slijedi

GD1

* * * * * * * * * * * * * * * GD2

* * * * * * * * * * * * * * *

Page 15: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

15

SD1

* * * * * * * * * * * * * * *

SD2

* * * * * * * * * * * * * * *

Kreiranje matrice realizuje se u okviru slijedećeg koda:

Posmatrajmo indekse elemenata matrice formata 5x5

a00 a01 a02 a03 a04

a10 a11 a12 a13 a14

a20 a21 a22 a23 a24

a30 a31 a32 a33 a34

a40 a41 a42 a43 a44

Možemo uočiti ovisnost između indeksa elemenata kako slijedi:

GD1: ai,j =

a00 a01 a02 a03 a04

a10 a11 a12 a13 a14

a20 a21 a22 a23 a24

a30 a31 a32 a33 a34

a40 a41 a42 a43 a44

Page 16: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

16

GD2: ai,j =

SD1: ai,j =

SD2: ai,j =

Primjer 8

Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te naći i ispisati koordinate (red i kolona) prve i zadnje pojave najmanjeg, odnosno najvećeg elementa matice.

Pretpostavimo da je učitana matrica kao na slici. Tada bi očekivani rezultati bili:

U ovoj matrici najmanji element je 0. Prva pojava ovog elementa je u redu 2 i koloni 1. Zadnja pojava je u redu 5 i koloni 4.

Najveći element je 8. Prva pojava ovog elementa je u redu 4 i koloni 5. Zadnja pojava je u redu 5 i koloni 5.

Rješenje

Obilježimo promjenljive kako slijedi:

a00 a01 a02 a03 a04

a10 a11 a12 a13 a14

a20 a21 a22 a23 a24

a30 a31 a32 a33 a34

a40 a41 a42 a43 a44

a00 a01 a02 a03 a04

a10 a11 a12 a13 a14

a20 a21 a22 a23 a24

a30 a31 a32 a33 a34

a40 a41 a42 a43 a44

a00 a01 a02 a03 a04

a10 a11 a12 a13 a14

a20 a21 a22 a23 a24

a30 a31 a32 a33 a34

a40 a41 a42 a43 a44

1 5 2 1 5

0 2 4 6 4

1 2 5 6 2

1 2 0 7 8

7 8 7 0 8

Page 17: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

17

mini – najmanji element

minip_i – indeks reda prve pojave najmanjeg elementa

minip_j – indeks kolone prve pojave najmanjeg elementa

miniz_i – indeks reda zadnje pojave najmanjeg elementa

miniz_j – indeks kolone zadnje pojave najmanjeg elementa

maxi – najveći element

maxip_i – indeks reda prve pojave najvećeg elementa

maxip_j – indeks kolone prve pojave najvećeg elementa

maxiz_i – indeks reda zadnje pojave najvećeg elementa

maxiz_j – indeks kolone zadnje pojave najvećeg elementa

Najprije pronađemo najveći i najmanji element matrice:

Zatim, pronađimo tražene indekse:

Page 18: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

18

Primjer 9

Učitati kvadratnu matricu (elementi matrice su cijeli brojevi, maximalan broj redova i kolona je 10).

Formirati novu matricu kod koje su u svakom redu elementi polazne matrice poredani u rastućem

redoslijedu. Ispisati obje matrice.

Npr. ako je učitana matrica x, onda matrica y treba da bude kao na slici.

x y

Rješenje

Za svaki red ulazne matrice (kontrolisan indeksom i) uradimo slijedeće:

- Prepišemo i.ti red ulazne umatrice x u i.ti red matrice y

- Sortiramo i.ti red. Za svaki element kolone (j) postavljamo najmanji element na poziciju j.

Koristimo algoritam za sortiranje niza „Bubble sort“. Treća petlja omogučava pristup elementima

j+1..n-1, s ciljem nalaženja najmanjeg elementa reda i i kolone j.

Primjer 10

Korisnik učitava n cijelih brojeva tipa long (n max =10). Prebrojati koliko puta se među učitanim

brojevima pojavljuju cifre Dekadnog brojnog sistema.

Npr. korisnik učitava 4 broja, kako slijedi:

1 5 2 1 5

0 2 4 6 4

1 2 5 6 2

1 2 0 7 8

7 8 7 0 8

1 1 2 5 5

0 2 4 4 6

1 2 2 5 6

0 1 2 7 8

0 7 7 8 8

Page 19: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

19

123123 3455 2232 98744 Program treba da ispiše: Cifra 0 pojavljuje se 0 puta. Cifra 1 pojavljuje se 2 puta. ... Cifra 9 pojavljuje se 1 puta. Rješenje:

U programu ćemo korisiti bibilioteku „climits“, pomoću koje ćemo pročitati maksimalnu vrijednost koja

se može upisati za „long“ tip podataka.

Konstanta LONG_MAX prikazuje maksimalnu vrijednost za tip long na datom sistemu i korištenom

kompajleru.

Cilj je od ucitanih brojeva formirati dvodimenzionalnu matricu čiji elementi će biti cifre učitanih brojeva.

Nakon učitavanja broja, pomoću operatora div i mode izdvajamo cifre broja i formiramo matricu cifara u

slijedećem kodu:

U prvu kolonu svakog reda upišemo koliko broj ima cifara (x[i][0]=j-1). Promjenljivu m koristimo da

bismo zapamtili maksimalan broj cifara.

Ako su ucitani brojevi

Page 20: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

20

123123 3455 2232 98744 Ovaj kod bi u memoriju upisao:

6 3 2 1 3 2 1

4 5 5 4 3

4 2 3 2 2

5 4 4 7 8 9

U prvoj koloni je broj cifara, a u ostalim su cifre ispisane u obrnutom poretku. Neki od elemenata niza

ostaju nedefinisani, tj. Imaju vrijednosti koje su prethodno bile dodjeljene lokacijama rezervisanim pri

deklaraciji niza. Stoga ćemo ih definisati, tako što ćemo im dodijeliti vrijednost -1. To radi slijedeći kod:

Sada u memoriji imamo

6 3 2 1 3 2 1

4 5 5 4 3 -1 -1

4 2 3 2 2 -1 -1

5 4 4 7 8 9 -1

Ispišimo učitane brojeve sa vodećim prazninama, vodeći računa o tome da je dekadni brojni sistem

pozicioni brojni sistem:

Brojeve ispisujemo u poretku kako su učitani, pa je brojač i u rastućem redoslijedu (for (i=0;i<n;i++)), ali

brojač j postavljamo da se mijenja u opdajućem redoslijedu (j=m-1;j>0;j--), s tim što ne ispisujemo prvu

kolonu koja sadrži broj cifara. Ako je u matrici -1, ispisujemo razmak.

Konačno, koristimo jednodimenzionalni niz bc, kojeg naprije inicijalizujemo na 0. Zatim za svaku cifru iz

dvodimenzionalne matrice cifara uvečavamo odgovarajući element jednodimenzionalnog niza.

Page 21: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

21

Primjer 11

Napisati program koji učitava kvadratnu matricu sa maksimalno 10x10 cijelih brojeva, a zatim ispisuje

sve sub matrice reda n-1xn-1. Npr. neka imamo matricu formata 3x3

A00 A01 A02

A10 A11 A12

A20 A21 A22

Treba ispisati matrice

A11 A12

A21 A22

A10 A12

A20 A22

A10 A11

A20 A21

Page 22: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

22

A01 A02

A21 A22

A00 A02

A20 A22

A00 A01

A20 A21

A01 A02

A11 A12

A00 A02

A10 A12

A00 A01

A10 A11

Za formiranje submatrica koristimo kod:

//formiranje sub matrica

for (r=0;r<n;r++)

for (k=0; k<n; k++)

{

cout << endl<<"Sub matrica ("<<r <<","<<k<<") "<<endl;

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

{

for (j=0;j<n; j++)

if ((i!=r) && (j!=k))

cout <<setw(6)<<x[i][j];

cout <<endl;

}

}

Page 23: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

23

ZADACI ZA VJEŽBU

1. Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te naći sumu (proizvod) svakog reda (stupca) matrice.

2. Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te naći sumu (proizvod) svakog reda matrice i ispisati red koji ima najveću (najmanju) sumu (proizvod).

3. Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te naći i ispisati najmanji (najveći) element matice.

4. Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te naći i ispisati u kojem koloni/redu se nalazi najmanji (najveći) element drugog reda/stupca matice.

5. Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te naći i ispisati koliko elemenata matrice je veće (manje) od prosjeka.

6. Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te učitati koordinate (r,s) nekog njenog elementa i ispisati koliko puta se taj element javlja u matrici. Također treba ispisati koliko elemenata matrice je veće (manje) od tog elementa.

7. Napiši program koji će učitati matricu dimenzija nxm (n,m ≤ 10), ispisati ju u obliku tabele te naći i ispisati najmanji (najveći) maksimum (minimum) redova matice. (Naći max svakog reda i onda min od tih brojeva. Analogno za najveći minimum)

8. Napiši program koji će učitati matricu reda n (n ≤ 10), ispisati ju u obliku tabele te naći i ispisati trag matrice. (Suma elemenata glavne dijagonale je trag matrice).

9. Napiši program koji će učitati matricu reda n (n ≤ 10), ispisati ju u obliku tabele te naći i ispisati sumu (proizvod) elemenata sporedne dijagonale.

10. Napiši program koji će učitati matricu reda n (n ≤ 10), ispisati ju u obliku tabele te naći i ispisati najveći (najmanji) element glavne (sporedne) dijagonale.

11. Napiši program koji će učitati matricu reda n (n ≤ 10), ispisati ju u obliku tabele te naći i ispisati najveći (najmanji) element ispod (iznad) glavne dijagonale.

12. Napiši program koji će učitati matricu reda n (n ≤ 10), ispisati ju u obliku tabele te naći i ispisati sumu (proizvod) element ispod (iznad) glavne dijagonale.

13. Napiši program koji će učitati matricu reda n (n ≤ 10), ispisati ju u obliku tabele te provjeriti i ispisati je li ona simetrična (ai,j=aj,i) / antisimetrična (ai,j=-aj,i)

14. Napiši program koji će učitati matricu reda n (n ≤ 10), ispisati ju u obliku tabele te provjeriti i ispisati je li ona gornja (svi elementi ispod glavne dijagonale su 0) / donja (svi elementi iznad glavne dijagonale su 0) trokutasta matrica.

15. Napiši program koji će učitati 2 matrice reda n (n ≤ 10), te naći njihovu sumu i proizvod. Novodobivenu matricu treba ispisati u obliku tabele.

16. Napiši program koji će učitati matricu A reda n (n ≤ 10), a zatim formirati drugu matricu B tako da je bi,j = proizvodu suma i-tog reda i j-tog stupca

17. Napisati program koji računa:

A) Sumu elemenata ispod glavne dijagonale, ne računajući elemente na glavnoj dijagonali

B) Sumu elemenata iznad glavne dijagonale, ne računajući elemente na glavnoj dijagonali

Page 24: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

24

C) Sumu elemenata ispod sporedne dijagonale, ne računajući elemente na glavnoj dijagonali

D) Sumu elemenata iznad sporedne dijagonale, ne računajući elemente na glavnoj dijagonali

18. Napiši program koji će učitati matricu reda n (n ≤ 10), ispisati ju u obliku tabele te provjeriti i ispisati je li ona simetrična / antisimetrična.

Matrica je simetrična ako važi, za svako i i j da je ai,j=aj,i.

Matrica je antsimetrična ako važi, za svako i i j da je ai,j=-aj,i.

Page 25: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

25

Modul 2:

Primjena struktura podataka i pointera

Povezane liste

Verzija Datum Autor Napomena

1.0 01.10.2010. skr Draft

1.1 16.10.2010. Skr Modifikacije Povezane liste

1.2 04.12.2011. Skr Modifikacije pointer + niz

1.3 28.01.2012 Skr Povezane liste, pocetni primjer

Page 26: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

26

Složeni tipovi i strukture podataka

Do sada smo koristili samo ugrađene, proste tipove podataka (int, float, char...). Svaka promjenljiva koju

smo koristili mogla je imati samo jednu vrijednost određenog tipa. U slučaju niza, svaki element niza

mogao je imati samo jednu vrijednost određenog prostog tipa podataka.

U praksi, često je potrebno obrađivati podatke čije svođenje na proste tipove podataka rješavanje

problema znatno komplikuje. U takvim situacijama, možemo sami kreirati složene, korisničke tipove

podataka.

Promjenljive koje prilikom deklaracije povezujemo sa ugrađenim ili korisničkim tipovima podataka imaju

određena ograničenja, naročito kada je u pitanju rad sa funkcijama i nizovima promjenljivih dimenzija.

U ovom modulu upoznaćemo napredne strukture podataka, a to su strukture, pokazivači, reference i

vezane liste.

Strukture

Često se javlja potreba za objedinjavanjem različitih tipova podataka u jednu cjelinu, kao što su npr.

podaci o jednom učeniku (ime, prezime, pol, razred...). U ovakvim situacijama prikladno je korištenje

složenog tipa podataka kojeg nazivamo struktura (slog ili zapis – record).

Struktura je skup jedne ili više promjenljivih koje su povezane, odnosno grupisane, zajedničkim imenom.

Razlikujemo jednostavne i složene strukture. Struktura može sadržavati bilo koji prosti tip podatka u

C++, niz, ili ugniježdene strukture (struktura u strukturi).

Definicija strukture U opštem slučaju, struktura se definiše na slijedeći način:

struct ime_strukture

{

tip_člana_1 naziv_člana_1;

tip_člana_2 naziv_člana_2;

...

tip_člana_n naziv_člana_n;

};

gdje je

struct ključna riječ koja označava početak definisanja strukture,

ime_strukture naziv strukture,

unutar vitičastih zagrada navodimo sve članove (elemente) koje želimo kreirati strukturom, tako

što navodimo tip a zatim naziv člana

Page 27: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

27

Definicija strukture može se navesti bilo gdje u programu, ali je obično izvan funkcije main, što je čini

dostupnom svugdje unutar programa.

Npr. slijedećim kodom definišemo strukturu učenik, koja ima tri elementa: prezime i ime tipa string i broj

tipa int.

struct Ucenik

{

string prezime;

string ime;

int broj;

};

Deklaracija promjenljive tipa struktura Ako želimo koristiti promjenljivu tipa struktura, deklarišemo je na potpuno isti način kao i kada se

koristimo standardnim tipovima podataka. To znači, navedemo naziv strukture a zatim ime promjenljive.

Primjer deklaracije

Ucenik osoba;

Na ovaj način deklarisali smo promjenljivu osoba koja je tipa strukture Ucenik.

Pristup članovima strukture Članovima strukture pristupamo navođenjem imena promjenljive tipa struktura, tačke i imena člana

Npr. Ako želimo ucitati prezime osobe, navodimo:

cin >> osoba.prezime;

Primjer 1

Napisati program koji definiše strukturu Ucenik, a zatim deklariše promjenljivu osoba. Učitati i ispisati

podatke o jednoj osobi.

Page 28: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

28

Zadatak za vježbu 1

Definisati strukturu pravougaonik, koja kao članice ima slijedeće realne podatke: a i b (stranice

pravougaonika), P (površina pravougaonika) i O (obim pravougaonika). Napraviti funkcije za računanje

površine (Povrs) i obima (Obim) pravougaonika ako im se kao argumenti proslijede stranice

pravougaonika. U glavnom programu učitati elemente strukture a i b, zatim pozvati odgovarajuće

funkcije za računanje članica strukture P i O. Ispisati sve vrijednosti članica strukture.

Primjer 2

Definišite strukturu „Vrijeme“ koja sadrži tri člana: sati, minute i sekunde i koja predstavlja tekuće

vrijeme u toku dana, izraženo u satima, minutama i sekundama. Definišite funkciju UcitajVrijeme, koja

učitava sate, minute i sekunde u strukturu Vrijeme. Zatim definišite funkciju IspisiVrijeme koja ispisuje

vrijeme, proslijeđeno kao parametar u funkciju, u obliku hh:mm:ss (tj. sati, minute i sekunde se ispisuju

kao dvocifreni brojevi sa, eventualno, vodećim nulama. Zatim definisati funkciju „SaberiVrijeme“ koja

prima dva vremena koja su proslijeđena kao parametri i vraća treće vrijeme koje nastaje sabiranjem dva

ulazna vremena (npr. sabiranjem 3h 34min 52sec i 4h 42min i 20sec treba da se dobije vrijeme 8h 17

min 12 sec).

Napraviti testni program koji testira sve funkcije

Rješenje

Najprije definišemo strukturu i sve funkcije.

Page 29: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

29

Funkcija UcitajVrijeme provjerava unos vrijednosti i vraća strukturu Vrijeme. Funkcija IspisiVrijeme ne

vraća nikakvu vrijednost:

U funkciji main testiramo ove dvije funkcije:

Page 30: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

30

Startovanjem programa dobijemo:

Funkcija SaberiVrijeme koristi cjelobrojno dijeljenje i operator modul za računanje sabranih sekundi,

minuta i sekundi, kako slijedi:

Za testiranje koristimo kod:

Zadaci za vježbu: 1. Ispraviti funkciju SaberiVrijeme iz prethodnog zadatka tako da vrši provjeru zbira sati kako bi

umjesto ispisa „25 sati“ ispisala vrijeme „01 sati“.

2. Napisati programi koji izračunava udaljenost između dvije tačke određene koordinatama x i y. U

programu koristiti strukturu tačka, koja sadrži članice x i y, a koje predstavljaju koordinate tačke

u ravni. Za unos koordinata tačke napraviti funkciju učitajTačku a za ispis funkciju ispisiTacku.

Napraviti i funkciju „udaljenost“ za računanje udaljenosti između dvije tačke u ravni.

Page 31: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

31

3. Napisati program koji izvšava osnovne operacije (+,- * i /) nad kompleksnim brojevima. Koristiti

strukturu kompleksan_broj koja ima dva člana: realni_dio i imaginarni_dio. Napraviti funkcije za

unos i ispis kompleksnog broja. Za svaku operaciju napisati funkciju, te je pozvati u glavnom

programu.

Uputstvo:

Neka su z1=x1+iy1 i z2=x2+iy2 dva kompleksna broja. Računske operacije su definisane na sljedeći

način:

Struktura i niz Promjenljive tipa niz također mogu kao elemente imati strukturu podataka. Npr, ako u programu treba

obrađivati podatke o više učenika, deklarišemo niz kao

Ucenik ucenici[30];

Elementima niza/ strukture pristupamo ovako:

Ucenici [i].prezime

Primjer 3

Definisati strukturu učenik, sa članovima prezime, ime i prosjek. Napraviti program koji učitava podatke

o N ucenika a zatim ispisuje ime, prezime i prosjek svakog učenika, a zatim učenika sa najvećim

prosjekom.

Rješenje

Definisanje strukture ucenik i promjenljive razred, koja je niz promjenljivih tipa učenik

Page 32: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

32

Struktura kao član strukture Definicja strukture može sadržati član koji je tipa struktura. Npr. definišimo strukturu datum

struct datum

{

int dan;

Page 33: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

33

int mjesec;

int godina;

};

Zatim definišimo strukturu čija članica je tipa datum:

struct ucenik

{

char ime[15];

char prezime[15];

int maticni;

float prosjek;

struct datum rodjendan;

}

Ako je član strukture također struktura, za pristup članicama strukture koristimo tačku da odvojimo

naziv promjenljive i ime člana, sve do posljenjeg člana složene strukture. Npr.

cout<<"Datum rodjenja, dan: ";

cin>>razred[i].rodjendan.dan;

cout<<" Datum rodjenja, mjesec: ";

cin>>razred[i].rodjendan.mjesec;

cout<<" Datum rodjenja, godina: ";

cin>>razred[i].rodjendan.godina;

Zadaci za vježbu: 1. Modifikovati primjer 3, tako što se, uz ostalo, za učenika učitava i datum rođenja. Također, kod

ispisa najboljeg učenika ispisati i datum rođenja.

2. Modifikovati primjer 3, tako da uzima u obzir mogućnost da više učenika ima isti prosjek. Ispisati

sve učenike čiji prosjek je jednak maksimalnom.

3. Modifikovati primjer 3, tako što dodajemo funkcije za sortiranje učenika po rednom broju,

prosjeku i prezimenu.

4. Napraviti strukturu tacka čije članice su koordinate x i y. Zatim definisati strukturu tougao, čije

članice su tri tačke koje predstavljaju tjemena trougla, kao i članice površina i obim trougla.

Napraviti funkcije za:

- Unos tjemena trogula

- Računanje udaljenosti između dvije tačke

- Računanje obima trougla

- Računanje površine trougla

U glavnom programu korisnik učitava podatke o n trouglova, a zatim ispisati podatke o trouglu

čija površina je najveća.

Page 34: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

34

Pokazivači (pointers)

Statičke i dinamičke promjenljive Do sada smo koristili statičke promjenljive. Npr. U naredbama koje slijede, određujemo da se u toku

prevođenja programa rezerviše memorijska lokacija za smještaj cjelobrojnog podatka sa simboličkim

imenom a, a zatim toj promjenljivoj dodjeljujemo vrijednost 10. a je statička promjenljiva

int a;

a=10;

Statička promjenljiva predstavlja imenovani prostor koji sadrži vrijednost. Memorijska lokacija na kojoj je

ta promjenljiva ostaje zauzeta svo vrijeme trajanja programa.

Za razliku od statičke, pokazivač je promjenljiva koja pokazuje na drugu promjenljivu. Pokazivač sadrži

memorijsku adresu na kojoj se nalazi vrijednost. Taj memorijski sadržaj na koji pokazuje pokazivač

predstavlja dinamičku promjenljivu.

Pokazivači Pokazivač je promjenljiva koja čuva memorijsku adresu.

Memorija računara je podijeljena na sekvencijalno označene memorijske lokacije. Svaka lokacija ima

adresu. Adresa lokacije može se čuvati u pokazivaču.

Kocka simbolički označava memorijsku lokaciju u kojoj se čuva objekat. “objekat” je

promjenljiva. Njena trenutna vrijednost je 6.

Promjenljiva koja sadrži adresu memorijske lokacije u kojoj se čuva objekat prikazana je strelicom kao na

slici (objekat_ptr). Promjenljiva objekat_ptr je pokazivač. Pokazivač sadrži adresu promjenljive.

Pokazivač „pokazuje“ na promjenljivu. Nazivamo ga i adresnom promjenljivom, jer sadrži adresu druge

promjenljive.

Deklaracija pokazivača Pokazivač deklarišemo navođenjem tipa promjenljive na koju će pokazivati i znaka asterisk (*) ispred

imena koje dodijelimo pokazivačkoj promjenljivoj. Npr.

int objekat; // objekat je promjenljiva tipa int

int *objekat_ptr; // *objekat_ptr je pokazivač na promjenljvu tipa integer

Operatori Operatori koji se koriste sa pokazivačima dati su u tabeli:

Operator Značenje

Page 35: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

35

* Dereferenciranje - Vraća vrijednost promjenljive koja je na lokaciji na koju pokazuje

pokazivač

& Referenciranje - Vraća adresu lokacije na kojoj je promjenljiva čije ime se navodi nakon

operatora

Slijede primjeri korištenja operatora.

int objekat =5;

int *objekat_ptr;

objekat_ptr = &objekat;

„objekat“ je promjenljiva koja ima vrijednost 5. „objekat_ptr“ je pokazivač na lokaciju na kojoj je cjelobrojna promjenljiva. Pokazivaču objekat_ptr dodjeljuje se adresa na kojoj je promjenljiva objekat.

drugi_objekat = *objekat_ptr;

Promjenljiva drugi_objekat dobiva vrijednost koja se čuva na adresi koja je u pokazivaču objekat_ptr. *objekat_ptr = 6;

U promjenljivu čija je adresa u pokazivaču objekat_ptr smješta se vrijednost 6. Objekat_ptr sadrži adresu promjenljive objekat, te promjenljiva objekat poprima vrijednost 6.

Primjetimo da se operator * može imati različite funkcije:

u deklaraciji pokazivača int int *x_ptr;

kao operator dereferenciranja y = *x_ptr;

kao operator množenja z =x*z;

Primjer 1

U slijedećem primjeru ilustrujemo korištenje pokazivača i operatora * i &. Deklarišemo statičku

promjenljivu Godina i pokazivač pGodina, a zatim dodjeljujemo adrese, vrijednosti sa adresa i

vrijednosti.

Page 36: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

36

Važno je istaknuti da postoji bitna razlika između deklaracije statičke promjenljive i deklaracije pointera.

Kada deklarišemo pointer, ne dovodimo ga u vezu ni sa jednom memorijskom lokacijom. Ako to želimo

uraditi, koristi se službena riječ new.

Ako deklarišemo pokazivač zadajemo naredbu:

int *a;

Ovom naredbom samo deklarišemo pokazivač, ali ne i lokaciju na koju on pokazuje. Pokazivač ne sadrži

nikakvu vrijednost.

Slijedećom naredbom rezervišemo memorijsku lokaciju u koju se može smjestiti cio broj a njenu adresu

dodjeljujemo pointeru. Kažemo, alociramo memoriju za pointer.

a=new int;

Ove dvije naredbe možemo objediniti naredbom:

int *a = new int;

I do sada smo statičke promjenljive istom naredbom deklarisali (najavljivali njihovo korištenje) i

inicijalizovali (dodjelivali početnu vrijednost promjenljivoj). Analogno tome, možemo reći da pointere u

jednoj naredbi deklarišemo i inicijalizujemo, pomoću new(). Dodatno, rezervišemo i memorijsku lokaciju

za promjenljivu čija adresa se smjesti u pokazivač.

U dosadšnjim primjerima, pointeru smo dodjeljivali vrijednost pomoću operatora referenciranja (&), uz

prethodnu deklaraciju statičke promjenljive. Korištenjem new izbjegavamo korištenje statičkih

promjenljivih.

Slijedi primjer koji ilustruje alokaciju memorije za pointer.

Page 37: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

37

Ovaj kod možemo predstaviti grafički kako slijedi:

Page 38: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

38

Pokušajmo napraviti analogiju između pokazivača i

daljinskog upravljača za neki uređaj. Daljinski uređaj

sam za sebe nema upotrebnu vrijednost ako nema i

uređaja kojim ćemo upravljati. Ako uređaj nema svoje

vlastite komande, onda ga je on neupotrebljiv ako

nemamo daljinski uređaj.

Ako je pokazivač daljinski za tv uređaj, onda naredbom

int *p;

samo „obezbjeđujemo“ daljinski. Slijedećom naredbom „obezbjeđujemo“ tv i dovodimo „ga u vezu“ sa

daljinskim:

p = new int;

Obje radnje obezbjeđujemo slijdećom naredbom:

Int *p = new int;

Ovom naredbom daljinski i tv postaju upotrebljivi!

Zadaci za vježbu Testirajte slijedeći kod i ispravite grešku

Page 39: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

39

Ma kako komplikovano izgledalo, pravila za rad sa pokazivačima se svode na slijedeća prosta pravila:

1. Pointeri čuvaju adrese promjenljivih. Promjenljive čuvaju podatke.

2. Do vrijednosti promjenljive na koju pokazuje pointer dolazimo pomoću operatora

dereferenciranje (*). Dereferenciranje se može izvršiti samo ako je prethodno u pointer

smještena adresa memorijske lokacije. Većina bug-ova sa pointerima posljedica je nepoštivanja

ovog pravila.

3. Samom deklaracijom pointera ne dovodimo ga u vezu sa promjenljivom. To možemo uraditi

pomoću new. Na ovaj način, inicijalizujemo pointer.

4. Operatorom dodjele vrijednosti između dva pointera postižemo da oni pokazuju na istu

memorijsku lokaciju (istu promenljivu).

Pitanja za ponavljanje

1. Koji operator se koristi za određivanje adrese promjenljive?

2. Koji operator se koristi za nalaženje vrijednosti na adresi koja se čuva u pokazivaču?

3. Šta je pokazivač?

4. Koja je razlika između adrese koju čuva pokazivač i vrijednosti na toj adresi?

5. Koja je razlika izmedu operatora referencijranja i dereferenciranja?

6. Šta rade ove deklaracije?

a. int *pOne;

b. int vTwo;

c. int *pThree = &vTwo;

7. Ako imate unsigned short promjeljivu yourAge, kako biste deklarisali pokazivač za manipulisanje

Page 40: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

40

promjenljivom yourAge?

8. Dodjelite vrijednost 50 promjenljivoj yourAge, korištenjem pokazivača, koji je deklarisan u

pitanju 7.

9. Napišite mali program koji deklariše cjelobrojnu vrijednost i pokazivač na cjelobrojnu vrijednost.

Dodjelite pokazivaču adresu cjelobrojne vrijednosti. Upotrijebite pokazivač za postavljanje

vrijednosti u cjelobrojnoj promjenljivoj.

10. Šta nije u redu sa ovim kodom:

int main()

{ int *pInt;

*pInt = 9;

cout << “Vrijednost na pInt je “<< *pInt;

return 0; }

11. Šta nije u redu sa ovim kodom:

int main()

{

int someVariable = 5;

cout <<“Some variable: “<<someVariable<<endl;

int *pVar =&someVariable;

pVar = 9;

cout << “someVariable: “<<*pVar << endl;

return 0;

}

Page 41: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

41

Reference

Referenca je alijas – alternativno ime drugog objekta. Kada kreirate referncu, inicjalizujete je imenom drugog objekta – mete. Od tog momenta, referenca se ponaša kao drugo ime tog objekta, te sve što radimo referenci uistinu radimo meti.

Referencu kreiramo navođenjem tipa ciljanog objekta, praćeno operatorom &, poslije čega slijedi ime reference. Npr. ako imamo cjelobrojnu promjenljivu someInt, referencu na tu promjenljivu pravimo naredbom:

int &rSomeRef = someInt;

Ovo se čita kao: “rSomeRef je referenca na cjelobrojnu vrijednost koja je inicijalizovana da pokazuje na

cjelobrojnu promjenljivu someInt“.

Pogledajmo slijedeće naredbe deklaracije:

int Godina;

int &rGodina = Godina;

Šta bi bio efekat ovih naredbi?

Godina = 2000;

cout << Godina;

cout << rGodina;

Na ekranu bi bila ispisana ista vrijednost!

Page 42: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

42

Područje primjene pokazivača i referenci

Prilikom korištenja funkcija, uočili smo da funkcije imaju dva ograničenja:

1. Argumenti se funkciji predaju po vrijednosti

2. Funkcija može vratiti samo jednu vrijednost

Zašto su to ograničenja?

Argumenti koji se predaju funkciji su lokalni za tu funkciju. Promjene koje se dešavaju nad tim

argumentima u funkciji ustvari ne mijenjaju originalne argumente u funkcije iz koje je pozvana. Ovo je

poznato kao predavanje po vrijednosti, što znaci da se u funkciji pravi lokalna kopija svakog argument.

Korištenjem pokazivača i referenci oba ova ograničenja mogu se prevazići. Korištenjem pokazivača i

referenci, funkcija neće kreirati kopiju objekta već će promjene vršiti nad orginalnim objektom.

U narednom primjeru funkciji Zamjena argumente predajemo po vrijednosti. To znači da de se pozivom

funkcije napraviti lokalne kopije. Funkcija mijenja lokalne kopije, a ne promjenljive iz pozivajuće funkcije.

Page 43: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

43

Pošto funkcija radi sa kopijama proslijeđenih vrijednost, nakon povratka u funkciju main, vrijednosti x i y

su nepromijenjene.

Ukoliko funkciji proslijedimo adrese promjenljivih tj. pokazivače na promjenljive, onda će funkcija

manipulisati vrijednostima na toj adresi. Ovo rješenje zahtijeva određene izmjene u samoj funkciji,

obratite pažnju. Pošto se funkciji prosljeđuju adrese promjenljivih, dereferenciranjem dolazimo do

njihovih vrijednosti.

Nakon povratka u funkciju main vrijednosti x i y su zamijenjene.

Ipak, ovo rješenje ima odredene nedostatke. Potreba za dereferenciranjem pokazivača čini ga teškim za

čitanje i podložnim greškama. Ovo bismo mogli uraditi i pomoću referenci, kao u listingu koji slijedi:

Page 44: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

44

Parametri funkcije deklarisani su kao reference, te se stoga mijenjaju i u funkciji main. Pozivajuća

funkcija “razlikuje” da li se parametar predaje po referenci ili po vrijednosti na osnovu prototipa

funkcije.

Prosljeđivanjem parametara kao pokazivača ili referenci rješavamo oba problema:

- funkcija mijenja promjenljive u onoj iz koje je pozvana, umjesto da radi sa lokanim kopijama

tih promjenljivih.

- Istovremeno, rješen je i drugi problem, jer sada funkcija može indirektno, preko

promjenjivih, vratiti više vrijednosti. Npr. U prethodnom primjeru izmjenjene su dvije

vrijednosti, x i y, što se može tumačiti kao vraćanje dvije vrijednosti.

Potvrdimo prethodno i slijedećim primjerom. Program sadrži funkciju koja izračunava kvadrat i kub

zadatog broja.

Prototip funkcije je

int Faktor (int n, int *kvadrat, int *kub);

Dakle, argumetni funkcije su:

n – cjelobrojna promjenljiva,

*kvadrat – pokazivac na cjelobrojnu promjenljivu i

Page 45: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

45

*kub – pokazivac na cjelobrojnu promjenljivu.

U pozivu funkcije imamo:

greska = Faktor(x, &x2, &x3);

Dakle, proslijeđujemo promjenljivu x i adrese promjenljivih x2 i x3.

Implementacija funkcije je data slijedećim kodom:

Posmatrajmo naredbe:

*kvadrat = n*n; //na adresu koju cuva pokazivac *kvadrat upisujemo kvadrat vrijednosti u promjenljivoj x

*kub = n*n*n; //na adresu koju cuva pokazivac *kub upisujemo kub vrijednosti u promjenljivoj x

Na ovaj način funkcija mijenja dvije vrijednosti koje su dostupne u funkciji iz koje je pozvana. Stoga,

korištenjem pokazivača možemo prevazići problem vraćanja jedne vrijenosti u okviru naredbe return.

5.1 Vježbe 1. Deklarisati funkciju Hex, koja uzima promjenljivu p kao parameter a vraća 8 znakova (heksadecimalni

broj) koji predstavlja sadržaj pokazivača, tj adresu koju on čuva.

void Hex(void* p)

{

cout << hex << setfill('0') << setw(8) << (long) p << ends;

return;

}

Deklarišite cjelobrojne promjenljive x i y, kao i int* pokazivače p i q. Promjenljivoj x dodijelite 2,

promjenljivoj y dodijelite 8, p adresu od x i q adresu od y. Zatim ispišite slijedeće informacije:

Adresu od x i vrijednost x.

Vrijednost p i vrijednost *p.

Adresu od y i vrijednost y.

Vrijednost q i vrijednost *q.

Adresu od p (ne sadržaj!)

Page 46: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

46

Adresu od q (ne sadržaj!)

Koristite Hex funkciju da biste ispisali vrijednost u pokazivaču.

2. Deklarišite cjelobrojne promjenljive x, y, z kao i int* pokazivače p, q, r. Postavite u x, y, z tri različite

vrijednosti. Postavite u p, q, r adrese promjenljivih x, y, z, respektivno.

Ispišite vrijednosti x, y, z, p, q, r, *p, *q, *r (svakoj vrijednosti prethodi komentar).

Ispišite: “Zamjena vrijednosti”.

Izvršite kod zamjene: z = x; x = y; y = z;

Ispišite vrijednosti x, y, z, p, q, r, *p, *q, *r (svakoj vrijednosti prethodi komentar).

Nacrtajte na papiru šta se dešava sa promjenljivim

Page 47: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

47

Pokazivači i nizovi

Pokazivače možemo koristiti i za rad sa nizovima. Posmatrajmo primjer slijedećih deklaracija:

char array[10];

char *array_ptr = array;

Prvom naredbom deklarisali smo niz znakova sa maksimalno 10 elemenata. Drugom naredbom

deklarišemo pokazivač array_ptr i inicijalizujemo ga adresom prvog elementa niza. Zadnja naredba

mogla bi se napisati i na slijedeći način:

char *array_ptr = &array[0];

Sada elementima niza možemo pristupati pomoću pokazivača array_ptr: Npr. ovom naredbom

ispisujemo prvi element niza

cout << *array_ptr;

Drugi element niza ispisujemo naredbom

cout << *(array_ptr+1);

Slijedeće naredbe imaju isti efekat:

cout << *array_ptr; isto što i cout << array[0] ; cout << *(array_ptr + 1); isto što i cout << array[1] ;

cout << *(array_ptr + 2); isto što i cout << array[2] ;

Kada deklarišemo niz, za elemente niza rezervišemo susjedne lokacije. Ako pokazivaču dodjelimo adresu

prvog elementa niza, onda ostalim elementima možemo pristupati tako što ćemo manipulisati adresom

prvog elementa – dodavanjem (ili oduzimanjem) cjelobrojne vrijednosti. Izraz *(array_ptr + 2) znači

„uvečaj adresu prvog elemnta za 2“, a efekat je da pokazivač zapravo sadrži adresu trećeg elementa

niza.

Ovo možemo predstaviti grafički, kako slijedi:

Adresa na kojoj je prvi element niza je u pokazivaču array_ptr (0x5000). Trećem elementu niza može se

pristupiti pomoću pokazivača ako mu dodamo vrijednost 2 (array_ptr+2).

array_ptr

0x5000

0x5000

array_ptr+2

0x5002

0x5000

Page 48: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

48

Primjer 1: Napisati program koji učitava niz od N znakova. Zatim ispisati elemente niza korištenjem

pokazivača.

Za vježbu: Modifikovati prethodni zadatak tako da omogučava da se učita rečenica (dozvoliti unos

razmaka) tako da se izvršavanjem programa može dobiti rezultat kao u drugom primjeru.

Na prvi pogled, ovo izgleda kao komplikovaniji način korištenja jednostavnih nizova. Počet ćemo sa

jednostavnom aritmetikom sa pokazivačima. Poslije ćemo koristiti složenije pokazivače za efikasan rad

sa znatno komplikovanijim strukturama.

Slijedeći program vraća broj elemenata prije prve nule u nizu, inicijalizovanom pri deklaraciji. U nizu

mora biti barem jedna nula. Program se zaustavlja kada naiđe na prvu nulu.

Slijedi rješenje bez pointera.

Page 49: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

49

Zatim, rješenje pomoću pointera na elemente niza:

Primjer 2

Učitati liniju teksta koja sadrži prezime i ime u slijededoj formi:

Prezime/Ime

(Dakle, ime i prezime su odvojeni znakom “/”). Napisati program koji razdvaja ime i prezime.

Primjer (Izgled ekrana po startovanju programa):

Unesite prezime/ime: Krajinovic/Selma

Prezime: Krajinovic

Ime: Selma

U ovom programu koristit ćemo funkciju strchr. Funkcija vraća pokazivač na poziciju na kojoj se prvi

puta pojavljuje navedeni karakter. Karakter koji označava kraj stringa ¸\n¸ također može da se locira

pomoću ove funkcije.

Format funkcije: char * strchr ( char * str, int character );

Parametri

str je pokazivac na C string.

character je znak cija pozicija se traži. (proslijeđuje se integer vrijednost karaktera, koja se

interno konvertuje u znak)

Povratna vrijednost

Pokazivač na poziciju na kojoj se prvi puta pojavljuje karakter. Ako karakter nije pronađen,

funkcija vraća null pokazivač

Page 50: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

50

Za rješavanje problema iz zadatka, pomoću funkcije strchr naći ćemo poziciju karaktera “/”. Koristimo

dva pokazivača:

ime_ptr – pokazuje na karakter kojim počinje ime

prezime_ptr – pokazuje na karakter kojim poćinje prezime

Karakter “/” u ulaznom stringu zamijenit ćemo karakterom “\0”. Ova Esc sekvenca označava prelazak u

novi red, što ćemo iskoristiti da ulazni niz ispišemo u dva reda. Pogledajmo grafički prikaz:

Slijedi kod:

Page 51: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

51

Slijedi objašnjenje za pojedine linije koda

Primjer 3

Učitati prezime i ime u format: Prezime/ime. Ispisati inicijale . Izgled ekrana:

Primjer 4

Napisati program koji učitava riječ i karakter, a zatim funkciju koja ispituje koliko puta se u nekom

stringu pojavljuje neki karakter. U glavnom programu pozvati funkciju i ispisati rezultat.

Page 52: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

52

Zadaci za vježbu

1. U ulaznoj datoteci “podaci.xls” nalaze se podaci o učenicima:

• Prezime

• Ime

• Adresa

• Grad

• Poštanski broj

Podaci su razdvojeni znakom “;”. Ispisati tekst za naljepnicu na koverti u obliku:

Prezime i ime

Adresa

Grad i postanski broj

2. Napraviti funkciju za spajanje dva stringa u jedan string, drugi se dodaje na početak prvog. Testirati

fju.

Page 53: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

53

3. Napraviti funkciju za upoređivanje jednog znakovnog niza (stringa) s drugim, vratiti nulu ako su

jednaki, odnosno 1 ako nisu jednaki. Testirati fju.

4. Unesite tekst sa standardnog ulaza, a zatim odredite koliko ima suglasnika u zadanom tekstu.

5. Unesi tekst sa standardnog ulaza, a zatim unesi slovo čiju prvu pojavu u unešenom tekstu tražite. Ako

je slovo pronadeno ispišite njegov položaj u rijeci. Koristite pokazivače.

6. Unesite rečenicu sa standardnog ulaza, a zatim unesite riječ koju tražite u unešenom tekstu. Ako je

riječ pronađena ispišite njen položaj u rečenici. Koristite pokazivače.

Page 54: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

54

Povezane liste

Za pohranjivanje skupa podataka istoga tipa do sada smo koristili nizove. Neka imamo slijedeće

deklaracije:

struct ucenik

{ char ime[20]; // ime do 20 karaktera

int godine; // godine starosti

float visina; // u metrima

}

ucenik razred[30];

Prethodnim naredbama smo deklarisali strukturu ucenik i niz čiji su elementi tipa strukture ucenik.

Prilikom deklaracije niza moramo navesti maksimalan broj elemenata niza, što predstavlja veliko

ograničenje ove vrste podataka. Naime, ukoliko navedemo veliki broj elemenata, rizikujemo da će

program nepotrebno zauzeti veliki memorijski prostor. Ako navedemo mali broj elemenata, rizikujemo

da program neće zadovoljavati potrebe korisnika. Stoga, potreba dimenzionisanja niza gotovo uvijek

predstavlja problem, jer je nemoguće predvidjeti koliko elemenata niz uistinu ima kada se program

pokrene.

Kao rješenje ovog problema može se koristiti povezana lista. Međutim, svako rješenje ima i

odgovarajuće mane. Jedna od mana povezane liste jeste i to što imaju loše performance kada je u

pitanju slučajan pristup. Naime, povezana lista zahtijeva sekvencijalnu obradu, koja zahtijeva mnogo

vremena za čitanje željene, slučajno odabrane vrijednosti.

Šta je povezana lista? Povezana lista je složena struktura podataka koju čine čvorovi. Čvor, kao osnovni element povezane

liste baziran je na tipu podataka struktura, koja sadrži informacioni dio (za čuvanje podataka) i bar jedan

pointer. Povezanu listu čini lanac čvorova koje međusobno povezuju pointeri.

Postoje jednostruko i dvostruko povezane liste. Jednostruko povezana lista sadrži pokazivač na slijedeći

čvor, a dvostruko povezane sadrži dva pokazivača: jedan pokazuje na slijedeći a jedan na prethodni čvor.

Jednostruko povezanu listu možemo predstaviti ovako:

Info info info info info slijedeći NULL

Dvostruko povezana lista sadrži dva pokazivača u svakom čvoru:

Info info info info info Slijedeći NULL NULL prethodni

Page 55: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

55

Upoznat ćemo jednostruko povezanu listu. Na slici je primjer jednostruko povezane liste:

START

Ime: Edo

Godine: 34

Visina: 1.7

Ime: Damir

Godine: 27

Visina: 1.2

Ime: Davor

Godine: 48

Visina: 1.4

Ime: Marina

Godine: 30

Visina: 1.3

NULL

Povezana lista na slici sadrži 4 čvora, pri čemu svaki, osim poslednjeg, sadrži pokazivač na slijedeći čvor.

Poslednji čvor umjesto pokazivača na slijedeći čvor, sadrži vezu sa specijalnom vrijednošću NULL, što

označava kraj liste. Postoji još jedan specijalni pokazivač, Start, koji pokazuje na prvi čvor u lancu.

Kako bismo razumjeli šta je uistinu povezana lista, posmatrajmo jednostavan primjer. Učitat ćemo riječ,

a zatim znakove smjestiti u jednostruko povezanu listu, dodavajući slovo po slovo na kraj liste.

Za kreiranje ovakve liste definisat ćemo najprije strukturu podataka:

Prvi element, slovo, sadržat će „korisnu“ informaciju. U ovom primjeru, tu ćemo upisivati slova iz

učitane riječi. Drugi element, slijedeci, je pokazivač na slijedeći element liste. Zadnji čvor imat će

vrijednost NULL u elementu slijedeci.

Koristit ćemo slijedeće pokazivača na ovu strukturu:

- start_ptr, pokazivač na prvi čvor liste. U svakom trenutku, ovaj pokazivač sadržat će

adresu prvog elementa u listi. Na početku, kada je lista prazna, ovaj pokazivač sadrži

vrijednost NULL. Kasnije, kada dodamo prvi čvor u listu, ovdje sačuvamo adresu prvog

čvora. Ne smijemo izgubiti ovu vrijednost, ako se to ipak desi, izgubili smo cijelu listu!

- zadnji, pokazivač na zadnji čvor u listi. Kada dodajemo čvor u listu, koristimo pokazivač

zadnji kako bismo novi čvor uistinu povezali sa listom.

- novi, pokazivač na čvor kojeg dodajemo u listu. Kada dodajemo novi čvor, pomoću ovog

pokazivača alociramo prostor, upisujemo vrijednosti i konačno, povezujemo novi čvor sa

listom.

F

E B R U

A R NULL

Page 56: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

56

Učitat ćemo riječ u promjenljivu tipa string. Zatim ćemo, slovo po slovo, dodavati čvorove na kraj liste.

Sada ćemo od učitane riječi formirati jednostruko povezanu listu. Najprije ćemo postaviti start_ptr na

NULL vrijednost. Koristit ćemo promjenljivu i za pristup karakterima učitanog stringa, te petlju while u

okviru koje testiramo da li je kraj stringa.

Alociramo memorijske lokacije za novi čvor. U članicu

structure slovo upišemo znak. Pošto se čvor dodaje na

kraj liste, slijedeci postaje NULL (nema više čvorova u

listi).

Provjeravamo da li je ovo prvi čvor. Ako jeste, njegovu

adresu sačuvamo u pokazivaču start_ptr. Ako nije prvi

čvor, upisujemo u zadnji čvor adresu novog. Za tu radnju

koristimo pointer zadnji. Ovim zapravo dodajemo novi

čvor u postojeću listu.

Za čvor kojeg ćemo upisati u nastavku, ovo (novi) će biti

zadnji čvor.

Da bismo provjerili prethodni kod, napisaćemo kod za ispisivanje podataka iz liste.

Pokazivač zadnji pokazivat će na element liste

kojeg ispisujemo. Polazimo od prvog čvora,

čija adresa je u pokazivaču start_ptr. Sve dok

zadnji ne sadrži vrijednost NULL, ispisujemo

slovo i pomjeramo pokazivač zadnji na

slijedeći element liste.

Kada pokrenemo program, dobijemo:

Page 57: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

57

Zadaci za vježbu:

1. Napisati program koji u povezanu listu upisuje znakove iz učitane riječi u redoslijedu obrnutom u

odnosu na redoslijed učitavanja. Ispisati podatke iz liste. Za ispisivanje liste napraviti funkciju.

2. Napisati program koji učitava cio broj proizvoljnog broja cifara, a zatim cifre broja upisuje u

jednostruko povezanu listu. Ispisati broj iz liste.

Definisanje strukture podataka za povezanu listu Osnova povezane liste je struktura koja čuva podatke za svaki čvor liste (npr. ime, adresa, godine) kao i

pokazivač na slijedeći čvor u listi. Slijedi primjer tipične structure koja se koristi u povezanoj listi

struct cvor

{ char ime[20]; // ime do 20 karaktera

int godine; // godine starosti

float visina; // u metrima

cvor *slijedeci; // Pointer na slijedeći čvor

};

Važan dio ove structure je zadnja linija definicije structure. Ovdje definišemo članicu strukture

slijedeci koja je pointer tipa cvor, tj. strukture koju ovim definišemo. Ovo je jedini slučaj kada je

dozvoljeno da upućujemo na tip podataka kojeg još nisamo definisali (u ovom slučaju cvor).

Page 58: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

58

cvor *start_ptr;

Prethodnom naredbom deklarišemo pointer start_ptr koji će sadržati pokazivač na prvi čvor liste. Na

početku, kada je lista prazna, tj. nema čvorova, u ovaj pointer postavljamo NULL vrijednost.

Funkcija za kreiranje čvora liste

Za kreiranje novog čvora liste možemo koristiti funkciju koja alocira memorijski prostor, upisuje podatke

i vraća pokazivač na kreirani čvor. S obzirom da funkcija vraća pokazivač, deklarišemo je ovako

cvor *kreiraj_novi_cvor….

Ova funkcija mora vratiti pokazivač, što znači da mora imati naredbu return “pokazivač”.

Funkcija može imati argumente, npr. vrijednosti koje se upisuju u informacioni dio čvora. Slijedi jedan

primjer takve funkcije:

Poziv funkcije realizuje se u naredbi dodjele vrijednosti u kojoj je lijevo od znaka jednakosti pokazivač.

Npr.

Funkcija može biti bez argumenata. U tom slučaju podatke koje upisujemo u informacioni dio čvora

učitavamo unutar funkcije, kao u zadatku na kraju poglavlja.

Dodavanje čvora u listu Prvi zadatak u vezi sa povezanom listom je kako dodati čvor u listu. Novi čvor možemo dodati na

početak, kraj ili unutar liste. Upoznaćemo najprije dodavanje čvora na kraj i početak liste.

U uvodnom primjeru pokazali smo kako formiramo listu unutar while petlje. Sada ćemo napraviti

funkciju za dodavanje čvora na kraj ili početak postojeće liste, koja se može pozivati prema potrebi.

Dodavanje čvora na kraj liste

Dodavanje čvora na kraj liste realizujemo u slijedećim koracima:

1. Deklarišemo promjenljivu tipa structure na kojoj se baziraju čvorovi liste i rezervišemo

memorijski prostor za novi čvor

2. Unosimo podatke u elemente structure čvora

Page 59: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

59

3. Ako lista nije prazna, onda postojeći zadnji čvor u listi mijenjamo tako što u pokazivač tog čvora

upišemo adresu novog čvora. Time novi čvor uistinu postaje dio liste.

Ako je lista prazna, adresu novog čvora dodjelimo pointeru koji pokazuje na početak liste, start_ptr.

Najprije deklarišemo promjenljivu tipa struktura cvor i rezervišemo memorijski prostor za čvor,

slijedećom naredbom:

cvor *novi = new cvor;

novi

nedefinisano

Zatim, korisnik unosi podatke koje upisujemo u članice promjenljive novi:

cout << "Upisite ime: ";

cin >> novi->ime;

cout << "Upisite godine: ";

cin >> novi->godine;

cout << "Upisite visinu osobe: ";

cin >> novi->visina;

novi->slijedeci = NULL;

U zadnjoj liniji postavljamo NULL vrijednost u članicu strukuture slijedeci, čime iniciramo da će ovaj

čvor, kada ga ubacimo u listu, biti zadnji čvor.

Sada postavljamo vrijednost za pointer start_ptr. Ako je lista prazna, onda samo adresu tmp čvora

podešavamo da pokazuje na novi čvor:

if (start_ptr == NULL)

start_ptr = novi;

Ako u listi već postoje čvorovi, koristimo drugi pointer, pom, i pomjeramo ga na kraj liste:

{

pom = start_ptr;

// postavljamo pom na kraj liste

while (pom->slijedeci != NULL)

{

pom = pom->slijedeci; // pomjeranje na slijedeći čvor

}

pom->slijedeci = novi; // pokazivač zadnjeg čvora u listi

//postavljamo da pokazuje na novi čvor

}

Page 60: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

60

Petlja će se završiti kada pom sadrži adresu zadnjeg čvora u lancu. U zadnjem čvoru liste slijedeci sadrži

null vrijednost. Kada smo pronašli zadnji čvor, postavljamo slijedeci zadnjeg čvora da pokazuje na čvor

kojeg dodajemo u listu:

pom->slijedeci = novi;

start_ptr

pom

novi

novi

čvor

dodan

NULL

Kompletan kod za dodavanje čvora u listu slijedi:

void dodaj_cvor_na_kraj ()

{ cvor *novi, *pom; // pomoćni pokazivači

// Rezervisanje prostora za novi čvor i unos podataka

novi = new cvor;

cout << "Upisite ime: ";

cin >> novi->ime;

cout << "Upisite godine: ";

cin >> novi->godine;

cout << "Upisite visinu osobe: ";

cin >> novi->visina;

novi->slijedeci = NULL;

// Ubacivanje čvora u listu

if (start_ptr == NULL)

start_ptr = novi;

else

{

pom = start_ptr;

// postavljamo pom na pocetak liste

while (pom->slijedeci != NULL)

{

pom = pom->slijedeci; // pomjeranje na slijedeći čvor

}

pom->slijedeci = novi; // pokazivač zadnjeg čvora u listi postavljamo da pokazuje na novi čvor

}

return;

}

Zadatak

Modifikovati prethodnu funkciju tako da se unutar nje poziva funkcija za kreiranje novog čvora.

Page 61: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

61

Dodavanje čvora na početak liste

Ovaj postupak je znatno jednostavniji. Nakon kreiranja novog čvora i unosa podataka, potrebno je u novi čvor upisati adresu trenutno prvog čvora u listi (novi->slijedeci = start_ptr), a zatim postaviti u start_ptr adrsu novog čvora (start_ptr = novi). Ako je lista prazna, samo postavimo da start_ptr pokazuje na novi čvor.

void dodaj_cvor_na_pocetak ()

{ cvor *novi, *pom; // pomocni pokazivaci

// Rezervisanje prostora za novi cvor i unos podataka

novi = new cvor;

cout << "Upisite ime: ";

cin >> novi->ime;

cout << "Upisite godine: ";

cin >> novi->godine;

cout << "Upisite visinu osobe: ";

cin >> novi->visina;

novi->slijedeci = NULL;

// Ubacivanje cvora u listu

if (start_ptr == NULL)

start_ptr = novi;

else

{

novi->slijedeci = start_ptr;

start_ptr = novi;

}

return;

}

Zadatak za vježbu: 1. Modifikovati uvodni zadatak, tako da se slova iz učitane riječi upisuju na početak liste.

Na ovaj način, učitana riječ treba da bude upisana u obrnutom redoslijedu. Ispisati elemente liste.

2. Napisati program koji učitava cio broj proizvoljnog broja cifara, a zatim cifre broja upisuje u

jednostruko povezanu listu. Čvorove dodavati na početak liste.

3. Prethodni zadatak može se riješiti korištenjem funkcija. Slijedi kompletan kod.

Page 62: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

62

Page 63: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

63

Pristup podacima u listi Slijedeći problem kojeg treba riješiti je kako pristupati elementima liste. Pokazaćemo kako možemo

čitati podatke iz liste i ispisivati ih na ekranu.

Uradit ćemo slijedeće:

Pomoćni pointer postavljamo da pokazuje na prvi čvor, tj. dodjeljujemo mu vrijednosrt startnog

pointera (start_ptr).

Ako pomoćni pointer sadrži null vrijednost, lista je prazna pa prikazujemo poruku: "Kraj liste" i

zaustavljamo prikaz.

Ako pomoćni pointer ne sadrži null vrijednost, prikazujemo detalje iz čvora na koji pokazuje

pomoćni pointer.

Mijenjamo vrijednost pomocnog pointera, dodjeljujući mu vrijednost iz pointera “slijedeci”

čvora čiji smo sadržaj upravo ispisali.

Vraćamo se na drugi korak.

Slijedi kod za ispisvanje podataka iz liste:

void ispisi_listu()

{

cvor *pom = start_ptr;

do

{

if (pom == NULL)

cout << endl<<"Kraj liste" << endl;

else

{ // Ispis detalja iz čvora na koji pokazuje pom pointer

cout << "Ime: " << pom->ime << endl;

cout << "Godina: " << pom->godine << endl;

cout << "Visina: " << pom->visina << endl;

cout << endl;

// Pomjeranje na slijedeći čvor

pom = pom->slijedeci;

}

}

while (pom != NULL);

return;

}

Brisanje čvora Čvor može da se nalazi na početku, kraju i u sredini liste. Ovisno o njegovoj poziciji, postupak brisanja je

drugačiji.

Kada obrišemo čvor, potrebno je osloboditi memorijski prostor. Ako to ne uradimo, rizikujemo “out of

memory”! Oslobađanje memorijskog prostora realizujemo naredbom delete:

delete pom;

Page 64: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

64

Međutim, ne možemo samo obrisati čvor iz liste, jer bismo u tom slučaju prekinuli lanac. Stoga, najprije

moramo izmjeniti vrijednost odgovarajućeg pokazivača pa onda obrisati čvor.

Evo kako bismo obrisali prvi čvor iz liste.

pom = start_ptr; // Sacuvamo startni pointer u pomocnom

start_ptr

etc.

pom

Nakon što smo sačuvali vrijednost startnog pointera u pom pointer, mijenjamo vrijednost start_ptr tako

da pokazuje na slijedeći čvor:

start_ptr = start_ptr->slijedeci; // drugi cvor u lancu

start_ptr

etc.

pom

delete pom; // obrisi pocetni start cvor

start_ptr

Page 65: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

65

etc.

pom

Slijedi funkcija za brisanje startnog čvora:

void brisi_prvi_cvor()

{ cvor *pom;

pom = start_ptr;

start_ptr = start_ptr->slijedeci;

delete pom;

return;

}

Brisanje čvora na kraju liste je teže, jer se pomoćni pointer mora najprije pomjeriti na kraj liste (kao kod

unosa novog čvora). Potrebna su dva pomoćna pointera, pom1 i pom2. Prvi će pokazivati na zadnji čvor

u listi, a drugi na njegovo prethodnika. Potrebne su nam obje vrijednosti kako bismo zadnji obrisali, a

predzadnji modifikovali tako da on u polju slijedeći sadrži null vrijednost, pokazujući na taj način da je

zadnji čvor liste.

Prikažimo proces brisanja zadnjeg čvora crtežima. Posmatrajmo listu. Najprije ćemo postaviti oba

pomoćna pokazivača, pom1 i pom2, da pokazuju na početak liste.

start_ptr

NULL

pom1 pom2

Zatim , pom1 pomjeramo na slijedeći čvor u listi:

start_ptr

Page 66: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

66

NULL

pom2

pom1

Pošto pom1 još uvijek ne pokazuje na zadnji čvor u listi, pomjeramo i pom2, tako da pokazuje isti čvor

kao i pom1

start_ptr

NULL

pom2 pom1

Opet pomjeramo pom1 na slijedeći:

start_ptr

NULL

pom2

pom1

Ovo ponavljamo sve dok pom1 ne pokazuje zadnji čvor u listi, a pom2 na njegovog prethodnika:

Page 67: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

67

start_ptr

NULL

pom2

pom1

Zatim brišemo čvor na kojeg pokazuje pom1

start_ptr

pom2

pom1

Zatim u pokazivač slijedeci čvora na kojeg pokazuje pom2 upisujemo NULL vrijednost:

start_ptr

NULL

pom2

Ako lista sadrži samo jedan čvor, onda samo treba postaviti start_ptr na null vrijednost i obrisati čvor.

Slijedi kod za brisanje čvora na kraju liste:

void brisi_zadnji_cvor()

{

Page 68: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

68

cvor *pom1, *pom2;

if (start_ptr == NULL)

cout << "Lista je prazna!" << endl;

else

{

pom1 = start_ptr;

if (pom1->slijedeci == NULL)

{

delete pom1;

start_ptr = NULL;

}

else

{

while (pom1->slijedeci != NULL)

{

pom2 = pom1;

pom1 = pom1->slijedeci;

}

delete pom1;

pom2->slijedeci = NULL;

}

}

return;

}

Navigacija kroz listu Za rad sa povezanom listom, potrebno je uspostaviti mehanizam kretanja po listi, unaprijed ili unazad.

Ovo je naročito potrebno aki želimo brisati ili upisivati čvor unutar liste.

Deklarišimo pointer tekuci. Najprije mu dodjeljujemo adresu prvog čvora u listi, koju čuvamo u pointeru

start_ptr :

cvor *tekuci;

tekuci = start_ptr;

Nakon ovih naredbi oba pointera pokazuju na isti čvor:

start tekuci

itd

Pomjeranje pointera tekuci unaprijed realizujemo naredbom u kojoj pointeru tekuci dodjeljujemo

adresu cvora koji slijedi, a koja je upisana u članicu slijedeci čvora na kojeg tekuci pokazuje:

tekuci = tekuci->slijedeci;

Page 69: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

69

Prije prethodne naredbe dodjele, potrebno je provjeriti da tekući u polju slijedeći ne sadrži null

vrijednost. Ako je to tako, onda tekuci pokazuje na zadnji čvor u list ii nema potrebe za njegovim

pomjeranjem.

if (tekuci->slijedeci == NULL)

cout << "Pozicionirani ste na kraj liste." << endl;

else

tekuci = tekuci->slijedeci;

Pomjeranje pointera unazad je nešto teža rutina. Jedini način da nađemo prethodni čvor jeste da

krenemo od početnog i pomjeramo pokazivač do čvora kojeg tražimo. To će se desiti kada pointer

slijedeci pokazuje na tekući čvor.

Pomoć!!!

Pokušajmo sa slikama:

Najprije ćemo provjeriti da li pointer tekuci (na slici current) pokazuje na prvi čvor. Ako je tako, onda on

nema prethodnika. Ako nije, onda provjeravamo sve čvorove dok ne naiđemo na prethodnika tekućeg.

if (tekuci == start_ptr)

cout << "Pocetak liste!" << endl;

else

{ cvor *prethodni; // pointer koji pokazuje na prethodnika

prethodni = start_ptr;

while (prethodni->slijedeci != tekuci)

{

prethodni = prethodni->slijedeci;

}

tekuci = prethodni;

}

Kod koji je naveden iza else određuje slijedeće:

Najprije deklarišemo pointer koji će pokazivati na prethodni čvor – pointer prethodni.

U prethodni postavljamo adresu prvog čvora.

Sve dok ne pokazuje na čvor koji prethodi tekućem, mijenjamo adresu u pointeru prethodni tako

da pokazuje na slijedeći čvor.

Kada pronađemo prethodnika u odnosu na tekući, pointer tekuci postavljamo da pokazuje na isti

čvor kao i pointer prethodni, kojeg smo „doveli“ do njegovog prethodnika

prethodni slijedeci

Page 70: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

70

Sada kada možemo da se “krećemo” unaprijed i unazad kroz listu, možemo uraditi još ponešto sa listom.

Naprimjer, možemo mijenjati podatke u čvoru liste na koji pokazuje tekuci:

cout << "Unesite novo ime: "; cin >> tekuci->ime; cout << "Unesite novi podatak o godinama : "; cin >> tekuci->ime; cout << "Upisite novi podatak o visini : "; cin >> tekuci->visina;

Slijedeća procedura je brisanje čvora koji se nalazi odmah iza čvora na kojeg pokazuje pokazivač tekuci.

Koristit ćemo pomoćni pokazivač koji će pokazivati na čvor kojeg želimo obrisati – pom (na slici temp).

Nabrojat ćemo šta treba uraditi da bismo obrisali čvor.

Najprije, podesimo da pomoćni pokazivač pokazuje na čvor iza tekućeg, tj. na čvor kojeg ćemo obrisati:

Zatim podešavamo da pointer u tekućem čvoru sadrži adresu čvora koji slijedi iza onog na kojeg

pokazuje pomoćni:

Zadnji korak je brisanje čvora na kojeg pokazuje pomoćni.

Slijedi kod za brisanje čvora iza tekućeg. Ovaj kod uključuje i provjeru da li je tekući zadnji u listi.

if (tekuci->slijedeci == NULL) cout << "Nema vise cvorova u listi" << endl; else { cvor *pom; pom =tekuci->slijedeci; tekuci->slijedeci = pom->slijedeci; delete pom; }

tekuci pom

tekuci pom

Page 71: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

71

Slijedi kod za dodavanje čvora iza tekućeg.

if (tekuci->slijedeci == NULL) dodaj_cvor_na_kraj(); else { cvor *novi; new novi; upisi_podatke_u_cvor(novi); // Postavi da novi cvor pokazuje na isti cvor kao i tekuci novi->slijedeci = tekuci->slijedeci; // Tekuci pokazuje na novi tekuci->slijedeci = novi; }

Funkcija dodaj_cvor_na_kraj() je ranije deifinisana. Funkcija upisi_podatke_u_cvor(novi) omogućava unos

podataka u strukturu čvor.

U slijedećem primjeru primjenićemo ove procedure i pokazati kako se implementiraju i neke dodatne

funkcionalnosti povezane liste.

Primjer programa za rad sa jednostruko povezanom listom Napisati program koji omogučava formiranje liste koja sadrži koeficijente kvadratne jednačine. Nakon

startovanja programa, prikazati glavni meni sa slijedećim opcijama:

Za pohranjivanje podataka program koristi strukturu „cvor“, kako slijedi:

Page 72: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

72

Opcija 5, „Sekvencijalna obrada liste“, nudi dodatni meni za pojedinačnu obradu čvorova liste.

Omogućava sekvencijalni prolazak kroz listu, gdje se za svaki čvor nude slijedeće opcije:

Svaka od opcija glavnog menija i menija za sekvencijalnu obradu podataka realizuje se kao zasebna

funkcija. I sam meni komandi je relizovan kao funkcija koja se poziva u funkciji main, kao na screenshot-

u koji slijedi.

Program je realizovan kroz slijedeće funkcije:

Page 73: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

73

Glavni meni poziva se u funkciji main, gdje se, nakon povratka iz menija, u okviru switch naredbe poziva

odgovarajuća funkcija:

Page 74: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

74

Glavni meni implementiran je na slijedeći način:

Page 75: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

75

Dodavanje čvora na početak liste već je objašnjeno:

Kako bi program bio funkcionalan, samo kreiranje novog čvora realizovano je u zasebnoj, pomoćnoj

funkciji „kreiraj_novi_cvor“ koja se poziva u prethodnoj, ali i u okviru drugih funkcija programa.

Page 76: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

76

Ova funkcija vraća pokazivač na čvor. Kao tip povratne vrijednosti navodimo strukturu „cvor“, a ispred

imena funkcije znak *, kako bismo odredili da funkcija vraća pokazivač na čvor.

Prednost ovakvog pristupa je što istu funkciju možemo koristiti na više mjesta u programu. S druge

strane, prednost je i u tome što istu metodologiju možemo koristiti i u drugim zadacima – jedino što

treba da prilagodima je struktura čvora u funkciji kreiraj_novi_cvor (isto i u ispisi_cvor).

Vec u slijedećoj funkciji opet koristimo funkciju „kreiraj_novi_cvor“

Za potrebe ispisivanja liste također koristimo pomoćnu funkciju za ispisivanje sadržaja jednog čvora.

Page 77: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

77

Argument ove funkcije je pokazivač sa fiktivnim imenom „tekuci“. On pokazuje na čvor čiji sadržaj želimo

ispisati .

Funkciju „ispisi_cvor“ koristimo u funkciji za ispisivanje liste od prvog do zadnjeg čvora, čiji algoritam

smo već objasnili.

Funkciju „ispisi_cvor“ koristimo i u funkciji za ispisivanje liste od zadnjeg ka prvom čvoru. Ova funkcija

radi na slijedeći način. Ako lista nije prazna i ako ne sadrži samo jedan čvor, koristimo dva pomoćna

pokazivača. Pom1 na početku funkcije pomjerimo na zadnji čvor u petlji i ispišemo njegov sadržaj:

Sve dok pom1 ne bude imao istu adresu kao i start_ptr, radimo slijedeće:

- pokazivač pom2 pozicioniramo na čvor koji prethodi čvoru pom1

- pokazivač pom1 pomjerimo na prethodni čvor i ispišemo njegov sadržaj

Page 78: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

78

Slijedi kompletan kod ove funkcije:

Brisanje čvora na početku i kraju liste također je objašnjeno ranije. Slijedi kod ovih funkcija:

Page 79: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

79

Sekvencijalna obrada liste realizuje se pomoću funkcije „sekvencijalna_obrada“. 1 U okviru ove funkcije

prolazimo kroz listu, od prvog do zadnjeg čvora, tako što mijenjamo vrijednost pokazovača „tekuci“.

Nakon svakog pomjeranja, prikazujemo sadržaj čvora i prikazujemo pomoćni meni iz kojeg korisnik bira

odgovarajuću akciju.

Koristi se i pomoćni pokazivač „pom“ u kojeg spremimo kopiju vrijednosti polja „slijedeci“ iz tekućeg

čvora. Ova vrijednost (adresa slijedećeg čvora) nam je potrebna u slučaju da korisnik izabere brisanje

tekućeg čvora. Ako ne bismo imali kopiju adrese slijedećeg čvora, nakon brisanja tekućeg čvora lista bi

bila prekinuta i ne bismo se mogli referencirati na slijedeći čvor (koji nakon izvršene operacije postaje

tekući).

1 Sekvencijalni pristup (engl. sequential access) je način pristupa podacima pri čemu su podaci na raspolaganju u

određenom poretku, a vrijeme pristupa podacima je zavisno o količini pohranjenih podataka i fizičkom smještaju podataka. Npr. magnetna traka ima sekvencijalni pristup podacima. Da bi se došlo do podatka koji je smješten na nekom dijelu trake, potrebno je pročitati cjelokupan sadržaj trake od mjesta na kome se nalazi magnetska glava pa sve do mjesta gdje se nalazi traženi podatak (ili premotati trake uz poznato mjesto na kome se nalazi traženi podatak). U svakom slučaju ispred glave za čitanje moraju proći svi podaci između trenutnog položaja glave i mjesta na kome se nalazi podatak. Kod direktnog pristupa, podacima se pristupa direktno bez potrebe čitanja prethodnih vrijednosti. Ovo je moguće zahvaljujući uspostavljanju ključa. Kad su u pitanju magnetski mediji, hard drive je primjer medija sa direktnim pristupom.

Page 80: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

80

Za svaki čvor iz liste prikazuje se pomoćni meni sa opcijama rasploživim nad odabranim čvorom:

Ista funkcija sadrži switch naredbu u okviru koje pozivamo odgovarajuću funkciju za sekvencijalnu

obradu:

Page 81: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

81

Funkcija za izmjenu tekućeg čvora jednostavno mijenja upisane podatke:

Dodavanje čvora prije tekućeg realizuje se tako što se najprije provjeri dali je tekući prvi čvor liste. Ako

jeste, pozivamo funkciju za dodavanje čvora na početak liste. Ako tekući nije prvi čvor, onda:

- kreiramo novi čvor pozivom funkcije „kreiraj_novi_cvor“

- pomoćni pokazivač „prethodni“ postavimo da pokazuje na čvor prije tekućeg, a zatim

o podesimo da u prethodnom čvoru polje slijedeći pokazuje na novi čvor

o podesimo da u novom čvoru polje slijedeći pokazuje na tekući

Page 82: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

82

Dodavanje čvora prije tekućeg realizujemo na slijedeći način.

A) Ako je lista prazna, pozivamo funkciju za dodavanje čvora na pocetak liste

B) Ako lista nije prazna:

a. Kreiramo novi čvor pozivamo funkciju kreiraj_novi_cvor(),

b. podešavamo da pokazivač u čvoru koji prethodi tekućem pokazuje na novi čvor, a

pokazivač u novom čvoru pokazuje na tekući

novi

prethodni novi

tekuci

Page 83: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

83

Brisanje čvora poslije tekućeg realizuje se u slijedećoj funkciji:

Čvor prije tekućeg brišemo pomoću funkcije:

Page 84: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

84

Konačno, snimanje podataka iz čvorova povezane liste realizuje se u funkciji kako slijedi:

Npr. pozivom ove funkcije kreirana je datoteka

Podaci iz jednog čvora upisuju se u jedan red sa razmacima između pojedinih vrijednosti. Osim za prvi

čvor, prije upisa podataka iz čvora, u datoteku se upisuje znak za novi red:

if (pom != start_ptr) Izlaz << endl;

Čitanje podataka iz datoteka u listu realizuje funkcija:

Page 85: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

85

Sve dok nije kraj datoteke (!Ulaz.eof()), kreiramo novi čvor i u njega upisujemo podatke pročitane iz

datoteke:

Zadaci za vježbu 1. Napisati program koji omogućava unos podataka o proizvoljnom broju učenika. Za svakog

učenika treba upisati slijedeće podatke:

a. Redni broj, cio broj

b. Prezime i ime, string

c. Broj bodova, cio broj

d. Ocjena, cio broj (1-5)

Nakon unosa podataka o jednom učeniku, provjeriti da li je potreban nastavak unosa, tj.

Postaviti pitanje: „Nastavak? (D/N)“.

Ispisati učitane podatke, tako što podatke o jednom učeniku ispisujemo u jednoj liniji. Koristiti

povezanu listu.

2. Modifikovati zadatak 1 dodavanjem menija iz kojeg korisnik može izarbrati slijedeće opcije:

a. Unos novog čvora, sa podacima redni broj i prezime i ime

i. Na početak liste

ii. Unutar liste, sa ažuriranjem postojećih rednih brojeva

Page 86: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

86

1. Prije zadanog rednog broja

2. Poslije zadanog rednog broja

iii. Na kraj liste

b. Unos broja bodova:

i. za sve ucenike u listi

ii. Za odabranog učenika, na osnovu rednog broja

c. Brisanje učenika sa zadanim rednim brojem

d. Unos kriterija za ocjenjivanje u formi

i. Ocjena 1: do ___ bodova

ii. Ocjena 2: od ____ do ____ bodova

iii. Ocjena 3: od ____ do ____ bodova

iv. Ocjena 4: od ____ do ____ bodova

v. Ocjena 5: od ____ do ____ bodova

e. Ispisivanje ocjena učenika

i. Svi učenici

ii. Odabrani učenik, zadavanjem rednog broja

f. Ispisivanje rang liste po broju bodova

g. Upisivanje liste u datoteku

h. Učitavanje liste iz datoteke

3. Napisati program koji omogučava unos podataka u povezanu listu. Svaki čvor sadrži prezime i

me učenika i broj osvojenih bodova. Prilikom unosa učenika, automatski se vrši sortiranje

podataka u opadajču listu pr broju osvojenih bodova. Nakon unosa ispisati listu sa kolonama:

prezime ii me, broj bodova.

4. Napisati program koji nudi iste opcije kao i primjer 1, samo što se u čvorovima liste čuvaju

podaci o vrijednostim tri otpora R1, R2 i R3. Prilikom ispisa podataka iz liste izračunava se i

ispisuje ukupan otpor ako su otpornici spojeni serijski i paralelno.

5. Napisati program koji omogućava formiranje liste (dodavanje čvora na početak i kraj) kao i

ispisivanje liste od prvog do zadnjeg čvora. Napraviti funkciju koja nalazi najveći element u

čvoru. Ova funkcija vraća vrijednost koja se traži a kao argument uzima pokazivač na prvi čvora

liste. Čvor sadrži samo dva elementa: cio broj i pokazivač.

6. Napisati program koji omogućava formiranje liste (dodavanje čvora na početak i kraj) kao i

ispisivanje liste od prvog do zadnjeg čvora. Napraviti funkciju koja od podataka u listi formira niz,

a zatim ispisuje taj niz sortiran u rastućem redoslijedu. Funkcija nema argumenata i ne vraća

nikakvu vrijednost. Čvor sadrži samo dva elementa: cio broj i pokazivač.

7. Napraviti funkciju za sortiranje liste.

Page 87: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

87

Zadaci za ponavljanje

POVEZANE LISTE, vježba 1 (osnovni pojmovi, deklaracija, kreiranje liste)

1. Šta je povezana lista?

2. Čvor povezane liste sadrži dva dijela. Navedi ih i opiši.

3. Nacrtaj kako izgleda jednostruko povezana lista

4. Nacrtaj kako izgleda dvostruko povezana lista

5. Potrebno je formirati jednostruko povezanu listu koja u informacionom dijelu ima podatke o

pravouglom trouglu. Čuvaju se dužine dvije stranice trougla a i b kao cijeli brojevi. Deklariši

strukturu cvor koja će omogučiti rad sa ovakvom listom.

6. Šta označava konstanta NULL i kako se koristi u povezanoj listi?

7. Koji je značaj pointera koji pokazuje na početak liste? Opiši ovaj pointer i njegov značaj.

8. Ako je deklarisana struktura cvor (kao u zadatku 5) koja će se koristiti za kreiranje jednostruko

povezane liste, napiši naredbu kojom se deklariše pointer koji će pokazivati na početak liste

(start_ptr), kao i pointer novi, pomoću kojeg ćemo dodavati čvorove u listu.

9. Napiši naredbu kojom će se alocirati memorijski prostor za novi čvor liste. Koristiti pokazivač

novi.

10. Prikaži grafički efekat naredbe iz zadatka 9, pod pretpostavkom da je lista prazna. Ucrtaj

pokazivače start_ptr i novi, kao i čvor(ove) liste.

11. Prikaži grafički efekat naredbe iz zadatka 9, pod pretpostavkom da lista nije prazna. Ucrtaj

pokazivače start_ptr i novi, kao i čvor(ove) liste.

12. Napisati naredbu kojom se u informacioni dio čvora za koji je u naredbi iz zadatka 9 alociran

memorijski prostor upisuju podaci. Pretpostavka je da se podaci nalaze u cjelobrojnim

promjenljivim v_a i v_b.

13. Deklarisati pokazivač zadnji, koji će pokazivati na kraj liste.

14. Napisati if naredbu kojom se provjerava da li je lista prazna. Ako jeste, onda zadati naredbu

kojom se određuje da start_ptr pokazuje na novi cvor (pointer novi), a ako nije onda podesiti da

postojeći zadnji čvor pokazuje na novi. Prikazati grafički oba slučaja.

15. Napisati naredbu kojom se određuje da pokazivač zadnji pokazuje na isti čvor na koji pokazuje i

novi.

16. Pretpostavimo da imamo formiranu slijedeću listu

NULL

Za ispisaivanje podataka u listi koristi se slijedeći kod:

cout <<"Podaci upisani u listu su "<<endl;

zadnji = start_ptr;

while (zadnji != NULL)

42

1 2

42

22

32

Page 88: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

88

{

cout << zadnji->a << zadnji->b;

zadnji = zadnji->slijedeci;

}

Predstaviti grafički kako će se izvršavati ovaj kod na prethodnom primjeru. Prikazati na koji čvor

pokazuju pokazivači start_ptr i zadnji, te koje vrijednosti se ispisuju.

Grafički prikaz povezane liste je grupisan u jedan grafički objekat, pa se može kopirati slijedeći

element.

Koristiti slijedeći obrazac:

1. Nakon naredbe zadnji = start_ptr, pokazivač start_ptr pokazuje na prvi čvor liste, kao na slici:

Start_ptr

2.

3.

4.

2. Prvi prolazak kroz petlju while

Start_ptr Zadnji ????

ISPIS:......

42

1 2

42

22

32

42

1 2

42

22

32

42

1 2

42

22

32

Page 89: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

89

Vježba 2

Potrebno je napraviti program koji omogučava

praćenje prevoza putnika i tereta korištenjem

povezane liste.

Voz čine vagoni različite namjene:

- Lokomotiva

- Kupe

- Teretni

- Restoran

Za svaki vagon treba upisati slijedeće podatke, ovisno o namjeni vagona:

- Namjena (lokomotiva,kupe,teretni,restoran)

- Broj ukrcanih putnika (popunjava se ako je namjena vagona kupe)

- Težina utovarene robe (popunjava se ako je namjena vagona teretni)

- Broj stolova (popunjava se ako je namjena vagona restoran)

- Broj stolica (popunjava se ako je namjena vagona restoran)

Ako je namjena vagona lokomotiva, upisuje se samo polje namjena.

Maximalan broj putnika vagona tipa kupe je 20. Maksimalna težina tereta koji se može utovariti u

teretni vagon je 5 tona. Voz može imati samo jedan vagon-restoran.

Potrebno je napraviti program koji omogučava evidentiranje broja putnika i utovarenog tereta,

dodavanje i isključivanje vagona.

Prema potrebi, omogučiti dodavanje ili isključivanje vagona u/iz voza, na kraj voza prije ili poslije

određenog vagona.

Isključivanje vagona iz voza uraditi automatski kada se desila jedna od slijedećih promjena:

- Broj ukracanih putnika postaje nula

- Težina utovarene robe postaje nula

Dodavanje putničkog vagona uraditi automatski ako je u svim kupe vagonima maksimalan broj putnika.

Omogučiti ispisivanje podataka o putnicima i teretu koji su trentuno u vozu.

Page 90: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

90

1. Kreirati strukturu podataka koja će se koristiti za pohranjivanje podataka o vagonu.

2. Napisati naredbu kojom se deklariše pokazivač „lokomotiva“ koji će se koristiti kao pokazivač na

prvi vagon voza – lokomotivu.

lokomotiva

3. Napisati naredbe kojima se kreiraju i povezuju čvorovi voza. Čvorove dodavati postpno, u tri

koraka: najprije dodati lokomotivu, zatim teretni vagon i na kraju putnički. Upisati kod i na slici

obilježiti na što pokazuju korišteni pokazivači

lokomotiva

4. Napisati kompletan program koji će kreirati podatke o vozu kao na slici na prethodnoj strani. Voz

čine lokomotiva, jedan putnički vagon čiji broj putnika upisuje korisnik i jedan teretni vagon bez

tereta. Ispisati podatke o ovom vozu.

5. Napisati funkciju koja ispisuje podatke o vagonu u odgovarajućoj formi. Argument funkcije je

pokazivač na čvor čiji podaci se ispisuju. Modifikovati program iz prethodnog zadatka tako što se

ispisivanje podataka o vozu vrši korištenjem ove funkcije.

6. Napisati kod koji na kraj voza dodaje novi vagon. Obilježiti na slici pokazivače koji se koriste da

bi se dodao čvor na kraj voza.

Page 91: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

91

7. Napisati kod za dodavanje novog vagona odmah iza lokomotive. Obilježiti na slici pokazivače koji

se koriste da bi se dodao čvor na željenu poziciju.

8. Napisati kod za brisanje zadnjeg vagona . Obilježiti na slici pokazivače koji se koriste za ovu

operaciju. Nakon brisanja voz treba izgledati ovako.

9. Napisati kod za brisanje drugog vagona. Obilježiti pokazivače. Nakon brisanja voz treba izgledati

ovako.

10. Napisati funkciju koja omogučava kreiranje novog čvora u kojeg se upisuju podaci o vagonu.

Funkcija treba da vrati pokazivač na novi vagon.

11. Za svaku od operacija iz zadataka 6-9 napisati odgovarajuću funkciju i program koji je testira.

12. Napraviti kompletan program na osnovu zadanog projektnog zadatka definisanog na prvoj

strani.

Koristiti meni komandi koji treba da sadrži slijedeće opcije:

Page 92: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

92

1. Dodavanje vagona

1.1 Lokomotiva

1.2 Putnički vagon

1.3 Teretni vagon

1.4 Restoran

A. Na kraj voza

B. Poslije lokomotive

C. Poslije restorana

D. Prije restorana

2. Ispisivanje podataka o vozu

2.1 Ispisivanje podataka o svim vagonima

2.2 Ispisivanje ukupnog broja putnika i tereta u vozu

2.3 Ispisivanje broja putnika po vagonima

2.4 Ispisivanje tereta po vagonima

3. Pretraživanje voza i izmjena podataka

3.1 Pronalaženje prvog vagona u kome ima x slobodnih mjesta; dodavanje x putnika

3.2 Pronalaženje prvog vagona u koji se može utovariti x kg robe, dodavanje x kg robe

4. Brisanje vagona

4.1 Brisanje zadnjeg vagona

4.2 Brisanje svih vagona koji imaju 0 putnika

4.3 Brisanje svih vagona koji su natovareni sa 0 kg tereta

4. 4 Brisanje restorana

5. Upisivanje podataka o vozu u datoteku

6. Učitavanje podataka o vozu iz datoteke

Page 93: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

93

MODUL 3: KLASE i OBJEKTI

Page 94: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

94

Uvod: Proceduralno i Objektno

Programiranje

Trip to Objectville2 U dosadašnjim programima, sav programski kod upisivali smo unutar funkcije main(). U prethodnom

modulu naučili smo kako sami možemo praviti tip podataka (strukturu), kako dinamički koristimo

memorijski prostor (pokazivači, povezane liste), ali nismo razvili ni jedan korisnički tip objekta. Sve

dosadašnje metode razvoja programa označavamo kao procedurealno programiranje.

Sada ćemo napustiti svijet proceduralnog programiranja i započeti korištenje objekata koje ćemo sami

kreirati. Upoznat ćemo pojmove klasa i objekat i naučiti ih razlikovati.

Chair Wars (ili kako objekti mogu promijeniti tvoj život)

Jednom davno, u prodavnici software-a radila su dva programera kojima

je data specifikacija i rečeno „Napravite to!“. Zaista neugodan vođa

projekta obećao je developeru koji prvi riješi problem dati „Aeron“ stolicu

koju imaju svi developeri u silikonskoj dolini. Larry, proceduralni

programer, i Brad, OO guy, oba su znala da je ovaj zadatak „mačiji kašalj“.

Larry je, sjedeći u svojoj „kutiji“ (cube), razmišljao o slijedećem: „Šta

program treba da radi? Koje procedure (funkcije) treba?“. I odgovorio je

sebi: „rotacija i emitujZvuk (rotate and playSpund)“. Onda je otišao i

počeo pisati funkcije. Na kraju, šta je program ako nije gomila procedura?

U međuvremenu, Brad se vratio u kafić i razmišljao: „Koje su stvari u ovom

programu... ko su ključni igrači?“. Najprije je razmišljao o oblicima (Shapes).

Naravno, razmišljao je i o drugim objektima, kao što su korisnici (Users),

zvukovima (Sounds) i događaju „click“. Ali već je imao bibilioteku sa kodom

za ove elemente programa, pa se fokusiorao na pravljenje objekta.

Čitajte dalje kako su Brad i Larry pravili program i ko je dobio stolicu....

Ideja za uvod i dijelovi teksta preuzeti iz knjige „Head First Java“, O Relly, Katty Sierra, Bert Bates

Upozorenje: kada jednom uđete u „Objectville“, nikada se nećete vratiti nazad. Pošalji razglednicu.

Page 95: Selma Krajnović - Programiranje 3, skripta

ETŠ Tuzla, Selma Krajinović

95

In Larry's cube Kao što je to uradio milion puta do sada, Larry je pravio važne procedure. Za tren je napisao kod za procedure rotate i playSound.... rotate (shapeNum)

{

// okretanje oblika ya 360 stepeni

}

playSo (shapeNum)

{

// koristiti shapeNum za izbor zvuka

kojeg treba emitovati

}

At Brad's laptop at the cafe Brad je napisao klasu za svaki od tri oblika....