Ist 2d-Array ein Doppelzeiger? [duplicate]

Lesezeit: 5 Minuten

Benutzeravatar von Angus
Angus

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

Aber wenn ein 2-D-Array als Parameter übergeben wird, wird es in (* Matrix) typisiert.[2] .. als welchen Typ speichert der Compiler dieses Array … speichert es als 2-D-Array oder als Doppelzeiger oder als Zeiger auf ein Array .. Wenn es als Array gespeichert wird, wie interpretiert es es in verschiedenen Situationen unterschiedlich? wie oben. Bitte helfen Sie mir zu verstehen.

  • Zeiger sind keine Arrays und Arrays sind keine Zeiger. Arrays (unabhängig von ihrer Dimension) Verfall in (einzelne) Zeiger, wenn sie an Funktionen übergeben werden.

    – Alexander C.

    28. September 2011 um 16:52 Uhr

  • (int) matrix ist irgendwie bedeutungslos. Es zwingt matrix zweimal zu einem Zeiger auf eine Ganzzahl zerfallen, aber das Ergebnis der Umwandlung eines Zeigers in eine Ganzzahl ist undefiniert.

    – David Schwartz

    28. September 2011 um 16:58 Uhr


  • @ David Schwartz: (int)matrix würde verfallen matrix einmal (nicht zweimal), und das Ergebnis ist nicht undefiniert, sondern implementierungsdefiniert.

    – jpalecek

    28. September 2011 um 17:17 Uhr

  • @jpalecek: Implementierungsdefiniert bedeutet, dass die Implementierung frei tun kann, was sie will. Wenn Sie also die Implementierung nicht kennen, haben Sie keine Definition. In dem Kontext, in dem die Implementierung unbekannt ist, ist sie undefiniert. (Nicht im formalen Sinne von ‘undefiniert’, im normalen Sinne.)

    – David Schwartz

    28. September 2011 um 17:22 Uhr

  • In C das Ergebnis eines Aufrufs nicht umwandeln malloc(), realloc()oder calloc() – es ist unnötig und maskiert möglicherweise den schwerwiegenden Fehler eines fehlenden Prototyps.

    – mlp

    15. Juli 2019 um 16:16 Uhr

Benutzeravatar von jpalecek
jpalecek

Ist 2d-Array ein Doppelzeiger?

Nein. Diese Zeile Ihres Programms ist falsch:

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

Diese Antwort behandelt das gleiche Thema

Wenn Sie ein konkretes Bild wünschen, wie mehrdimensionale Arrays implementiert werden:

Die Regeln für mehrdimensionale Arrays unterscheiden sich nicht von denen für gewöhnliche Arrays, ersetzen Sie einfach den “inneren” Array-Typ als Elementtyp. Die Array-Elemente werden direkt nacheinander im Speicher abgelegt:

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

Daher zum Adresselement matrix[x][y]du nimmst the base address of matrix + x*4 + y (4 ist die innere Array-Größe).

Wenn Arrays an Funktionen übergeben werden, zerfallen sie in Zeiger auf ihr erstes Element. Wie Sie bemerkt haben, wäre dies der Fall int (*)[4]. Das 4 im Typ würde dem Compiler dann die Größe des inneren Typs mitteilen, weshalb es funktioniert. Bei der Zeigerarithmetik eines ähnlichen Zeigers fügt der Compiler Vielfache der Elementgröße hinzu, also z matrix_ptr[x][y]du erhältst matrix_ptr + x*4 + ydas ist genau das gleiche wie oben.

Die Besetzung ptr=(int**)matrix ist daher falsch. Einmal, *ptr würde bedeuten, dass ein Zeigerwert an der Adresse der Matrix gespeichert ist, aber es gibt keinen. Zweitens gibt es keinen Hinweis darauf matrix[1] irgendwo im Speicher des Programms.

