Tablica a wskaźnik to dwa osobne typy. Nie mniej jednak tablica może być niejawnie konwertowana na wskaźnik - wtedy jest ona zamieniana na wskaźnik do pierwszego elementu tablicy.
Natomiast tablica dwuwymiarowa to jednowymiarowa tablica jednowymiarowych tablic. Tak samo może być niejawnie konwertowana na wskaźnik do pierwszego elementu, z tym że w tym przypadku pierwszym elementem jest cały wiersz (tablica jednowymiarowa).
Zatem:
cout<<&tab;
Tutaj niejawna konwersja nie zachodzi - jawnie pobierasz adres tablicy. Jest to wskaźnik typu int (*)[4][3]
(wskaźnik do tablicy dwuwymiarowej). Wskaźnik ten wskazuję na miejsce w pamięci w którym leży tablica - będzie to ten sam adres co adres pierwszego wiersza, czy elementu [0][0] (adres ten sam, ale typ wskaźnika już inny).
cout<<tab;
Tutaj zachodzi niejawna konwersja na adres pierwszego elementu czyli tak jakbyśmy pobrali &tab[0]
(adres pierwszego wiersza). Wskaźnik ten jest typu int (*)[3]
(wskaźnik do tablicy jednowymiarowej).
int (*wsk)[3] = &tab;
Tutaj nie mamy niejawnej konwersji - jawnie pobierasz adres całej tablicy dwuwymiarowej. Tak jak w pierwszym przypadku będzie to wskaźnik typu int (*)[4][3]
(wskaźnik do tablicy dwuwymiarowej). Zmienna wsk
ma typ int (*)[3]
(wskaźnik do tablicy jednowymiarowej) więc typy się nie zgadzają.
//tab[0] to samo co *tab
Tak. Ale czym to jest? Jest to tablicą jednowymiarową typu int [3]
(pierwszy wiersz tab
). Dlaczego? Przy tab[0]
wiadomo - pierwszy element tablicy dwuwymiarowej czyli pierwszy wiersz (tablica jednowymiarowa). Przy *tab
sprawa jest ciut bardziej skomplikowana. Operatora *
nie można użyć na tablicy, ale można użyć na wskaźniku. Więc najpierw zachodzi niejawna konwersja na wskaźnik czyli tak jakby tab
było zamieniane na &tab[0]
. Następnie zachodzi dereferencja (*
) i otrzymujemy *&tab[0]
czyli adres pierwszego wiersza zamieniany jest na wiersz - pierwszy wiersz tablicy tab
, wiersz typu int [3]
. W pierwszym i drugim przypadku wynikiem jest tablica jednowymiarowa.
int (*wsk)[3] = tab[0];
int (*wsk)[3] = *tab;
Jak ustaliliśmy tab[0]
jaki i *tab
to tablica jednowymiarowa (pierwszy wiersz). Natomiast wsk
to wskaźnik. Przypisując tablicę wskaźnikowi zachodzi niejawna konwersja - ów pierwszy wiersz zamieniany jest na wskaźnik do pierwszego elementu tegoż wiersza czyli &tab[0][0]
lub &*tab
- jest to wskaźnik typu int*
czyli inny niż typ wsk
.