OR2010 Pred 08

You might also like

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

Sadraj predavanja 08

Memorijske klase
Najvanije svojstvo neke varijable je njen tip
tip.
Meutim, mogue je jo detaljnije definirati karakteristike zadane varijable
pomou svojstva varijabli koje se naziva memorijska klasa.

Memorijske klase:auto, extern, static, register


Pokazivai (eng. pointers)

Strane u skripti:

Deklaracija i inicijalizacija pokazivaa

37 41

Pristup varijabli preko pokazivaa

57-59

Prenos podataka u funkciju preko pokazivaa

149-156

Aritmetika pokazivaa

173-185

Pokazivai i polja
Jednodimenzionalno polje kao argument
funkcije

Napomena:

Pokazivai i stringovi
Primjeri

itanje preporuene literature je


obavezno

Tip podataka odreuje raspon vrijednosti koje varijabla moe poprimiti i


nain pohranjivanja varijable u memoriji.
j
klasom se odreuje
j vrijeme
j
zadravanja
j varijable
j
u
Memorijskom
memoriji, tj. vrijeme ivota varijable (eng. lifetime).
Programski jezik C definira etiri memorijske klase:
- auto
- extern
- static
- register
Oznaka memorijske klase se navodi ispred tipa varijable. Prema tome,
opi oblik deklaracije varijabli
arijabli je
je:
tip_memorijske_klase tip_varijable ime_varijable

Memorijska klasa auto

Registarske varijable

Sve lokalne varijable su po pretpostavljenoj vrijednosti automatske varijable.


To znai da se oznaka auto moe izostaviti pri deklaraciji lokalnih varijabli.
Na primjer:

int f1(int a)
{
auto int b,i;
i=0;
while(i<10)
{
int c;
..
i++;
}
}

Preporuka
P
k kompajleru
k
jl
d
da kkoristi
i ti registre
i t procesora sa pohranjivanje
h ji
j varijabli
ij bli
oynaenih kao registarske.
g
kojij koriste registarske
g
varijable
j
su krai i bri jjer se tedi vrijeme
j
Programi
pristupa memoriji poto varijabla nije smjetena na nekoj lokaciji u memoriji ve u
nekom od registara procesora.

Mogli smo pisati samo:

Varijabla deklarirana kao pokaziva ne moe biti registarska varijabla


varijabla.

int b,i;

Broj registarskih varijabli se ne smije prekoraiti jer e inae kompajler proglasiti


varijable neregistarskim ako je broj registarskih varijabli prekoraio dozvoljenu
granicu.

Varijabla c je dostupna samo


tokom izvravanja
programske petlje while.

Memorijska klasa register moe se pridruiti samo nekim tipovima podataka, to


ovisi o duljini registra procesora
procesora.
Primjeri deklaracije registarskih varijabli:
register int x;
register char y;

Statike varijable
Koriste se za lokalizaciju podruja djelovanja varijabli
varijabli.
Primjer deklaracije:
static

int

a;

Statike varijable trajno zauzimaju mjesto u memoriji.


Postoje dvije vrste statikih varijabli:
lokalne statike varijable
Izlaskom iz funkcije vrijednost statike varijable ostaje zapisana.
Svakim ponovnim pozivom funkcije, vrijednost lokalne statike varijable se postavlja
na vrijednost koju je varijabla imala pri zadnjem izlasku is dotine funkcije.
Bez obzira to je varijabla trajno zapisana u memoriji njena vrijednost nije dostupna
ostalim funkcijama.
globalne
l b l statike
t tik varijable
ij bl
Globalne statike varijable najee deklariramo u funkcijama koje se smjetaju u
biblioteke funkcija, odnosno, u programske module.
Tada je varijabla dostupna samo za funkcije koje se nalaze unutar bibliteke
bibliteke, odnosno
odnosno,
programskog modula.

Primjer 9.1
#include <stdio.h>

#include <stdio.h>

void f1()
{
int a=0;
a++;
printf("\na=%d",a);
}

void f1()
{
static int a=0;
a++;
printf("\na=%d",a);
}

void main()
{
f1();
f1();
f1();
}

void main()
{
f1();
f1();
f1();
}

Program e ispisati:
a=1
a=1
a=1

Eksterne varijable (1/2)

Ako elimo proiriti podruje djelovanja globalne varijable na sve funkcije


programa bet obzira u kojoj se datoteci te funkcije nalaze, onda te
varijable moramp proglasiti eksternim.

