Professional Documents
Culture Documents
C++ Pokaz I Nizovi PDF
C++ Pokaz I Nizovi PDF
6 Pokazivai u C++
5.6.1 Osnove pokazivaa
5.6.2 Osnovna podruja primjene pokazivaa
5.6 Pokazivai u C++
Pokazivai u osnovi predstavljaju memorijske adrese. Na tim adresama mogu se nalaziti
podaci razliitih tipova : varijable, funkcije ili objekti. Takve podatke kojima pristupamo preko
pokazivaa nazivamo dinamikim, i to zato jer njihova lokacija u memoriji nije zadana
prilikom prevoenja programa, nego tek u toku izvravanja.
Upotreba pokazivaa doprinosi fleksibilnosti programiranja : pokazivaka varijabla koja
sadri adresu jednog dinamikog podatka moe se preusmjeriti tako da pokazuje na neki
drugi dinamiki podatak istog tipa.
Uobiajena, tzv. statika varijabla predstavlja imenovani memorijski prostor, koji sadri
vrijednost. Na primjer, ako napiemo ovako :
int a;
a = 10;
int *p;
ovime kaemo da je varijabla p pokaziva na dinamiku varijablu tipa int. Sada pokazivakoj
varijabli treba dodijeliti memorijski prostor za dinamiku varijablu :
p = new int;
time osiguramo da neka nova naredba new ne zauzme isti memorijski prostor, odnosno, da
ne brljamo po ve rezerviranom prostoru. Dinamikoj varijabli moemo pridruiti vrijednost :
*p = 100;
Kada dinamika varijabla vie nije potrebna, poeljno je osloboditi (dealocirati) memorijski
prostor koji zauzima :
delete p;
Time se memorijski prostor dinamike varijable oslobaa za neku drugu namjenu, ali
pokaziva zadrava staru vrijednost, to je potencijalno opasno. Zbog toga je poeljno
takvom, trenutno slobodnom pokazivau pridruiti vrijednost NULL (nulta adresa, oznaava
neupotrijebljeni pokaziva) :
p = NULL;
ili
p = 0;
Dok pokazivai sadre adrese dinamikih podataka, pomou adresnog operatora moemo
dohvatiti adresu nekog statikog podatka. Primjer :
int *pok;
int a = 10;
pok = &a; // usmjeravamo pokaziva na statiku varijablu a
cout << *pok << endl; // ispisuje se 10
Izraz &a ima znaenje memorijska adresa varijable a i moe se pridruiti pokazivau.
Adresni operator moemo iskoristiti za prosljeivanje adrese neke podatkovne strukture
funkciji :
#include <iostream.h>
#include <string.h>
struct tslog{
int mat_br;
char prez_i_ime[30];
};
void ispis(tslog *arg){ // pokaziva arg dobiva adresu strukture
cout << arg -> mat_br << endl;
cout << arg -> prez_i_ime << endl;
};
void main(){
tslog slog;
slog.mat_br = 32000;
strcpy (slog.prez_i_ime,"Mati Mate");
ispis (&slog); // prosljeujemo adresu strukture
}
U primjeru prosljeujemo funkciji ispis adresu strukture slog, koju ova dohvaa pomou
pokazivaa *arg.
5.6.1.1.1 Reference
Reference se oznaavaju adresnim operatorom (&), a slue kao drugo ime za neki
memorijski prostor. Primjer :
int a = 10;
int &b = a;
cout << b << endl; // 10
#include <iostream.h>
#include <string.h>
struct tslog{
int mat_br;
char prez_i_ime[30];
};
void ispis(tslog &arg){ // referenca arg predstavlja drugo ime za
// strukturu slog
cout << arg.mat_br << endl;
cout << arg.prez_i_ime << endl;
};
void main(){
tslog slog;
slog.mat_br = 32000;
strcpy (slog.prez_i_ime,"Mati Mate");
ispis (slog); // identifikator slog bit e zamijenjen referencom
}
U ovom sluaju argument arg predstavlja drugo ime za memorijski prostor koji zauzima
struktura slog.
Strukture podataka koje zauzimaju memorijski prostor u toku izvoenja programa nazivamo
dinamikim. Tipini primjer za dinamike strukture podataka je vezana lista. Svaki element
vezane liste sadri pokaziva s adresom slijedeeg (eventualno i drugi pokaziva s adresom
prethodnog) elementa liste. Pokaziva zadnjeg elementa u listi ima vrijednost NULL, to
oznaava kraj liste. U sluaju da dodajemo novi element u listu, tada jednostavno njegovu
adresu pridruimo pokazivau do sada zadnjeg elementa liste. Dakle, broj elemenata nije
unaprijed zadan, nego se mogu dodavati novi tako dugo dok ima raspoloivog memorijskog
prostora.
Vezana lista je vrlo pogodna struktura za objektno-orijentirano programiranje, kakvo nam
omoguuje C++. Naime, elementi liste mogu biti objekti, implementacije jedne, zajednike
osnovne klase ili iz njih izvedenih klasa. Iz toga proizlazi da elementi liste mogu biti
heterogeni. Zahvaljujui polimorfizmu, svim elementima liste moemo pristupiti pomou istog
pokazivaa (vidi : Primjer (dvostruko vezana lista s heterogenim elementima).
5.6.2.2 Pokazivai i reference kao zamjena za varijabilne argumente funkcija
var x, y : integer;
procedure proc1 (a : integer; var b : integer);
begin
a := 10;
b := 10;
end;
begin
x := 5;
y := 5;
proc1 (x,y);
writeln (x = , x);
writeln (y = , y);
end;
Ispisuje se :
x=5
y = 10
#include <stdio.h>
int x, y;
void proc1 (int a, int *b){
a = 10;
*b = 10;
};
void main (){
x = 5;
y = 5;
proc1 (x, &y);
printf ("x = %d\n",x);
printf ("y = %d\n",y);
}
#include <iostream.h>
int x, y;
void proc1 (int a, int &b){
a = 10;
b = 10;
};
void main (){
x = 5;
y = 5;
proc1 (x, y);
cout << "x = " << x << endl;
cout << "y = " << y << endl;
}
Niz znakova (za koji u Pascalu koristimo tip string) u C/C++ predstavlja jednostavno polje
znakova. U slijedeoj programskoj liniji definiramo polje znakova koje moe sadravati do
100 znakova :
char niz[101];
U ovom polju niz[0] predstavlja prvi znak niza, a niz[100] zadnji znak u nizu. Na kraju niza
nalazi se znak za terminiranje niza ASCII vrijednost nula (nul znak), koji se oznaava s \0.
Odnosno, kaemo da C/C++ radi s nul-terminiranim nizovima znakova. Primjer :
var
niz : string [100];
Definiran je niz znakova veliine najvie 100 znakova. Meutim, ne koristi se znak za
terminiranje, nego nulti lan niza sadri podatak o duini niza. Primjer :
Iz ovoga se takoer vidi da nizovi u Pascalu ne mogu sadravati vie od 255 znakova, dok u
C/C++ nisu ogranieni po duljini.
5.6.2.3.2 Operacije nad poljima znakova
Za razliku od npr. Pascala, C/C++ nema ugraenu podrku za rad s nizovima znakova, nego
se oslanja na standardne biblioteke. Na primjer, elimo li u C++ realizirati neto ovakvo
(primjer u Pascalu) :
var
niz1, niz2 : string;
begin
niz1 := Primjer u Pascalu;
niz2 := niz1;
if niz1 = niz2 then
writeln (Nizovi su isti!);
end;
#include <iostream.h>
#include <string.h>
void main(){
char niz1[100], niz2[100];
strcpy (niz1, Primjer u C/C++);
strcpy (niz2, niz1);
if (strcmp(niz1, niz2) == 0)
cout << Nizovi su isti! << endl;
}
U C/C++ ne moe se jednostavno pridruiti jedno polje drugom. Umjesto toga za nizove
znakova koristimo funkciju strcpy, odnosno funkciju strcmp za usporeivanje vrijednosti
nizova. Za sluaj da elimo spojiti nizove, odnosno saznati duljinu niza, koristimo funkcije
strcat, odnosno strlen :
#include<iostream.h>
void main(){
char *s2;
s2 = "Programiranje u C++";
cout << s2 << endl;
}
Ispisuje se :
Programiranje u C++
Instrukcija cout u ovom sluaju ne ispisuje adresu, nego, zahvaljujui ugraenoj konverziji
tipova podataka (s2 je definiran kao pokaziva na znakovni tip podataka), sadraj
odgovarajuih memorijskih lokacija, do znaka za terminiranje. U sluaju da elimo ispisati
adresu, tada koristimo odgovarajui operator dodjele tipa :
#include <string.h>
#include <iostream.h>
void main(){
char s1[100]; // polje od 100 znakova
strcpy (s1,"Programiranje u C++");
Ispisuje se :
Programiranje u C++
C++
#include <iostream.h>
void main(){
char ispiti [3][16] = {"Matematika","Statistika","Programiranje I"};
cout << ispiti[2] << endl; // Programiranje I
}
Ovaj pristup ima taj nedostatak da moramo zadati obje dimenzije niza, to znai da emo
imati neiskoriteni memorijski prostor. Umjesto toga, moemo definirati polje pokazivaa :
#include <iostream.h>
void main(){
char *ispiti[4] = {"Matematika","Statistika","Programiranje I"};
cout << ispiti[2] << endl; // Programiranje I
ispiti[3] = "Engleski jezik";
cout << ispiti[3] << endl; // Engleski jezik
}
Sadraj odgovarajuih memorijskih lokacija bit e slijedei (u uglatoj zagradi je indeks polja
pokazivaa ispiti) :
[0] [1]
M a t e m a t i k a \0 S t a t i s t i k a
[2] [3]
\0 P r o g r a m i r a n j e I \0 E n g l
e s k i j e z i k \0
Dakle, vidimo da ovdje imamo bolje iskoritenje memorijskog prostora. Ako gornjem
promjeru dodamo slijedeih nekoliko programskih redaka :
char *pom;
pom = ispiti[0];
ispiti[0] = "Oblikovanje baza podataka";
cout << ispiti[0] << endl; // Oblikovanje baza podataka
cout << pom << endl; // Matematika
rezultat e biti da emo pokazivau ispiti[0] pridruiti novi memorijski sadraj (adresu teksta
Oblikovanje baza podataka). Primjer radi, meutim, ostaje nam memorijski sadraj na
memorijskoj lokaciji na koju je prije pokazivao ispiti[0], koju smo sauvali u pokazivau pom,
na to treba obratiti panju u radu s pokazivaima, jer se prijanja uteda memorijskog
prostora u tom sluaju gubi.