Kurs języka C: Spis treści
Część początkujących unika wskaźników jak ognia nie rozumiejąc istoty i zawiłości z nimi związanych. Jest to zrozumiałe, bo faktycznie na początku drogi łatwo popełniać błędy. Dlatego też wskaźniki są naturalnym kolejnym, ale bardzo istotnym stopniem wtajemniczenia, na którego poznanie należy i warto poświęcić nieco czasu.
Zacznijmy więc od tego, że:
Deklaracja zmiennej rezerwuje miejsce w pamięci, czyli kompilator przydziela dla niej określony (jej typem) obszar w pamięci (jeden lub kilka bajtów).
Jako, że każda komórka pamięci ma swój adres, stąd każda zmienna takowy adres posiada.
Aby uzyskać adres zmiennej przydzielony jej przez kompilator należy użyć:
Operator adresu: &
Poniższy przykład pozwala na wyświetlenie adresu, pod którym znajduje się zadeklarowana zmienna a. W celu poznania adresu wykorzystamy operator adresu (symbol &), a do jego wyświetlenia wykorzystamy funkcję printf wraz z formatowaniem adresów wskaźników, czyli %p. (więcej na temat printf w artykule: Printf() i funkcje pochodne).
Aby więc uzyskać adres zmiennej a, należy użyć jej wraz z operatorem adresu, czyli: &a
Przykład 1 (w kompilatorze)
#include <stdio.h> unsigned char a; //deklaracja zmiennej int main(void){ printf("adres zmiennej a: %p \n", &a); //pokaż adres zmiennej a return 0; }
Zobacz jakie będą adresy zmiennych deklarowanych w funkcji i poza nią:
Przykład 2 (w kompilatorze)
#include <stdio.h> unsigned char a, b; int main(void){ unsigned char c, d; printf("adres zmiennej a: %p \n", &a); //zmienna w obszarze 1 printf("adres zmiennej b: %p \n", &b); //zmienna w obszarze 1 printf("adres zmiennej c: %p \n", &c); //zmienna w obszarze 2 printf("adres zmiennej d: %p \n", &d); //zmienna w obszarze 2 return 0; }
Po skompilowaniu w CManiaku powyższego przykładu zauważysz, że zmienne deklarowane są w dwóch różnych obszarach pamięci. Gdy kompilowałem powyższy program w trakcie pisania artykułu adresy były następujące:
adres zmiennej a: 0x80497cd
adres zmiennej b: 0x80497cc
adres zmiennej c: 0xbfc12f9e
adres zmiennej d: 0xbfc12f9f
adres zmiennej b: 0x80497cc
adres zmiennej c: 0xbfc12f9e
adres zmiennej d: 0xbfc12f9f
Zauważ że:
- zmienne deklarowane są w dwóch różnych obszarach pamięci w zależności od tego, czy były deklarowane w funkcji, czy poza nią,
- adresy zmiennych a oraz b są malejące, a zmiennych c oraz d rosnące,
- po niewielkiej zmianie kodu programu i nowej kompilacji adresy zmiennych mogą być inne (decyduje o tym kompilator).
Teraz już wiesz dlaczego wskaźniki nazywają się wskaźnikami - po prostu wskazują położenie zmiennej w pamięci.
Wskaźniki mogą wskazywać nie tylko położenie zmiennych, ale także np. adres funkcji:
Przykład 3 (w kompilatorze)
#include <stdio.h> void funkcja(void){ //jakis kod return; } int main(void){ printf("adres funkcji funkcja(): %p \n", &funkcja); printf("adres funkcji main(): %p \n", &main); return 0; }
Ale po co znać adres funkcji? Na przykład po to, by móc skatalogować adresy funkcji w tablicy i wywoływać funkcje w zależności od jakiegoś parametru, ale o tym napiszę w jednym z kolejnych artykułów.
Kurs języka C: Spis treści
42
Naukę zacząłem od arduino, analizując poniższy kod, zastanawiałem się dlaczego to jest tak (&onewire).
OdpowiedzUsuń#define ONEWIRE_PIN 10
OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);
A teraz już wiem. Dzięki
Ten komentarz został usunięty przez autora.
OdpowiedzUsuń