Rozdział ten opisuje jedno z ciekawszych i jednocześnie najtrudniejszych zagadnień związanych z programowaniem w języku C
Tablice
Tablica to zbiór danych określonego typu. Dostęp do danych możliwy jest za pomocą kluczy, będących ich indeksami. Wykorzystanie tablic umożliwia operowanie na dużych ilościach danych tego samego typu. Deklaracji dokonujemy w sposób następujący:
typ_danych nazwa_tablicy[ilość_elementów];
Przykładowa deklaracja tablicy typuint o nazwietabelkai 10-ciu elementach wygląda następująco:
int tabelka[10];
Wszystkie elementy w tabelach numerowane są od 0. Stąd powyższa deklaracja zarezerwuje w pamięci miejsce dla 10-ciu elementów typu int, do których możemy się odwołać poprzez zmienne: tabelka[0]..tabelka[9]
W języku C możemy zadeklarować tablice wielowymiarowe:
int tabelka[10][3];
Są one jednak rzadko wykorzystywane, w przeciwieństwie do tablic jednowymiarowych. Istnieje możliwość zadeklarowania dowolnego typu tablicy, włącznie z typem zadeklarowanym przez programistę. Często wykorzystuje się tablice struktur danych. Informacje na ten temat w rozdziale "struktury danych". Poniższy przykład przedstawia wykorzystanie tablicy w programie:
int tab[100],i;
for (i=0;i<100;i++)
tab[i]=i;
W prosty sposób możemy operować na 100 zmiennych typu int.
Wskaźniki
Wskaźnik jest zmienną przechowującą adres innej zmiennej. Osoby rozpoczynające naukę programowania często zastanawiają się nad zasadnością przechowywania adresu jakiejś zmiennej. Okazuje się jednak, że mechanizm wskaźników jest potężnym narzędziem umożliwiającym zwarte i efektywne programowanie. Deklaracja wskaźnika wygląda prawie identycznie jak deklaracja typowej zmiennej:
int *wskaznik;
gdzie, * oznacza, że deklarowany jest wskaźnik, do zmiennych typu int. Typ wskaźnika jest bardzo ważny, ponieważ w pamięci operacyjnej komputera zmienne poszczególnych typów zajmują określoną ilość bajtów.
Podstawowe operacje na wskaźnikach
& - podaje adres obiektu,
* - adresowanie pośrednie, zastosowane do wskaźnika daje zawartość obiektu, którego adres przechowuje wskaźnik.
Wskaźnik przechowuje adres zmiennej znajdującej się w pamięci komputera. Odczytując bezpośrednio wartość wskaźnika otrzymamy przechowywany adres. Przykładowo:
int *wsk,k;
k=10;
wsk=&k;
printf("%d", wsk);
W wyniku wykonania powyższego przykładu otrzymamy np. 231352. W celu uzyskania wartości przechowywanej w zmiennej k wyświetlamy zawartość *wsk, a nie wsk.
int *wsk,k;
k=10;
wsk=&k;
printf("%d", *wsk);
W wyniku wykonania powyższego przykładu otrzymamy wartość 10. Poniżej przedstawimy kilka przykładów z wykorzystaniem wskaźników.
int a=1, b=2;
int *wsk; /* wsk jest wskaźnikiem do zmiennych typu int */
wsk=&a /* teraz wsk wskazuje na a */
b=*wsk /* teraz b=1 */
*wsk=10 /* teraz a=10 */
Najczęściej wskaźniki stosuje się w połączeniu z tablicami. Przypisując do wskaźnika adres tablicy ustawiamy wskaźnik na jej początku. Przykładowo:
int *wsk;
int tablica[10];
wsk=&tablica[0];
printf("%d", *wsk);
W powyższym przykładzie wyświetlona zostanie zawartość pierwszego elementu tablicy (tablica[0]) Do tego momentu nie widać uzasadnienia do stosowania wskaźników Rozbudujemy nasz przykład o kolejne 2 linie:
int *wsk;
int tablica[10];
wsk=&tablica[0];
printf("%d",*wsk);
wsk++;
printf("%d",*wsk);
Efektem wykonania programu jest wyświetlenie dwóch pierwszych elementów tablicy (tablica[0], tablica[1]). Jak widać z powyższego przykładu możliwe jest poruszanie się po elementach tablicy z wykorzystaniem wskaźników. Upraszcza to pisanie programów wykotrzystujących tablice, umożliwając jednocześnie łączenie różnych obszarów pamięci w jedną całość. Powiązanie pomiędzy tabelami, a wskaźnikami umożliwia uproszczenie zapisu:wsk=&tablica[0] do postaci: wsk=&tablica
int *wsk;
int tablica[10];
wsk=&tablica;
printf("%d",*wsk);