You are on page 1of 95

ETŠ Tuzla, Selma Krajinović

PROGRAMIRANJE 3

Modul 1: Dvodimenzionalni niz

1
ETŠ Tuzla, Selma Krajinović

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,
2
ETŠ Tuzla, Selma Krajinović

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

3
ETŠ Tuzla, Selma Krajinović

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.

4
ETŠ Tuzla, Selma Krajinović

Ispisivanje dvodimenzionalnog niza


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

Ako testiramo kodi zadamo dimenizije niza 3x3, dobijemo

5
ETŠ Tuzla, Selma Krajinović

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

6
ETŠ Tuzla, Selma Krajinović

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

7
ETŠ Tuzla, Selma Krajinović

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:

8
ETŠ Tuzla, Selma Krajinović

Rješenje 2

Formira se novi dvodimenzionalni niz Y prema formuli:

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

9
ETŠ Tuzla, Selma Krajinović

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.

10
ETŠ Tuzla, Selma Krajinović

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.

11
ETŠ Tuzla, Selma Krajinović

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.

12
ETŠ Tuzla, Selma Krajinović

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.

13
ETŠ Tuzla, Selma Krajinović

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

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

14
ETŠ Tuzla, Selma Krajinović

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

15
ETŠ Tuzla, Selma Krajinović

GD2: 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

SD1: 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

SD2: 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

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
1 5 2 1 5 redu 2 i koloni 1. Zadnja pojava je u redu 5 i koloni 4.
0 2 4 6 4
Najveći element je 8. Prva pojava ovog elementa je u redu 4 i koloni 5.
1 2 5 6 2
Zadnja pojava je u redu 5 i koloni 5.
1 2 0 7 8
7 8 7 0 8
Rješenje

Obilježimo promjenljive kako slijedi:

16
ETŠ Tuzla, Selma Krajinović

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:

17
ETŠ Tuzla, Selma Krajinović

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.

1 5 2 1 5 1 1 2 5 5
0 2 4 6 4 0 2 4 4 6
1 2 5 6 2 1 2 2 5 6
1 2 0 7 8 0 1 2 7 8
7 8 7 0 8 0 7 7 8 8

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:

18
ETŠ Tuzla, Selma Krajinović

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

19
ETŠ Tuzla, Selma Krajinović

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.

20
ETŠ Tuzla, Selma Krajinović

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

21
ETŠ Tuzla, Selma Krajinović

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;
}
}

22
ETŠ Tuzla, Selma Krajinović

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

23
ETŠ Tuzla, Selma Krajinović

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.

24
ETŠ Tuzla, Selma Krajinović

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

25
ETŠ Tuzla, Selma Krajinović

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

26
ETŠ Tuzla, Selma Krajinović

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.

27
ETŠ Tuzla, Selma Krajinović

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.

28
ETŠ Tuzla, Selma Krajinović

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

U funkciji main testiramo ove dvije funkcije:

29
ETŠ Tuzla, Selma Krajinović

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.

30
ETŠ Tuzla, Selma Krajinović

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

31
ETŠ Tuzla, Selma Krajinović

Struktura kao član strukture


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

struct datum
{
int dan;

32
ETŠ Tuzla, Selma Krajinović

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.

33
ETŠ Tuzla, Selma Krajinović

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

34
ETŠ Tuzla, Selma Krajinović

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

35
ETŠ Tuzla, Selma Krajinović

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.

36
ETŠ Tuzla, Selma Krajinović

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

37
ETŠ Tuzla, Selma Krajinović

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

38
ETŠ Tuzla, Selma Krajinović

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

39
ETŠ Tuzla, Selma Krajinović

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;
}

40
ETŠ Tuzla, Selma Krajinović

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!

41
ETŠ Tuzla, Selma Krajinović

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.

42
ETŠ Tuzla, Selma Krajinović

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:

43
ETŠ Tuzla, Selma Krajinović

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

44
ETŠ Tuzla, Selma Krajinović

*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!)

45
ETŠ Tuzla, Selma Krajinović

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

46
ETŠ Tuzla, Selma Krajinović

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:

array_ptr
0x5000

0x5000

array_ptr+2
0x5002

0x5000

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

47
ETŠ Tuzla, Selma Krajinović

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.

48
ETŠ Tuzla, Selma Krajinović

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č

