4 Polja I Pokazivaci

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 30

Polja i pokazivači

1
Polja i pokazivači

 Ime polja je pokazivač.


 Ime polja pokazuje samo na prvi element, a ne na
cijelo polje.

a
Ime polja je pokazivačka
konstanta na njegov prvi
element (ne može se
preusmjeriti!).

2
Primjer:

#include <iostream.h>
void main(){
int a[5];
cout << "Adresa elementa a[0]: " << &a[0] << endl
<< "Ime je pokazivac: " << a << endl
<<&a << endl;
}

/* ispis:
Adresa elementa a[0]: 0x00427D50
Ime je pokazivac: 0x00427D50
0x00427D50
*/

3
Dereferenciranje imena polja
Kako možemo dobiti vrijednost elementa
a[0] pomoću operatora dereferenciranja, “*”?

Sadržaju nultog
elementa pristupamo sa
a[0] ili *a.

#include <iostream.h> Ispis:


int main(){ 2 2
int a[5]={2, 4, 6, 8, 22};
cout<<*a<<" "<<a[0];
return 0;
}
4
Pokazivači na polje

Da bi pristupili polju, možemo koristiti bilo koji


pokazivač na prvi element, umjesto imena
polja. Možemo zamijeniti *p sa *a.
p #include <iostream.h>
a int main(){
int a[5]={2, 4, 6, 8, 22};
Ispis:
int *p=a;
2 2
int i=0;
cout<<a[i]<<" "<<*p;
return 0;
} 5
Više pokazivača na isto polje
#include <iostream.h>
 a i p su pokazivači na isto polje.