Hinweis: Die Berechnungen in diesem Beitrag gehen davon aus sizeof(int)==1um unnötige Komplexität zu vermeiden.

Benutzeravatar von Dmitri
Dimitri

Nein. Ein mehrdimensionales Array ist ein einzelner Speicherblock. Die Größe des Blocks ist das Produkt der Dimensionen multipliziert mit der Größe des Typs der Elemente, und die Indizierung in jedem Klammerpaar versetzt in das Array mit dem Produkt der Dimensionen für die verbleibenden Dimensionen. So..

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

ist ein Array, das 30 enthält ints. arr[0][0][0] gibt den ersten, arr[1][0][0] ergibt die siebte (Offsets um 3 * 2). arr[0][1][0] ergibt die dritte (Offsets um 2).

Die Zeiger, auf die das Array abfällt, hängen von der Ebene ab; arr zerfällt zu einem Zeiger auf ein 3×2-Int-Array, arr[0] zerfällt zu einem Zeiger auf ein int-Array mit 2 Elementen und arr[0][0] zerfällt zu einem Zeiger auf int.

Sie können jedoch auch ein Array von Zeigern haben und es als mehrdimensionales Array behandeln – aber es erfordert einige zusätzliche Einstellungen, da Sie jeden Zeiger auf sein Array setzen müssen. Außerdem verlieren Sie die Informationen über die Größe der Arrays innerhalb des Arrays (sizeof würde die Größe des Zeigers angeben). Andererseits erhalten Sie die Möglichkeit, Unterarrays unterschiedlicher Größe zu haben und zu ändern, wohin die Zeiger zeigen, was nützlich ist, wenn sie in der Größe geändert oder neu angeordnet werden müssen. Ein Array von Zeigern wie dieses kann wie ein mehrdimensionales Array indiziert werden, auch wenn es anders zugewiesen und angeordnet ist und sizeof wird sich damit nicht immer gleich verhalten. Ein statisch zugewiesenes Beispiel für dieses Setup wäre:

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;

Nach dem oben, arr[1][0] ist 12. Aber anstatt das zu geben int gefunden am 1 * 2 * sizeof(int) Bytes nach der Startadresse des Arrays arres gibt die int gefunden am 0 * sizeof(int) Bytes nach der Adresse, auf die von gezeigt wird arr[1]. Ebenfalls, sizeof(arr[0]) ist äquivalent zu sizeof(int *) Anstatt von sizeof(int) * 2.

In C müssen Sie nichts Besonderes wissen, um mehrdimensionale Arrays zu verstehen. Sie funktionieren genau so, als ob sie nie ausdrücklich erwähnt worden wären. Alles, was Sie wissen müssen, ist, dass Sie ein Array jeden Typs erstellen können, einschließlich eines Arrays.

Also, wenn Sie sehen:

int-Matrix[2][4];

Denken Sie nur: „matrix ist ein Array aus 2 Dingen – diese Dinge sind Arrays aus 4 ganzen Zahlen”. Es gelten alle normalen Regeln für Arrays. Zum Beispiel: matrix kann leicht in einen Zeiger auf sein erstes Mitglied zerfallen, genau wie jedes andere Array, das in diesem Fall ein Array aus vier ganzen Zahlen ist. (Was natürlich selbst zerfallen kann.)

Wenn Sie den Stapel für diese Daten (kleines Volumen) verwenden können, definieren Sie normalerweise die Matrix:

int matrix[X][Y]

Wenn Sie es im Heap (großes Volumen) zuweisen möchten, definieren Sie normalerweise Folgendes:

int** matrix = NULL;

und weisen dann die beiden Dimensionen mit malloc/calloc zu. Sie können das 2d-Array als int** behandeln, aber das ist keine gute Praxis, da es den Code weniger lesbar macht. Ansonsten

**matrix == matrix[0][0] is true

1403160cookie-checkIst 2d-Array ein Doppelzeiger? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy