7.3 Tablice jednowymiarowe dynamiczne Tablice statyczne nie daj nam mo»liwo±ci decydowania o ich wymiarach podczas dziaªania programu. Oznacza to»e musimy zna wielko± tablicy na poziomie tworzenia aplikacji. Przykªadowo, poni»szy kod tworzy tablic o rozmiarze n, chocia» si skompiluje, nie jest zgodny ze standardem j zyka C (poniewa» rozmiar tablicy nie byª znany w czasie kompilowania programu, a dopiero w czasie jego uruchomienia): 3 i n t main ( i n t argc, char ** argv ) 5 i n t n, i ; 7 printf ( "Podaj n : \ n> " ) ; 8 scanf ( "%d", &n ) ; 9 10 i n t tab [ n ] ; 11 1 f o r ( i=0; i<n ; i++) 13 { 14 tab [ i ] = ( i+1) ; 15 printf ( " tab[%d ] = %d\n", i, tab [ i ] ) ; 1 } 17 18 return 0 ; 19 } Nale»y unika sytuacji takich, jak powy»sza. Aby tworzy tablic, której rozmiar poznamy dopiero na etapie uruchomienia programu, nale»y wykorzysta dynamiczny przydziaª pami ci oraz wska¹niki. Dynamiczna alokacja pami ci pozwala na przydzielenie odpowiedniej ilo±ci pami ci, a tak»e zwolnienie jej od razu, gdy nie b dzie ju» potrzebna. Mówi c inaczej, dynamiczna alokacja pami ci pozwala» cznie«i zarz dza. Do zarz dzania pami ci w j zyku C wykorzystujemy wska¹niki, oraz poni»sze 4 funkcje z biblioteki stdlib.h (nale»y doª czy nagªówek #include <stdlib.h>) oraz operator sizeof: Nazwa funkcji Zadanie funkcji Nagªówek funkcji malloc() Przydziela pami void *malloc(size_t size) calloc() Przydziela pami i wypeªnia tablic zerami void *calloc(size_t nitems, size_t size) free() Zwalnia poprzednio przydzielon pami void free(void *ptr) realloc() Zmienia rozmiar poprzednio przydzielonej pami ci void *realloc(void *ptr, size_t size) Tablicy dynamicznej u»ywamy tak samo, jak zwykª, poznan wcze±niej tablic statyczn. Nie trzeba na takiej tablicy operowa wska¹nikami, wska¹niki potrzebne s tylko przy jej deklaracji (chocia» mo»na na niej operowa za pomoc wska¹ników, ale do tego przejdziemy pó¹niej.) Mo»liwo± ta wynika z faktu, ¹e tablica statyczna to te» wska¹nik, tylko nie jest to do ko«ca widoczne. 7.3.1 Operator sizeof Zanim nauczymy si tworzy dynamiczne tablice jednowymiarowe, musimy najpierw pozna dziaªanie operatora sizeof. Operator sizeof inaczej nazywany jest operatorem rozmiaru - operator ten dost pny jest w j zyku C i C++. Operatora u»ywamy podobnie jak funkcji, która jako argument pobiera (w naszym przypadku) nazw typu danych, którego rozmiar chcemy pozna, oraz zwraca jego rozmiar w bajtach. Przykªadowe u»ycie operatora zaprezentowano poni»ej: 158
3 i n t main ( ) 5 i n t rozmiar = s i z e o f ( i n t ) ; printf ( " Int zajmuje %d bajty w pamieci RAM\n", rozmiar ) ; 7 return 0 ; 8 } 7.3. Tworzenie i usuwanie jednowymiarowej dynamicznej tablicy Do utworzenia jednowymiarowej dynamicznej tablicy potrzebna nam b dzie funkcja malloc, która przydziela pami (a mówi c dokªadniej: okre±lon liczb bajtów) i zwraca wska¹nik do pierwszego bajtu przydzielonej pami ci tak,»eby±my mieli dost p do wszystkich jej elementów. 1 i n t * tab = malloc ( s i z e o f ( i n t ) * n ) ; W powy»szym przykªadzie tworzony jest wska¹nik (tablica) tab, której dynamicznie przydzielana jest pami. Chcemy stworzy tablic o n elementach, gdzie ka»dy z elementó b dzie liczb caªkowit. W takim wypadku musimy powiedzie, ile bajtów potrzebujemy na tablic. Skoro rozmiar jednego inta mo»emy sprawdzi za pomoc operatora sizeof, to wiemy, ile miejsca w bajtach b dziemy potrzebowa na tablic : sizeof(int) * n, bo mamy n intów, z których ka»dy zajmuje sizeof(int) bajtów. Dwa poni»sze programy robi to samo - tworz tablic liczb caªkowitych o rozmiarze 100, zeruj j, a nast pnie usuwaj za pomoc funkcji free: 3 i n t main ( i n t argc, char ** argv ) 7 // d e f i n i c j a t a b l i c y 8 i n t * tab ; 9 // p r z y d z i e l e n i e pamieci na 100 elementow typu i n t 10 tab = malloc ( s i z e o f ( i n t ) * 100) ; 11 1 f o r ( i=0; i <100; i++) 13 tab [ i ] = 0 ; 14 15 // z w o l n i e n i e pamieci 159
1 free ( tab ) ; 17 tab = NULL ; 18 19 return 0 ; 0 } 3 i n t main ( i n t argc, char ** argv ) 7 // d e f i n i c j a t a b l i c y i p r z y d z i e l e n i e pamieci na 100 elementow typu i n t 8 i n t * tab = malloc ( s i z e o f ( i n t ) * 100) ; 9 10 f o r ( i=0; i <100; i++) 11 tab [ i ] = 0 ; 1 13 // z w o l n i e n i e pamieci 14 free ( tab ) ; 15 tab = NULL ; 1 17 return 0 ; 18 } Przeanalizujmy poni»szy przykªad. Zaªó»my,»e chcemy stworzy dynamiczn, jednowymiarow tablic o ilo±ci elementów (rozmiarze) podanym przez u»ytkownika. Aby to zrobi, na pocz tku wczytujemy rozmiar tablicy, nast pnie przydzielamy dla niej pami... : 1 i n t n ; scanf ( "%d", &n ) ; 3 i n t * wski = NULL ; 4 wski = ( i n t *) malloc ( n * s i z e o f ( i n t ) ) ; 7.3.3 Dost p do elementów dynamicznej tablicy jednowymiarowej... zerujemy tablic, wy±wietlamy jej zawarto± (czyli uzyskujemy dost p do elmentów tablicy): 1 f o r ( i=0; i<n ; i++) wski [ i ] = 0 ; 3 4 f o r ( i=0; i<n ; i++) 5 printf ( "%d ", wski [ i ] ) ; printf ( "\n" ) ; 7.3.4 Usuwanie dynamicznej tablicy jednowymiarowej... i usuwamy przydzielon pami : 1 free ( wski ) ; wski = NULL ; 7.3.5 Tworzenie, dost p do elementów oraz usuwanie dynamicznej tablicy jednowymiarowej Wszystkie powy»sze operacje, aby mogªy dziaªa jako program, zostaªy zebrane na listingu poni»ej. Zaprezentowany kod: 10
1. Wczytuje od u»ytkownika ilo± elementów tablicy. Deniuje wska¹niki na typy danych int, float, double, char 3. Korzystaj c ze wska¹ników przydziela pami dla ka»dej tablicy (dla tablicy elementów typu int, float, double, char) 4. Wypeªnia ka»d z tablic 5. Wy±wietla ka»d z tablic. Zwalnia pami na ka»d z przydzielonych tablic Podsumowuj c, na poni»szych przykªadach widzimy schematy tworzenia dynamicznych tablic jednowymiarowych o n elementach, dla ka»dego typu danych: 3 i n t main ( ) 7 /* i l o s c elementow t a b l i c y */ 8 i n t n ; 9 /* wczytanie i l o s c i elementow t a b l i c y */ 10 printf ( "Podaj i l o s c elementow t a b l i c y : \ n> " ) ; 11 scanf ( "%d", &n ) ; 1 13 /* wskaznik na zmienna typu i n t */ 14 i n t * wski = NULL ; 15 1 /* p r z y d z i e l e n i e pamieci na n elemenotwa t a b l i c e intow */ 17 wski = malloc ( n * s i z e o f ( i n t ) ) ; 18 19 /* wyzerowanie t a b l i c y dynamicznej */ 0 f o r ( i=0; i<n ; i++) 1 wski [ i ] = 0 ; 3 /* w y s w i e t l e n i e t a b l i c y */ 4 f o r ( i=0; i<n ; i++) 5 printf ( "%d ", wski [ i ] ) ; printf ( "\n" ) ; 7 8 /* z w o l n i e n i e pamieci p r z y d z i e l o n e j na t a b l i c e */ 9 free ( wski ) ; 30 wski = NULL ; 31 3 return 0 ; 33 } 3 i n t main ( ) 7 /* i l o s c elementow t a b l i c y */ 8 i n t n ; 9 /* wczytanie i l o s c i elementow t a b l i c y */ 10 printf ( "Podaj i l o s c elementow t a b l i c y : \ n> " ) ; 11 scanf ( "%d", &n ) ; 1 13 /* wskaznik na zmienna typu f l o a t */ 14 f l o a t * wsk = NULL ; 11
15 1 /* p r z y d z i e l e n i e pamieci na n elemenotwa t a b l i c e f l o a t */ 17 wsk = malloc ( n * s i z e o f ( f l o a t ) ) ; 18 19 /* wyzerowanie t a b l i c y dynamicznej */ 0 f o r ( i=0; i<n ; i++) 1 wsk [ i ] = 0 ; 3 /* w y s w i e t l e n i e t a b l i c y */ 4 f o r ( i=0; i<n ; i++) 5 printf ( "%.1 f ", wsk [ i ] ) ; printf ( "\n" ) ; 7 8 /* z w o l n i e n i e pamieci p r z y d z i e l o n e j na t a b l i c e */ 9 free ( wsk ) ; 30 wsk = NULL ; 31 3 return 0 ; 33 } 3 i n t main ( ) 7 /* i l o s c elementow t a b l i c y */ 8 i n t n ; 9 /* wczytanie i l o s c i elementow t a b l i c y */ 10 printf ( "Podaj i l o s c elementow t a b l i c y : \ n> " ) ; 11 scanf ( "%d", &n ) ; 1 13 /* wskaznik na zmienna typu double */ 14 double * wsk = NULL ; 15 1 /* p r z y d z i e l e n i e pamieci na n elemenotwa t a b l i c e double */ 17 wsk = malloc ( n * s i z e o f ( double ) ) ; 18 19 /* wyzerowanie t a b l i c y dynamicznej */ 0 f o r ( i=0; i<n ; i++) 1 wsk [ i ] = 0 ; 3 /* w y s w i e t l e n i e t a b l i c y */ 4 f o r ( i=0; i<n ; i++) 5 printf ( "%.1 f ", wsk [ i ] ) ; printf ( "\n" ) ; 7 8 /* z w o l n i e n i e pamieci p r z y d z i e l o n e j na t a b l i c e */ 9 free ( wsk ) ; 30 wsk = NULL ; 31 3 return 0 ; 33 } 3 i n t main ( ) 7 /* i l o s c elementow t a b l i c y */ 8 i n t n ; 9 /* wczytanie i l o s c i elementow t a b l i c y */ 10 printf ( "Podaj i l o s c elementow t a b l i c y : \ n> " ) ; 11 scanf ( "%d", &n ) ; 1 1
13 /* wskaznik na zmienna typu char */ 14 char * wsk = NULL ; 15 1 /* p r z y d z i e l e n i e pamieci na n elemenotwa t a b l i c e char */ 17 wsk = malloc ( n * s i z e o f ( char ) ) ; 18 19 /* wyzerowanie t a b l i c y dynamicznej */ 0 f o r ( i=0; i<n ; i++) 1 wsk [ i ] = ' 0 ' ; 3 /* w y s w i e t l e n i e t a b l i c y */ 4 f o r ( i=0; i<n ; i++) 5 printf ( "%c ", wsk [ i ] ) ; printf ( "\n" ) ; 7 8 /* z w o l n i e n i e pamieci p r z y d z i e l o n e j na t a b l i c e */ 9 free ( wsk ) ; 30 wsk = NULL ; 31 3 return 0 ; 33 } 7.3. Tablice jednowymiarowe dynamiczne jako argumenty funkcji Tablice jednowymiarowe mog by przekazywane do funkcji jako jej argumenty. Wraz z przekazaniem do funkcji tablicy, nale»y do funkcji, jako kolejny jej argument, przekaza liczb elementów tablicy. Do funkcji mo»emy przekaza pojedynczy element z tablicy, lub te» wszystkie jej elementy - czyli caª jednowymiarow tablic. Istniej 3 sposoby na przekazanie do funkcji caªej jednowymiarowej tablicy (wszystkich jej elementów). Wa»ne informacje dotycz ce funkcji i tablic dynamicznych: ˆ mo»na napisa funkcj zwracaj c tablic dynamiczn ˆ tablica dynamiczna do funkcji jest zawsze przekazywana przez jej adres, oznacza to, i» je±li przeka»emy do funkcji dynamiczn, jednowymiarow tablic, funkcja b dzie j mogªa zmodykowa (b dzie mogªa zmienia jej elementy, poniewa» pracuje na oryginale tablicy) - inaczej, ni» w przypadku zmiennych, które przekazywane s do funkcji przez warto±, dzi ki czemu funkcja pracuje na ich kopiach ˆ Nale»y zawsze po zako«czeniu korzystania z tablicy dynamicznej zwolni przydzielon dla niej pami Przykªad 7.3.1. Przekazywanie do funkcji pojedynczego elementu tablicy: prze±led¹my poniszy przykªad. Funkcja suma pobiera argumenty - liczby caªkowite, oraz zwraca jako wynik ich sum. Do funkcji mo»emy przekaza zmienne (linia 17), dowolne liczby (linia 0), czwarty element tablicy (czyli jedn warto± ) oraz zmienn (linia 3), czwarty element tablicy (czyli jedn warto± ) oraz liczb (linia ) lub czwarty element tablicy (czyli jedn warto± ) oraz pierwszy element tablicy (czyli jedn warto± ) (linia 9). Jak wynika z ponizszego kodu, je±li przeka»emy do funkcji pojedynczy element tablicy, jest on w funkcji traktowany jako zwykªa zmienna przekazana do niej: warto± danego elementu tablicy jest KOPIOWANA do funkcji, dzi ki czemu funkcja pracuje na kopii elementu tablicy, tak, jak dzieje si to w przypadku zwykªych zmiennych. 3 i n t suma ( i n t a, i n t b ) 5 return a+b ; } 7 8 i n t main ( ) 13
9 { 10 i n t i ; 11 i n t * tab = malloc ( s i z e o f ( i n t ) * 5) ; 1 f o r ( i=0; i<5; i++) 13 tab [ i ] = ( i *) ; 14 15 i n t n = 5, m =, wynik ; 1 17 wynik = suma ( n, m ) ; 18 printf ( "wynik = %d\n", wynik ) ; 19 0 wynik = suma (, 4) ; 1 printf ( "wynik = %d\n", wynik ) ; 3 wynik = suma ( tab [ 3 ], n ) ; 4 printf ( "wynik = %d\n", wynik ) ; 5 wynik = suma ( tab [ 3 ], 3) ; 7 printf ( "wynik = %d\n", wynik ) ; 8 9 wynik = suma ( tab [ 3 ], tab [ 0 ] ) ; 30 printf ( "wynik = %d\n", wynik ) ; 31 3 free ( tab ) ; 33 tab = NULL ; 34 35 return 0 ; 3 } Przykªad 7.3.. Jak wspomniano wcze±niej, istnieje mo»liwo± przekazania do funkcji caªej tablicy, dzi ki czemu funkcja ma dost p do wszystkich jej elementów i MO E JE MODYFIKOWA w takim sensie, i» zmiany przeprowadzone na tablicy wewn trz funkcji, s widoczne PO wyj±ciu z funkcji. Przekazywanie do funkcji wszystkich elementów statycznej dynamicznej tablicy (caªej tablicy): 3 void fun1 ( i n t * tab, i n t n ) f o r ( i=0; i<n ; i++) 7 printf ( " t a b l i c a [%d ] = %d\n", i, tab [ i ] ) ; 8 printf ( "\n" ) ; 9 } 10 11 void fun ( i n t tab [ ], i n t n ) 1 { 13 i n t i ; 14 f o r ( i=0; i<n ; i++) 15 printf ( " t a b l i c a [%d ] = %d\n", i, tab [ i ] ) ; 1 printf ( "\n" ) ; 17 } 18 19 void fun3 ( i n t tab [ 5 ] ) 0 { 1 i n t i ; f o r ( i=0; i<5; i++) 3 printf ( " t a b l i c a [%d ] = %d\n", i, tab [ i ] ) ; 4 printf ( "\n" ) ; 5 } 7 i n t main ( ) 8 { 9 i n t i ; 30 i n t * tab = malloc ( s i z e o f ( i n t ) * 5) ; 31 f o r ( i=0; i<5; i++) 14
3 tab [ i ] = ( i *) ; 33 34 i n t n = 5 ; 35 3 fun1 ( tab, n ) ; 37 fun ( tab, n ) ; 38 fun3 ( tab ) ; 39 40 free ( tab ) ; 41 tab = NULL ; 4 43 return 0 ; 44 } Omówmy i przeanalizujmy ka»d z 3 funkcji z powy»szego programu. Funkcja pierwsza, tj. fun1: ˆ pobiera argumenty (z funkcji main mo»emy przesªa do niej, przekaza jej argumenty): caª, jednowymiarow tablic liczb caªkowitych tab, oraz ilo± jej elementów n ˆ jednowymiarowa tablica przekazywana jest z funkcji main do funkcji fun1 za pomoc wska¹nika (b dziemy o nich mówi pó¹niej) ˆ funkcja nie zwraca warto±ci, jej typ zwracany to void ˆ funkcja wy±wietla wszystkie elementy tablicy ˆ w funkcji main, aby przekaza tablic do funkcji fun1 podczas wywoªania nale»y poda nazw funkcji, przekaza jako argument jedynie nazw tablicy (tutaj kompilator ju» sam wie,»e skoro funkcja pobiera jako pierwszy argument tablic, to przekazana jest jej tablica, wystarczy wi c poda jedynie nazw tablicy podczas wywoªania) oraz ilo± jej elementów ˆ funkcja fun1 jest uniwersalna, poniewa» dziaªa dla dowolnie du»ej tablicy - dla tablicy o n elementach Funkcja druga, tj. fun: ˆ pobiera argumenty (z funkcji main mo»emy przesªa do niej, przekaza jej argumenty): caª, jednowymiarow tablic liczb caªkowitych tab, oraz ilo± jej elementów n ˆ jednowymiarowa tablica przekazywana jest z funkcji main do funkcji fun za pomoc nazwy tablicy, bez podania ilo±ci elementów - przekazywana jest caªa tablica, bez podania ilo±ci jej elementów (tzw. unsized array) ˆ funkcja nie zwraca warto±ci, jej typ zwracany to void ˆ funkcja wy±wietla wszystkie elementy tablicy ˆ w funkcji main, aby przekaza tablic do funkcji fun podczas wywoªania nale»y poda nazw funkcji, przekaza jako argument jedynie nazw tablicy (tutaj kompilator ju» sam wie,»e skoro funkcja pobiera jako pierwszy argument tablic, to przekazana jest jej tablica, wystarczy wi c poda jedynie nazw tablicy podczas wywoªania) oraz ilo± jej elementów ˆ funkcja fun jest uniwersalna, poniewa» dziaªa dla dowolnie du»ej tablicy - dla tablicy o n elementach Funkcja trzecia, tj. fun3: ˆ pobiera argumenty (z funkcji main mo»emy przesªa do niej, przekaza jej argumenty): caª, jednowymiarow tablic liczb caªkowitych tab, oraz ilo± jej elementów n 15
ˆ jednowymiarowa tablica przekazywana jest z funkcji main do funkcji fun3 za pomoc nazwy tablicy, wraz z podaniem ilo±ci przekazywanych elementów tablicy - funkcja przyjmuje wi c tablic o okre±lonej liczbie elementów - tutaj funkcja mo»e przyj jedynie tablic, która ma 5 elementów (sized array) ˆ funkcja nie zwraca warto±ci, jej typ zwracany to void ˆ funkcja wy±wietla wszystkie 5 elementów tablicy ˆ w funkcji main, aby przekaza tablic do funkcji fun3 podczas wywoªania nale»y poda nazw funkcji, przekaza jako argument jedynie nazw tablicy (tutaj kompilator ju» sam wie,»e skoro funkcja pobiera jako pierwszy argument tablic, to przekazana jest jej tablica, wystarczy wi c poda jedynie nazw tablicy podczas wywoªania), nie trzeba ju» podawa ilo±ci elementów tablicy ˆ funkcja fun3 jest NIE JEST uniwersalna, poniewa» dziaªa jedynie dla 5 elementowej tablicy - dla tablicy o 5 elementach, wi c nie jest zbyt u»yteczn funkcj Przykªad 7.3.3. Kolejny przykªad pokazuje, i» przekazuj c do funkcji tablic w jakikolwiek z 3 poznanych sposobów i modykuj c warto±ci jej elementów w funkcji, po wyj±ciu z niej i powrocie do funkcji main zmiany naniesione w funkcji w main s widoczne. W poni»szym przykªadzie mamy funkcj o nazwie dosth, która pobiera jako argument dynamiczn tablic liczb caªkowitych, oraz jej rozmiar n. W funkcji nie musimy ju» dynamicznie tworzy tablicy, poniewa» zostaªa ona stworzona i wypeªniona w gªownej funkcji programu - funkcji main. Po utworzeniu i wypeªnieniu tablicy, zostaªa ona przekazana do funkcji dosth, która to funkcja wykonaªa na wszystkich jej elementach pewne dzia- ªanie. Po wyj±ciu z funkcji widzimy,»e modykuj c w funkcji przekazan do niej jako argument tablic, zmiany mo»emy zobaczy w gªownej funkcji naszego programu. Dzieje si tak poniewa» tablica do funkcji przekazywana jest jako oryginaª, nie jako kopia (funkcja pracuje na oryginalnej, utworzonej w mainie tablicy), jak ma to miejsce w przypadku zwykªych zmiennych: 3 void dosth ( i n t * tab, i n t n ) 5 i n t i=0; while ( i<n ) 7 { 8 tab [ i ] = tab [ i ] * tab [ i ] ; 9 i++; 10 } 11 } 1 13 i n t main ( ) 1 15 i n t * tab = malloc ( s i z e o f ( i n t ) * 3) ; 1 tab [ 0 ] = 1 ; 17 tab [ 1 ] = ; 18 tab [ ] = 3 ; 19 0 i n t n = 3, i ; 1 printf ( "PRZED WYKONANIEM FUNKCJI: \ n\n" ) ; 3 f o r ( i=0; i<n ; i++) 4 printf ( " t a b l i c a [%d ] = %d\n", i, tab [ i ] ) ; 5 printf ( "\n" ) ; 7 dosth ( tab, n ) ; 8 9 printf ( "PO WYKONANIU FUNKCJI: \ n\n" ) ; 30 f o r ( i=0; i<n ; i++) 31 printf ( " t a b l i c a [%d ] = %d\n", i, tab [ i ] ) ; 3 printf ( "\n" ) ; 1
33 34 free ( tab ) ; 35 tab = NULL ; 3 37 return 0 ; 38 } Powy»szy program wy±wietli: 7.3.7 Tablice jednowymiarowe dynamiczne jako typ zwracany funkcji Tablice mog by równie» typem zwracanym funkcji, mówimy wówczas,»e funkcja zwraca tablic (wªa- ±ciwie: wska¹nik do tablicy). Taka tablica powinna by dynamicznie utworzona (za pomoc wska¹nika i funkcji malloc) w funkcji, która j zwraca, a nast pnie pami jej przydzielona powinna zosta zwolniona w funkcji wywoªuj cej dan funkcj (najcz ±ciej w funkcji main). Poni»ej znajduj si przykªady nagªówków funkcji, które zwracaj dynamiczne tablice jednowymiarowe: 1 i n t * funkcja1 ( i n t a, i n t b, char c ) ; 3 char * funkcja ( double d ) ; 4 5 f l o a t * funkcja3 ( ) ; 7 double * funkcja4 ( i n t i, f l o a t f, double *d ) ; Na poni»szym przykªadzie mo»emy zobaczy zwracanie tablicy z funkcji. Nale»y pami ta,»eby typ zwracany funkcji zgadzaª si z warto±ci, któr faktycznie zwracamy. Nasza funkcja tworzy dynamiczn tablic o rozmiarze podanym jako jej argument, wypeªnia j zerami, a nast pnie zwraca. W funkcji main wy±wietlamy stworzon tablic, i po zako«czeniu korzystania z niej, zwalniamy pami : 3 f l o a t * create_array ( i n t n ) f l o a t * tab = malloc ( s i z e o f ( f l o a t ) * n ) ; 7 8 f o r ( i=0; i <10; i++) 9 tab [ i ] = 0. 0 ; 17
10 11 return tab ; 1 } 13 14 i n t main ( i n t argc, char ** argv ) 15 { 1 i n t * tab ; 17 i n t n = 1 0 ; 18 19 // utworzenie t a b l i c y w f u n k c j i i p r z y p i s a n i e zwroconej t a b l i c y 0 // do t a b l i c y utworzonej w f u n k c j i main 1 tab = create_array ( n ) ; 3 // w y s w i e t l e n i e t a b l i c y 4 i n t i ; 5 f o r ( i=0; i<n ; i++) printf ( " tab[%d ] = %. f \n", i, tab [ i ] ) ; 7 8 // z w o l n i e n i e pamieci 9 free ( tab ) ; 30 tab = NULL ; 31 3 return 0 ; 33 } 18
7.4 Zadania do wykonania Zadanie 1 Napisz funkcj, która przyjmuje jako argument rozmiar tablicy n, a nast pnie tworzy dynamiczn tablic liczb typu f loat i wypeªnia j zerami. Funkcja ma zwróci wska¹nik do dynamicznie utworzonej tablicy. Przetestuj napisan funkcj w mainie, wy±wietl zawarto± tablicy i usu«pami przydzielon na tablic. Zadanie Napisz program, który wczyta od u»ytkownika liczb caªkowit n, dynamicznie zaalokuje tablic n liczb zmiennoprzecinkowych, wczyta je wszystkie od u»ytkownika, wypisze ich maksimum, minimum, ±redni i sum, a nast pnie zwolni pami zajmowan przez t tablic. Zadanie 3 Napisz funkcj, która przyjmuje jako argumenty dynamicznie utworzon tablic liczb caªkowitych, oraz rozmiar tablicy. Funkcja powinna wy±wietli tylko parzyste elementy tablicy. W funkcji main stwórz dynamiczn tablic, wypeªnij j liczbami a nast pnie przeka» do funkcji. Po wykonaniu funkcji (gdy ju» nie korzystasz z dynamicznie utworzonej tablicy) zwolnij przydzielon pami. Zadanie 4 Napisz funkcj, która przyjmuje jako argumenty dynamicznie utworzon tablic liczb caªkowitych, oraz rozmiar tablicy. Funkcja powinna wy±wietli tylko te elementy tablicy, które znajduj si pod jej nieparzystymi indeksami. W funkcji main stwórz dynamiczn tablic, wypeªnij j liczbami a nast pnie przeka» do funkcji. Po wykonaniu funkcji (gdy ju» nie korzystasz z dynamicznie utworzonej tablicy) zwolnij przydzielon pami. Zadanie 5 Napisz funkcj o nazwie przepisz_pn, która przyjmuje 3 tablice typu int i liczb caªkowit n. Pierwsza tablica ma rozmiar n, a dwie pozostaªe maj rozmiar n. Funkcja ma skopiowa wszystkie elementy drugiej tablicy na parzyste miejsca w tablicy pierwszej i wszystkie elementy tablicy trzeciej na nieparzyste miejsca w tablicy pierwszej. Wszystkie tablice utwórz dynamicznie w funkcji main, wypeªnij je liczbami, a nast pnie przeka» do funkcji przepisz_pn. Po wywoªaniu funkcji zwolnij pami przydzielon na tablice. Zadanie Napisz funkcj, która otrzymuje dwa parametry: liczb n oraz n-elementow tablic tab o elementach typu int i zwraca indeks najwi kszego elementu tablicy tab. W funkcji main stwórz dynamiczn tablic, wypeªnij j liczbami a nast pnie przeka» do funkcji. Po wykonaniu funkcji (gdy ju» nie korzystasz z dynamicznie utworzonej tablicy) zwolnij przydzielon pami. Zadanie 7 Napisz funkcj, która dostaje jako parametry tablic tab liczb caªkowitych, jej rozmiar n oraz warto± x. Funkcja nadaje warto± 0 wszystkim komórkom tablicy tab, które zawieraj warto± x. (czyli zeruje wszystkie wyst pienia danej warto±ci x). Dodatkowo, funkcja powinna zwraca liczb, ile razy w tablicy dokonaªa podmiany warto±ci x na 0. W funkcji main stwórz dynamiczn tablic, wypeªnij j liczbami a nast pnie przeka» do funkcji. Po wykonaniu funkcji (gdy ju» nie korzystasz z dynamicznie utworzonej tablicy) zwolnij przydzielon pami. Przykªad We: tab = {1,, 4, 5, 3,, 8, 7, 3,, 3, 0, 9, 3, 3}, n = 15, x = 3, Wy: tab = {1,, 4, 5, 0,, 8, 7, 0,, 0, 0, 9, 0, 0}, liczba podmian to 5. Zadanie 8 Napisz funkcj, która przyjmuje wska¹niki do 3 tablic liczb caªkowitych tab1, tab, tab3 oraz jeden argument n b d cy dªugo±ci tablic (wszystkie tablice maj t sam dªugo± ). Funkcja ma za zadanie zaalokowa now tablic tab4 tej samej dªugo±ci, do której pod i-tym indeksem ma wpisa liczb kryj c si pod tym samym indeksem z tab lub tab3 w zale»no±ci od warto±ci znajduj cej si pod i-tym indeksem w tablicy tab1. Je±li w tab1 warto± jest wi ksza lub równa 0, to ma wybra warto± z tab, w przeciwnym razie z tab3. Funkcja ma zwróci wska¹nik do tablicy tab4 (inaczej mówi c, ma zwróci tablic tab4). Wszystkie tablice (tab1, tab, tab3) utwórz dynamicznie w funkcji main, wypeªnij je liczbami, a nast pnie przeka» do funkcji. Po wywoªaniu funkcji wy±wietl zawarto± tablicy tab4, i zwolnij pami przydzielon na wszystkie tablice. Przykªad We: tab1 = { 1, 0, 3, 4, 10}, tab = {1,, 3, 4, 5}, tab3 = {10, 11, 1, 13, 14}, Wy: tab4 = {10,, 3, 13, 5}. 19
Zadanie 9 Napisz funkcj, która przyjmuje rozmiar n i trzy tablice jednowymiarowe liczb caªkowitych (dwie pierwsze maj rozmiar n, a ostatnia rozmiar n). Funkcja ma podstawi warto±ci z dwóch pierwszych tablic do trzeciej tablicy wedªug reguªy: tab1 = {3, 3, 3}, tab = {4, 4, 4} tab3 = {3, 4, 3, 4, 3, 4}. Wszystkie tablice (tab1, tab) utwórz dynamicznie w funkcji main, wypeªnij je liczbami, a nast pnie przeka» do funkcji. Po wywoªaniu funkcji wy±wietl zawarto± tablicy tab3, i zwolnij pami przydzielon na wszystkie tablice. Zadanie 10 Napisz funkcj, która dostaje w argumentach tablic liczb caªkowitych oraz liczb jej elementów n i wypisuje najwi ksz sum dwóch s siednich elementów tablicy. Na przykªad dla tablicy o elementach 1, 4, 3, 8, 5, 0 poprawna odpowied¹ to 13. W funkcji main stwórz dynamiczn tablic, wypeªnij j liczbami a nast pnie przeka» do funkcji. Po wykonaniu funkcji (gdy ju» nie korzystasz z dynamicznie utworzonej tablicy) zwolnij przydzielon pami. Zadanie 11 Napisz funkcj, która jako argumenty pobiera tablic liczb caªkowitych tab oraz liczb caªkowit n b d c ilo±ci elementów tablicy a tak»e liczb caªkowit m. Funkcja ma za zadanie zwróci informacj o tym, ile razy liczba m pojawiªa si w tablicy tab. W funkcji main stwórz dynamiczn tablic, wypeªnij j liczbami a nast pnie przeka» do funkcji. Po wykonaniu funkcji (gdy ju» nie korzystasz z dynamicznie utworzonej tablicy) zwolnij przydzielon pami. Zadanie 1 Napisz funkcje, która jako argumenty dostaje tablice liczb caªkowitych tab oraz jej rozmiar n i wyswietla na standardowym wyjsciu srednia arytmetyczna nieujemnych elementów tablicy tab oraz srednia arytmetyczna ujemnych elementów tab. W funkcji main stwórz dynamiczn tablic, wypeªnij j liczbami a nast pnie przeka» do funkcji. Po wykonaniu funkcji (gdy ju» nie korzystasz z dynamicznie utworzonej tablicy) zwolnij przydzielon pami. Przykªad We: n = 7, tab = { 3, 3, 4, 5, 4, 5, 3, 0}, Wy: sr. arytm. elem. nieujemnych: 3., sr. arytm. elem. ujemnych: 3 Zadanie 13 Napisz funkcje, która na wejsciu otrzyma tablice z wartosciami rzeczywistymi i ich rozmiar. Funkcja ma wymienic miedzy tablicami elementy o jednakowych indeksach tak, aby element wiekszy znalazª sie w tablicy pierwszej. Wszystkie tablice (tab1, tab) utwórz dynamicznie w funkcji main, wypeªnij je liczbami, a nast pnie przeka» do funkcji. Po wywoªaniu funkcji wy±wietl zawarto± tablicy tab3, i zwolnij pami przydzielon na wszystkie tablice. Przykªad Zadanie 14 Napisz funkcj, która jako argumenty dostaje tablic liczb caªkowitych oraz jej rozmiar. Zakªadamy,»e w tablicy na pewno tylko jedna komórka ma warto± 0 i nie jest ona ani na pocz tku, ani na ko«cu tablicy. Funkcja ma wy±wietli na standardowym wyj±ciu dwie ±rednie arytmetyczne: liczb przed w/w komórk i po niej. W funkcji main stwórz dynamiczn tablic, wypeªnij j liczbami a nast pnie przeka» do funkcji. Po wykonaniu funkcji (gdy ju» nie korzystasz z dynamicznie utworzonej tablicy) zwolnij przydzielon pami. Przykªad We: tab = {5, 3, 1, 0, 3, 3, 4, 4}, n = 8, Wy: 3, 3.5 Zadanie 15 Napisz funkcj, która dostaje jako argumenty trzy tablice liczb caªkowitych tab1, tab i tab3, z których dwie ostatnie zapeªnione s zerami oraz liczb n b d c ich rozmiarem, a nast pnie przepisuje do tablicy tab kolejno elementy nieparzyste z tab1, a do tab3 kolejno elementy parzyste z tab1. Wszystkie tablice (tab1, tab, tab3) utwórz dynamicznie w funkcji main, wypeªnij je liczbami, 170
a nast pnie przeka» do funkcji. Po wywoªaniu funkcji wy±wietl zawarto± wszystkich tablic, i zwolnij pami przydzielon na wszystkie tablice. Przykªad We: tab1 = {1,, 4, 5, 7, 8, }, n = 8, Wy: tab = {1, 5, 7, 0, 0, 0, 0}, tab3 = {, 4, 8,, 0, 0, 0}. Zadanie 1 Wykonaj wszystkie zadania z tablic statycznych (lab.pdf) zast puj c je tablicami dynamicznymi (w zadaniu zamiast tablicy statycznej (inaczej: automatycznej) wykorzystaj poznane tablice dynamiczne). 171