kot-niepłot
Dołączył: 29 Lis 2005
Posty: 324
Przeczytał: 0 tematów
Ostrzeżeń: 0/5 Skąd: Gliwice BioAut
|
Wysłany: Pon 21:28, 06 Lis 2006 Temat postu: Pseudokurs: Wskaźniki |
|
|
Z tego co p. Metzger tłumaczył na wykładzie nic nie zrozumiałem
Wstęp teoretyczny:
Wszystkie zmienne są przechowywane w pamięci. Pamięć się dzieli na "komórki". Żeby system mógł się odwoływać do komórek, każda komórka musi posiadać adres. W ten sposób zmienna też posiada adres - bo jest przechowywana w komórkach. Możemy sobie więc w dowolnej chwili odczytać adres jakiejś zmiennej (jest w postaci liczby) albo odczytać wartość komórki spod tego adresu (i to zdanie jest gwoździem programu), wartość którą przechowuje, czyli po prostu wartość zmiennej, która mieści się w tym adresie.
Opis właściwy:
Deklaracja wskaźnika:
int *p; lub
int* p; - niektórzy polecają w ten sposób, ale efekt jest zupełnie ten sam.
Jest to wskaźnik do typu int. Można deklarować wskaźniki razem z innymi zmiennymi, np:
int x, *p, y;
Dla smakoszy: int* x, y; deklaruje tylko x jako wskaźnik, należy na to uważać.
Teraz: cóż to jest wskaźnik:
Wskaźnik to zmienna co przechowuje adres.
Natomiast żeby wyciągnąć ("wyłuskać") wartość spod adresu przechowywanego przez wskaźnik stosujemy operator wyłuskania (myślę że nie trzeba pamiętać nazwy ), czyli * , np:
int *x; ... ... ... cout << *x; - wyświetli wartość spod adresu przechowywanego w x
Do kompletu brakuje jeszcze tylko operatora pobierania adresu: jest nim &.
Konieczne jest by typ wskaźnika i zmiennej się zgadzały.
Teraz można napisać w miarę kompletny przykład:
Kod: | ...
int *x, y;
y = 5; // znana wszystkim akcja ;)
x = &y; // x teraz będzie przechowywało adres zmiennej y
/* Wyświetlamy teraz adres y, potem samą wartość y, potem poprzez wskaźnik: */
cout << &y << " " << y << "\n";
cout << x << " " << *x << "\n"; // operacje równoważne
|
Oczywiście takie wykorzystanie wskaźników jest profanacją ich potęgi Głównie wykorzystuje się je po to, by zmienić jakąś komórkę (zmienną):
Kod: |
/* ciąg dalszy */
*x = 3; // modyfikowana jest komórka wskazywana przez x
x = 564365; // chcemy sami wpisać jakiś adres - BŁĄD
x++; // co ciekawe, nie ma błędu, ale wyłuskanie tego wyświetli bzdury
|
Wykorzystanie wskaźników przy tablicach:
int p[5];
Samo p jest wskaźnikiem do zerowego elementu.
Dodawanie do p liczb (całkowitych) tak naprawdę zwiększa adres, który możemy oczywiście wyłuskać:
Kod: |
int p[] = {1, 2, 3, 4, 5, 6, 7};
cout << p << "\n"; // adres zerowego elementu
cout << p+1 << "\n"; // adres następnego elementu*
cout << *p << "\n"; // wartość zerowego elementu
cout << *(p+1) << "\n"; // wartość pierwszego elementu*
cout << *p + 1 << "\n"; // wartość zerowego elementu + 1, czyli 2
|
* - dla smakoszy: nie należy się przejmować rozmiarem zmiennych. (Jeśli int ma rozmiar 4, tamta operacja automatycznie przeskoczy o 4 bajty)
Oczywiście mnożenie, dzielenie adresu przez liczbę czy dodawanie dwóch adresów nie ma większego sensu, toteż jest niedozwolone.
Większa moc wskaźników ujawni się przy funkcjach, gdzie można przekazać całą tablicę lub strukturę.
Ciekawostka: jak już prof. Metzger wspominał, funkcja scanf() wykorzystuje wskaźnik:
scanf("%d", &x);
Przekazuje do funkcji adres, a ona zmienia zawartość tego adresu - w tym wypadku opiekuje się nim zmienna x. Sprytne
Alternatywa:
Kod: |
int *p;
p = &x;
...
scanf("%d", p); // bez &
|
Zmienna wskaźnikowa p już przechowuje adres, więc nie pobieramy z niej dodatkowo adresu, tylko przekazujemy ten który nas interesuje.
Inne (dla smakoszy):
-> Operacja w stylu x = &x jest niedozwolona. Można robić wskaźnik do wskaźnika, ale trzeba go deklarować jako int **x .
->int x[5][5]; - x jest wskaźnikiem typu int**
->Można zadeklarować wskaźnik jako int *x; a potem odwoływać się do niego przez operator tablicy: x[0]. Odwołanie się do x[1] lub x[150] nie zgłosi błędu składni, jednak wyświetli jakieś bzdury (co tam tylko jest w pamięci) lub po prostu spowoduje błąd wykonania programu.
->Ale za to zrobimy tak:
Kod: | int t[2] = { 0, 1 };
int *p;
p = t; |
I już mamy dwie nazwy do jednej tablicy
Post został pochwalony 0 razy
|
|