Programowanie w Języku C 2
Transkrypt
Programowanie w Języku C 2
Programowanie w Języku C 2 Laboratorium 1 Zarządzanie pamięcią. Wskaźniki i funkcja malloc(). Opracował: mgr inż. Leszek Ciopiński Wskaźniki Podobnie jak w języku Pascal, również język C oferuje dynamiczne zarządzanie pamięcią. Podstawowym narzędziem pracy ze strukturami dynamicznymi jest wskaźnik. Deklaruje się go poprzez wstawienie przed nazwą zmiennej symbolu asterysk (gwiazdka *). Przykład jego deklaracji przedstawiono poniżej: int *wsk1; //wskaźnik na wartość typu int Należy pamiętać, że deklaracja wskaźnika nie jest równoznaczna z rezerwacją pamięci na dane. Ponadto rozmiar każdego wskaźnika jest taki sam, niezależnie od docelowego rozmiaru pamięci. W celu odwołania się do wartości spod wskaźnika należy poprzedzić nazwę zmiennej symbolem asterysk. Przykład: *wsk1 = 5; // przypisanie wartości 5 do pamięci oznaczonej przez // wskaźnik wsk1 = 5; // zmiana adresu pamięci na który wskazuje wskaźnik Istnieje też możliwość uzyskania wskaźnika do zmiennej zadeklarowanej statycznie przy pomocy operatora oznaczonego symbolem ampersand (and &). Przykład: int a, *wsk; a=3; wsk=&a; // po tej operacji prawdziwa jest równość: *wsk==a; a=2; // po tej operacji prawdziwa jest równość: *wsk==2; sizeof() Funkcja sizeof() jako parametr pobiera dowolną zmienną lub nazwę typu. Wartością zwracaną jest rozmiar pamięci zajmowany przez daną zmienną lub typ wyrażoną w bajtach. W przypadku wskaźników funkcja ta zwraca zawsze ten sam rozmiar, niezależnie od rozmiaru alokowanej pamięci oraz tego, czy dana pamięć już została przydzielona czy nie. Przykłady: int a = b = //a a, b, c; sizeof(int); sizeof(c); ==b Programowanie w Języku C2 Laboratorium strona: 1 z 3 malloc() Funkcja malloc() jest w języku C podstawową funkcją do dynamicznej alokacji pamięci. Opis funkcji przedstawiono poniżej: #include <stdlib.h> void *malloc(size_t size); Jako parametr funkcja przyjmuje wielkość obszaru jaki ma zostać zaalokowany wyrażony w bajtach. W praktyce najczęściej w celu określenia rozmiaru używa się funkcji sizeof(). Wartością zwracaną przez funkcję malloc() w przypadku powodzenia jest wskaźnik na typ void. Dlatego wartość tą należy rzutować w celu uzyskania odpowiedniego typu. W przypadku, gdy niemożliwe było zarezerwowanie odpowiedniej ilości pamięci zwracana jest wartość NULL. calloc() Funkcja calloc() służy głównie do alokowania tablic. Jej opis jest następujący: #include <stdlib.h> void *calloc(size_t nelem, size_t elsize); Parametr nelem określa ilu elementowa ma być tablica, a parametr elsize jaki jest rozmiar w bajtach każdego z elementów. W przeciwieństwie do funkcji malloc(), funkcja calloc() dodatkowo po zarezerwowaniu pamięci wypełnia wszystkie jego bity wartością 0. Podobnie jak w przypadku funkcji malloc(), jeśli zwrócona wartość to NULL to znaczy, że operacja zakończyła się niepowodzeniem. W przeciwnym przypadku zwrócony wskaźnik należy rzutować na odpowiedni typ danych. free() Podstawowym sposobem zwolnienia uprzednio zarezerwowanej pamięci jest użycie funkcji free(), której opis jest następujący: #include <stdlib.h> void free(void *ptr); Jedynym parametrem przekazywanym funkcji jest wskaźnik na zwalniany obszar pamięci. Należy pamiętać, że nie wolno zwalniać niezarezerwowanego obszaru pamięci, gdyż działanie programu nie jest określone w takich przypadkach. Przykład: #define ROZMIAR 10 int i; int **tabliczka = malloc(ROZMIAR * sizeof *tabliczka); *tabliczka = malloc(ROZMIAR * ROZMIAR * sizeof **tabliczka); for (i = 1; i<ROZMIAR; ++i) { tabliczka[i] = tabliczka[0] + (i * ROZMIAR); } Programowanie w Języku C2 Laboratorium strona: 2 z 3 for (i = 0; i<ROZMIAR; ++i) { int j; for (j = 0; j<ROZMIAR; ++j) { tabliczka[i][j] = (i+1)*(j+1); } } free(*tabliczka); free(tabliczka); Źródło: pl.wikibooks.org Zadania: 1. 2. 3. a) b) c) d) Napisz program, w którym zostanie zadeklarowana zmienna typu int i przypisz do niej dowolną wartość. Następnie utwórz wskaźnik do tej zmiennej i przy jego pomocy wyświetl wartość uprzednio wpisaną do zmiennej zadeklarowanej statycznie. (1 punkt) Napisz program, w którym zadeklarujesz typ strukturalny zawierający dwa pola: jedno typu liczbowego i jedno typu tablicowego na napis. Następnie napisz funkcję, która jako parametry przyjmuje dane do zapisania w strukturze i zwraca wskaźnik do niej. Funkcja ta musi zaalokować miejsce dla tej struktury. Kolejnym elementem programu powinna być funkcja, która jako parametr przyjmuje wskaźnik na strukturę i wyświetla wartość jej pól, po czym zwalnia miejsce zajmowane przez tą strukturę. (1 punkt) Napisz program, który będzie posiadał czteroelementową tablicę wskaźników wskazujących na strukturę zawierającą pola: imię, nazwisko i wiek. Program powinien posiadać funkcje: dodaj – dodaje dane do struktury, do której wskaźnik umieszczany jest w tablicy na pierwszej wolnej pozycji. Jeśli brakuje miejsca w tablicy, należy zwrócić informację o błędzie. usuń – usuwa strukturę z tablicy o podanym indeksie i zwalnia zajmowaną przez nią pamięć wyświetl – wyświetla wszystkie zapisane struktury w tablicy wyczyść – program powinien usunąć wszystkie elementy tablicy i zwolnić całą zajmowaną pamięć. Należy utworzyć menu umożliwiające użytkownikowi na swobodne wybieranie funkcji, którą chce wykonać. (3 punkty) Programowanie w Języku C2 Laboratorium strona: 3 z 3