Czy tablica 2d jest podwójnym wskaźnikiem? [duplikat]

To pytanie ma już odpowiedź tutaj:

int main()
{
    matrix[2][4] = {{11,22,33,99},{44,55,66,110}};
    int **ptr = (int**)matrix;
    printf("%d%d",**matrix,*ptr);
}

Ale gdy tablica 2-d jest przekazywana jako parametr, jest ona wpisywana do (*matrix)[2] .. jakiego typu kompilator przechowuje tę tablicę... czy jest przechowywany jako tablica 2-d lub Podwójny wskaźnik lub wskaźnik do tablicy .. Jeśli jest przechowywana jako tablica, jak interpretuje się ją inaczej w różnych sytuacjach, jak powyżej. Proszę, pomóż mi zrozumieć.

Author: Jason Orendorff, 2011-09-28

4 answers

Czy tablica 2d jest podwójnym wskaźnikiem?

Nie. Ta linia programu jest niepoprawna:

int **ptr = (int**)matrix;

Ta odpowiedź dotyczy tego samego tematu

Jeśli chcesz uzyskać konkretny obraz, jak zaimplementowane są tablice wielowymiarowe:

Reguły dla tablic wielowymiarowych nie różnią się od reguł dla tablic zwykłych, po prostu zastępują typ tablicy "wewnętrznej" jako Typ elementu. Pozycje tablicy są zapisywane w pamięci bezpośrednio po każdym inne:

matrix: 11 22 33 99 44 55 66 110
        -----------               the first element of matrix
                    ------------  the second element of matrix

Dlatego, aby adresować element matrix[x][y], bierzemy the base address of matrix + x*4 + y (4 to wewnętrzny rozmiar tablicy).

Gdy tablice są przekazywane do funkcji, rozkładają się na wskaźniki do pierwszego elementu. Jak zauważyłeś, będzie to int (*)[4]. 4 w typie powie kompilatorowi Rozmiar typu wewnętrznego, dlatego działa. Gdy wykonujemy arytmetykę wskaźnika na podobnym wskaźniku, kompilator dodaje wielokrotności rozmiaru elementu, więc dla matrix_ptr[x][y], otrzymujemy matrix_ptr + x*4 + y, co jest dokładnie tak jak wyżej.

Obsada ptr=(int**)matrix jest zatem Niepoprawna. Raz *ptr oznaczałoby wartość wskaźnika przechowywaną pod adresem macierzy, ale jej nie ma. Po drugie, w pamięci programu nie ma wskaźnika matrix[1].

Uwaga: obliczenia w tym poście zakładają sizeof(int)==1, aby uniknąć niepotrzebnej złożoności.

 37
Author: jpalecek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:09

Nie. Tablica wielowymiarowa jest pojedynczym blokiem pamięci. Wielkość bloku jest iloczynem wymiarów pomnożonych przez wielkość typu elementów, a indeksowanie w każdej parze nawiasów przesuwa do tablicy iloczyn wymiarów dla pozostałych wymiarów. Więc..

int arr[5][3][2];

Jest tablicą, która zawiera 30 ints. arr[0][0][0] daje pierwszy, arr[1][0][0] daje siódmy (przesunięcie o 3 * 2). arr[0][1][0] daje trzecią (przesunięcie o 2).

The pointers the tablica rozpada się na będzie zależeć od poziomu; arr rozpada się na wskaźnik do tablicy int 3x2, arr[0] rozpada się na wskaźnik do tablicy int 2 element, a arr[0] [0] rozpada się na wskaźnik do tablicy int.

Jednakże, możesz również mieć tablicę wskaźników i traktować ją jako tablicę wielowymiarową -- ale wymaga to dodatkowej konfiguracji, ponieważ musisz ustawić każdy wskaźnik na jego tablicę. Dodatkowo, tracisz informacje o rozmiarach tablic w tablicy (sizeof dałoby rozmiar pointer). Z drugiej strony zyskujesz możliwość posiadania różnej wielkości tablic podrzędnych i zmiany miejsca Wskazywania wskaźników, co jest przydatne, jeśli trzeba je zmienić rozmiar lub zmienić układ. Tablica wskaźników jak ta może być indeksowana jak tablica wielowymiarowa, nawet jeśli jest przydzielona i ułożona inaczej i sizeof nie zawsze będzie zachowywać się tak samo. Statycznie przypisany przykład tego ustawienia to:

int *arr[3];
int aa[2] = { 10, 11 }, 
    ab[2] = { 12, 13 }, 
    ac[2] = { 14, 15 };
arr[0] = aa;
arr[1] = ab;
arr[2] = ac;

Po powyższym, arr[1][0] jest 12. Ale zamiast podajemy int Znalezione w 1 * 2 * sizeof(int) bajtach po adresie początkowym tablicy arr, podajemy int Znalezione w 0 * sizeof(int) bajtach po adresie wskazywanym przez arr[1]. Również {[18] } jest równoważne sizeof(int *) zamiast sizeof(int) * 2.

 9
Author: Dmitri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-21 16:21:57

W C, nie ma nic specjalnego, co trzeba wiedzieć, aby zrozumieć tablice wielowymiarowe. Działają dokładnie tak samo, jak gdyby nigdy nie zostały konkretnie wymienione. Wszystko, co musisz wiedzieć, to to, że możesz utworzyć tablicę dowolnego typu, w tym tablicę.

Więc kiedy widzisz:

Int macierz[2][4];

Po prostu pomyśl, "matrix jest tablicą 2 rzeczy - te rzeczy są tablicami 4 liczb całkowitych". Obowiązują wszystkie normalne reguły dla tablic. Na przykład matrix można łatwo rozkłada się na wskaźnik do pierwszego członu, tak jak każda inna tablica, która w tym przypadku jest tablicą czterech liczb całkowitych. (Który może, oczywiście, sam się rozpadać.)

 2
Author: David Schwartz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-28 17:01:22

Jeśli możesz użyć stosu dla tych danych (małej objętości), to zwykle definiujesz macierz:

int matrix[X][Y]

Gdy chcesz przydzielić go w stercie (duży wolumin), Zwykle definiujesz a:

int** matrix = NULL;

A następnie przydziel dwa wymiary za pomocą malloc / calloc. Możesz traktować tablicę 2d jako int**, ale nie jest to dobra praktyka, ponieważ sprawia, że kod jest mniej czytelny. Inne niż to

**matrix == matrix[0][0] is true
 0
Author: long404,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-28 17:00:25