In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg.
To laboratorium jest przypomnieniem informacji o wskaźnikach, które powinny zostać przyswojone w poprzednim semestrze na „Językach i Metodach Programowania I”.
Z racji, że nie jest to „regularne” laboratorium, za rozwiązanie zadań nie będą przyznawane plusy/punkty.
Wskaźniki są zmiennymi przechowującymi adresy pamięci innych zmiennych. Operatory związane ze wskaźnikami:
#include <iostream> using namespace std; int main(void){ int liczba = 10; int *pointer = &liczba; cout << liczba << endl; // wyświetli 10 cout << *pointer << endl; // wyświetli 10 cout << &liczba << endl; // wyświetli (rys.) 0xbf8d6d4c cout << pointer << endl; // wyświetli (rys.) 0xbf8d6d4c return 0; }
Stosowanie słowa kluczowego const w kontekście wskaźników, może być powodem błędów:
Może przechowywać wartość wskaźnika dowolnego typu. Nie może jednak podlegać dereferencji - wcześniej konieczne jest rzutowanie na typ konkretny.
int zmienna; int* ptr = &zmienna; void* vptr = ptr; //NIEPOPRAWNIE cout << "Wartość zmiennej to: " << *vptr << endl; //Poprawnie: cout << "Wartość zmiennej to: " << *(int*)vptr << endl;
Podobnie jak nazwa tablicy jest wskaźnikiem do jej pierwszego elementu, tak nazwa funkcji jest początkowym adresem w pamięci kodu dokonywującego zadanie.
Wskaźniki do funkcji najczęściej przekazywane są jako parametry innych funkcji. Definicja funkcji przyjmującej jako parametr wskaźnik do innej funkcji:
// funkcja foo przyjmuje jako parametr wskaźnik do funkcji zwracającej int // oraz przyjmującej dwa parametry typu int void foo(int (*fooptr)(int,int)){ // Wywołanie funkcji przekazanej jako parametr cout << "Wynik : " << (*footptr)(10,10) << endl; }
Do wskaźników można stosować podstawowe operatory matematyczne:
Należy pamiętać, że inkrementowanie wskaźnika nie zwiększa wartości adresu o 1, ale o rozmiar wskaźnika. Jeśli jest to wskaźnik do typu int, to standardowo o 4 bajty, jeśli double, to o 8 bajtów, etc.
Są to aliasy zmiennych. Referencja wskazuje na dokładnie tą sama komórkę pamięci co „oryginalna” zmienna. Referencja musi być zainicjalizowana w momencie deklaracji! Jedyne sensowne zastosowanie referencji, to przekazywanie parametrów do funkcji poprzez referencję. To samo jednak można osiągnąć używając wskaźników…
#include <iostream> using namespace std; int main(void){ int liczba = 10; int &ref = liczba; cout << liczba << endl; // wyświetli 10 cout << ref << endl; // wyświetli 10 cout << &liczba << endl; // wyświetli (rys.) 0xbf8d6d4c cout << &ref << endl; // wyświetli (rys.) 0xbf8d6d4c return 0; }
#include <iostream.h> using namespace std; int * potega(int liczba, int potega){ int* wynik = &liczba; for(int i = 1; i < potega; i++) *wynik *= liczba; return wynik; } int main(void){ cout << *(potega(3,3)) << endl; }
void showTable(int tab[][5], int rows, int cols);
Napisz program umożliwiający wypełnienie tablicy kilkoma elementami stworzonej struktury. Następnie wykorzystując funkcje qsort napisz program sortujący tablicę struktur według roku urodzenia lub według nazwiska.