Ako je p pokazivač na neki element niza, tada p++ povećava p da bi pokazivao na naredni element, dok p+=i ga uvećavatako da pokazuje na i-ti element nakon trenutnog. To su najjednostavniji primeri pokazivačke ili adresne aritmetike.

*

Rečeno je da nakon deklaracije int a[10], vrednosti a odgovara pokazivač na prvi element niza, vrednosti a+1 odgovara pokazivač na drugi element niza, itd. Izraz p+1 i slični uključuju izračunavanje koje koristi pokazivačku aritmetiku i koje se razlikuje od običnog izračunavanja. Naime, izrazu p+1, ne označava dodavanje vrednosti 1 na p, već dodavanje dužine jednog objekta tipa na koji ukazuje p. Na primer, ako p ukazuje na int, onda p+1 i p mogu da se razlikuju za dva ili četiri - onoliko koliko bajtova na tom sistemu zauzima podatak tipa int. Tako, ako je p pokazivač na int koji sadrži na adresu 100, na mašini na kojoj int zauzima 4 bajta, vrednost p+3 će biti adresa 100 + 3 * 4 = 112.

Od pokazivača je moguće oduzimati cele brojeve (na primer, p-n), pri čemu je značenje ovih izraza analogno značenju u slučaju sabiranja. Na pokazivače je moguće primenjivati prefiksne i postfiksne operatore ++ i --, sa sličnom semantikom.

Pored dereferenciranja, dodavanja i oduzimanja celih brojeva, nad pokazivačima je moguće izvoditi još neke operacije. Pokazivači se mogu porediti relacijskim operatorima (na primer, p1 < p2, p1 == p2, …). Ovo ima smisla ukoliko pokazivači ukazuju na elemente istog niza. Tako je, na primer, p1 < p2 tačno ako p1 ukazuje na raniji element niza od pokazivača p2.

Dva pokazivača je moguće oduzimati. I u tom slučaju se ne vrši prosto oduzimanje dve adrese, već se razmatra veličina tipa pokazivača, sa kojom se razlika deli. Dva pokazivača nije moguće sabirati.

Unarni operatori & i * imaju viši prioritet nego binarni aritmetiči operatori. Zato je značenje izraza *p+1 zbir sadržaja lokacije na koju ukazuje p i vrednosti 1 (a ne sadržaj na adresi p+1).

Unarni operatori &, *, i prefiksni ++ se primenjuju zdesna nalevo, pa naredba ++*p inkrementira sadržaj lokacije na koju ukazuje p. Postfiksni operator ++ kao i svi unarni operatori koji se primenjuju s leva na desno, imaju viši prioritet od unarnih operatora koji se primenjuju s desna nalevo, tako da *p++ vraća sadržaj na lokaciji p, dok se kao bočni efekat p inkrementira.

*****

Do sada ste naučili šta su pokazivači i rekli smo da oni mogu pokazivati na neku drugu promenljivu, tačnije na mestu u memoriji koje je odvojeno(rezervisano) za tu drugu promenljivu. Međutim, koristeći funkciju malloc() iz stdlib.h mi možemo da rezervišemo određeno „parče“ memorije - memorija će biti zauzeta ali je ni jedna promenljiva neće koristiti. Pa šta će nam onda? Naime, pomenuta funkcija malloc() kao povratnu vrednost daje adresu memorije koja je upravo zauzeta, a koji tip podatka jedini može čuvati adrese? Naravno, pokazivači. Pomoću ovog mehanizma u mogućnosti smo dinamički, u toku izvršavanja programa, da alociramo (zauzimamo) određene količine memorije i na njih će pokazivači pokazivati pa ćemo moći da u tu memoriju skladištimo podatke. Sledi primer za dinamičku alokaciju memorije.

/* PROGRAM MEMORIJA_1 */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

void main(void)

{

//deklaracija

char *text;

 

//alociranje memorije

text = malloc( sizeof(char) * 50);

 

//upisi neku vrednost u memoriju na koju pokazuje TEXT

strcpy(text, "jos jedna trivijalna poruka!");

 

//prikazi vrednost

printf("TEXT-> %s\n", text);

 

}

 

Sve sem naredbe u kojoj pozivamo malloc() treba da vam je jasno.

Funkciji malloc() smo kao argument predali jednu pomalo cudno vrednost:

sizeof(char) * 50

sizeof je operator C jezika( kao što su i recimo + ili / operatori) a njegova uloga je da odredi koliko memorije zauzima neki tip podatka. U ovom slučaju tražili smo koliko bajtova zauzima tip podatka char i tu vrednost pomnožili sa 50. Time ćemo dobiti broj bajtova koji je potreban da bi se smestilo 50 char-ova u memoriju. Drugim rečima, ako želimo da rezervišemo memoriju za npr. 10 promenljivih tipa INT, ne možemo funkciji malloc() predati vrednost 10. Razlog je taj što bismo na taj način tražili od funkcije da rezerviše 10 bajtova a ne 10 puta po onaj broj bajtova koji zauzima tip INT. Pa zato moramo da napišemo:

sizeof(int) * 10

Dakle ovo govori prevodiocu(kompajleru) „izračunaj koliko bajtova zauzima tip INT a zatim taj broj pomnoži sa 4“ i time ćemo dobiti broj bajtova koji nam je potreban da bi smestili 10 INTova u memoriju računara.

Kada je potrebna količina memorije rezervisana ( alocirana) funkcija malloc() nam vraća adresu te memorije i mi je u gornjem primeru dodeljujemo pokazivaču TEXT. Zatim upisujemo vrednosti u alociranu memoriju pomocu funkcije strcpy(), da bi na kraju i isčitavali vrednost iz te memorije. Zaključak je da se sa dinamički zauzetom memorijom može baratati kao i sa „normalno“ zauzetom memorijom ( memorija koja je zauzeta pravljenjem obicnih promenljivih).

Last modified: Tuesday, 16 October 2018, 10:46 AM