Wskaźnik na zmienną prostą o danym typie, na przykład int
Transkrypt
Wskaźnik na zmienną prostą o danym typie, na przykład int
Wskaźnik na zmienną prostą o danym typie, na przykład int int x; int *w; x=150; w=&x; // // // // zwykła zmienna typu int wskaźnik w na daną typu int na razie jest pusty, NULL, dopóki nie przypiszę mu adresu jakiejś zmiennej lub nie przydzielę mu pamięci słowem new na przechowywanie wartości wskazywanej // wskaźnik w jest teraz adresem zmiennej x // *w, czyli wartość wskazywana przez w, to jest x // & jest operatorem pobrania adresu zmiennej cout<<"x="<<x<<endl; cout<<"pod adresem "<<w<<" jest wartosc "<<*w<<endl<<endl; *w=287454020; // zmieniam wartość wskazywaną przez wskaŜnik w cout<<"pod adresem "<<w<<" jest teraz wartosc "<<*w<<endl; cout<<"x="<<x<<endl<<endl; // czy wartość x się zmieniła ? // tak, bo przecieź w jest adresem zmiennej x // wskaźnikowi w przydzielę teraz nowy obszar pamięci, // taki duŜy, jaki jest potrzebny dla wartości typu int (czyli 4 bajty) *w = new int; *w=200; // wpiszę do tego obszaru pamięci wartość 200 cout<<"*w="<<*w<<endl; // mogę odczytać tę wartość delete w; // zwalniam pamięć wskazywana przez w1, słowa new i delete stanowią parę ! Wskaźnik na tablicę liczb int T[3] = {15,-3,7}; // tablica statyczna ma stały rozmiar, znany juŜ podczas kompilacji for (int i=0; i<3 ; i++) cout<<T[i]<<" "; cout<<endl<<endl; cout<<"T="<<T<<endl; cout<<"*T="<<*T<<endl<<endl; int *w; w=T; cout<<"*w="<<*w<<endl; w++; cout<<"*w="<<*w<<endl; w++; cout<<"*w="<<*w<<endl; w++; cout<<"*w="<<*w<<endl; // wyświetli wszystkie elementy tablicy T // nazwa tablicy jest wskaźnikiem do tablicy // i wskazuje na pierwszy element // czy moŜna przypisywac wskaźnikowi inny wskaźnik // TAK jeśli wskazują na ten sam typ wartości // wyświetli pierwszy element tablicy T // // // // ? na wskaźniku mozna wykonywać opercje arytmetyczne ! o ile bajtów zmieni sie adres umieszczony we wskaźniku w ? o tyle ile zajmuje zmienna wskazywana, tu o 4 bo typ int teraz pokaŜe drugi element tablicy T // a teraz pokaŜe trzeci element tablicy T // wskaźnik juŜ wyszedł poza 3-elementową tablicę T, // wyświetli śmieci z pamięci cout<<"\njeszcze raz cala tablica T \n"; w=T; // w ponownie wskazuje na pierwszy element tablicy T for (int i=0; i<3; i++) { // wyświetl element wskazywany przez w cout<<*w<<" "; w++; // przesuń wskaźnik do nastepnego elementu T } cout<<endl<<endl; Tablica dynamiczna int n; cout<<"Podaj n "; cin>>n; int *T = new int[n]; // dynamiczna tablica, dostępna przez wskaźnik // nie musi mieć zdefiniowanego rozmiaru w chwili kompilacji srand(time(0)); for (int i=0; i<n; i++) { T[i]=rand()%100; // odwołanie do elementu tablicy dynamicznej cout<<T[i]<<" "; // wygląda tak samo jak dla tablicy statycznej } // trzeba zwolnić pamięć po dynamicznej tablicy cout<<endl<<endl; delete [] T; // słowa new i delete są ze soba w parze ! Tablica statyczna jest umieszczana w części pamięci zwanej stosem (stack), przydzielanej programowi przez system podczas uruchamiania. W tym obszarze umieszczane są wszyskie 'normalne' zmienne oraz parametry wywołania funkcji. Ten obszar pamięci jest zwykle stosunkowo niewielki i można go łatwo zapchać tablicą o dużej ilości elementów, wóczas system operacyjny zgłosi błąd i program 'wysypie się'. Tablice dynamiczne (i w ogóle zmienne dynamiczne) umieszczane są w innym obszarze pamięci, zwanej stertą (heap). Sterta może być znacznie większa od stosu, system przydzieli programowi na żądanie tyle pamięci na stercie, ile ma do dyspozycji. Dlatego można tu umieszczać znacznie większe zbiory danych niż w stosie. Tablice dynamiczne mogą być wielokrotnie większe od tablic statycznych. A jeśli podczas pracy programu okaże się, że elementów jest więcej niż zadeklarowano dla tablicy, to zawsze można zadeklarować nową wiekszą tablicę dynamiczną, przepisać do niej wszystkie elementy ze starej tablicy i wskażnikowi do starej tablicy przypisać adres nowej tablicy. Zastosowanie tablic dynamicznych straciło wiele na popularności od czasu, gdy biblioteka standardowa STL (Standard Template Library) udostępniła typ vector. Ćwiczenie: Napisz program który generuje losowo 10 liczb typu całkowitego z przedziału (0;100), umieszcza je w tablicy i wyświetla. Następnie odwraca kolejność elementów tablicy, to znaczy zamienia miejscami odwołując się do elementów poprzez ich wskaźniki (nie przez indeks): • • pierwszy element z ostatnim, drugi z przedostatnim itd…. aż do środka tablicy Wskaźnik na zmienną strukturalną struct Pies { string imie; int lata;}; Pies p = {"Burek",3}; // zwykła zmienna typu Pies, odwołania do składowych za pomocą notacji kropki cout << p.imie << " ma lat " << p.lata << endl; Pies *wp = new Pies; // wskaźnik na Psa, przydzielam mu pamięć wp->imie = "Azor"; // odwołania do składowych za pomocą notacji strzałki wp->lata = 5; cout << wp->imie << " ma lat " << wp->lata << endl; delete wp; // zwalniam pamięć