PROGRAMOWANIE I ALGORYTMY

Wskaźniki


Definicja. Wskaźnik to zmienna przechowująca adres innej zmiennej. Inaczej mówiąc, jest to zmienna wskazująca na adres innej zmiennej. Skoro jest zmienną, więc posiada także swój adres.

Wskaźniki mają szerokie zastosowanie w C++ co daje temu językowi ogromną elastyczność.

Tworzenie wskaźnika

Zmienną wskaźnikową tworzymy podobnie jak zwykłe zmienne pamiętając tylko, aby przed nazwą wpisać operator "*". Operator ten służy także do wyłuskania wartości ze zmiennej wskaźnikowej (wyciągnięcia wartości ze zmiennej, na którą wskazuje).

int *a, *b; //stworzenie dwóch zmiennych wskaźnikowych typu int 

Przypisywanie wartości

Aby przypisać wartość należy użyć nazwy zmiennej z operatorem "*" (operator wyłuskania). Tak samo postępujemy w sytuacji, gdy wartość tej zmiennej chcemy przypisać do innej zmiennej lub ją wyświetlić.

int *a, b; //stworzenie zmiennej wskaźnikowej a i zwykłej zmiennej b
*a = 5; //przypisanie wartości do zmiennej a
 b = *a; //przypisanie wartości znajdującej się w zmiennej wskaźnikowej a do zmiennej b
cout<<*a<<" "<<b; //zostanie wypisana dwa razy liczba 5

Przypisywanie adresu drugiej zmiennej

Przypisując adres zmiennej, należy wymusić, aby przekazała swój adres a nie wartość. W takim przypadku należy użyć operatora "&".

Przypisując do zmiennej wskaźnikowej adres drugiej zmiennej wypisujemy tylko nazwę tej zmiennej, bez operatora "*":

int *liczba, b;
b = 6;
liczba = &b; //przypisanie adresu zmiennej b
cout<<*liczba; //wypisanie wartości przechowującej przez b

Zastosowanie wskaźników

Za pomocą wskaźników można kontrolować wartości innych zmiennych:

#include<iostream>
using namespace std;

int main()
{
  int *a, *b, c;
  
  c = 5;
  a = &c; //zmienna a wskazuje na adres zmiennej c
  b = &c; //zmienna b wskazuje na adres zmiennej c
  
  cout<<*a<<" "<<*b<<endl; //wypisanie wartości, którą przechowuje zmienna  c (2 razy 5)
  
  *a = 7; //zmiana wartosci zmiennej c
  
  cout<<*a<<" "<<*b<<" "<<c; //zostanie wypisana trzy razy wartość 7 
  
  return 0;
}

Wskaźniki jako argumenty funkcji.

Przekazując wskaźniki jako argumenty mamy zagwarantowane, że każda zmiana wartości zmiennej wewnątrz funkcji będzie "widoczna" w miejscu, w którym została wywołana:

#include<iostream>
using namespace std;
 
void zamien(int *a, int *b)
{
    int pom = *a;
        *a = *b;
        *b = pom;
}
 
int main()
{
        int a, b;
        cin>>a>>b;
        
        zamien(&a,&b); //przekazujemy adresy zmiennych
        
        cout<<a<<" "<<b; //wartości zmiennych zostały zamienione
        
        return 0;
}

Przykładowe wejście:

2 3

Wyjście:

3 2

Użycie zwykłych zmiennych nie spowoduje zamiany wartości, ponieważ funkcja będzie pracować na kopiach tych zmiennych.

Przydzielanie dynamiczne pamięci dla tablic, obiektów, struktur itp.

Gdy nie znamy wielkości tablicy lub tablica jest bardzo duża - większa niż stos programu, należy ją przydzielić dynamicznie.

#include<iostream>
using namespace std;

class klasa
{
  public:
    void f()
    {
      cout<<"metoda klasy";
    }
  private:
    int a;
};

int main()
{
  int *tab, n;
  
  klasa * obiekt = new klasa; //przydzielenie pamięci na obiekt klasy klasa
  
  cout<<"Podaj ilość elementów tablicy: ";
  cin>>n;
  
  tab = new int [n]; //przydzielenie pamięci na n elementów tablicy
  
  /*******************************
    operacje na tej tablicy
  *******************************/
  
  delete [] tab; //zwolnienie pamięci dla tablicy
  delete obiekt; //zwolnienie pamięci dla objektu
  
  return 0;
}

Wskaźniki wykorzystywane są przy tworzeniu dynamicznych struktur danych takich jak drzewa, kolejki, listy czy stosy.