Na dzisiaj mam dla Was treść materiału dotyczącą wskaźników w języku C. Ze względu na ostatnie wydarzenia w ciągu tych kilku dni, postanowiłem podzielić się zdobytą wiedzą na ten temat mając szansę utrwalić sobie ten materiał. Na razie takie proste podpunkty. Dowiemy się co to są "wskaźniki", jak je utworzyć w kodzie, co się pod nimi kryje oraz w jaki sposób mogą nam ułatwić pisanie kodu. Do dzieła!

WSKAŹNIKI W JĘZYKU C. CHARAKTERYSTYKA

Zdarzyło mi się to napisać wcześniej jednak powtórzę po raz kolejny, aby wszystkie informacji "siedziały" koło siebie w jednym miejscu. Wskaźnik jest to typ danych przechowujący odniesienie do innej naszej danej ("referencja", pamiętacie?). Napisałem "danej" bo może to być zmienna, może to być stała, może to być nawet funkcja i w ten sposób jest możliwe tworzenie tzw. "wywołań zwrotnych" ("callback"), ale nie wchodźmy w trudne detale. Wskaźniki przechowują adres i to za jego pośrednictwem powstaje "relacja" z danym obiektem danych. Tworzone są za pomocą znaku gwiazdki (*) umieszczanej pomiędzy typem danych, a nazwą np. "int *x".

Adres najczęściej składa się z ciągu liter i cyfr ułożonych w systemie heksadecymalnym. Posiada własny specyfikator formatu dla funkcji "printf" (%p) i może ulegać zmianie przypisując adres innego obiektu do wskaźnika. W językach C i C++, adres danego obiektu "wydobywany" jest za pomocą znaku "ampersand" (&) jako przedrostek występujący przed nazwą zmiennej, stałej czy jeszcze innego obiektu. Wyjątkiem są tablice i łańcuchy znaków, gdyż wstawiając ich nazwę, już od razu traktowane są jak adres do pierwszego argumentu.

PRAKTYCZNE UŻYCIA WSKAŹNIKÓW

Wskaźniki są trudne do opanowania jednak dają mnóstwo możliwości. Rzekłbym nawet, że dopiero one odkrywają cały potencjał języka C. Po pierwsze, jeden wskaźnik można wykorzystać do przechowywania różnych adresów i go swobodnie zmieniać przy pomocy operatora przypisania. Po drugie (o ile jawnie "wskażemy" odpowiedni adres) jesteśmy w stanie w każdej chwili dostać się do wskaźnika i "wyciągnąć" wartość o odpowiednim typie przy pomocy operatora dereferencji. Proces ten spotkacie również pod nazwą "wyłuskanie" i powoduje ono dostanie się do wartości kryjącej się pod aktualnie przypisanym adresem. Ten operator również jest gwiazdką (*) umieszczaną przed nazwą wskaźnika. Po trzecie, tablice mają bardzo ścisły związek ze wskaźnikami. Mało tego, one same są wskaźnikami! Tłumaczyłem to całkiem niedawno w tym miejscu więc tym razem to sobie daruję. Po czwarte, łańcuchy znaków w języku C również opierają się o wskaźniki. Wszystkie podstawowe funkcje operujące na łańcuchach też jak najbardziej korzystają ze wskaźników. Z pewnością można wymienić jeszcze parę dużych zalet, które pozwalają "sięgnąć dalej" niż programowanie bez wskaźników. Tyle na ten moment Wam wystarczy.

KOD ŹRÓDŁOWY

Na finał, zaprezentuję teraz prosty kod źródłowy, który podsumowuje powyższe akapity i prezentuje jak zdefiniować wskaźnik, prawidłowo przypisać adres oraz jak wykonać "wyłuskanie" czyli "deferencję". Zwróćcie uwagę na to, że przy zmianie wartości danej "podpiętej" pod wskaźnik, zmienna "x" RÓWNIEŻ ulega zmianie! Całokształt wygląda w taki sposób:

#include <stdio.h>

int main(void)
{
	int x = 56;
	int *px;
	
	px = &x;
	
	printf("Adres zmiennej x: %p\n", &x);
	printf("Wskaznik przechowuje nastepujacy adres: %p\n", px);
	
	*px += 20;
	
	printf("Dodajemy 20 do wartosci obiektu poprzez adres przechowywany przez wskaznik!\n");
	printf("Wartosc zmiennej x: %d\n", x);
	printf("Po zastosowaniu dereferencji odkryto, ze wskaznik wskazuje na obiekt danych o wartosci %d.\n", *px);
	getchar();
	
	return 0;
}

Ostatnia przestroga jest taka, żebyście POD ŻADNYM POZOREM nie operowali na niezainicjowanym wskaźniku! Wskaźniki muszą mieć przypisany przez Was adres i to Wy jesteście za to odpowiedzialni! Zignorowanie tej informacji nie przyniesie Wam żadnych przyjemnych rezultatów...


Na razie tyle Wam wystarczy. Traktujcie to jako małe wprowadzenie do wskaźników bo na pewno coś jeszcze o nich napiszę.