Jak kompilator lokalizuje elementy tablicy wielowymiarowej?

0

Wyczytałem, że pierwszy wymiar tablicy nie jest potrzebny kompilatorowi do odnalezienia danego elementu tablicy x wymiarowej. Rozumiem, że tablica [2][2] jest zapisywana w pamięci tak:

0,0
0,1
1,0
1,1

jak więc kompilator odróżni element 0,0 od 1,0, skoro pierwszy wymiar nie jest potrzebny?

Dlaczego potrzebuje jednak pozostałe wymiary w tablicach >2 wymiarowych, tj. dlaczego tylko pierwszy można pominąć?

Wygooglowałem to na kilku stronach, ale nigdzie nie znalazłem szerszego wytłumaczenia, poza lakonicznym stwierdzeniem, że "tak jest".

Wyjaśnijcie mi to jak 5-latkowi, proszę.

2

Załóżmy taką tablicę:

int tablica[2][3]; // 2 wiersze, 3 kolumny

Takie coś składowane jest w pamięci w porządku row-major czyli wierszami. Dlatego ułożenie elementów tej tablicy w pamięci wyglądać będzie tak:

(0,0) (0,1) (0,2) (1,0) (1,1) (1,2)

Dla przykładu weźmy taką tablicę: (celowo nie zagnieżdżam nawiasów klamrowych)

int tablica[2][3] = {1, 2, 3, 4, 5, 6};

Ułożenie tych elementów w pamięci jest dokładnie takie jak w nawiasach klamrowych (liniowe), ale dla człowieka jej układ jest taki:

1 2 3
4 5 6

Aby obliczyć gdzie znajduje się dany element tablicy dany przez tablica[x][y] kompilator używa prostego wzoru:

adres_elementu = adres_bazowy + rozmiar_elementu * (x * liczba_kolumn + y);

Adres bazowy dany jest przez nazwę tablicy, rozmiar elementu jest znany (sizeof(int)), x oraz y podał programista, jedyną rzeczą, która musi być jeszcze znana jest liczb kolumn tablicy, czyli właśnie drugi wymiar. Jak widzisz nie ma tu nigdzie informacji o pierwszym wymiarze - jest ona niepotrzebna. Z tego właśnie powodu w deklaracji funkcji wystarczy napisać tak:

void funkcja(int tablica[][3]);

Dodatkowo zauważ, że podczas inicjalizacji drugi wymiar też nie jest potrzebny:

int tablica[][3] = {1, 2, 3, 4, 5, 6};

Elementów jest 6 a drugi wymiar wynosi 3 - jedynym możliwym pierwszym wymiarem jest 2, bo 2*3=6.

0

Dzięki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1