Wskaźniki i tablice dynamiczne

#include <iostream>
 
using namespace std;
 
double dodaj_liczby(int a, int b) {
    return a + b;
}
 
int main(int argc, const char *argv[])
{
    int a = 10, b = 20;
 
    // Tworzenie wskaźników. Wartością wskaźnika jest adres w pamięci komputera.
    // Operator & pobiera adres zmiennej, np. &a zwraca adres zmiennej a.
    int* wsk1 = &a;
 
    // *wsk1 - odwołanie do zmiennej wskazywanej przez wskaźnik
    // wsk1 - odwołanie do wskaźnika, przy wyświetleniu pokaże wskazywany adres
    // w postaci szesnastkowej
    cout << *wsk1 << " adres: " << wsk1 << endl;
 
    // Zmiana wartości wskazywanej zmiennej
    *wsk1 = 13;
    cout << "nowa wartość a: " << a << endl;
    b = *wsk1; // równoważne b = a
 
    // Wskaźnikowi można przypisać adres przechowywany przez inny wskaźnik
    int *wsk2 = wsk1;
    *wsk2 += 1; // teraz a = 14
 
    // Tworzenie zmiennej dynamicznej (na stercie) - operator new
    double* wsk3 = new double; // Zwraca adres przydzielonej pamięci
    // Nowa zmienna ma nieokreśloną wartość, chociaż w większości kompilatorów
    // domyślnie przypisywana jest wartość 0 dla typów wbudowanych.
    cout << *wsk3 << " adres wsk3: " << wsk3 << endl;
    // Gdy zmienna dynamiczna nie jest potrzebna należy ją usunąć z pamięci przy
    // użyciu operatora delete.
    //
    // Zwolnienie pamięci operatorem delete nie zmienia adresu wskaźnika, mimo
    // że wkaźnik nadal przechowuje ten sam adres w pamięci, to jednak pamięć ta
    // została zwolniona i nie jest już dłużej dostępna
    delete wsk3;
    cout << "adres wsk3: " << wsk3 << endl;
 
    // Można również podać domyślną wartość w nawiasach, nie działa dla tablic.
    wsk3 = new double (5);
    cout << *wsk3 << " adres wsk3: " << wsk3 << endl;
    delete wsk3;
 
    char nazwisko[] = "Kowalski";
    // Nazwa tablicy jest domyślnie wskaźnikiem do pierwszego jej elementu
    char* wsk4 = nazwisko; // równoważne wsk4 = &nazwisko[0];
    cout << wsk4 << endl;
 
    // Wskaźniki umożliwiają dostęp do pamięci podobnie jak tablice
    cout << "Czwarty znak łańucha: " << wsk4[3] << endl;
 
    // Tworzenie dynamicznej tablicy
    int* dtab = new int[a];
    // lub int (* dtab) = new int[a];
    // Usuwanie dynamicznej tablicy
    delete [] dtab;
    // Możliwe jest tworzenie tablic o większej liczbie wymiarów
    // Tylko skrajny lewy wymiar tablicy może być określany dynamicznie, reszta
    // musi być wyrażeniami stałymi.
    int (* tab2w)[10] = new int[a][20/2];
    tab2w[2][4] = 5;
    cout << tab2w[2][4] << endl;
    // Usuwanie podobne jak poprzednio.
    delete [] tab2w;
    // Operator new w przypadku niepowodzenia rzuca wyjątek std::bad_alloc
    // wsk3 = new double[2000000000];
 
    // Można również użyć wersji, która nie generuje wyjątków.
    wsk3 = new (nothrow) double[2000000000];
    cout << wsk3 << endl; // 0 - ponieważ alokacja nie powiodła się 
    delete [] wsk3; // jeżeli wskaźnik jest równy 0 to nic się nie stanie
 
    // Tworzenie tablic wielowymiarowych w przyadku, gdy więcej niż jeden wymiar
    // jest dynamiczny jest nieco bardziej złożone
    int** tab3 = new int*[a];
    for (int i = 0; i < a; i++) {
        tab3[i] = new int[b];
    }
    // Zwalnianie pamięci
    for (int i = 0; i < a; i++) {
        delete [] tab3[i];
    }
    delete [] tab3;
 
    // Można również tworzyć wskaźniki do funkcji.
    // Nazwa funkcji jest równocześnie jej wskaźnikiem.
    double (*wfun) (int, int) = dodaj_liczby;
    cout << wfun(5, 12) << endl;
    return 0;
}

Post a Comment

Your email is kept private. Required fields are marked *

Możesz użyć następujących tagów oraz atrybutów HTML-a: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>