Upload
truongminh
View
225
Download
3
Embed Size (px)
Citation preview
1.3.2011
1
POKAZIVAČI
Odjel za matematiku 1
Pokazivači, dinamička alokacija memorije
VJEŽBE 1
Pokazivači
Odjel za matematiku 2
Ponovimo …
Svakoj varijabli u programu pridružena je memorijska lokacija (ili blok lokacija)čija veličina ovisi o tipu varijable.Svakoj memorijskoj lokaciji pridružena je jedinstvena adresa.
adresa varijable = adresa prve lokacije u bloku memorijskih lokacija kojipredstavljaju varijablu.
Varijabli se može pristupiti korištenjem:imena varijable — prevoditelj “zna” adresu,adrese varijable — pokazivačem na tu varijablu.
VJEŽBE 1
1.3.2011
2
Pokazivači
Odjel za matematiku 3
Deklaracija pokazivača
Pokazivač nekog tipa je varijabla koja sadrži adresu neke varijable tog tipa:
tip *p;
int *pi //pokaziva č tipa intchar *pc // pokaziva č tipa charfloat *f // pokaziva č tipa floatvoid *p //generi čki pokaziva č
*p=NULL //prazan pokaziva č
Primjer
VJEŽBE 1
Pokazivači
Odjel za matematiku 4
Operatori pokazivača
Adresni operator &x= //adresa varijable x
Operator referenciranja
*ptr= // vrijednost spremljena u memorijsku lokaciju na koju pokazuje ptr
VJEŽBE 1
1.3.2011
3
Pokazivači
Odjel za matematiku 5
Inicijalizacija pokazivača
int i=5; //cjelobrojna varijabla sa sadržajem 5int *pi=&i;
VJEŽBE 1
Pokazivači
Odjel za matematiku 6
Operacije nad pokazivačima
Dozvoljene operacije nad pokazivačima:� svakom pokazivaču možemo dodati ili oduzeti cijeli broj� oduzimanje pokazivača istog tipa� usporeñivanje pokazivača istog tipa relacijskim
operatorima
++px --px px + n px – n//px pokaziva č i n varijabla cjelobrojnog tipa
VJEŽBE 1
1.3.2011
4
Pokazivači
Odjel za matematiku 7
Primjer 1:
int main(){float x[]={1.0,2.0},*px=x; // px=&x[0]printf("Vrijednosti: x[0]=%g,x[1]=%g\n",x[0],x[1]);printf("Adrese: x[0]=%p, x[1]=%p\n",px,px+1);
}
Vrijednosti: x[0]=1.0,x[2]=2.0Adrese: &x[0]=0012FF44, &x[1]=0012FF48
Pristupanje elementima polja pokazivačem.
VJEŽBE 1
Pokazivači
Odjel za matematiku 8
Primjer 2:
#include <stdio.h>int main(void){
double x[] = {10.0, 20.0, 30.0, 40.0}, *px;px=&x[0];printf("%g, %g\n", *px+1, *px+2); /* 11, 12 */px=&x[0];printf("%g, %g\n", *px++, *px+2); /* 10, 22 */return 0;
}
Po pokazivačima i vrijednostima na koji pokazuju može se inkrementirati.
VJEŽBE 1
1.3.2011
5
Pokazivači
Odjel za matematiku 9
Primjer 3:
int d(int a[]) {int *pa = a;while (*pa != 0) ++pa;return pa - a; /* razlika pokazivaca */}-----------------------…-----------------------int x[5] = {3, 2, 0, 0, 4};...printf("%d\n", d(x)); //output: 2
Pokazivači istog tipa mogu se oduzimati.
VJEŽBE 1
Pokazivači i jednodimenzionalna polja
Odjel za matematiku 10
Neka je p bilo koji pokazivač osim generičkog.Onda p možemo interpretirati kao:
1. pokazivač na prvi element u polju odgovarajućeg tipa, p=&p[0]
2. Pristupanje ostalim elementima polja uključuje aritmetiku nad pokazivačem p.
Veza izmeñu aritmetike pokazivača i indeksiranja elemenata polja je :p+i=&p[i], *(p+i)=p[i]
gdje je i cijeli broj.
char *px, x[28]={‘a’,’b’,...,’z’};px = &x[0]; /* Isto kao px = x; */*(px + 3) = ’d’; /* Isto kao x[3] = ’d’; */px++; /* Isto kao px = &x[1]; */*(px + 1) = ’b’; /* Isto kao px[1] = ’b’;ekviv. s x[2] = ’b’; */*(px + 30) = ’z’; /* NIJE GRESKA,
ali prelazimo po memoriji! */
VJEŽBE 1
1.3.2011
6
Nizovi
Odjel za matematiku 11
Zadatak. 1 “Zbroj elemenata” primjenom pokazivača
Napravite program koji će za uneseni niz realnih podataka ispisati sumu njegovih elemenata primjenom pokazivača.
VJEŽBE 1
Pokazivači i funkcije
Odjel za matematiku 12
Polje može biti argument funkcije. Funkcija tada ne dobiva kopiju čitavog polja, već samo kopiju pokazivača na prvi element polja.
void funkcija(float v[]) ili void funkcija (float *v )
Zadatak 2 “Aritmetička sredina” primjenom pokazivača
Napravite funkciju koji će za uneseni niz realnih podataka ispisati aritmetičku sredinu njegovih podataka. Primjenite pokazivače.
VJEŽBE 1
1.3.2011
7
Pokazivači i funkcije
Odjel za matematiku 13
Osim pokazivača na osnovne tipove podataka postoje i pokazivači na funkcije.
int (*fptr)(int)
Definiran je pokazivač fptr na funkciju koja prima jedan int argument i vraća int vrijednost.
Primjer 3:
double integracija(double a, double b, double (*f)( double)){return 0.5*(b-a)*((*f)(a)+(*f)(b));}…printf("Sinus: %f\n",integracija(0,1,sin));…
VJEŽBE 1
Pokazivači i višedimenzionalna polja
Odjel za matematiku 14
Indeksiranje jednodimenzionalnog polja
Indeksiranje po dvodimenzionalnom polju:
VJEŽBE 1
1.3.2011
8
Pokazivači i stringovi
Odjel za matematiku 15
Analogija jednodimenzionalnog polja – string je niz tipa char.
Indeksiranje po stringu:
Primjer 4:
void strcpy(char *s, char *t){ //kopiranje stringov awhile((*s=*t)!='\0') {
s++;t++;}
}
VJEŽBE 1
Dinamička alokacija memorije
Odjel za matematiku 16
Rezerviranje memorije za objekte (varijable) može biti:� statički – prilikom definicije i inicjializacije varijabli memorija se
automatski rezervira. Nakon završetka programa memorija se oslobaña automatski.
� dinamički – proizvoljna veličina memorije može se staviti na raspolaganje varijablama i bude tako alocirana sve dok je eksplicitno ne oslobodimo.
VJEŽBE 1
1.3.2011
9
Dinamička alokacija memorije
Odjel za matematiku 17
Dinamička memorija – upotreba:- polja za koje nije unaprijed zadana dimenzija- dinamičke strukture: povezane liste, stabla, matrice …
Funkcije za alokaciju i delokaciju memorije su deklarirane u biblioteci <stdlib.h>:
- alokacija: funkcije malloc, calloc (C)operator new (C++)
- delokacija: funkcija free (C)operator delete (C++)
VJEŽBE 1
Dinamička alokacija u C-u
Odjel za matematiku 18
size_t cjelobrojni tip bez predznakan - ukupan broj bajtova koje treba rezervirati
Funkcija malloc rezervira blok memorije od n bajtova. Vraća:• pokazivač na rezervirani blok memorije, ili• NULL, ako zahtjev nije mogao biti ispunjen.
Vraćeni pokazivač je generički, tipa void* — prije upotrebe treba ga eksplicitno konvertirati u potrebni tip pokazivača (cast operatorom).
malloc
VJEŽBE 1
1.3.2011
10
Dinamička alokacija u C-u
Odjel za matematiku 19
Funkcija calloc rezervira blok memorije za spremanje:� nobj objekata, od kojih svaki pojedini objekt ima veličinu size , tj. ukupan broj
rezerviranih bajtova je nobj * size .� inicijalizira cijeli rezervirani prostor na nule, preciznije, na nul-znakove (’\0’).
Vraćeni pokazivač je generički, tipa void* — prije upotrebe treba ga eksplicitno konvertirati u potrebni tip pokazivača (cast operatorom).
calloc
VJEŽBE 1
Dinamička alokacija u C-u
Odjel za matematiku 20
double *p;p=(double *) malloc(128*sizeof(double)); // ili ...p = (double *) calloc(128, sizeof(double)); if(p==NULL) {printf("Greska: alokacija nije uspjela!");exit(-1);}
Primjer 5:
Alokacija bloka memorije od 128 objekata tipa double.
VJEŽBE 1
1.3.2011
11
Dinamička alokacija u C-u
Odjel za matematiku 21
Alociranu memoriju, nakon upotrebe, možemo osloboditi funkcijom free .
Funkcija free uzima pokazivač p na početak alociranog bloka memorije i oslobaña taj blok memorije.
Funkcija free ne mijenja pokazivač p. Nakon poziva free(p) ; taj pokazivač i dalje pokazuje na (sad) osloboñeni dio memorije i ne smije se koristiti.
Najbolje je odmah iza poziva free(p) ; staviti i p = NULL ;.
free
VJEŽBE 1
Dinamičko alokacija u C-u
Odjel za matematiku 22
Primjer 6:
#include<cstdlib>#include<stdio.h>
int main(){int *a;int i, n, zbroj;
printf("Upisi broj elemenata polja a: ");scanf("%d",&n);if ((a=(int*) calloc(n,sizeof(int)))==NULL){
printf("Alokacija nije uspjela"); exit(-1);}for (i=0;i<n;i++){
printf("Upisi element polja: ");scanf("%d",&a[i]);
}zbroj=0;for(i=0;i<n;i++)
zbroj=zbroj+a[i];printf("%d ",zbroj);free(a);}
Program dinamički stvori polje a tipa int s tim da se duljina polja nučitava. Ispisuje zbroj elemenata.
VJEŽBE 1
1.3.2011
12
Dinamičko alokacija u C++-u
Odjel za matematiku 23
float tip podatkan - ukupan broj bajtova koje treba rezervirati
Operator new rezervira blok memorije od n bajtova. Vraća:� pokazivač na rezervirani blok memorije, ili� NULL, ako zahtjev nije mogao biti ispunjen.
Ukoliko se ne može rezervirati memorijski prostor C++ podiže iznimku.
new
float *b=new float[n]
VJEŽBE 1
Dinamičko alokacija u C++-u
Odjel za matematiku 24
Operator delete osloboña rezervirani blok memorije od n bajtova. Premda vraća alocirane blokove memorije na ponovo raspologanje korisno je i pokazivač koji je pokazivao na alocirani memorijski sadržaj postaviti na NULL kako bi se izbjegli problemi memorijske redundancije.
delete
delete [ ]b;
delete [ ]b;b=NULL;
VJEŽBE 1
1.3.2011
13
Dinamičko alokacija u C++-u
Odjel za matematiku 25
Primjer 7:
#include<cstdlib>#include<iostream.h>int main(){
cout<<"Upisite n:";int i,n;cin>>n;float *a=new float[n];float suma=0;
cout<<"Upisite elemente polja: "<<endl;for(i=0;i<n;i++){
cin>>a[i];suma=suma+a[i]; }
cout<<"Zbroj elemenata polja je "<<suma;delete []a;system("PAUSE");
}
Program dinamički kreira polje a tipa float s tim da se duljina polja nučitava. Ispisuje zbroj elemenata.
VJEŽBE 1
Dinamička alokacija u C++-u
Odjel za matematiku 26
Primjer 8:
void matvec(float **A, float *b, float *x, int n){for(int i=0;i<n;i++){
float temp=0;for (int j=0;j<n;j++)temp=temp+A[i][j]*x[j];}
}int main(){
int n;int i;printf("Upisite n:"); scanf("%d",&n);float *b=new float[n];float *x=new float[n];for(i=0;i<n;i++) x[i]=i;
float **A; //A je pokazivac na pokazivac;A=new float*[n]; // alociraj spremanje za n pokaziv ačafor(i=0;i<n;i++)
A[i]=new float[n]; //alociraj spremanje za matricufor(i=0;i<n;i++) // inicijalizacija vrijednosti
for(int j=0;j<n;j++)A[i][j]=i+j;
matvec(A,b,x,n);printf("%3.2f %3.2f",&b[0],&b[1]); system("PAUSE");
}
Množenje matrice s vektorom.
VJEŽBE 1
1.3.2011
14
Zadaci
Odjel za matematiku 27
Napiši program koji će koristiti funkciju locate(s,c) gdje je s string, a c znak za koji želimo znati na kojem se mjestu stringu pojavio prvi puta.
Napiši C++ program koji će izračunati duljinu stringa pomoću funkcije strlen(const char* s) (Potrebno je definirati takvu funkciju)
Zadatak. 5.2: “strlen” u C++
Zadatak. 5.1: “Nadji znak” u C++
Napiši C++ funkciju strcat koja će za 2 stringa s1,s2 izvršiti konkatenaciju s2 na s1; char* strcat (char* sl, const char* s2)
Zadatak. 5.3: “strcat” u C++-u
VJEŽBE 1
Odjel za matematiku 28
STRUKTURE
Apstraktni tipovi podataka
VJEŽBE 1
1.3.2011
15
Strukture
Odjel za matematiku 29
Struktura je složeni tip podataka, kao i polje. Za razliku od polja, koje služigrupiranju podataka istog tipa, struktura služi grupiranju podataka različitih tipova.
Elementi (ili članovi) strukture mogu, ali ne moraju, biti različitog tipa i svaki element ima svoje posebno ime.
Uvod ...
Kako predstaviti na kompaktan način strukture podataka koje sadrže u
sebi različite tipove podataka?
Primjer: Baze podataka, povezane liste, kompleksni brojevi, ...
Odgovor: ADT – apstract data type
VJEŽBE 1
Deklaracija strukture
Odjel za matematiku 30
struct – rezervirana riječ, a ime je ime strukture, tip_1, tip_2, … tipovi podataka s pripadnim imenima varijabli
Primjer 1:
struct tocka{int x;int y;
}struct tocka p1,p2;
typedef struct {int x;int y;} Tocka;...Tocka t1, t2, *pt1;
Deklaracija
VJEŽBE 1
1.3.2011
16
Inicijalizacija strukture
Odjel za matematiku 31
struct – ključna riječ za definiciju strukture, racun je ime strukture, int, char, float tipovi podataka s pripadnim imenima varijabli
struct racun kupac = { 1234, "Pero Bacilova“,-12345 .00 };
struct racun kupci[] = { // polje ciji elementi su tipa struct kupac2234, "Goga", 456.00, 1235, "Josip", -234.00,436, "Martina", 0.00 };
struct racun {int broj_racuna;char ime[80];float stanje;};
Inicijalizacija
VJEŽBE 1
Inicijalizacija strukture
Odjel za matematiku 32
Struktura može u svojoj definiciji sadržavati i drugu strukturu:
struct pravokutnik {struct tocka pt1; /* ili Tocka pt1; */struct tocka pt2; /* ili Tocka pt2; */};
Deklaracija strukture tocka mora prethoditi deklaraciji strukture pravokutnik.
Članovima strukture se može pristupati membership operatorom .
struct tocka{int x;int y;
}struct tocka p1,p[10];
p1.x=1 //prvi clan od p1p2.y=0 //drugi clan od p1p[5].x=-2.3 //prvi clan petog
elementa polja tipa tocka
VJEŽBE 1
1.3.2011
17
Strukture i funkcije
Odjel za matematiku 33
Operacije nad strukturom kao cjelinom su:� Pridruživanje.� Uzimanje adrese, primjena sizeof operatora.� Struktura može biti argument funkcije, funkcija tada dobiva kopiju
strukture kao argument;� funkcija može vratiti strukturu.
struct tocka {int x;int y;} t, ishodiste = {0, 0};
struct tocka suma(struct tocka p1, struct tocka p2) {p1.x+=p2.x;p1.y+=p2.y;return p1;}
Primjer 2:
VJEŽBE 1
Strukture i pokazivači
Odjel za matematiku 34
Pokazivač na strukturu definira se kao i pokazivač na osnovne tipove varijabli.
struct tocka {int x;int y;} p1, *pp1;...pp1 = &p1;(*pp1).x = 13;(*pp1).y = 27;*pp1.x = 13; /* GRESKA *//* *pp1.x je isto sto i *(pp1.x) */// ILI …pp1->x = 13;pp1->y = 27;
Primjer 4:
Jednostavniji način korištenja pokazivača na strukture :
VJEŽBE 1
1.3.2011
18
Zadaci
Odjel za matematiku 35
Napišite program koji će definirati strukturu complex. typedef struct {
float re;float im;
} complex;
Definirajte slijedeće operacije nad strukturom:1. float modul(complex z) – funkcija koja vraća modul vrijednost
kompleksnog broja z.2. complex sum(complex z1,complex z2) – funkcija koja računa zbroj 2
kompleksna broja3. complex devide(complex z1,complex z2) – funkcija koja računa
kvocijent 2 kompleska broja4. complex power(complex z1, int n) – funkcija koja vraća n-tu potenciju
kompleksnog broja
Zadatak. 6.1: “Kompleksni broj” u C++
VJEŽBE 1
Primjena: Povezane liste
Odjel za matematiku 36
Uvod
Promotrimo slučaj gdje imamo vektor velike dimenzije s relativno malo elemenata različitih od 0:
Problem: veliki dio memorije rezerviran, relativno malo iskorišteno. Rješenje: spremati podatke na strukturu koja “pamti” samo unesene vrijednosti, ali dopuštati da je struktura dinamička (npr. zbrajanje vektora u mjestu).
VJEŽBE 1
1.3.2011
19
Primjena: Povezane liste
Odjel za matematiku 37
Povezane liste
Povezana lista – apstraktna struktura podataka u kojoj se objekti nalaze u linearnom poretku.Povezana lista je određena pokazivačem na sljedeći objekt – “samoreferentna struktura”, za razliku od polja koji ima direktan pristup elementima.
headhead pointer pointer pointer pointer
data data data data
VJEŽBE 1
Primjena: Povezane liste
Odjel za matematiku 38
Povezane liste
headhead pointer pointer pointer pointer
data data data data
Operacije nad (jednostrukom) listom:• PRETRAŽIVANJE LISTE - pronalaženje člana liste koji sadrži određeni podatak• UBACIVANJE U LISTU - novi član liste se ubacuje na početak liste ili po dogovoru• BRISANJE ČLANA IZ LISTE – izbacivanje odabranog člana iz liste
(Jednostruka) povezana lista se sastoji od:• elementi (podaci) liste – temelji tipovi podaka ili ADT• pokazivač na slijedeći član – pokazivač na sljedeći element liste.• pokazivač head na početak liste
VJEŽBE 1
1.3.2011
20
Primjena: Povezane liste
Odjel za matematiku 39
Vektor kao povezana lista // deklaracije strukture: node - clan listestruct node{node *next;int index;float value;};
int main(){node Node4={NULL,365,2.819};node Node3={&Node4,121,1.426};node Node2={&Node3,35,3.142};node Node1={&Node2,4,4.815};node *head = &Node1;
cout<<"index 4. clanu: "<<Node4.index<<endl; cout<<"Pocetak liste: "<<head->index;
}
Član liste definiramo kao strukturu:• pokazivač next na slijedeći član• vrijednosti indeksa• vrijednost koja se nalazi na indeksu
head&Node1 &Node2 &Node3 &Node4 NULL
head
Node1 Node2 Node3 Node4
4
4.815
35
3.142
121
1.426
365
2.819
VJEŽBE 1
Zadaci
Odjel za matematiku 40
Napiši program koji će definirati strukturu node na sljedeći način: struct node{
node *next;int index;float value;
};
i pripadne funkcije:1) node *member(node *head, int ind) – funkcija koja će vraćati
pokazivač na član liste koji sadrži indeks ind2) void PrintList(node *head) – procedura koja će nam ispisivati elemente
liste.3) void AddNode(node* &head, int ind, val) – procedura koja će nam
dodavati novi član s podacima s indeksom ind i vrijednosti val u listu u uzlaznom poretku. Pretpostavljamo da će lista sadržavati sve različite indekse.
4) void DelNode(node* &head, int ind, val) – procedura koja će brisati element s podacima s indeksom ind i vrijednosti val iz liste.
Zadatak. 7.1: Funkcije nad povezanom listom
VJEŽBE 1