У програмском језику 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); }
Повратни пинг: Основни алгоритми са низовима – Рачунари и програмирање