Примена адресне аритметике

Све законитости и својства које смо до сада разматрали нашли су примену у тзв. показивачкој аритметици.

Из табеле оператора уочи да заграда () има највећи приоритет: 15. Оператори ++, --, *, &, sizeof имају исти приоритет: 14 и групишу се здесна улево. Табела оператора је дата у прилогу.

Најједноставније ћемо основе показивачке аритметике показати користећи познати низ и на њему применити одговарајуће изразе.

Као и у претходним примерима свака од наредби ће се извршавати суксесивно, једна за другом.

int a[] = {7, 12, 36, 4, 18};
int  x, y;
int *p;

Стање оперативне меморије после наредби int a[] = {7, 12, 36, 4, 18}, x, y, *p:

../_images/Slika23.jpg

p = a + 2;

Овом наредбом додељујемо показивачу р адресу трећег елемента.

Стање оперативне меморије после наредбе p = a + 2:

../_images/Picture24.png

x = *p + 2;

Вредност на мемориjској локацији на коју указује показивач (*р) износи 36, тако да x добија вредност 38.

Стање оперативне меморије после наредбе x = *p + 2:

../_images/Picture25.png

y = *p--;

Рекли смо да оператори * и -- имају исти приоритет, читају се здесна улево. Особина унарног оператора -- се односи на показивач, а не на податак на који он указује. Зато je y = 36, а показивач се помера за једно место уназад.

Стање оперативне меморије после наредбе y = *p--:

../_images/Picture26.png

x = *(p + 2);

Знамо да заграда има највећи приоритет, тако да x добија вредност елемента низа на четвртом месту, x = 4.

Стање оперативне меморије после наредбе x=*(p + 2):

../_images/Picture27.png

y = (*p) + 3;

Показивач је „остао“ на својој позицији, тако да се овом наредбом повећава показивани податак, односно y = 15.

Стање оперативне меморије после наредбе y = (*p) + 3:

../_images/Picture28.png

x = --(*p) + 7;

Аналогно претходном примеру, поштујућу префиксну нотацију, као и то да заграда има највећи приоритет, прво се чита вредност на коју указује показивач, а затим се та вредност декрементира, односно израз --(*p) добија вредност 11. Јасно је да је x = 18.

Стање оперативне меморије после наредбе x = --(*p) + 7:

../_images/Picture29.png

И још једна карактеристична наредба:

y = *(++p) - 4

У овом случају, вредност показивача се у загради прво инкрементира, односно показивач указује сада на наредни елемент низа, а затим се чита вредност на тој позицији, односно израз *(++p) враћа вредност 36.

y = 32

Стање оперативне меморије после наредбе y = *(++p) - 4:

../_images/Picture30.png

Решење задатка:

#include<stdio.h>
int main(void)
{
    int a[] = {7, 12, 36, 4, 18};
    int x, y;
    int* p;
    p = a + 2;
    x = *p + 2;
    printf("x = *p + 2 \t x = %d\n", x);
    y = *p--;
    printf("y = *p-- \t y = %d\n", y);
    x = *(p + 2);
    printf("x = *(p + 2) \t x = %d\n", x);
    y = (*p) + 3;
    printf("y = (*p) + 3 \t y = %d\n", y);
    x = --(*p) + 7;
    printf("x = --(*p) + 7 \t x = %d\n", x);
    y = *(++p) - 4;
    printf("y = *(++p) - 4 \t y = %d\n", y);
    return 0;
}

Резултат извршавања програма:

x = *p + 2       x = 38
y = *p--         y = 36
x = *(p + 2)     x = 4
y = (*p) + 3     y = 15
x = --(*p) + 7   x = 18
y = *(++p) - 4   y = 32

Задаци за вежбу:

int a[5] = {10, 15, 20, 25, 30}, *p, x, y;
p = a + 2;
x = *(++p) + 3;
y = --(*p) - 7;

Поштујући правила показивачке аритметике, одредити вредности променљивих x и y после извршења задатог кодa.

x = 23, y = 13

x = 20, y = 10

x = 28, y = 17

int x = 17, y = -25, z = 30, *p1, *p2;
p1 = &y;
p2 = p1;
y = (*p2) - 12;
z = *p1 - 3;

Поштујући правила показивачке аритметике, одредити вредности променљивих x, y и z после извршења задатог кодa.

x = 17, y = -27, z=-30

x = 20, y = -30, z = -33

x = 17, y = -37, z = -40