Оперативна меморија рачунара организована је као низ локација са придруженим адресама, где је најмања адресабилна јединица један бајт. Подаци у оперативној меморији записују се у узастопним бајтовима. На пример, податак типа int
записује се у четири узастопна бајта, податак типа double
у осам узастопних бајтова итд.
Показивачка променљива садржи меморијску адресу податка на кога показује (то је увек адреса бајта са најнижом адресом, односно, адреса првог бајта у низу узастопних бајтова). Иако су меморијске адресе цели бројеви, показивачки типови се у програмском језику C стриктно разликују од целобројног типа. Такође, у програмском језику C постоји више показивачких типова, где се показивачки тип одређује на основу типа податка на који показује.
Показивачка променљива декларише се на следећи начин…
tip *identifikator;
…где је tip
тип податка на који се показује, а identifikator
име показивачке променљиве. Приликом декларације није битно да ли постоји размак између звездице и типа или звездице и идентификатора – звездица се увек односи на идентификатор. У следећем примеру…
int* pa;
int *pb;
int * pc;
…декларисане су показивачкe променљивe pa
, pb
и pc
које показују на податкe типа int
.
Унарни оператор &
(којег називамо адресним оператором, односно оператором референцирања) враћа меморијску адресу свог операнда, стим да операнд не може бити константа, нити израз. У следећем примеру…
int a = 3, *pa;
pa = &a;
…у меморијски простор целобројне променљиве a
уписана је вредност 3
, а у меморијски простор показивачке променљиве pa
уписана је меморијска адреса променљиве a
. За показивачку променљиву pa
каже се да показује на целобројну променљиву a
. Ово се може записати и у једној линији:
int a = 3, *pa = &a;
Поред улоге означавања показивачких променљивих, унарни оператор *
(који се називама оператором дереференцирања) враћа вредност која се налази у меморијском простору на коју показивачка променљива показује, увек водећи рачуна о типу податка који се у њој налази. У следећем примеру…
int a = 3, *pa = &a;
printf("%d", *pa);
…у простор променљиве a
уписана је вредност 3
, у простор променљиве pa
уписана је адреса променљиве a
, па је на крају на стандардни излаз исписана вредност на коју показује pa
. Шта ће се исписати на излазу? Исписаће се 3
јер је вредност на коју показује pa
у ствари вредност променљиве a
.
Резимирајмо све до сада. У следећем програму…
#include <stdio.h>
int main(void)
{
int x = 100, *px = &x;
printf("x : %d\n", x);
printf("&x : %p\n", &x);
printf("px : %p\n", px);
printf("*px : %d\n", *px);
return 0;
}
…на стандардном излазу исписаће се…
- вредност целобројне променљиве
x
- адреса целобројне променљиве
x
, тј.&x
- вредност показивачке променљиве
px
- и вредност показивачке променљиве на коју показује
px
, тј.*px
…што може да изгледа овако:
x : 100
&x : 0000008E4F79F594
px : 0000008E4F79F594
*px : 100
Јасно је да су једнаке вредности променљиве x
и променљиве на коју показује px
, као и да је адреса променљиве x
једнака са вредношћу променљиве px
, док ће меморијске адресе бити различите приликом сваког покретања програма.
Ако се у изразу дереференцираном показивачу додељује вредност, онда измена његове вредности утиче и на простор на који показује (ако показује на променљиву, мења се садржај те променљиве). У следећем примеру…
#include <stdio.h>
int main(void)
{
int a, * pa;
a = 3;
pa = &a;
*pa = 6;
printf("%d", a);
return 0;
}
…у простор променљиве a
уписана је вредност 3
, у простор променљиве pa
уписана је адреса променљиве a
, па је у простор на који показује pa
уписана вредност 6
. Уписом вредности 6
у простор на који показује pa
промењена је и вредност променљиве a
на 6
!