Beherrschen von Zeigern und mehrdimensionalen Arrays in C
In der Sprache C ist ein Array eine Sammlung von Werten ähnlichen Typs, die an fortlaufenden Speicherorten gespeichert sind. Jedes Element in einem Array (eindimensional oder mehrdimensional) wird durch einen oder mehrere eindeutige Ganzzahlindizes identifiziert.
Ein Zeiger hingegen speichert die Adresse einer Variablen. Die Adresse des 0. Elements in einem Array ist der Zeiger des Arrays. Sie können den „Dereferenzierungsoperator“ verwenden, um auf den Wert zuzugreifen, auf den ein Zeiger verweist.
Sie können in C ein eindimensionales, zweidimensionales oder mehrdimensionales Array deklarieren. Der Begriff „Dimension“ bezieht sich auf die Anzahl der Indizes, die erforderlich sind, um ein Element in einer Sammlung zu identifizieren.
Zeiger und eindimensionale Arrays
In einem eindimensionalen Array wird jedes Element durch eine einzelne Ganzzahl identifiziert:
int a[5] = {1, 2, 3, 4, 5};
Hier steht die Zahl „1“ am 0. Index, „2“ am Index 1 usw.
Eine Variable, die die Adresse des 0. Elements speichert, ist sein Zeiger −
int *x = &a[0];
Der Name des Arrays verweist einfach auch auf die Adresse des 0. Elements. Sie können also auch diesen Ausdruck verwenden:−
int *x = a;
Beispiel
Da der Wert des Zeigers um die Größe des Datentyps erhöht wird, verschiebt „x++“ den Zeiger auf das nächste Element im Array.
#include <stdio.h>
int main(){
int arr[] = {1, 2, 3, 4, 5};
int length = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int *ptr = arr;
while (i < length){
printf("arr[%d]: %d \n", i, *(ptr + i));
i++;
}
return 0;
}
Ausgabe
Wenn Sie diesen Code ausführen, wird die folgende Ausgabe erzeugt:
arr[0]: 1 arr[1]: 2 arr[2]: 3 arr[3]: 4 arr[4]: 5
Zeiger und zweidimensionale Arrays
Wenn ein eindimensionales Array wie eine Liste von Elementen ist, ähnelt ein zweidimensionales Array einer Tabelle oder einer Matrix.
Man kann davon ausgehen, dass die Elemente in einem 2D-Array logisch in Zeilen und Spalten angeordnet sind. Daher wird die Position eines Elements durch zwei Indizes bestimmt, seine Zeilennummer und seine Spaltennummer. Sowohl Zeilen- als auch Spaltenindizes beginnen bei „0“.
int arr[2][2];
Ein solches Array wird als −
dargestelltEs ist zu beachten, dass es sich bei der tabellarischen Anordnung lediglich um eine logische Darstellung handelt. Der Compiler weist einen Block fortlaufender Bytes zu. In C erfolgt die Array-Zuweisung zeilenweise, was bedeutet, dass die Elemente zeilenweise in das Array eingelesen werden.
Hier deklarieren wir ein 2D-Array mit drei Zeilen und vier Spalten (die Zahl in der ersten eckigen Klammer bezieht sich immer auf die Anzahl der Zeilen) als −
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
Der Compiler weist den Speicher für das obige 2D-Array in zeilenweiser Reihenfolge zu. Unter der Annahme, dass sich das erste Element des Arrays an der Adresse 1000 befindet und die Größe des Typs „int“ 4 Bytes beträgt, erhalten die Elemente des Arrays die folgenden zugewiesenen Speicherplätze −
Wir weisen dem Zeiger ptr die Adresse des ersten Elements des Arrays num zu, indem wir den Adressenoperator &verwenden.
int *ptr = &arr[0][0];
Beispiel 1
Wenn der Zeiger um 1 erhöht wird, bewegt er sich zur nächsten Adresse. Auf alle 12 Elemente im Array „34“ kann in einer Schleife wie folgt zugegriffen werden −
#include <stdio.h>
int main(){
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
};
// pointer ptr pointing at array num
int *ptr = &arr[0][0];
int i, j, k = 0;
// print the elements of the array num via pointer ptr
for (i = 0; i < 3; i++){
for (j = 0; j < 4; j++){
printf("%d ", *(ptr + k));
k++;
}
printf("\n");
}
return 0;
}
Ausgabe
Wenn Sie diesen Code ausführen, wird die folgende Ausgabe erzeugt:
1 2 3 4 5 6 7 8 9 10 11 12
Im Allgemeinen kann die Adresse eines beliebigen Elements des Arrays mithilfe der folgenden Formel ermittelt werden:−
add of element at ith row and jth col = baseAddress + [(i * no_of_cols + j) * sizeof(array_type)]
In unserem 34-Array,
add of arr[2][4] = 1000 + (2*4 + 2)*4 = 1044
Sie können sich auf die obige Abbildung beziehen und sie bestätigt, dass die Adresse von „arr[3][4]“ 1044 ist.
Beispiel 2
Verwenden Sie den Dereferenzierungszeiger, um den Wert an der Adresse abzurufen. Lassen Sie uns diese Formel verwenden, um das Array mit Hilfe seines Zeigers −
zu durchlaufen
#include <stdio.h>
int main(){
// 2d array
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int ROWS = 3, COLS = 4;
int i, j;
// pointer
int *ptr = &arr[0][0];
// print the element of the array via pointer ptr
for (i = 0; i < ROWS; i++){
for (j = 0; j < COLS; j++) {
printf("%4d ",*(ptr + (i * COLS + j)));
}
printf("\n");
}
return 0;
}
Ausgabe
Wenn Sie diesen Code ausführen, wird die folgende Ausgabe erzeugt:
1 2 3 4 5 6 7 8 9 10 11 12
Zeiger und dreidimensionale Arrays
Ein dreidimensionales Array ist ein Array aus zweidimensionalen Arrays. Ein solches Array wird mit drei Indizes −
deklariertint arr [x] [y] [j];
Dieses Array kann als „x“ Anzahl von Tabellenebenen betrachtet werden, wobei jede Tabelle „x“ Zeilen und „y“ Anzahl Spalten hat.
Ein Beispiel für ein 3D-Array ist −
int arr[3][3][3] ={
{ {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
{ {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
{ {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};
Ein Zeiger auf das 3D-Array kann als −
deklariert werdenint * ptr = &arr[0][0][0];
Wenn wir wissen, dass der Name des Arrays selbst die Adresse des 0. Elements ist, können wir den Zeiger eines 3D-Arrays als −
schreibenint * ptr = arr;
Jede Schicht aus „x“-Zeilen und „y“-Spalten belegt −
x * y * sizeof(data_type)
Anzahl der Bytes. Unter der Annahme, dass der dem 3D-Array „arr“ wie oben deklariert zugewiesene Speicher bei der Adresse 1000 beginnt, beginnt die zweite Schicht (mit „i =1“) bei 1000 + (3 3) 4 =1036 Byte-Position.
ptr = Base address of 3D array arr
Wenn JMAX die Anzahl der Zeilen und KMAX die Anzahl der Spalten ist, dann ist die Adresse des Elements in der 0. Zeile und der 0. Spalte des 1. Slice −
arr[1][0][0] = ptr + (1 * JMAX * KMAX)
Die Formel zum Erhalten des Werts eines Elements in der j-ten Zeile und der k-ten Spalte des i-ten Slice kann als −
angegeben werdenarr[i][j][k] = *(ptr + (i * JMAX*KMAX) + (j*KMAX + k))
Beispiel:Drucken eines 3D-Arrays mithilfe der Zeiger-Dereferenzierung
Lassen Sie uns diese Formel verwenden, um das 3D-Array mit Hilfe der Zeiger-Dereferenzierung −
zu drucken
#include <stdio.h>
int main(){
int i, j, k;
int arr[3][3][3] = {
{ {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
{ {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
{ {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};
int JMAX = 3, KMAX = 3;
int *ptr = arr; // &arr[0][0][0];
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
for(k = 0; k < 3; k++){
printf("%d ",*(ptr+(i*JMAX*KMAX)+(j*KMAX+k)));
}
printf("\n");
}
printf("\n");
}
return 0;
}
Ausgabe
Wenn Sie diesen Code ausführen, wird die folgende Ausgabe erzeugt:
11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 31 32 33 34 35 36 37 38 39
Im Allgemeinen ähnelt der Zugriff auf ein Array mit einem Zeiger dem Zugriff auf ein Array mit Indexdarstellung. Der Hauptunterschied zwischen den beiden besteht darin, dass die tiefgestellte Deklaration eines Arrays den Speicher statisch zuweist, während wir Zeiger für die dynamische Speicherzuweisung verwenden können.
Um ein mehrdimensionales Array an eine Funktion zu übergeben, müssen Sie Zeiger anstelle von Indizes verwenden. Allerdings ist die Verwendung eines indizierten Arrays praktischer als die Verwendung von Zeigern, was für neue Lernende schwierig sein kann.
C Sprache