Tablice dynamiczne

Ostatania modyfikacja: 28 września 2017, kategoria: C++

Tablice dynamiczne jednowymiarowe oraz dwuwymiarowe są ściśle związane ze wskaźnikami. Użycie wskaźników to jedyna metoda uzyskania tablicy dynamicznej. Istnieje duża potrzeba na używanie tablic dynamicznych, programista ma nad nimi pełną kontrolę. Możemy decydować o ich wymiarach (kształcie) oraz o wielkości. 

Informacje o tablicach statycznych

Aby dobrze poznać tablice dynamiczne należy zrozumieć działanie zwykłych statycznych tablic. Inicjowanie tablicy jest bardzo proste, podczas inicjacji możemy z góry określić elementy jakie zawiera tablica.

 

int tablica[5] = { 10, 11, 12, 13, 14};

Odwoływanie się i wyświetlanie poszczególnych elementów oczywiście nie stanowi dla Ciebie problemu. Ciekawostką może okazać się fakt, że nazwa tablicy jest jednocześnie wskaźnikiem na jej pierwszy element.

int tablica[5] = { 10, 11, 12, 13, 14};

cout << *tablica;   // wyświetli tablica[0];
cout << tablica;    // wartość wskaźnika, adres pierwszego elementu

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. Kolejną wadą takowych tablic jest fakt, iż generując tablicę dwuwymiarową musi być ona prostokątna.

int tablica[2][3];

Powyższy kod to deklaracja tablicy prostokątnej o wymiarach 2×3.

Tablica dynamiczna jednowymiarowa

Deklarując tablicę dynamiczną należy zadeklarować wskaźnik tego samego typu co elementy tablicy. Następnie rezerwujemy miejsce w pamięci o określonym typie (takim samym jak wskaźnik). Służy do tego rozkaz new. Tablicy dynamicznej używamy tak samo jak zwykłą tablice statyczną, nie trzeba operować wskaźnikami, wskaźniki potrzebne są tylko przy deklaracji. Wynika to z faktu opisanego wyżej – tablica statyczna to też wskaźniki chociaż nie są do końca widoczne.

int * tablica = new int[3];

tablica[0] = 11;
tablica[1] = 12;
tablica[2] = 13;

delete [] tablica;

Każdy dynamiczny obiekt utworzony podczas działania programu należy na końcu  usunąć poleceniem delete. Przy usuwaniu tablicy dodatkowo dodajemy kwadratowy nawias czyli delete []. Dzięki użyciu tablicy dynamicznej użytkownik ma możliwość decydowania o rozmiarze tablicy podczas działania programu:

int rozmiar;

cout << "Podaj rozmiar tablicy:" << endl;
cin >> rozmiar;

int * tablica = new int[rozmiar];

delete [] tablica;

Tablica dynamiczna dwuwymiarowa

Tablica dynamiczna dwuwymiarowa to tak naprawdę tablica wskaźników do poszczególnych wymiarów. Jaka płynie z tego korzyść? Podczas deklaracji tablicy mamy pełną kontrolę nad wielkością poszczególnych wymiarów, statycznie nie da się osiągnąć takich efektów:

tabs

Generowanie tablicy dwuwymiarowej dynamicznej odbywa podobnie jak jednowymiarowej. Zamiast tworzyć wskaźnik do jednego wymiaru, tworzymy tablicę wskaźników wskazujących na wymiary.

int ** tablica = new int * [3];

tablica[0] = new int [3];   // wskaźnik tablica[0] wskazuje na nową tablicę
tablica[1] = new int [3];   // wskaźnik tablica[1] wskazuje na nową tablicę
tablica[2] = new int [3];   // wskaźnik tablica[2] wskazuje na nową tablicę

tablica[2][2] = 123;
cout << tablica[2][2];

// zwalniamy pamiec
delete [] tablica[0];
delete [] tablica[1];
delete [] tablica[2];
delete [] tablica;

Graficzne przedstawienie powyższego kodu:

