Deo zbornika Uvod u programiranje kroz C

Pokazivačka aritmetika

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 akko 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.

Primer

Ilustrujmo sve ovo primerom strukture podataka poznate kao stog (eng. stack). Stek je predstavljen nizom elemenata i elementi se dodaju i uzimaju sa istog kraja.

#define MAX_SIZE 1024
int a[MAX_SIZE];
int* top = a;

int push(int x)
{
    if (top < a + SIZE - 1)
        *top++ = x;
    else {
        printf("Greska");
        exit(EXIT_FAILURE);
    }
}

int pop()
{
    if (top > a)
        return *--top;
    else {
        printf("Greska");
        exit(EXIT_FAILURE);
    }
}

int size() { return top - a; }

Prilikom dodavanja elementa vrši se provera da li je stek možda pun i to izrazom top < a + SIZE - 1 koji uključuje pokazivačku aritmetku sabiranje pokazivača (preciznije adrese početka niza) i broja, i zatim oduzimanje broja od dobijenog pokazivača. Slično, prilikom uklanjanja elementa, vrši se da li je stek prazan i to izrazom top > a koji uključuje poredenje dva pokazivača (preciznije, pokazivača i niza). Napokon, funkcija koja vraća broj elemenata postavljenih na stek uključuje oduzimanje dva pokazivača (preciznije, pokazivača i niza).

Potrebno je naglasiti i suptilnu upotrebu prefiksnog operatora dekrementiranja u funkciji pop, odnosno postfiksnog operatora inkrementiranja u funkciji push, kao i njihov odnos sa operatorom dereferenciranja.

Izvor: Mala škola referenciranja u programskom jeziku C