Professional Documents
Culture Documents
PR1 P6 Dinamicki Nizvoi 2013 14
PR1 P6 Dinamicki Nizvoi 2013 14
Stek (stog)
Stek predstavlja tzv. LIFO (last-in-first-out) strukturu u
kojoj
se
posljednje
pohranjena
vrijednost
(komponenta) brie prva
Stek se smatra glavnim dijelom memorije za alokaciju
i pohranjivanje statikih objekata
Postupak alokacije i dealokacije na steku je u
potpunoj ingerenciji raunara, te se obavlja
automatski
Glavne operacije na steku su : push, pop i top
Hrpa (heap)
Heap predstavlja tzv. FIFO (first-in-first-out) strukturu
u kojoj se prvo brie vrijednost (komponenta) koja je
prva i pohranjena
Smatra se da heap predstavlja glavni dio memorije za
alokaciju i pohranjivanje dinamikih podataka
Postupak
dinamike
memorijske
alokacije
(rezervisanja) i dealokacije (oslobaanja) je u
ingerenciji programera i obavlja se koristei operatore
new (alokacija) i delete (dealokacija)
Alociranje memorije
Deklaracija varijable int broj kompajleru daje instrukciju
da:
Alocira blok memorije dovoljno veliki da pohrani vrijednost tipa
int
Pridrui (asocira) ime broj adresi memorijskog bloka
Alociranje memorije
Deklaracija niza
const int duzina = 50;
double niz[duzina];
alocira memorijski prostor u koji se moe smjestiti 50
double vrijednosti. Definisani broj elemenata esto nee
biti iskoriten (moda se bude koristilo npr. 5 - 10 vrijednosti
tipa double) pa e vei dio memorijskog bloka najee biti
neiskoriten.
Alociranje memorije
Naa elja i potreba je da u vrijeme izvravanja programa
alociramo onoliki memorijski blok koliki je potreban za odreeni
objekat (varijablu, niz ...) i da taj memorijski blok oslobodimo
kada nam vie nije potreban
Programski jezik C++ omoguava koritenje free memory store-a
(hrpa, gomila) upotrebom operatora new (alokacija) i delete
(dealokacija)
Operator new od operativnog sistema zahtijeva dodatni
memorijski prostor u vremenu izvravanja programa. Ako je
zahtjev mogue ispuniti, operator new vraa adresu alociranog
memorijskog bloka, a u spurotnom vraa NULL vrijednost.
Alociranje memorije
Poto operator new vraa adresu, a adresa moe biti
pohranjena u pokaziva, oekivano je je da se operator new,
gotovo uvijek, koristi u kombinaciji sa pokazivaem.
int * pok = new int;
Alociranje memorije
Drugi nain za provjeru da li je alocirana zahtijevana memorija je
koritenje mehanizma assert:
assert(pok!=NULL);
Alociranje memorije
int * pok = new int;
pok
0x20
0x20
*pok = 35;
pok
0x20
Memorija alocirana,
adresa dodijeljena
pokazivau
*pok
0x20
35
Dereferencirani
pokaziva ima pristup
objektu
Oslobaanje memorije
Kada odreeni dio memorije vie nije potreban, operator delete
vraa (oslobaa) memoriju u free store
Forma (sintaksa) :
delete pok;
ili
delete [] pok;
Proces:
prvi iskaz oslobaa memoriju alociranu u run-time vremenu za
objekt ija je adresa pohranjena u pokazivau
drugi iskaz oslobaa memoriju alociranu u run-time vremenu za
niz objekata ija je adresa pohranjena u pokazivau
Vraanje memorije u free store je mogue uraditi i koristei funkciju
free
Dinamiki nizovi
#include <iostream>
#include <assert.h>
using namespace std;
void main(){
int brojElemenata=0;
int * niz = NULL;
cout<<"Koliko brojeva unosite: ";
cin>>brojElemenata;
niz = new int [brojElemenata];
assert(niz!=NULL);
for(int i=0;i<brojElemenata;i++){
cout<<"niz["<<i<<"]: ";
cin>>niz[i];
}
cout<<"niz["<<brojElemenata<<"] = { ";
for(int i=0;i<brojElemenata;i++)
cout<<niz[i]<<" ";
cout<<"}"<<endl;
delete [] niz;
niz = NULL;
system("pause");
}
Dinamiki nizovi
#include<iostream>
#include<assert.h>
using namespace std;
void main(){
//...
//funkcija prima broj bajta koje je potrebno alocirati
//i vraca void *
niz = (int*)malloc(brojElemenata * sizeof(int));
assert(niz != NULL);
//...
free(niz);
niz = NULL;
system("pause");
}
Koliko brojeva unosite:
niz[0]: 1
niz[1]: 2
niz[2]: 3
niz[3]: 4
niz[4]: 5
niz[5] = { 1 2 3 4 5 }
Press any key to continue . . .
int(*a)[5]=new int[2][5];
float(*b)[5]=new float[n][5];
a
------------100
a[0][0]:
a[0][1]:
a[0][2]:
a[0][3]:
a[0][4]:
adresa 100
adresa 102
adresa 104
adresa 106
adresa 108
a[1][0]:
a[1][1]:
a[1][2]:
a[1][3]:
a[1][4]:
adresa 110
adresa 112
adresa 114
adresa 116
adresa 118
Pokaziva na pokaziva
PROBLEM: Potrebno je kreirati niz dimenzija n*m, tj. niz kome
dimenzije nisu unaprijed poznate
Dvodimenzionalni dinamiki niz moe imati varijabilan broj
redova, ali broj kolona mora biti poznat
RJEENJE: Deklarisanjem pokazivaa na jednodimenzionalni
niz pokazivaa. Svaki lan podniza pokazivaa e pokazivati na
poetak jednog reda
Deklarisanjem reda dimenzije [kolona+1] pri emu prva kolona
sadri informaciju o stvarnom broju lanova s podacima.
Ukoliko e broj kolona biti identian u svim redovima, onda je
potrebna dimenzija [kolona]
Alociranje memorije
Deklaracija pokazivaa na pokaziva
Alociranje memorije
pok
002F8B08
3
0
kolona-1
kolona-1
002F8B08
004A8B40
004A8118
002F8B0C
004A8B40
004A8158
002F8B10
77
004A8118
0
redova-1
004A8158
pok[1][2] = 77;
kolona-1
Viedimenzionalni nizovi
#include<iostream>
#include<iomanip>
using namespace std;
void main() {
int Kraj=1;
do {
int** niz = nullptr;
int redova =0, kolona = 0;
cout<<"Unesite broj redova: ";
cin>>redova;
niz = new int*[redova]; // da li je potreban assert
for(int i=0;i<redova;i++) {
cout<<"Unesite broj kolona u "<<(i+1)<<". redu: ";
cin>>kolona;
niz[i]=new int[kolona+1];
niz[i][0]=kolona;
for(int j=1;j<=kolona;j++)
niz[i][j]=i*10+j+10;
}
Viedimenzionalni nizovi
//u ovom primjeru svaki red moze imati razlicit broj kolona,
//pa je zbog toga u svakom redu potrebno pamtiti odabrani broj
for(int j=1;j<=kolona;j++)
niz[i][j]=i*10+j+10;
}
//ispis
cout<<"Ispis clanova polja: "<<endl;
Unesite broj redova: 3
for(int i=0;i<redova;i++) {
Unesite broj kolona u 1. redu: 5
cout<<endl;
Unesite broj kolona u 2. redu: 8
Unesite broj kolona u 3. redu: 2
for(int j=1;j<=niz[i][0];j++)
Ispis clanova polja:
cout<<setw(4)<<niz[i][j];
}
11 12 13 14 15
21 22 23 24 25 26 27 28
//dealokacija
31 32
for(int i=0;i<redova;i++)
Za nastavak <1>, za kraj <0>:
delete[]niz[i];
delete[]niz;
niz = NULL;
cout<<endl<<"Za nastavak <1>, za kraj <0>: ";
cin>>Kraj;
}while(Kraj==1);
}
Viedimenzionalni nizovi
#include<iostream>
#include<iomanip>
#include<assert.h>
using namespace std;
void Unos(int ** niz, int redova, int kolona){
for(int i=0;i<redova;i++)
for(int j=0;j<kolona;j++){
//ako zelite unositi vrijednosti clanova niza
//uklonite komentar sa naredne dvije linije code-a
//a stavite komentar na trecu liniju koja automatski
//inicijalizuje vrijednosti
//cout<<"niz["<<i<<"]["<<j<<"]: ";
//cin>>niz[i][j];
niz[i][j]=i*10+j+10;
}
}
void Alokacija(int **& niz, int & redova, int & kolona){
cout<<"Unesite dimenzije matrice: ";
cin>>redova>>kolona; //obavite provjere validnosti
niz = new int*[redova];
assert(niz!=NULL);
for(int i=0;i<redova;i++)
niz[i]=new int[kolona];
}
Viedimenzionalni nizovi
Viedimenzionalni nizovi
void main() {
int Kraj=1;
do {
int** niz = NULL;
int redova=0, kolona=0;
Alokacija(niz,redova,kolona);
Unos(niz,redova,kolona);
Ispis(niz,redova,kolona);
Dealokacija(niz,redova);
cout<<endl<<"Za nastavak <1>, za kraj <0>: ";
cin>>Kraj;
}while(Kraj==1);
Unesite dimenzije matrice: 5 8
}
+----+----+----+----+----+----+----+----+
| 10| 11| 12| 13| 14| 15| 16| 17|
+----+----+----+----+----+----+----+----+
| 20| 21| 22| 23| 24| 25| 26| 27|
+----+----+----+----+----+----+----+----+
| 30| 31| 32| 33| 34| 35| 36| 37|
+----+----+----+----+----+----+----+----+
| 40| 41| 42| 43| 44| 45| 46| 47|
+----+----+----+----+----+----+----+----+
| 50| 51| 52| 53| 54| 55| 56| 57|
+----+----+----+----+----+----+----+----+
Za nastavak <1>, za kraj <0>:
Zadatak
Za vjebu rada s dinamikim viedimenzionalnim poljima u
nastavku je opisan jednostavan problem stepenovanja
(gradacije) studenata na takmienju iz programiranja
Analiza
Problem podataka: Potrebno je pronai metodu koja e omoguiti da
se, nakon uitavanja, sauvaju svi bodovni rezultati i izraunati
prosjeci svih uesnika
Rjeenje: Program e raditi s tri (3) polja: jedno cjelobrojno
dvodimenzionalno polje dimenzija [N] redova (broj uesnika)* [3]
kolona (uitani rezultati), i dva (2) realna jednodimenzionalna polja jedno od [N] kolona (izraunati prosjeci) i jedno od [3] kolone (skupni
prosjeci pojedinih programskih zadataka):
int (*Bodovi)[N] = new int[N][3];
float * Prosjek = new float[N];
float Prog[3];
Analiza
S obzirom na to da se indeksi u C++ jeziku raunaju od nule (0),
imati emo sljedee algoritme:
int i = rbs - 1;
int j = rbpz - 1;
Organizacija podataka
Naredni crte prikazuje mogue vrijednosti polja Bodovi, Prosjek i Prog za 4
uesnika i 3 programska zadatka.
Prosjek
Bodovi
Prog
10
10
10
10.0
Prosjek[0]
1.0
Prosjek[1]
7.7
Prosjek[2]
10
7.7
Prosjek[3]
7.0
5.3
7.5
Prog[0]
Prog[1]
Prog[2]
Algoritam
KRAJ PREZENTACIJE