tabs2

Generowanie tablicy dwuwymiarowej dynamicznej bardzo wygodnie robić za pomocą pętli. Każdy obrót pętli przypisuje wskaźnik do nowego wymiaru:

Użytkownik Wojtek K napisał:

29 grudnia 2012


Wytłumaczone tak jak należy!

Użytkownik PPP napisał:

16 września 2013


Wszystko elegancko wytłumaczone… A tak swoją drogę w C# jest to o wiele bardziej elegancko wymyślone.

int[,,]tablica = new int[wysokość, szerokość, wysokość];

Użytkownik Marcin napisał:

17 września 2013


Krótko zwięźle i na temat. Dzięki,

Użytkownik wino napisał:

19 października 2013


I wszytko rozumiem, lepiej niż w książkach i kursach C++ ;/

Użytkownik Bartek napisał:

22 listopada 2013


Wszystko jasne lepiej niż u Beaty !! <3

Użytkownik Mateusz napisał:

22 stycznia 2014


Wytłumaczone w bardzo prosty i przejrzysty sposób. Dzięki :)

Użytkownik Rafał napisał:

25 lutego 2014


Czy uwalnianie pamięci nie powinno wyglądać w ten sposób:

for(unsigned int i = 0; i < size; i++)
delete [] tablica[i];

delete [] tablica;

Z góry dzięki za odpowiedź, pozdrawiam.

Użytkownik Karol napisał:

25 lutego 2014


@Rafał
Witaj, podany przez Ciebie sposób jest w 100% dobry i logiczny.

Podany przeze mnie sposób znalazłem w wielu źródłach, sprawdzę go kiedyś z debbugerem w ręce.

Użytkownik Paweł napisał:

10 maja 2014


W końcu to zrozumiałem, dzięki za graficzne przedstawienie kodu :)

Użytkownik Mateusz napisał:

14 listopada 2014


Serdecznie dziękuję :) Lepiej wytłumaczone niż w moich książkach :))

Użytkownik Igor napisał:

26 grudnia 2014


A gdybym chciał, aby moja dynamiczna dwuwymiarowa tablica obiektów przy tworzeniu obiektów wywoływała konstruktor to jak mam to zrobić? :/

Użytkownik Zielony napisał:

01 stycznia 2015


Nie czaje :/ dwuwymiarowej dynamicznej tablicy

Użytkownik Marek napisał:

17 lutego 2015


Wszystko git! Tylko mógłbyś mi wytłumaczyć jak wczytywać liczby do dynamicznej tablicy 2D? Z góry dzięki! :)

Użytkownik Kamil napisał:

02 marca 2015


Ekstra wytłumaczone, myślałem że to czarna magia a teraz już jest to dla mnie jasne. Dzięki!!!

Użytkownik S napisał:

22 września 2015


Czy w C++ są tablice nieregularne (dwa wymiary i więcej)? O ile wiem, w C# istnieją takie rodzynki. Pozdro

Użytkownik Majki napisał:

13 lutego 2016


Dzięki za opis, bardzo się przydał :)

Użytkownik Arek napisał:

15 września 2016


Wszystko jasne, czytelne i dobrze przedstawione. Kole mnie w oczy tylko jeden szczegół. Jak na boga można inicjować tablice czy zmienną? Inicjacja to może być seksualna albo jako obrzęd sekt… Zmienne czy tablice się INICJALIZUJE.

Użytkownik Piotr napisał:

25 stycznia 2017


Bardzo przejrzyście wytłumaczone. 9/11

Użytkownik Kamil W napisał:

07 lutego 2018


Nareszcie to rozumiem po tylu miesiącach unikania tablic dynamicznych jak ognia wreszcie to rozumiem

Użytkownik Bogdan napisał:

10 maja 2018


Moim zdaniem kapitalnie prosto wytłumaczone. Gratuluję !

Zachęcam Cię do zostawienia komentarza!

Ilość znaków: 0