Forum ::BIOTECHNOLOGIA:: Strona Główna ::BIOTECHNOLOGIA::
Forum studentów kierunku biotechnologia Politechniki Śląskiej
 
 FAQFAQ   SzukajSzukaj   UżytkownicyUżytkownicy   GrupyGrupy   GalerieGalerie   RejestracjaRejestracja 
 ProfilProfil   Zaloguj się, by sprawdzić wiadomościZaloguj się, by sprawdzić wiadomości   ZalogujZaloguj 

Pseudokurs: Wskaźniki

 
To forum jest zablokowane, nie możesz pisać dodawać ani zmieniać na nim czegokolwiek   Ten temat jest zablokowany bez możliwości zmiany postów lub pisania odpowiedzi    Forum ::BIOTECHNOLOGIA:: Strona Główna -> Informatyka
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
kot-niepłot




Dołączył: 29 Lis 2005
Posty: 324
Przeczytał: 0 tematów

Ostrzeżeń: 0/5
Skąd: Gliwice BioAut

PostWysł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 Razz

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 Wink ), 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 Wink 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 Wink
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 Wink


Post został pochwalony 0 razy
Powrót do góry
Zobacz profil autora
Wyświetl posty z ostatnich:   
To forum jest zablokowane, nie możesz pisać dodawać ani zmieniać na nim czegokolwiek   Ten temat jest zablokowany bez możliwości zmiany postów lub pisania odpowiedzi    Forum ::BIOTECHNOLOGIA:: Strona Główna -> Informatyka Wszystkie czasy w strefie EET (Europa)
Strona 1 z 1

 
Skocz do:  
Możesz pisać nowe tematy
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach

fora.pl - załóż własne forum dyskusyjne za darmo
Powered by phpBB © 2001, 2005 phpBB Group
Regulamin