Wskaźniki
DarkGL
22.06.2010
Wskaźnik to obiekt przechowujący adres innego obiektu.
Prosty przykład:
wyjaśnijmy linijkę
Skoro mamy wskaźnik możemy na niej wykonać dwie rzeczy.
1.uzyskać wartość obiektu na którą wskazuje wskaźnik służy do tego operator *
2.zmienienie jej wartości kod:
Wskaźniki stałe to wskaźniki które zawsze mają te samą wartość (zawsze wskazują ten sam obiekt) wskaźniki stałem muszą być zainicjowane adresem obiektu od razu przy tworzeniu.
Wskaźniki na wskaźniki
Void*
jest to specjalny typ wskaźników który charakteryzuje się tym że można przypisać mu wartość wskaźnika dowolnego typu
taki kod służy w C do przekazywania do funkcji argumentów dowolnego typu nie jest to zbyt ładne prawda ?
dlatego w swoim kodzie nigdy nie używaj void* w c++ slużą do tego szablony
Wskaźnik zerowy
jest to wskaźnik o wartości 0 oznacza to że nie wskazuje on na żaden obiekt można też używać NULL
Tablice a wskaźniki
jeżeli wykonamy taki kod
dostaniemy ten sam adres
więc możemy powiedzieć że nazwa tablicy może być traktowana jak wskaźnik na jej pierwszy element
dalej
w pierwszej linijce dostaniemy ten sam adres jaki byśmy zobaczyli gdybyśmy przesłali tab
w następnej zobaczymy 0 czyli wartość pierwszego elementu
a w następnej wartość drugiego elementu czyli 1;)
czyli podsumowując
Wskaźników można używać jak nazw tablic , a nazw tablic jak wskaźników
Użytkownik DarkGL edytował ten post 03.08.2010 16:05
Prosty przykład:
int main(){ int liczba = 7; std::cout<<"Adres liczba"<<&liczba<<std::endl; int* wsk = &liczba // zmienna wsk przechowuje adres liczba std::cout<<"Pod adresem"<<wsk<<"jest liczba"<<*wsk<<std::endl; *wsk = 15; std::cout <<"Teraz liczba = "<<liczba<<std::endl; }do odczytania adresów zmiennych służy operator &.
wyjaśnijmy linijkę
int* wsk = &x // zmienna wsk przechowuje adres liczbatutaj na lewo od gwiazdki znajduje się identyfikator typu int , dlatego zmienna wsk może przechowywać adresy liczb typu int. Typem zmiennej wsk jest int*
Skoro mamy wskaźnik możemy na niej wykonać dwie rzeczy.
1.uzyskać wartość obiektu na którą wskazuje wskaźnik służy do tego operator *
2.zmienienie jej wartości kod:
int x = 0 , y =2; int* wsk = &x; p = &y
Wskaźniki stałe to wskaźniki które zawsze mają te samą wartość (zawsze wskazują ten sam obiekt) wskaźniki stałem muszą być zainicjowane adresem obiektu od razu przy tworzeniu.
int x =0; int* const wsk = &x; // wsk jest stalym wskaźnikiem na xWskaźniki na stałą to wskaźniki umożliwiające jedynie odczytanie stanu obiektu
int x =0; const int* wsk = &x; // wsk jest wskaźnikiem na stałąi dodatkowo można utworzyć stały wskaźnik na stałą
int x = 0; const int* const wsk = &x;
Wskaźniki na wskaźniki
int x = 0; int* wsk = &x; int** wsk2 = &wsk;
Void*
jest to specjalny typ wskaźników który charakteryzuje się tym że można przypisać mu wartość wskaźnika dowolnego typu
int x = 0; int* wsk = &x; // wsk wskazuje na x void* wsk2 = wsk; //w wsk2 jest wartość wsk czyli adres x
taki kod służy w C do przekazywania do funkcji argumentów dowolnego typu nie jest to zbyt ładne prawda ?
dlatego w swoim kodzie nigdy nie używaj void* w c++ slużą do tego szablony
Wskaźnik zerowy
jest to wskaźnik o wartości 0 oznacza to że nie wskazuje on na żaden obiekt można też używać NULL
Tablice a wskaźniki
jeżeli wykonamy taki kod
int tab[2] = {0}; std::cout<<tab<<std::endl; std::cout<<&tab[0]<<std::endl;
dostaniemy ten sam adres
więc możemy powiedzieć że nazwa tablicy może być traktowana jak wskaźnik na jej pierwszy element
dalej
int tab[2] = {0,1}; int* wsk = tab; std::cout<<wsk<<std::endl; std::cout<<*wsk<<std::endl; std::cout<<wsk[1]<<std::endl;po koleji
w pierwszej linijce dostaniemy ten sam adres jaki byśmy zobaczyli gdybyśmy przesłali tab
w następnej zobaczymy 0 czyli wartość pierwszego elementu
a w następnej wartość drugiego elementu czyli 1;)
czyli podsumowując
Wskaźników można używać jak nazw tablic , a nazw tablic jak wskaźników
Użytkownik DarkGL edytował ten post 03.08.2010 16:05
-PainKiller- 22.06.2010
nigdy tego nierozkminama m i teraz tez nie ale mnoze rano sprobuje bo teraz jestem w stanie niewazkosci alkoholowej
pozdrawiam
ogolnie nie wiem do czegostuo suje sie wskazniki
pozdrawiam
ogolnie nie wiem do czegostuo suje sie wskazniki
R3X
22.06.2010
Trochę zabrakło prezycji, bo wskaźniki to nie obiekty w C90 są wskaźniki, a nie jest obiektowe.
Wskaźniki (i referencje) służą do lekkiego przekazywania parametrów do funkcji, np dlatego tablice zawsze są przekazywane przez wskaźnik.
int [] tab jest tym samym co int *tab;
Wskaźniki (i referencje) służą do lekkiego przekazywania parametrów do funkcji, np dlatego tablice zawsze są przekazywane przez wskaźnik.
int [] tab jest tym samym co int *tab;
DarkGL
22.06.2010
warto dodać że w c nie ma referencji więc wskaźniki to podstawa chociaż w programach pisanych w c++ nie warto ich używać
C90 ?
Użytkownik DarkGL edytował ten post 22.06.2010 22:06
C90 ?
Użytkownik DarkGL edytował ten post 22.06.2010 22:06
R3X
22.06.2010
Brakuje mi tu praktycznych przykładów
PS. chodziło mi raczej o standard C z roku 1990, ale wyrzutnia jest ok też
PS. chodziło mi raczej o standard C z roku 1990, ale wyrzutnia jest ok też
G[o]Q
23.06.2010
hmm mozesz opisac tez wskazniki do funkcji i ich przekazywanie do innej funkcji (jak cos to ci moge materialy podeslac) bo to jest o tyle ciekawa rzecz ze mozna zrobic cos jak w pawnie funkcje majace obslugiwac sortowanie
Owner123
28.07.2010
Mała poprawka - nie ma wskaźnika zerowego, są jedynie wskaźniki ustawione na adres zerowy.
-PainKiller- 24.10.2010
przeczytałem twoją teorię i szczerze mówiąc ciężko się połapać, jako że ostatnio intensywnie działam w c++ to napiszę to po swojemu może komuś będzie łatwiej zrozumieć...
musimy uruchomić wyobraźnię i zejść nieco niżej niż c++...
Na początek musimy zrozumieć istotną rzecz w programowaniu, jak wiadomo niektóre języki wymagają kompilatorów, niektóre nie. C++ nie jest językiem niskopoziomowym dlatego musi być kompilowany na poziom niższy, maszynowy lub binarny, jak zwał tak zwał chodzi o to że procesor sam z siebie nie rozumie języka c++ dlatego musi go dostać w postaci binarnej (0101010101) do tego służy kompilator który jakby przekonwertuje nasz kod c++ na kod maszynowy - zrozumiały dla procesora.
Gdy procesor ma już kod, który rozumie to w zależności od programu (właściwie tylko prymitywny program nie spełni tego warunku) tworzy sobie ileś tam obiektów, zmiennych. Każda definicja zmiennej jest jakby poleceniem, podam dla przykładu...
co sie dzieje?
procesor wysyła cynka do pamięci że chce owy typ danych zarezerwować, oczywiście można zagłębiać sie w szczegóły ile zajmie to komórek (mówimy o RAMIE) w kości i tak dalej.. ale chodzi o to że teraz możemy w pamięci mieć te dane i jakoś się do nich odwołać, czy to wywołać czy wprowadzić...
sposobów jest wiele ale na ten temat wystarczą:
- przez nazwe zmiennej
- przez utworzony wskaźnik
mała anegdota jaka podaje Grębosz w symfoni c++ (zmienie tresc, sens ten sam)
robisz zadanie z angielskiego i korzystasz z słownika który ma 1000 stron, załóżmy że szukasz słowa "wskaźnik" jest ono na 820 stronie jednak nie masz spisu treści, masz tylko ułożone wg alfabetu więc jedziesz po kolei kartka za kartką aż udaje ci sie dojść do owej strony, odczytujesz jak jest po angielsku i zamykasz słownik. Niestety w tym czasie mama weszła do pokoju i mowi ci wyłacz komputer a ty nie chcesz tego zrobic, ona wyszla a ty w tym czasie zapomniales jak "wskaźnik" było po angielsku.... no to jedziesz od nowa znowu kartka za kartką (zakładamy że masz IQ = 0 i nie wiesz nawet mniej więcej że jest to w drugiej czesci slownika, bo komputer jak wiadomo nie ma inteligencji wiec on to bedzie tak robil....) i nagle ci sie udało, znowu wiesz jak jest "wskaźnik" po angielsku ale teraz wszedł to pokoju tata i zaczyna ci nawijać żebyś mu umył auto, tym razem sie wycwaniłeś i zapisujesz sobie obok na kartce na której stronie masz tłumaczenie słowa wskaźnik....
Teraz już chyba znasz istote wskaźników- chodzi o szybszy dostęp do komórek pamięci gdzie zapisane są dane(wskaźnik wskazuje na adres w pamieci RAM gdzie jest owa zmienna, obiekt)
wskaźnik musi być tego samego typu co zmienna wskazywana a więc
Ogólnie bez wskaźników da sie życ, są one przydatne w naprawdę wielkich projektach, jak na dzisiejsze pamieci RAM można napisać sporo wieloplikowych aplikacji z konkretna zawartoscia kodu bez wskaźników bez utraty szybkości ale gdy ktos sie programowaniem bardziej interesuje to chyba powinien to wiedzieć.
większość napisałęm od siebie, ja tak rozumiem wskaźniki jeśli coś źle ujałem a jest tu ktoś kto wie lepiej to czekam na korekty....
musimy uruchomić wyobraźnię i zejść nieco niżej niż c++...
Na początek musimy zrozumieć istotną rzecz w programowaniu, jak wiadomo niektóre języki wymagają kompilatorów, niektóre nie. C++ nie jest językiem niskopoziomowym dlatego musi być kompilowany na poziom niższy, maszynowy lub binarny, jak zwał tak zwał chodzi o to że procesor sam z siebie nie rozumie języka c++ dlatego musi go dostać w postaci binarnej (0101010101) do tego służy kompilator który jakby przekonwertuje nasz kod c++ na kod maszynowy - zrozumiały dla procesora.
Gdy procesor ma już kod, który rozumie to w zależności od programu (właściwie tylko prymitywny program nie spełni tego warunku) tworzy sobie ileś tam obiektów, zmiennych. Każda definicja zmiennej jest jakby poleceniem, podam dla przykładu...
int x;klepiąc taki kod dajemy procesorowi polecenie: "zarezerwuj w pamięci mi na przyszłość miejsce pod kryptonimem x, w którym później będę mógł trzymać dane w postaci liczb całkowitych"
co sie dzieje?
procesor wysyła cynka do pamięci że chce owy typ danych zarezerwować, oczywiście można zagłębiać sie w szczegóły ile zajmie to komórek (mówimy o RAMIE) w kości i tak dalej.. ale chodzi o to że teraz możemy w pamięci mieć te dane i jakoś się do nich odwołać, czy to wywołać czy wprowadzić...
sposobów jest wiele ale na ten temat wystarczą:
- przez nazwe zmiennej
- przez utworzony wskaźnik
mała anegdota jaka podaje Grębosz w symfoni c++ (zmienie tresc, sens ten sam)
robisz zadanie z angielskiego i korzystasz z słownika który ma 1000 stron, załóżmy że szukasz słowa "wskaźnik" jest ono na 820 stronie jednak nie masz spisu treści, masz tylko ułożone wg alfabetu więc jedziesz po kolei kartka za kartką aż udaje ci sie dojść do owej strony, odczytujesz jak jest po angielsku i zamykasz słownik. Niestety w tym czasie mama weszła do pokoju i mowi ci wyłacz komputer a ty nie chcesz tego zrobic, ona wyszla a ty w tym czasie zapomniales jak "wskaźnik" było po angielsku.... no to jedziesz od nowa znowu kartka za kartką (zakładamy że masz IQ = 0 i nie wiesz nawet mniej więcej że jest to w drugiej czesci slownika, bo komputer jak wiadomo nie ma inteligencji wiec on to bedzie tak robil....) i nagle ci sie udało, znowu wiesz jak jest "wskaźnik" po angielsku ale teraz wszedł to pokoju tata i zaczyna ci nawijać żebyś mu umył auto, tym razem sie wycwaniłeś i zapisujesz sobie obok na kartce na której stronie masz tłumaczenie słowa wskaźnik....
Teraz już chyba znasz istote wskaźników- chodzi o szybszy dostęp do komórek pamięci gdzie zapisane są dane(wskaźnik wskazuje na adres w pamieci RAM gdzie jest owa zmienna, obiekt)
wskaźnik musi być tego samego typu co zmienna wskazywana a więc
#include <iostream> using namespace std; main(){ int zmienna=8, drugi = 4; //załózmy ze pod nazwa "zmienna" jest owe słowo "wskaźnik"(ze słownika) a pod nazwa "drugi" jest hasło "pamięć" też ze słownika czyli ma ono inną strone w słowniku (w przypadku wskaźników ma inny adres komórek w RAM) int *wskaznik; //tworznie wskaźnika typu int wskaznik = &zmienna; //ustawienie wskaźnika na zmienną, zmienna o nazwie "drugi" nie posiada w tym momencie wskaźnika, nie wiesz gdzie w słowniku jest słowo "pamięć" cout<<"zmienna odczytana przez nazwe zmiennej: "<<zmienna<<"a odczytana przez wskaznik"<<*wskaznik<<endl; zmienna = 100; // ZMIENIAMY WARTOŚĆ ZMIENNEJ nie odwołujac sie przez wskaznik ale przez jej nazwe cout<<"zmienna odczytana przez nazwe zmiennej: "<<zmienna<<"a odczytana przez wskaznik"<<*wskaznik<<endl; *wskaznik = 200; //zmieniamy wartość zmiennej "zmienna" ale nie przez jej nazwe a przez wskaźnik, wskaźnik caly czas jest ustawiony na zmienną "zmienna" cout<<"zmienna odczytana przez nazwe zmiennej: "<<zmienna<<"a odczytana przez wskaznik"<<*wskaznik<<endl; wskaznik = &drugi; //ZMIENIAMY OBIEKT NA KTÓRY WSKAZYWAŁ BĘDZIE WSKAŹNIK czyli jakby skreślamy z naszej kartki strone słowa "wskaźnik" a zapisujemy strone na której jest tłumaczenie słowa "pamięć" cout<<"zmienna odczytana przez nazwe zmiennej: "<<zmienna<<"a odczytana przez wskaznik"<<*wskaznik<<endl; }
Ogólnie bez wskaźników da sie życ, są one przydatne w naprawdę wielkich projektach, jak na dzisiejsze pamieci RAM można napisać sporo wieloplikowych aplikacji z konkretna zawartoscia kodu bez wskaźników bez utraty szybkości ale gdy ktos sie programowaniem bardziej interesuje to chyba powinien to wiedzieć.
większość napisałęm od siebie, ja tak rozumiem wskaźniki jeśli coś źle ujałem a jest tu ktoś kto wie lepiej to czekam na korekty....
G[o]Q
25.10.2010
w symfonii bylo o pociagach i szczerze mowiac to gdybym nie znal c++ to twojego textu bym nie zrozumial bo wskaznik tylko pokazuje na dany adres w pamieci wiec mozemy sie dostac do danego obszaru kiedy chcemy
-PainKiller- 25.10.2010
raczej nikt by nie zrozumiał bo nikt o zdrowym umyśle nie zacznie nauki c++ od wskaźników...szczerze mowiac to gdybym nie znal c++ to twojego textu bym nie zrozumial
MaDaFaKa 17.11.2010
Ładny poradnik. Niestety jest jedno "ale". Gdybym nie znał c++ to bym niestety nic z tego nie zrozumiał
MaDaFaKa 17.11.2010
Wiem o tym, bo jest to sprawa, że tak powiem "bardziej zaawansowana". Moim zdaniem poradniki powinny być zrozumiałe dla wszystkich, nawet początkujących, dlatego ująłem to w tamtym poście.
mgr inż. Pavulon
18.11.2010
ale każdy poradnik musi wymagać jakiejś wiedzy w danej dziedzinie...Moim zdaniem poradniki powinny być zrozumiałe dla wszystkich, nawet początkujących, dlatego ująłem to w tamtym poście.
nie da się uczyć programowania od stopnia zaawansowanego, to tak jakby uczyć się całkowania, różniczkowania czy liczb zespolonych bez znajomości funkcji trygonometrycznych