Podstawy Programowania - semestr drugi
sie posługiwać wskaźnikami. Ponieważ zmienna wskaźnikowa przechowuje adres, wiec możemy przypisać jej adres zmiennej, która nie jest wskaźnikiem4. Aby poznać adres zmiennej możemy użyć funkcji tuklr, zwracającej wartość typu pointer, czyli po prostu adres zmiennej lub użyć operatora « (czytaj: .et"), który zwraca tą samą informacje Operator ten należy do grupy operatorów o najwyższym priorytecie. W przypadku tak«go przypisania kompilator nie sprawdza zgodnośa typów, wiec wskaźnikiem typu byte można wskazywać na zmienna typu integer. Takie rozwiązanie ma oczywiście swoie zalety, ale należy go stosować tylko w tedy. kiedy ma sie pełna świadomość co sie robi. Wskażn*. który na nic nie wskazuje zawiera wartość oznaczona stała nil. która jest „wartością zerowa* dla wskażn*ów. Do sprawdzenia, czy wskażnfc ma wartość różna od nil możemy użyć zwykłego operatora <> lub funkqi asagned, która jako parametr wywołania pobiera zmienna wskaźnkowa dowolnego typu. a zwraca wartość typu boolean . W ramce poniżej zamieszczono bardzo prosty program*, który demonstruje opisane wyżej zastosowanie wskaźników.
1 program wskaźniki;
2 uscs crt;
3 var
4 s:byte;
5 w:* by te;
6 bogiń
7 drscr;
9 w:-@s;
10 writcłn(s);
11 wrilełn<wA);
13 writełn(w');
15 writełn($);
16 readłn;
W werszu 4 togo programu deklarowana jest zmienna s typu byte, natomiast w następnym wierszy deklarowany jest wskażnk w typu byte. W wierszu 8 zmiennej s jest przypisywana wartość 4, natomiast następny wiersz zawiera instrukcje, która wskaźnikowi w przypisuje adres zmienne i przy użyciu operatora <9. W dwóch kolejnych wierszach wypisywana jest na ekran wartość zmiennej s i wartość zmiennej na którą wskazuje wskaźnik *»-. Proszą zauważyć, że nie możemy wypisać ostatniej wartości r»a ekran w ten sposób: wriieln(w). Ponieważ wskaźnik zawiera adres zmiennej, a nie jej wartość to kompilator zasygnabzuje. że jest błąd. gdyż nie można wypisać wartości zmiennej tego typu. Jeśli chcemy wypisać zawartość fragmentu pamięć, na który wskazuje zmienna wskażnkowa. musimy wykonać tzw. defeforenqe wskaźnika, lub inaczej wyłuskać wartość ze wskaźnika. Robimy to za pomocą znanego już nam operatora A, który informuje, że chcemy pobrać wartość z pamięć wskazywanej przez wskaźnik. Po wypisaniu obu wartość okaże sie. że sa one takie same. gdyż wskaźnik w wskazujo na zmienna *. Jeśi teraz zmienimy wartość zmiennej ». to okaże sie że zmieniła sie również wartość na którą wskazuje wskaźnik *• (wiersze 12 i 13). Możemy wykonać podobną operacje posługując sie wskaźnikiem. W wierszu 14 zmieniamy wartość tego na co wskazuje wskaźnik, a nie wartość samego wskaźnika. Po wypisaniu na ekran wartość zmiennej s okaże sie. że jest nią 3. czyli że wartość zmiennej uległa zmianie. W zrozumieniu działania wskaźników pomocny bądztó przedstawiony poniżej uproszczony' model fragmentu pamięci operacyjnej komputera. Załóżmy, ze wskaźnikowi w jest przypisana komórka o adresie 1. natomast zmiennej s jest przypisana komórka o adresie 2. Na rysunku jest pokazany stan pamięć po wykonaniu 9 wiersza programu. Zmienna s zawiera po prostu przypisana jej wartość natomiast wskaźnik h- zawiera adres zmiennej s.
adrct |
zawartość |
1 |
2 |
2 |
4 |
3 | |
4 |
Wskaźniki, tak jak inne zmienne mogą być zmiennymi globalnymi lub zmiennymi lokalnymi (w tym parametrami). Zanim zapiszemy coś do fragmentu pamięci, na który wskazuje wskaźnik, to musimy pamiętać aby go zainiqalizować. Wskażnfci globalne mają
5 A nawet zmiennej, która jest wskaźnfciem. ale tego przypadku nie będziemy analizować zęby nie stwarzać sobie dodatkowych trudności w zrozumieniu zasady działania wskaźników.
6 Takie sformułowanie zastępuję wyrażenie: wskaźnk. który wskazuje na daną typu byte (jak widać jest bardziej wygodne w użyću).
7 Osobiście nie spotkałem jeszcze programu w jeżyku Pascal, który korzystałby z drugiego rozwiązania, co oznacza, że jest ono dosyć rzadko stosowane.
8 Numery wierszy nie sacząśća kodu źródłowego programu! Zostały one dodane, aby ułatwić jego opisywanie.
9 Dokładny model fizycznej pamięć komputera PC byłby zbyt szczegółowy, jak na nasze potrzeby.
2