Wskaźnik?
Dla wielu wskaźniki to najgorszy temat w całym C++. A teraz, jak już jesteście w pełni zmotywowani przedstawię wam je: *, &. Tak, to wszystko co będziesz musiał dzisiaj zrozumieć.
& - To jest ampersand
Jak wiesz wszystkie dane naszego programu siedzą w komórkach pamięci, których jest bardzo, bardzo dużo. Aby komórki można było odróżnić każda została obdarzona własnym, unikatowym adresem zapisanym w kodzie szesnastkowym. Ampersand potrafi wskazać nam adres komórki, w której siedzi zmienna.
int x = 0;
cout << &x;
I tak oto uzyskaliśmy nasz adres.
* - A to jest gwiazdka
Gwiazdka odpowiada nam na takie pytanie: "Jaka jest zawartość komórki o adresie ...?". Ktoś inteligenty zauważy, że gwiazdka jest prawie jak odwrotność ampersanda. Ale chwila, przecież to jest totalnie bezużyteczne bo nie znamy adresów komórek naszej pamięci i nie planujemy co w nich może siedzieć. Teraz właśnie przyda nam się głowa:
int x = 10;
int *wsk; // deklaracja zmiennej wskaźnikowej
wsk = &x; // przypisanie zmiennej adresu komórki, w której mieści się x
cout << *wsk; // Jaka jest zawartość komórki o adresie &x? Oczywiście 10
Niesamowite, właśnie za pomocą 2 zmiennych i dziwnych znaków wyświetliliśmy zawartość 1 zmiennej! Ale zauważcie, że wskaźnik można przestawiać:
int x = 10;
int y = 30;
int *wsk;
wsk = &x;
cout << *wsk << endl;
wsk = &y;
cout << *wsk;
A teraz zagadka:
int x = 10;
int y = 30;
int *wsk;
int *wsk2;
wsk = &x;
wsk2 = &y;
cout << *&*&*wsk << endl;
cout << &*&*wsk << endl;
cout << &*&*&y << endl;
cout << *&*&wsk2 << endl;
Jeżeli jesteś w stanie powiedzieć gdzie wyświetli się adres zmiennej, a gdzie jej wartość możesz być z siebie dumny. Pamiętaj, kartka i długopis nie gryzą. Wiedz również, że zmienna wskaźnikowa równiesz siedzi w jakiejś komórce z własnym adresem.
Jak działa referencja
void operacja(int * zmienna) // zmienna wskaźnikowa wskazuje na adres x!
{
*zmienna +=10;
}
int main()
{
int x = 0;
operacja(&x); // do funkcji wysyłamy adres zmiennej x
cout << x << endl;
return 0;
}
Takim sposobem przełamaliśmy się przez magiczną ścianę między 2 funkcjami. Funkcja "operacja" ma bezpośredni dostęp do zmiennej z funkcji main(). Obie funkcje operują na 1 adresie. Jakie są tego zalety? Bez tego tworzona jest kopia wysłanej zmiennej. A może tablicy? A tablica może być bardzo duża. Samo kopiowanie jej spowolniłoby program. Dlatego właśnie wymyślono referencję - przekazywanie przez adres, a nie przez wartość. W C++ wszystkie tablice są automatycznie przekazywane przez referencję, a my możemy korzystać z niej w przypadkach kiedy chcemy mieć coś "na żywo" udostępniane innym funkcją.
Jeszcze tylko krótszy sposób tego co zapisałem powyżej:
void operacja(int &zmienna) // wszystko to samo w skróconej formie
{
zmienna +=10;
}
int main()
{
int x = 0;
operacja(x);
cout << x << endl;
return 0;
}
Wiem, że teraz może to nie pasować do roli ampersanda, ale to tylko specjalnie ustanowiony skrót na to, co zrobiłem nieco powyżej. Dodam jeszcze, że wskaźniki będą miały jeszcze znaczenie w polimorfiźmie, ogromnej zalecie programowania obiektowego, dlatego myślę, że już nigdy nie będziecie gadali "Po co te wskaźniki?!"