void main()
{
a int a[5]={2,4,6,8,22};
int *p=&a[1];
cout <<a[0]<< " "<<a[1] <<
p endl;
p pokazuje na p[0]
cout <<p[-1]<< " "<<p[0] <<
endl;

Ispis: 2 4
2 4 6
Aritmetika pokazivača
 Za zadani pokazivač p, izraz p+n
označava element koji je udaljen od p
za n mjesta u polju.

7
Aritmetika pokazivača i različiti tipovi
podataka
 adresa = pokazivač + (pozicija u polju * veličina elementa)

8
Dereferenciranje pokazivača na polje

*(a+n) i a[n] su jednake vrijednosti

9
Ime polja kao pokazivač

 int a[10];

 O imenu polja možemo razmišljati kao o


pravom pokazivaču.

 a[0] = *(a+0) = sadržaj adrese (a+0)


 a[1] = *(a+1) = sadržaj adrese (a+1)
 a[2] = *(a+2) = sadržaj adrese (a+2)

10
Primjer aritmetike pokazivača na polju sa elementima
tipa int i double
#include <iostream.h>
void main() {
int i[10];
double d[10];
int *ip = i;
double *dp = d;
cout << "ip = " << (long)ip << endl;
ip++;
cout << "ip = " << (long)ip << endl;
cout << "dp = " << (long)dp << endl;
dp++;
cout << "dp = " << (long)dp << endl;
}
11
Ispis:
 ip = 6684124 // ispisi se mogu
 ip = 6684128 // razlikovati
 dp = 6684044 // ovisno o mem. prost.
 dp = 6684052 // koji je dodijeljen

 Pokazivač se promijenio za 4 byte-a u slučaju


int*, ali za 8 byte-ova za double*.
 Aritmetika s pokazivačima ima smisla samo s
poljima.

12
Primjer s poljem čiji su elementi tipa strukture:
#include <iostream.h>
typedef struct {
char c; short s; int i; long l; float f; double d; long
double ld; } Element;
void main() {
Element p[10];
Element *pp = p;
cout << "sizeof(Element) = "
<<sizeof(Element) << endl;
cout << "pp = " << (long)pp << endl;
pp++;
cout << "pp = " << (long)pp << endl;
}
13
 Ispis:
 sizeof(Element) = 32
 pp = 1244736
 pp = 1244768
 Prevoditelj, dakle na isti način brine o aritmetici u
slučaju pokazivača kada se radi o poljima čiji su
elementi strukture.

14
Pokazivač na 2-dimenzionalno polje

float a[3][4]; // deklaracija dvodimenzionalnog polja


a[0], a[1] i a[2] su pokazivači na početne članove
jednodimenzionalnih polja

#include <iostream.h>
void main(){
float a[3][4]={{2.2, 4.1, 6.4, 8.0},{3.2, 2.1}};
cout<<*a[0]<<" "<<*a[1]<<endl; // Ispis: 2.2 3.2
}
15
Pokazivač na 2-dimenzionalno polje

16
Pokazivač na 2-dimenzionalno polje

#include <iostream.h>
void main(){
float a[3][4]={{2.2, 4.1, 6.4, 8.0},{3.2, 2.1}};
cout<<(long)*(a+0)<<" "<<(long)*(a+1)<<endl;
cout<<(long)a[0]<<" "<<(long)a[1]<<endl;

}
Ispis:
1245008 1245024 Adrese su udaljene 16 bajta.
1245008 1245024 (4 float vrijednosti )

17
#include <iostream.h>
#include <iomanip.h>
void main(){
float a[3][4]={{2.2, 4.1, 6.4, 8.0},{3.2, 2.1,3.4,6.6},
{4.0,5.0,2.2,0.0}};
for(int i=0;i<3;i++){
for(int j=0;j<4;j++)
cout<<setw(6)<<*(*(a+i)+j); // a[i][j]
sadržaj adrese (*(a+i)+j)
cout<<endl; Ispis:
2.2 4.1 6.4 8
} 3.2 2.1 3.4 6.6
} 4 5 2.2 0

18
Prosljeđivanje polja funkciji

 Kada deklariramo polje kao parametar


funkcije zapravo deklariramo pokazivač. U
slijedećem primjeru, funk1( ) i funk2( )
imaju istu listu parametara:

19
void funk1(int a[], int n) {
void funk1(int a[], int n); for(int i = 0; i < n; i++)
void funk2(int* a, int n); a[i] = 2*i ; }
void ispis(int a[5], int n);
void funk2(int* a, int n) {
void main(){ for(int i = 0; i < n; i++)
a[i] = 2* i; }
int n=5;
int a[]={1,3,5,6,8}; void ispis(int a[5], int n) {
ispis(a,n); for(int i = 0; i < n; i++)
funk1(a,n); cout <<" a["<<i<<"]= "<<a[i];
ispis(a,n); cout<<endl;}
funk2(a,n);
ispis(a,n);
} Ispis:
a[0]= 1 a[1]= 3 a[2]= 5 a[3]= 6 a[4]= 8
a[0]= 0 a[1]= 2 a[2]= 4 a[3]= 6 a[4]= 8
a[0]= 0 a[1]= 2 a[2]= 4 a[3]= 6 a[4]= 8

20
Primjer (kviz): Kakav je izlaz programa?

#include <iostream.h>
p

void main(){ 2 4 6 8 22
int a[5] = {2,4,6,8,22};
int *p = &a[1]; a[0] a[1] a[2] a[3] a[4]
cout <<" "<< a[0] << " " << p[-1];
Izlaz:
cout <<" "<< a[1] << " "<< p[0];
cout <<" "<< a[2] <<" "<<
*(p+2); 2 2 4 4 6 8 1
cout <<" "<< (a[4] = = *(p+3));
}

21
Pokazivači i nizovi
#include <iostream.h> // Kopiranje niza
char nizA[80]="Kratak niz", nizB[]="Ovaj niz je nesto dulji";
void main(){
char *pA; // pokazivač na znakovni tip
char *pB; // drugi pokazivač na znakovni tip
pA=nizA;
cout<<nizA<<endl;
pB=nizB; // usmjerava pB na nizB
while(*pA != '\0'){
*pB++ = *pA++; // vraća se vrijednost na koju pokazuje
} // pokazivač i zatim se pokazivač povećava za 1
*pB='\0';
cout<<nizB<<endl;}

22
Kopiranje niza (uz uporabu funkcije)
#include <iostream.h>
char *kopiranje_niza(char *izlazni,const char *ulazni);

void main(){
char nizA[80]="Kratak niz";
char nizB[]="Ovaj niz je nesto dulji";
kopiranje_niza (nizB,nizA);
cout<<nizB<<endl;}
// nije potrebno prenijeti duljinu niza jer niz ima oznaku kraja '\0'
char *kopiranje_niza(char *izlazni,const char *ulazni){
char *p=izlazni; // usmjeravanje pokazivača
while(*ulazni != '\0'){
*p++ = *ulazni++;} // aritmetika pokazivača
*p = '\0';
return izlazni;}

23
 Primjer: Nalaženje najvećeg elementa u polju
realnih brojeva

float max(int len, float *p);

void main(){
float x[10];
int n;
cout<<"Velicina polja=";
cin>>n;
cout<<endl<<"Polje a:"<<endl;
for(int i=0;i<n;i++)
cin>>*(x+i); // isto što i x[i]
cout<<"Max= "<<max(n,x);
}

24
float max(int velicina, float *p) // prijenos polja preko
{ // pokazivaca
float rez;
int i;
rez=p[0];
for(i=1;i<velicina;i++,p++) // aritmetika pokazivača
if(*p>rez)
rez=*p;
return rez;
}

25
Primjeri sa kviza

Kakav je izlaz programa? Prikaži crtežom


situaciju u memoriji.
int b[] = {4,5,3,1,2};
int *ptr = &b[1];
cout <<" "<< b[2] << " " << *ptr;
cout <<" "<< b[3] << " "<< *(ptr+1);
cout <<" "<< b[4] <<" "<< ptr[2]<<endl;

26
Ispis:
__3___ __5___ ___1__ ___3__ __2___ __1___

Situacija u memoriji:

b[0] b[1] b[2] b[3] b[4]


4 5 3 1 2

ptr

27
Primjeri sa kviza

Napisati funkciju koja sva pojavljivanja


zadanog znaka u nizu zamjenjuje novim
znakom. Funkcija ima prototip:
int zamjena(char * niz, char novi, char stari);
Funkcija vraća broj zamjena znakova u nizu.

28
int main(){
Primjeri sa kviza char niz[15],znak1,znak2;
#include <iostream.h> int broj_zamjena;
cout<<"\nNiz: ";
int zamjena(char * niz, cin>>niz;
char novi, char stari){ cout<<"\nStari znak: ";
char *p = niz; cin>>znak1;
int br=0; cout<<"\nNovi znak: ";
while (*p != '\0'){ cin>>znak2;
if(*p==stari){*p=novi; broj_zamjena=zamjena(niz,zn
br++;} ak2,znak1);
p++; cout<<"\Novi niz: "<<niz;
} cout<<"\nBroj zamjena:
return br; "<<broj_zamjena<<endl;
return 0;
}
} 29
 Preporuke za čitanje:
 Šribar (125-132)
 Vulin (101-111)
 Ted Jensen: A Tutorial on Pointers and Arrays in
C ili u pdf formatu

30

You might also like