Nie wiem czemu autor rozwiązania tak robi jak piszesz. Jednak od początku.
Tablica w C/C++ to nic innego jak n (rozmiar tablicy) komórek pamięci znajdujące się obok siebie.
Jeśli piszesz:
int tab[5];
Taki zapis powoduje zadeklarowanie tablicy składającej się z 5 komórek. Każda z komórek może przechowywać liczbę będącą typem int. Rozmiar tablicy to tak naprawdę 5*4 bajty czyli 20 bajtów. Oczywiście jeśli typowo int ma 4 bajty. Sama zaś nazwa tab to nic innego jak wskaźnik na element o indexie zero. Z arytmetyki wskaźników zapis tab+4 to nic innego jak taki zapis tab[4].
Tablica dwuwymiarowa to nic innego jak tablica zawierająca wskaźniki. Myślę że ten zapis rozjaśni ci:
int **tab=new int*[5];
for(int i=0;i<5;i++)
{
tab[i]=new int[5];
}
W ten sposób jest tworzona tablica dynamiczna dwuwymiarowa o wymiarach 5 na 5. Oczywiście tak stworzoną tablice trzeba usunąć (zwolnić pamięć aby nie doszło do wycieku pamięci ale o tym później).
Jak widzisz najpierw tworzymy tablice zawierającą wskaźniki. Tablica ta ma 5 komórek, ko każdej z nich możemy przypisać jakąś pamięć. Inaczej mówiąc do każdej z komórek tablicy tab można dowiązać inna tablice. Ta operacja realizowana jest w pętli. Nawiasem mówiąc tablica trójwymiarowa to nic innego jak potrójny wskaźnik.
Oczywiście usuwanie takiej tablicy powinno przebiegać odwrotnie do jej tworzenia.
for(int i=0;i<5;i++)
{
delete []tab[i];
}
delete []tab;
Jeśli chodzi o twoje pytania to ta linia:
int(*t)[5];
Powoduje stworzenie tablicy wskaźników o rozmiarze pięć elementów. W każdej komórce tablicy możemy wpisać adres na zmienna typu int.
Zapis ten jest poprawny ponieważ pointerToTo jest pojedynczym wskaźnikiem dlatego potrzebujemy operatora wyłuskania.
int const* pointerToT = *t;
Ten zapis jest równoznaczny temu:
int const* pointerToT = t[0];
Zwróć uwagę że nazwa tablicy to wskaźnik więc jeśli zmienna t to tablica wskaźników to samo t jest wskaźnikiem na t[0] zaś t[0] to zmienna przechowująca wskaźnik. Z tego wynika że t jest podwójnym wskaźnikiem.
Jeśli już mówimy o wskaźnikach to polecam sobie poczytać o wskaźniku na stały adres i na stałą wartość.
Zapis ten :
int const* pointerToT=t[0];
Powoduje że tworzymy wskaźnik na stały adres. Inaczej mówiąc nie będziemy mogli później przypisać zmiennej pointerToT innego adresu, zaś jesteśmy w stanie za pomocą tego wskaźnika zmienić wartość komórki na którą wskazuje ten wskaźnik.