Frage

In C, ich weiß, ich dynamisch ein zweidimensionales Array auf dem Heap mit dem folgenden Code zuordnen kann:

int** someNumbers = malloc(arrayRows*sizeof(int*));

for (i = 0; i < arrayRows; i++) {
    someNumbers[i] = malloc(arrayColumns*sizeof(int));
}

Natürlich ist dies tatsächlich schafft ein eindimensionales Array von Zeigern auf ein Bündel von separater eindimensionaler Arrays von ganzen Zahlen, und „The System“ kann herausfinden, was ich meine, wenn ich frage nach:

someNumbers[4][2];

Aber wenn ich erkläre statisch einen 2D-Array, wie in der folgenden Zeile ...:

int someNumbers[ARRAY_ROWS][ARRAY_COLUMNS];

... hat eine ähnliche Struktur auf dem Stapel erstellt bekommen, oder ist es völlig eine andere Form? (Das heißt es ist ein 1D-Array von Zeigern? Wenn nicht, was es ist, und wie Verweise auf sie herausgefunden werden?)

Auch wenn ich sage: „Das System“, was ist eigentlich dafür verantwortlich, dass aus herauszufinden? Der Kernel? Oder hat die C-Compiler sort it out beim Kompilieren?

War es hilfreich?

Lösung

Ein statische zweidimensionale Anordnung sieht aus wie ein Array von Arrays - es ist einfach zusammenhängend im Speicher angelegt. Arrays sind nicht das gleiche wie Zeiger, sondern weil man sie oft ziemlich verwenden können austauschbar kann es manchmal verwirrend. Der Compiler hält richtig Spur, obwohl, das alles macht Linie auf den Punkt. Sie haben mit statischen 2D-Arrays vorsichtig sein, wie Sie erwähnen, denn wenn Sie versuchen, eine auf eine Funktion zu übergeben einen int ** Parameter genommen wird, schlimme Dinge passieren. Hier ist ein kleines Beispiel:

int array1[3][2] = {{0, 1}, {2, 3}, {4, 5}};

Im Speicher sieht wie folgt aus:

0 1 2 3 4 5

genau die gleiche wie:

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

Aber wenn Sie versuchen, array1 auf diese Funktion zu übergeben:

void function1(int **a);

Sie erhalten eine Warnung erhalten (und die App wird nicht das Array richtig zuzugreifen):

warning: passing argument 1 of ‘function1’ from incompatible pointer type

Da ein 2D-Array nicht die gleichen wie int ** ist. Die automatischen abklingenden eines Arrays in einen Zeiger geht nur „eine Ebene tiefer“ sozusagen. Sie müssen die Funktion als deklarieren:

void function2(int a[][2]);

oder

void function2(int a[3][2]);

Um alles glücklich zu machen.

Das gleiche Konzept erstreckt sich auf n -dimensionalen Arrays. Unter Ausnutzung dieser Art von lustigem Geschäft in Ihrer Anwendung im Allgemeinen macht es nur schwerer zu verstehen, though. Seien Sie also vorsichtig da draußen.

Andere Tipps

Die Antwort basiert auf der Idee basiert, dass C nicht wirklich wird 2D-Arrays - es hat Arrays-of-Arrays. Wenn Sie erklären diese:

int someNumbers[4][2];

Sie werden nach someNumbers fragt ein Array von 4 Elementen zu sein, wobei jedes Element des Arrays des Typs int [2] ist (das selbst ein Array von 2 ints).

Der andere Teil des Puzzles ist, dass Arrays immer zusammenhängend im Speicher angelegt. Wenn Sie fragen nach:

sometype_t array[4];

dann das wird wie folgt aussehen immer:

| sometype_t | sometype_t | sometype_t | sometype_t |

(4 sometype_t Objekte nebeneinander gelegt, ohne Leerzeichen dazwischen). Also in Ihrem someNumbers Array-of-Arrays, es wird wie folgt aussehen:

| int [2]    | int [2]    | int [2]    | int [2]    |

Und jedes int [2] Element selbst ein Array, das wie folgt aussieht:

| int        | int        |

Also insgesamt Sie diese:

| int | int  | int | int  | int | int  | int | int  |
unsigned char MultiArray[5][2]={{0,1},{2,3},{4,5},{6,7},{8,9}};

im Speicher ist gleich:

unsigned char SingleArray[10]={0,1,2,3,4,5,6,7,8,9};

In Antwort auf Ihre auch. Beide, obwohl der Compiler die meisten schweres Heben tut

Im Fall von statisch zugewiesenen Arrays „Das System“ wird der Compiler sein. Es wird den Speicher wie es wäre für jeden Stapel Variable reservieren.

Im Fall des malloc'd Array „Das System“ wird die Implementierer von malloc (den Kernel in der Regel). Alle der Compiler ist der Basiszeiger zuteilen wird.

Der Compiler wird immer die Art, wie zu handhaben, was sie deklariert ist, außer im Beispiel zu Carl gab, wo es austauschbar Nutzung herausfinden kann. Aus diesem Grund, wenn Sie in einem Pass [] [] auf eine Funktion muss davon ausgehen, dass es sich um eine statisch zugewiesene flach ist, wobei ** angenommen wird, Zeiger auf Zeiger sein.

Um ein bestimmte 2D-Zugriff Array die Speicherkarte für eine Array-Deklaration prüfen, wie im Code unten dargestellt:

    0  1
a[0]0  1
a[1]2  3

Um jedes Element zuzugreifen, seine ausreichend nur passieren, das Array Sie als Parameter an die Funktion interessiert sind. Dann verwenden Sie Offset für Spalte Zugriff jedes Element einzeln.

int a[2][2] ={{0,1},{2,3}};

void f1(int *ptr);

void f1(int *ptr)
{
    int a=0;
    int b=0;
    a=ptr[0];
    b=ptr[1];
    printf("%d\n",a);
    printf("%d\n",b);
}

int main()
{
   f1(a[0]);
   f1(a[1]);
    return 0;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top