Program e ispisati:
a=1
a=2
a=3

Eksterne varijable (2/2)

prog.c

j
su zajednike
j
za sve funkcije
j unutar p
programa.
g
Eksterne varijable
Globalne varijable su dostupne samo funkcijama koje se nalaze u
datoteci u kojoj je globlna varijabla deklarirana.
Eksterne varijable su dostupne svim funkcijama u kojima je eksterna
varijabla deklarirana.

Zbog toga to je varijabla a


oznaena kao static njena
vrijednost iz prethodnog poziva
se pamti.

#i l d <stdio.h>
#include
di h
int a,b;
int f1(int x){
.
}
void main(){
int c;
.
}

b
c
a

dat2.c

#include <stdio.h>
extern int a;
int d;
(
x){
){
int f2(int
.
}
i t f3 (i
int
(int
t y){
){
.
}

Pokazivai (eng. pointers)

Deklaracija i inicijalizacija pokazivaa

Pokaziva je varijabla koja sadri adresu u memoriji.


Drugim rijeima,
rijeima pokaziva preko adrese pokazuje na neku varijablu u memoriji
memoriji.

Kao i ostale varijable i pokazivake varijable se moraju deklarirati.


Opi
O i oblik
blik d
deklaracije
kl
ij pokazivaa
k i jje:

Adresa moe biti adresa na kojoj je zapisana vrijednost neke druge varijable
Takoer,
T k adresa
d
moe
biti i vrijednost
ij d
t adrese
d
na kkojoj
j j jje zapisana
i
ffunkcija.
k ij
U radu s pokazivaima vano je upoznati se sa unarnim operatorima:
&

adresni operator,vraa adresu nekog objekta u memoriji.

j s adrese koja
j jje p
pridruena varijabli
j
vraa sadrajj memorije
ispred koje se nalazi operator *.

tip *ime_pok_varijable;
tip
*

predstavlja jedan od osnovnih ili korisniki definiranih


tipova podataka.
je unarni operator koji ukazuje da e varijabla
ime pok varijable biti pokaziva
ime_pok_varijable
pokaziva.

Na primjer:
int *p;
deklarira pokaziva p na cjelobrojnu varijablu.

Deklaracije varijabli i pokazvaa

Postavljanje poetne vrijednosti pokazivau

iintt a,b;
b
int *p;

0100000

0100002

0100004

Definicijom
D fi i ij
iinteger
t
varijabli rezerviran je
odgovarajui prostor u
e o j
memoriji.

0100000

0100002

0100004

Definicijom pokazivaa
rezerviran je odreeni
prostor u memoriji (npr. 4
bajta).

0100000

Izrazom:
Sve varijable koje se definiraju kao pokazivake zauzimaju istu koliinu memorije.

p=&a;
pokaziva
k i p sadri
d i adresu
d
varijable
ij bl a.

Pristup varijabli preko pokazivaa


Preko
P k pokazivaa
k i moe
se indirektno
i di kt pristupiti
i t iti vrijednosti
ij d
ti neke
k varijable.
ij bl
Na primjer:
, ;
int a=24,b;

Prenos podataka u funkciju preko adrese(eng. Call by reference)


Prilikom prenosa podataka preko adrese u pozvanu funkciju prenosi se adresa
varijable.
Svaka promjena vrijednosti argumenta funkcije predstavlja istovremenu
promjenu vrijednosti prenesene varijable.

Naredbom:
b=*p;
vrijednost varijable b e biti jednaka vrijednosti koja je zapisana na lokaciji na
koju pokazuje pokaziva p a to je 24.
0100000

24

0100002

24

void main()
{
int a=30;
f1(& )
f1(&a);
}

void f1(int *p)


{
*p=50;
}
adresa
.
0100000

0100004

30 50

0100000

Primjer 9.2
(Poreenje prenosa preko vrijednosti i prenosa preko adrese)

#include <stdio.h>
void dodaj2(int c, int d)
{
c c+2;
c=c+2;
d=d+2;
}
void dodaj3(int *p1, int*p2)
{
Program e ispisati:
*p1=*p1+3;
*p2=*p2+3;
Nakon poziva funkcije dodaj2():a=1,b=2
}
Nakon poziva funkcije dodaj3():a=4,b=5
int main()
{
int a=1,b=2;
dodaj2(a,b);
printf("\nNakon poziva funkcije dodaj2():a=%d,b=%d",a,b);
dodaj3(&a,&b);
printf("\nNakon
printf(
\nNakon poziva funkcije dodaj3():a=%d,b=%d",a,b);
dodaj3():a %d,b %d ,a,b);
return 0;
}

Vrijednost varijable a iz glavnog programa smo promijenili funkciji f1 to je


mogue jer smo koristili prenos podataka u funkciju preko adrese (pokazivaa).

Izvoenje naredbi *p1=*p1+3; i *p2=*p2+3;

Izvoenjem naredbe *p1=*p1+3; varijabli a u glavnom programu se mijenja


vrijednost sa 1 na 4.
Izvoenjem naredbe *p2=*p2+3; varijabli b u glavnom programu se mijenja
vrijednost sa 2 na 5.

Izvoenje naredbi c=c+2; i d=d+2;

Primjer 9.3
ta
e ispisati slijedei program:

glavni program

stog

adrese

povratna adresa

122FF6C a

122FF68

Iz voenjem naredbe c=c+2; varijabli c na stogu se mijenja vrijednost sa 1 na 3.


Izvoenjem naredbe d=d+2; varijabli d na stogu se mijenja vrijednost sa 2 na 4.

#include <stdio.h>
(
*a,
, int b)
)
int f(int
{
int c;
c=*a+b;
*a *a+5;
*a=*a+5;
b=b+5;
return c;
}
void main()
{
int a=1, b=1,c;
printf("\nPrije
printf(
\nPrije funkcije f:a=%d,
f:a=%d b=%d
b=%d",a,b);
a b);
c=f(&a,b);
printf("\nPoslije funkcije f: a=%d, b=%d c=%d",a,b,c);
}
Odgovor:

Primjer 9.4

Prije funkcije f:a=1,b=1


Poslije funkcije f:a=6,b=1,c=2

Aritmetika pokazivaa
Operatori koji se mogu primijeniti na pokazivae su: + i -

ta e ispisati program:

ta e ispisati program:

#include <stdio.h>
void main()
{
int p[5]={1,2,3,4,5};
int *pp;
pp=p;
printf("%d",*(pp+2));
}

#include <stdio.h>
void main()
{
int p[5]={1,2,3,4,5};
int *pp;
pp=&p[2];
printf("%d",*(pp+1));
}

Odgovor: 3

Odgovor: 4

Prilikom svakog inkrementa ili dekrementa pokaziva pokazuje na adresu


sljedeeg ili prethodnog podatka u memoriji.
Za koliko e se poveati ili smaniti pokaziva ovisi o tipu podataka na koji
pokazuje pokaziva
pokaziva.
Na primjer:

pc+1
pi+1
pf+1

char
*pc;
int
*pi;
float *pf;
adresa se poveava za vrijednost koja predstavlja broj bajtova koje
zauzima znakovni tip (jedan bajt)
adresa se poveava za vrijednost koja predstavlja broj bajtova koje
j
j tip ((ovisi o implementacijij C-a).
)
zauzima cjelobrojni
adresa se poveava za vrijednost koja predstavlja broj bajtova koje
zauzima realni tip float (etiri bajta)

Primjer 9.5 (1/2)

Primjer 9.5 (2/2)

#include <stdio.h>
int main()
{
char a=3;int
b=3;float c=1.0;
char *pc; int *pi;float *pf;
pc=&a;pi=&b;pf=&c;
printf("\npc=%x",pc);
printf("\npi=%x",pi);
printf("\npf=%x",pf);
printf("\npc+1=%x",pc+1);
printf("\npi+1=%x",pi+1);
printf("\npf+1=%x",pf+1);
printf("\npc+2=%x"
printf(
\npc+2 %x ,pc+2);
pc+2);
printf("\npi+2=%x",pi+2);
printf("\npf+2=%x",pf+2);
getch();
return 0;

Adresa koja pokazuje na znakovni tip (pc) je poveana za jedan.


Adresa koja pokazuje na cjelobrojni tip (pi) je poveana za etiri.
Adresa koja pokazuje na realni tip float (pf) je poveana za etiri.
Adresa koja pokazuje na znakovni tip (pc) je poveana za dva.
Adresa koja pokazuje na cjelobrojni tip (pi) je poveana za osam.

Adresa koja pokazuje na realni tip float (pf) je poveana za osam.

Polja i pokazivai (1/2)

Polja i pokazivai (2/2)

int a[5]={1
a[5]={1, 3,
3 5,
5 7
7, 9}

x=a[0];
x=a[1];
x=a[2];
xx=a[3];
a[3];
x=a[4];

Neka imamo cjelobrojno polje sa 5 elemenata:

x=*p;
x=*(p+1);
x=*(p+2);
xx=*(p+2);
(p+2);
x=*(p+2);

int *p;
1

Inicijalizacija pokazivaa na prvi element:


Naredbom:

p=&a[0]; ili p=a;

p=p+1;
postiemo da pokaziva p pokazuje na slijedei element polja a.

p
p
1

9
1

Jednodimenzionalno polje kao argument funkcije

Primjer 9.6 (1/3)


(Jednodimenzionalno polje kao argument funkcije)

Polje se u funkciju prenosi tako da se prenese adresa prvog elementa polja.


Argument funkcije se moe deklarirati:
p j ;
- kao polje;
- kao pokaziva odgovarajueg tipa.
Primjer:
Napisati program koji ispisuje elemente 5-lanog cjelobronog polja a:
int a[5]={1,3,5,7,9};
zatim mijenja elemente polja tako to dodaje svakom elementu broj 3 i na kraju
ispisuje ponovno elemente promijenjenog polja a.
Z dodavanje
Za
d d
j broja
b j 3 treba
t b kkoristiti
i titi ffunkciju
k ij prototipa:
t ti
void dodaj3(int *x);

Ime polja je sinonim za lokaciju


#include <stdio.h>
<stdio h>
poetnog elementa polja.
void dodaj3(int *x);
void ispis(int x[]);
int main()
{
int i,a[5]={1,3,5,7,9};
printf("\nElementi polja prije promjene su:");
ispis(a);
dodaj3(a);
printf("\nElementi polja nakon promjene su:");
ispis(a);
return 0;
0
}

Za ispis elemenata pola treba koristiti funkciju prototipa:


void ispis(int x[]);

Primjer 9.6 (2/3)

Primjer 9.6 (3/3)

(Jednodimenzionalno polje kao argument funkcije)

(Jednodimenzionalno polje kao argument funkcije)

Mogli smo takoer pisati:


void dodaj3(int *x)
{
int i;
for(i=0;i<5;i++)
*x=(*x++)+3;
}

Rezultat izvoenja programa:


void dodaj3(int x[]);

Mogli smo takoer pisati:


void ispis(int x[])
{
void ispis(int *x);
int i;
for (i=0;i<5;i++)
printf("\na[%d]=%d",i,x[i]);
}

Pokazivai i stringovi

Primjer 9.7

Pokazivaku varijablu moemo deklarirati i tako da pokazuje na lokaciju na


kojoj poinje zapis niza znakova, odnosno, zapis stringa.

Napisati funkciju koja kao argument uzima neki string a vraa broj znakova od

Primjer:

kojih se sastoji taj string. Prototip funkcije je:


char
h
*
*p;
char a[]=Danas je cetvrtak;

int

duzina(char

*string)

Naredbama:
p=a;; ili p
p
p=&a[0];
[ ];
pokaziva p se postavlja na prvi element polja a.
p

p+1

p+4
n

Rjeenje:

p+9
j

printf(%c,*(p+1));

ispisat e znak a

printf(%c,*(p+4));
(
, (p ));
p

ispisat
p
e znak s

printf(%c,*(p+9));

ispisat e znak c

int duzina(char *string)


{
int d=0;
while(*string++!='\0')
d++;
return d;
}

Primjer 9.8

Primjer 9.9

Napisati funkciju koja kao argument uzima neki string, te ispisuje taj string na
standardnom izlazu. Funkcija ne vraa nita. Prototip funkcije je:
void

ispis(char

*string)

Napisati funkciju koja kao argument uzima neki string i neki znak c,
c te vraa
vrijednost koja pokazuje koliko se puta znak c pojavljuje u stringu.
Na primjer, ako je string Danas je cetvrtak a znak c=a, funkcija treba vratiti
vrijednost 3.
Prototip funkcije je:
int izbroji (char *string, char c)
Rjeenje:

Rjeenje:
void ispis(char *string)
{
while(*string!='\0')
{
printf("%c",*string);
string++;
}
}

int izbroji(char *string, char c)


{
int b=0;
while(*string!='\0')
{
if (*string==c)
b++;
string++;
}
return b;
}

You might also like