Низови и показивачи

У програмском језику C постоји јака веза између низова и показивача. Свака операција која се може постићи индексирањем низа, може се урадити и помоћу показивача.

Ако је p показивач на цео број декларисан помоћу:

int *p;

тада наредбом додељивања

p = &a[0];

дефинишемо да p показује на нулти елемент низа a, тј. p садржи адресу елемента a[0].

По дефиницији, име низа је синоним за адресу почетног (нултог) елемента низа.

Наредба додељивања

p = &a[0];

еквивалентна је наредби додељивања

p = a;

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

Запис a[i] значи исто што и *(a + i), а то је вредност i-тог елемента низа a.

Са друге стране, показује се да су и изрази &a[i] и a+i идентични, оба представљају адресу i-тог елемента низа.

a+i је адреса i-тог елемента низа a.

a је адреса нултог елемента.

Такође, израз p[i] тумачи се као *(p + i). Дакле, збир показивача на тип T и целог броја је израз типа „показивач на тип T. Вредност израза је адреса целог броја који се у низу налази i позиција иза елемента на који показује p.

Дакле, важи следеће:

p + i = &p[i] /* adresa i-tog elementa */
*(p + i)  =  p[i] /* vrednost i-tog elementa */

Дакле, ако p показује на одређени елемент низа a, тада p+1 показује на наредни елемент, док p+i показује на елемент који се у низу a налази i позиција иза елемента на који показује p, а p-i показује на елемент који се у низу a налазиi позиција пре елемента на који показује p.

Разлика између имена низа (a) и показивача (p) је у томе што је показивач
променљива, док име низа није променљива, па самим тим му се не може променити вредност.

Другим речима, изрази p = a и p++ су дозвољени (поставља да p показује на нулти елемент низа a, односно помера показивач p за једну позицију у низу a у десно).

Изрази a = p и a++ нису дозвољени – a није променљива показивачког типа, већ је типа „низ целих бројева“ и само је аутоматски конвертована у показивач на први члан низа.

Пример: Програм демонстрира везе низова и показивача у програмском језику C.

#include <stdio.h>
main()
{
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *p = a;
int i;
printf("Vrednost izraza a (tipa int *): %p\n", a); /* a sadrzi ADRESU pocetnog elementa niza, odnosno adresu elementa a[0] */
printf("Vrednost izraza p (tipa int *): %p\n", p); /* pokazivac p takodje sadrzi adresu pocetnog elementa niza */
printf("Vrednost izraza *a (tipa int): %d\n", *a); /* iako a nije pokazivac, s obzirom na cinjenicu da je a niz brojeva, on se moze posmatrati kao pokazivac, pa je zbog toga dozvoljeno koristiti *a. U tom slucaju *a sadrzi prvi elemenat niza, odnosno vrednost elementa a[0], a to je 0 */
printf("Vrednost izraza *p (tipa int): %d\n", *p); /* *p je vrednost prvog elementa niza */
for(i = 0; i < 10; i++)
{
printf("Vrednost izraza &a[%d] (tipa int *): %p\n",i,&a[i]); /* adresa i-tog podatka u nizu */
printf("Vrednost izraza &p[%d] (tipa int *): %p\n",i,&p[i]); /* adresa i-tog podatka u nizu */
printf("Vrednost izraza (a + %d) (tipa int *): %p\n",i,a+i); /* a+i je takodje adresa i-tog elementa */
printf("Vrednost izraza (p + %d) (tipa int *): %p\n",i,p+i); /* p+i je takodje adresa i-tog elementa */
printf("Vrednost izraza a[%d] (tipa int): %d\n", i, a[i]); /* vrednost i-tog elementa */
printf("Vrednost izraza p[%d] (tipa int): %d\n", i, p[i]); /* vrednost i-tog elementa */
printf("Vrednost izraza *(a + %d) (tip int):%d\n",i,*(a+i)); /* vrednost i-tog elementa */
}
printf("Vrednost izraza *(p + %d) (tip int):%d\n",i,*(p+i)); /* vrednost brojaca i u ovom trenutku je 10. p+10 je adresa koja ne pripada nasem nizu. *(p+10) je vrednost lokacije p+10, ali mi ne znamo kolika je ta vrednost! */
}

Извршавањем програма може се уочити разлика у примени разних израза везаних за употребу индекса низа или показивача:

Пример:

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

#include<stdio.h>
main()
{
int a[20],*p,zbir,n,i;zbir=0;
printf("unesi n");scanf("%d",&n);
printf("unesi elemente niza");
for(p=a;p<a+n;p++)scanf("%d",p);/* elemente niza unosimo koriscenjem pokazivaca. Pokazivac ima i ulogu brojaca u ciklusu */
for(p=a;p<a+n;p++)zbir=zbir+(*p);
printf("zbir=%d",zbir);
}

Пример:

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

#include<stdio.h>
#define MAX 100
main()
{
int a[MAX]; /* deklaracija niza a od najvise MAX elemenata */
int n; /* broj elemenata niza a */
int *p, *q; /* pokazivaci na elemente niza a */
int t; /* pomocna promenljiva, koristicemo je prilikom obrtanja niza */
/* unosimo broj elemenata niza */
printf("unesi broj elemenata niza n<=100");scanf("%d",&n);
/* proveravamo da li je prekoraceno ogranicenje, n se postavlja na MAX u slucaju da je uneta veca vrednost */
if(n>MAX)n=MAX;
/* unosimo elemente niza */
printf("unesi elemente niza");
for(p=a;p<a+n;p++)scanf("%d",p);
/* prikaz niza */
printf("uneli ste niz:");
/* prikaz pocetnog niza */
for(p=a;p<a+n;p++)printf("%d\t",*p);/* elemente niza prikazujemo koriscenjem pokazivaca. Pokazivac ima i ulogu brojaca u ciklusu */
printf("\n");
/* obrcemo niz */
for(p=a,q=a+n-1;p<q;p++,q--)/* pokazivaci *p i *q, koji predstavljaju brojace u ciklusu, krecu sa suprotnih strana niza. Zamenjuju se mesta elementima niza na koje pokazuje pokazivac *p i pokazivac *q. U sledecem koraku pokazivac *p se povecava za 1, pa pokazuje na sledeci elemenat niza; pokazivac *q se smanjuje za 1, pa i on pokazuje na sledeci elemenat niza (sa suprotne strane). Ukoliko je jos uvek p<q prelazi se na zamenu sledeca dva elementa niza */
{t=*p;*p=*q;*q=t;}
/* prikaz niza nakon obrtanja */
printf("nakon obrtanja:");
for(p=a;p<a+n;p++)printf("%d\t",*p);
}

1 thoughts on “Низови и показивачи

  1. Повратни пинг: Основни алгоритми са низовима – Рачунари и програмирање

Постави коментар