Dzień dobry.
Mam 3 pytania związane z dynamiczną alokacją tablic wielowymiarowych.
1. Co dokładnie oznaczają i czym różnią się zapisy wskaźników: int ***t
, int **t
, int *t
? Bo wiem, że ten pierwszy używamy przy tablicach trójwymiarowych , drugiego przy dwuwymiarowych, trzeciego przy jednowymiarowych lub przy pojedynczych zmiennych. Ale, czy one się różnią i jak je odczytywać? Gdybym tworzył tablicę czterowymiarową to bym musiał najpierw zadeklarować int **** t
i wtedy to by oznaczało, że deklaruję wskaźnik czterowymiarowy na inne wskaźniki ?
2. Tworząc tablicę trójwymiarową najpierw deklaruję wskaźnik int ***t
(oto jak to nazwać pytam w poprzednim pytaniu). Teraz ten wskaźnik tworzy pierwszy wymiar tablicy i składa się z tablicy wskaźników wskazujących i zarazem tworzących drugi wymiar. Ten wskaźnik tworzący pierwszy wymiar wskazuje na tablicę wskaźników drugiego wymiaru t = new int ** [3];
(tak dokładnie to ten wskaźnik przechowuje adres pierwszej zmiennej tablicy wskaźników z drugiego wymiaru, czyli adres pierwszego wskaźnika drugiego wymiaru). Następnie każdy z tych wskaźników tworzących drugi wymiar wskazuje na zmienne w tworzące trzeci wymiar (np. t[i] = new int * [1]
i- to pewien nr indeksu). I na koniec tworzymy zmienne trzeciego wymiaru t[i][j] = new int [4]
-i,j - numery indeksów odpowiednio wymiaru pierwszego i drugiego.
Czy dobrze rozumiem?
3. Poniżej w listingu znajduje się napisany przeze mnie kod tworzenia tablicy trójwymiarowej. Czy jest on poprawny? Proszę pominąć na razie część oznaczoną jako " //przypisanie wartości trójwymiarowej tablicy
" Tego dotyczyć będzie moje następne pytanie.
4. Proszę mi wyjaśnić jedną kwestię związaną z poniższym listingiem,. Jak widać dla trzeciej komórki I wymiaru (indeks 2), 2 komórki II wymiaru (indeks 1) mamy dostępną tylko 1 komórkę III wymiaru. W kodzie jest zapis t[2][1] = new int [1]; , co powinno oznaczać, że utworzona zostaje 1 komórka trzeciego wymiaru o indeksie 0 (komórka 1 wymiaru 2 z komórki 2 wymiaru 1).
Zapis t[x][y][z] oznacza: t-nazwa wskaźnika, x-komórka I wymiaru, y - komórka II wymiaru, a z - komórka III wymiaru.
Skoro tak to dlaczego, gdy wpiszę coś takiego:
//przypisanie wartości trójwymiarowej tablicy // tu jest pewien problem*******************************
t[2][1][0]=555;
t[2][1][1]=888;
t[2][1][2]=345;
cout<<t[2][1][0]<<"\t"<<t[2][1][1]<<"\t"<<t[2][1][2];
To program wyświetla mi liczby 555 888 345
. Przecież ja przekroczyłem (celowo w celu sprawdzenia) wymiar w przypadku liczb 888
i 345
.
Powinna zostać przypisana tylko liczba 555
indeksowy 0 z trzeciego wymiaru. Wymiar ten zawiera tylko 1 komórkę o indeksie 0, więc nie może zawierać komórek o indeksach 1 i 2.
To dlaczego kompilator utworzył komórki trzeciego wymiaru o indeksach 1 i 2 (t[2][1][1]=888;
oraz t[2][1][2]=345;
), przypisał im wartości i jeszcze na dodatek można je wyświetlić,
skoro te komórki nie powinny istnieć? Czy chodzi oto, że te wartości zostały wstawione do grupy 4 komórek trzeciego wymiaru znajdujących się dalej, czyli do t[2][2] = new int [4]; //tworzymy trzeci wymiar (komórka 2 wymiaru 2 z komórki 2 wymiaru 1)
? Chodzi oto, że te komórki znajdują się za komórką t[2][1][0] i kompilator wpisał 888 i 345 odpowiednio do komórek t[2][2][0]
i t[2][2][1]
, a ja odwołują się do t[2][1][1]
i t[2][1][2]
odwołuję się do t[2][2][0]
i t[2][2][1]
?
Listing
int ***t;
//wymiar I
t = new int ** [3]; // tworzymy pierwszy wymiar składający się z tablicy trzech wskaźników na wskaźniki drugiego wymiaru
//wymiar II
t[0] = new int * [1]; // tworzymy drugi wymiar (komórka 0 wymiaru 1) składający się z tablicy wskaźników na tablice zmiennych wymiaru trzeciego
t[1] = new int * [2]; // tworzymy drugi wymiar (komórka 1 wymiaru 1) składający się z tablicy wskaźników na tablice zmiennych wymiaru trzeciego
t[2] = new int * [3]; // tworzymy drugi wymiar (komórka 2 wymiaru 1) składający się z tablicy wskaźników na tablice zmiennych wymiaru trzeciego
//wymiar III
t[0][0] = new int [3]; //tworzymy trzeci wymiar (komórka 0 wymiaru 2 z komórki 0 wymiaru 1), czyli przypisujemy zmiennym z drugiego wymiaru zmienne tworzące trzeci wymiar
t[1][0] = new int [2]; //tworzymy trzeci wymiar (komórka 0 wymiaru 2 z komórki 1 wymiaru 1)
t[1][1] = new int [1]; //tworzymy trzeci wymiar (komórka 1 wymiaru 2 z komórki 1 wymiaru 1)
t[2][0] = new int [4]; //tworzymy trzeci wymiar (komórka 0 wymiaru 2 z komórki 2 wymiaru 1)
t[2][1] = new int [1]; //tworzymy trzeci wymiar (komórka 1 wymiaru 2 z komórki 2 wymiaru 1)
t[2][2] = new int [4]; //tworzymy trzeci wymiar (komórka 2 wymiaru 2 z komórki 2 wymiaru 1)
//przypisanie wartości trójwymiarowej tablicy // tu jest pewien problem*******************************
t[2][1][0]=555;
t[2][1][1]=888;
t[2][1][2]=345;
cout<<t[2][1][0]<<"\t"<<t[2][1][1]<<"\t"<<t[2][1][2];
// zwalnianie pamięci;
delete [] t[0][0]; // usuwam komórki 3 wymiaru
delete [] t[1][0]; // usuwam komórki 3 wymiaru
delete [] t[1][1]; // usuwam komórki 3 wymiaru
delete [] t[2][0]; // usuwam komórki 3 wymiaru
delete [] t[2][1]; // usuwam komórki 3 wymiaru
delete [] t[2][2]; // usuwam komórki 3 wymiaru
delete [] t[0]; // usuwam komórki 2 wymiaru
delete [] t[1]; // usuwam komórki 2 wymiaru
delete [] t[2]; // usuwam komórki 2 wymiaru
delete [] t; // usuwam komórki 1 wymiaru