Upload
petar-ursic
View
29
Download
0
Embed Size (px)
Citation preview
Programiranje 2 2009 ETF Beograd 1/34
P2: Sedma nedeljaPokazivai i dinamika alokacija
memorije
Programiranje 2 2009 ETF Beograd 2/34
Zadatak 1 pokazivai (C55a) ta ispisuje sledei program?
#include void main() {
int a[]={1,0}, *p;p=a;printf("%d, ", *p++);printf("%d\n", *p);
}
Odgovori:A) 1, 2B) 1, 0C) 0, 0
Programiranje 2 2009 ETF Beograd 3/34
Pokazivai Pokaziva je promenljiva koja sadri adresu neke
lokacije u operativnoj memoriji svi pokazivai imaju istu veliinu, u zavisnosti od veliine adresnog
prostora na odgovarajuoj maini
Definisanje pokazivaatip *ime;
tip predstavlja tip podatka na koji se pokazuje (int, double) tip je potreban da bismo znali o kakvom se podatku radi prilikom
pristupa podatku preko pokazivaa
Adresa nekog podatka se pokazivau dodeljuje pomou adrsnog operatora &
pa = &a; Lokaciji na koju pokaziva ukazuje se pristupa
pomou operatora za indirektan pristup (dereferenciranje) *
*pa = 1;Programiranje 2 2009 ETF Beograd 4/34
Adresna aritmetika Dodela vrednosti
pa = pb; Sabiranje i oduzimanje celobrojnog podatka
jedinica mere pri sabiranju i oduzimanju pokazivaa sa celobrojnimpodatkom je veliina pokazivanog podatka!
pa = pa + x; nova adresa pa e biti formirana kao zbir stare adrese pa i
x*sizeof(pokazani_tip) Oduzimanje i uporeivanje dva pokazivaa
binarni operator za oduzimanje i svi relacioni operatori ima smisla samo za pokazivae koji pokazuju na elemente istog niza
Uporeivanje pokazivaa sa nulom konstanta 0 ili simbolika konstanta NULL iz
#define NULL (0L) dodela vrednosti 0 ili NULL nekom pokazivau oznaava da pokaziva
ne pokazuje ni na koji podatak
Programiranje 2 2009 ETF Beograd 5/34
Pokazivai i nizovi Ako je definisan neki statiki niz:
int a[] = {1,2,3,4}; Ime niza a predstavlja konstantni pokaziva na poetak niza!
&a[0] a&a[i] a+ia[i] *(a+i)
Zbog ove osobine, pokazivake promenljive se mogu tretirati kao nizovi mogue je koristiti operator za indeksiranje [], kao kod nizova
a+3a+2a+1a+0a[3]a[2]a[1]a[0]4321a:
Programiranje 2 2009 ETF Beograd 6/34
Zadatak 1 - reenje Posmatramo deklaraciju:
int a[]={1,0} a je niz celih brojeva, indeksira se od 0 duina niza nije eksplicitno zadata, ali se moe doznati iz broja inicijalizatora
Dodela vrednostip=a;
01a:
01a:
p
Programiranje 2 2009 ETF Beograd 7/34
Zadatak 1printf("%d, ", *p++);
Prioritet operatora * i ++ je jednak, ali je asocijativnost ove grupe operatora sdesna ulevo
Prema tome, prvo e se izvriti operator ++, ime se uveava vrednost pokazivaa i on pokazuje na naredni celobrojni podatak u memoriji
Zbog osobine operatora ++, operator * e biti primenjen na staru adresu pokazivaa p i bie ispisana vrednost 1
printf("%d\n", *p); Ispis: 1, 0 Odgovor: B
01a:
p
Programiranje 2 2009 ETF Beograd 8/34
Zadatak 2 pokazivai (C55b) ta ispisuje sledei program?
#include void main() {
int a[]={0, 1, 2, 3, 4};int i, *p;
for (p=a, i=0; p
Programiranje 2 2009 ETF Beograd 9/34
Zadata 2 reenjefor (p=a; p
Programiranje 2 2009 ETF Beograd 13/34
Zadatak 3 reenje Programski jezik C automatski uzima u obzir
veliinu pokazanog podatka prilikom primene operatora ++, --, +, - nad pokazivaima
Veliina nekog podatka u memoriji, izraena u bajtovima, programskim putem moe da se odrediprimenom operatora sizeof(tip) ilisizeof(promenljiva)
p++ p = p + sizeof(*p)
Rezultat je : 1000 + 4 = 1004 Odgovor: C
Programiranje 2 2009 ETF Beograd 14/34
Zadatak 4 obrtanje niza (4.2) Napisati program na programskom jeziku C koji
sa standardnog ulaza uitava niz celih brojeva, obre redosled brojeva u nizu i ispisuje niz redomod poetka.
Algoritam: krenuti sa dva pokazivaa, od poetka i sa kraja zamenjivati mesta pokazanim elementima dok god se pokazivai ne
sretnu
43210a:
p:q:
Programiranje 2 2009 ETF Beograd 15/34
Zadatak 4 - reenje Reenje ciklus sa izlaskom na sredini
#include #define NMAX 100void main () {
int a[NMAX], *p, *q, n;while (1) {printf ("n? "); scanf ("%d", &n);if (nNMAX) break;printf ("A? "); for (p=a; p
Programiranje 2 2009 ETF Beograd 17/34
Dinamika alokacija memorije Prilikom definisanja skalarnih promenljivih ili
nizova, memorija se zauzima statiki sve potrebe za memorijom moraju biti poznate unapred, pre
prevoenja izvornog programa alocira se najee vie prostora nego to je potrebno prostor se zauzima u statikoj zoni memorije bilo kakva izmena kapaciteta zahteva ponovno prevoenje programa
Reenje dinamika alokacija memorije radi se u vreme izvravanja programa broj i veliinu podataka ne moramo znati unpared memorija se alocira u dinamikoj zoni memorije (eng. heap) podacima u dinamikoj zoni memorije se pristupa preko pokazivaa ogranienje samo ukupan raspoloiv memorijski prostor u sistemu
Odgovornost programera za ispravnu alokaciju i dealokaciju dinamike memorije!
Programiranje 2 2009 ETF Beograd 18/34
Manipulacija dinamikom memorijom (1) U C-u se za rad sa dinamikom memorijom koriste funkcije
iz standardnog zaglavlja Zauzimanje dinamike memorije
void* malloc(vel) vel predstavlja traenu veliinu memorije u bajtovima
void* calloc(n,vel) n predstavlja broj elemenata niza vel predstavlja veliinu jednog elementa inicijalizuje zauzeti prostor nulama
Obe funkcije vraaju generiki (void) pokaziva! ovakav pokaziva sadri samo adresu, a nije poznat tip podatka na koji ukazuje ne moe se dereferencirati, niti koristiti u adresnoj aritmeticij, osim poreenja ukoliko elimo da pristupimo memoriji preko njega, moramo izvriti eksplicitnu
konverziju (cast) u neki tip
Ukoliko je alokacija neuspena ove funkcije vraaju NULL
Programiranje 2 2009 ETF Beograd 19/34
Manipulacija dinamikom memorijom (2)
Zauzeta memorija se obavezno mora osloboditifree(p)
gde je p pokaziva koji sadri poetnu adresu bloka u memoriju koji je zauzet sa malloc, calloc ili realloc
Promena veliine zauzetog prostoravoid* realloc(p, vel)
menja veliinu dodeljene memorije na koju ukazuje pokaziva p na velbajtova
bie detaljno objanjeno kasnije
Programiranje 2 2009 ETF Beograd 20/34
Zadatak 4 dinamiki nizovi Modifikovan da radi sa dinamikim nizovima
#include #include
void main () {int *a, *p, *q, n;printf ("n? "); scanf ("%d", &n);
while (n>0) {a = calloc(n, sizeof(int));if (a == NULL) {
printf("Neuspesna alokacija memorije!");exit(1);
}
Programiranje 2 2009 ETF Beograd 21/34
Zadatak 4printf ("A? "); for (p=a; p
Programiranje 2 2009 ETF Beograd 25/34
Dinamike matrice (2) U C-u je mogue definisanje pokazivaa na neki
drugi pokaziva, do proizvoljne "dubine" pokaziva na pokaziva na celobrojni podatak
int **p; Prvi korak u stvaranju dinamike matrice je
alokacija memorije za niz pokazivaa p = calloc(m, sizeof(int*));
p je statiki alociran dvostruki pokaziva u koji e biti smetena adresa niza pokazivaa
m je broj vrsta (redova) matrice svaki pokaziva u alociranom nizu pokazivaa e ukazivati na jedan niz
elemenata koji e predstavljati vrste (redove) matrice p mora biti dvostruki pokaziva, jer da bi se pristupilo jednom elementu
matrice (p[i][j]), mora se prvo odrediti adresa i-te vrste i pristupiti i-tom pokazivau u nizu pokazivaa, a zatim odrediti adresa j-tog elementa u nizu elemenata i pristupiti tom elementu
p[i][j] *(*(p+i)+j)Programiranje 2 2009 ETF Beograd 26/34
Dinamike matrice (3) Drugi korak u stvaranju dinamike matrice je
alokacija vrsta matrice
for (i=0; i
Programiranje 2 2009 ETF Beograd 29/34
Zadatak 6 Izraz: *(*(a+i)+n-1-i));
15
11
7
3
161413->a[3]
12109->a[2]
865->a[1]
421->a[0]Za i = 3*(a + 3) a[3]
*(*(a + 3) + 4 1 - 3) a[3][0]
15
11
7
3
161413->a[3]
12109->a[2]
865->a[1]
421->a[0]Za i = 1*(a + 1) a[1]
*(*(a + 1) + 4 1 - 1) a[1][2]
Ispisuje sadraj sporedne dijagonale matrice sleva-udesno (odozdo nagore)
Odgovor: AProgramiranje 2 2009 ETF Beograd 30/34
Zadatak 7 transponovanje (4.5) Sastaviti na jeziku C program za transponovanje
pravougaone matrice celih brojeva. Matricu smestiti u dinamiku zonu memorije. Postupak ponavljati sve dok se za dimenzije matrice ne unesu nekorektne vrednosti.
Transponovanje matrice: zamena mesta vrsta i kolona matrice prva vrsta postaje prva kolona, druga vrsta druga kolona itd...
222
444333
111
333
421421421
=>
Programiranje 2 2009 ETF Beograd 31/34
Zadatak 7 - reenje Reenje uz ouvanje originalne matrice
#include #include void main () {int **a, **b, m, n, i, j;printf ("\nBroj vrsta i kolona? ");scanf ("%d%d", &m, &n);while (m>0 && n>0) {
/* Stvaranje matrice i citanje elemenata matrice: */a = malloc (m*sizeof(int*));for (i=0; i
Programiranje 2 2009 ETF Beograd 33/34
Zadatak 7 Reenje uz izmenu originalne matrice
zadata matrica ne mora biti kvadratna mora se alocirati prostor kao za kvadratnu matricu cija je dimenzija jednaka
vecoj dimenziji zadate matrice
#include #include void main () {int **a, dim, m, n, i, j, t;/* Citanje dimenzija matrice: */printf ("\nBroj vrsta i kolona? ");scanf ("%d%d", &m, &n);while (m>0 && n>0) {
dim = (m > n) ? m : n;
Programiranje 2 2009 ETF Beograd 34/34
Zadatak 7a = malloc (dim*sizeof(int*));for (i=0; i