49
ETŠ Tuzla, Selma Krajinović

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:

50
ETŠ Tuzla, Selma Krajinović

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.

51
ETŠ Tuzla, Selma Krajinović

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.

52
ETŠ Tuzla, Selma Krajinović

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.

53
ETŠ Tuzla, Selma Krajinović

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

54
ETŠ Tuzla, Selma Krajinović

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

START

Ime: Edo Ime: Damir Ime: Davor Ime: Marina


Godine: 34 Godine: 27 Godine: 48 Godine: 30
Visina: 1.7 Visina: 1.2 Visina: 1.4 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.
NULL

R A R
E U
B
F
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.

55
ETŠ Tuzla, Selma Krajinović

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:

56
ETŠ Tuzla, Selma Krajinović

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

57
ETŠ Tuzla, Selma Krajinović

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

58
ETŠ Tuzla, Selma Krajinović

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:

novi

cvor *novi = new cvor;

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
}

59
ETŠ Tuzla, Selma Krajinović

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.

60
ETŠ Tuzla, Selma Krajinović

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.

61
ETŠ Tuzla, Selma Krajinović

62
ETŠ Tuzla, Selma Krajinović

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;

63
ETŠ Tuzla, Selma Krajinović

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

64
ETŠ Tuzla, Selma Krajinović

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

65
ETŠ Tuzla, Selma Krajinović

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:

66
ETŠ Tuzla, Selma Krajinović

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()
{

67
ETŠ Tuzla, Selma Krajinović

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;

68
ETŠ Tuzla, Selma Krajinović

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:
prethodni slijedeci

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

69
ETŠ Tuzla, Selma Krajinović

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:
tekuci pom

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

tekuci pom

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;
}

70
ETŠ Tuzla, Selma Krajinović

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:

71
ETŠ Tuzla, Selma Krajinović

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:

72
ETŠ Tuzla, Selma Krajinović

Glavni meni poziva se u funkciji main, gdje se, nakon povratka iz menija, u okviru switch naredbe poziva
odgovarajuća funkcija:

73
ETŠ Tuzla, Selma Krajinović

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

74
ETŠ Tuzla, Selma Krajinović

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.

75
ETŠ Tuzla, Selma Krajinović

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.

76
ETŠ Tuzla, Selma Krajinović

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

77
ETŠ Tuzla, Selma Krajinović

Slijedi kompletan kod ove funkcije:

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

78
ETŠ Tuzla, Selma Krajinović

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.

79
ETŠ Tuzla, Selma Krajinović

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:

80
ETŠ Tuzla, Selma Krajinović

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

81
ETŠ Tuzla, Selma Krajinović

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
tekuci

novi

prethodni novi

82
ETŠ Tuzla, Selma Krajinović

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

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

83
ETŠ Tuzla, Selma Krajinović

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:

84
ETŠ Tuzla, Selma Krajinović

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

85
ETŠ Tuzla, Selma Krajinović

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.

86
ETŠ Tuzla, Selma Krajinović

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
1 4 2 3
4 2 2 2 2
2

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

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


zadnji = start_ptr;
while (zadnji != NULL)

87
ETŠ Tuzla, Selma Krajinović

{
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.

1 4 2 3
4 2 2 2 2
2

Koristiti slijedeći obrazac:


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

Start_ptr

1 4
2. 2 3
4 2 2
3. 2 2
2
4.

2. Prvi prolazak kroz petlju while

Start_ptr Zadnji ????

1 4 2 3
4 2 2 2 2
2

ISPIS:......

88
ETŠ Tuzla, Selma Krajinović

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.

89
ETŠ Tuzla, Selma Krajinović

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.

90
ETŠ Tuzla, Selma Krajinović

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:

91
ETŠ Tuzla, Selma Krajinović

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

92
ETŠ Tuzla, Selma Krajinović

MODUL 3: KLASE i OBJEKTI

93
ETŠ Tuzla, Selma Krajinović

Uvod: Proceduralno i Objektno


Upozorenje: kada jednom uđete u
Programiranje „Objectville“, nikada se nećete vratiti
nazad. Pošalji razglednicu.
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

94
ETŠ Tuzla, Selma Krajinović

In Larry's cube At Brad's laptop at the cafe

Kao što je to uradio milion puta do sada, Larry je Brad je napisao klasu za svaki od tri oblika....
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
}

95

You might also like