Skip to content

Показивачи

Оперативна меморија рачунара организована је као низ локација са придруженим адресама, где је најмања адресабилна јединица један бајт. Подаци у оперативној меморији записују се у узастопним бајтовима. На пример, податак типа 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!