#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; } |