Pointers En Multidimensionale Arrays In C Meesteren
In de C-taal is een array een verzameling waarden van een gelijkaardig type opgeslagen in opeenvolgende geheugenlocaties. Elk element in een array (één-dimensionaal of multidimensionaal) wordt geïdentificeerd door een of meer unieke integer indices.
Een pointer daarentegen slaat het adres van een variabele op. Het adres van het 0-de element in een array is de pointer van de array. Je kunt de "dereference operator" gebruiken om de waarde te benaderen waar een pointer naar verwijst.
Je kunt een één-dimensionale, twee-dimensionale of multidimensionale array declareren in C. De term "dimensie" verwijst naar het aantal indices dat nodig is om een element in een verzameling te identificeren.
Pointers En Eén-Dimensionale Arrays
In een één-dimensionaal array wordt elk element geïdentificeerd door een enkele integer:
int a[5] = {1, 2, 3, 4, 5};
Hier staat het getal "1" op de 0-de index, "2" op index 1, en zo verder.
Een variabele die het adres van het 0-de element opslaat is zijn pointer:
int *x = &a[0];
Eenvoudigweg wijst de naam van de array ook naar het adres van het 0-de element. Dus je kunt ook deze expressie gebruiken:
int *x = a;
Voorbeeld
Omdat de waarde van de pointer incrementeert met de grootte van het datatype, verplaatst "x++" de pointer naar het volgende element in de 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;
}
Output
Wanneer je deze code runt, produceert het de volgende output:
arr[0]: 1 arr[1]: 2 arr[2]: 3 arr[3]: 4 arr[4]: 5
Pointers En Twee-Dimensionale Arrays
Als een één-dimensionaal array lijkt op een lijst van elementen, is een twee-dimensionaal array als een tabel of matrix.
De elementen in een 2D array kunnen logisch gerangschikt worden in rijen en kolommen. Daarom wordt de locatie van elk element bepaald door twee indices, het rijnummer en het kolomnummer. Zowel rij- als kolomindices beginnen bij "0".
int arr[2][2];
Zo'n array wordt weergegeven als:
| Kol0 | Kol1 | Kol2 | |
|---|---|---|---|
| Rij0 | arr[0][0] | arr[0][1] | arr[0][2] |
| Rij1 | arr[1][0] | arr[1][1] | arr[1][2] |
| Rij2 | arr[2][0] | arr[2][1] | arr[2][2] |
Het is goed om te noteren dat de tabelvormige rangschikking slechts een logische weergave is. De compiler reserveert een blok van opeenvolgende bytes. In C wordt de array-allocatie in een row-major manier gedaan, wat betekent dat de elementen rij-gewijs in de array worden ingelezen.
Hier declareren we een 2D array met drie rijen en vier kolommen (het getal in de eerste haak verwijst altijd naar het aantal rijen) als:
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
De compiler zal het geheugen voor de bovenstaande 2D array in een rij-gewijs volgorde alloceren. Aannemend dat het eerste element van de array op adres 1000 staat en de grootte van type "int" 4 bytes is, krijgen de elementen van de array de volgende toegewezen geheugenlocaties:
| Rij 0 | Rij 1 | Rij 2 | |
|---|---|---|---|
| Waarde | 1 2 3 4 | 5 6 7 8 | 9 10 11 12 |
| Adres | 1000 1004 1008 1012 | 1016 1020 1024 1028 | 1032 1036 1040 1044 |
We wijzen het adres van het eerste element van de array num toe aan de pointer ptr met behulp van de address-of & operator.
int *ptr = &arr[0][0];
Voorbeeld 1
Als de pointer met 1 wordt geïncrementeerd, beweegt het naar het volgende adres. Alle 12 elementen in de "3x4" array kunnen in een lus als volgt worden benaderd:
#include <stdio.h>
int main(){
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
};
// pointer ptr wijst naar array num
int *ptr = &arr[0][0];
int i, j, k = 0;
// print de elementen van de 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;
}
Output
Wanneer je deze code runt, produceert het de volgende output:
1 2 3 4 5 6 7 8 9 10 11 12
In het algemeen kan het adres van elk element van de array met behulp van de volgende formule worden verkregen:
adres van element op i-de rij en j-de kol = basisAdres + [(i * aantal_kolommen + j) * sizeof(array_type)]
In onze 3x4 array:
adres van arr[2][2] = 1000 + (2*4 + 2)*4 = 1044
Je kunt naar de bovenstaande tabel verwijzen en het bevestigt dat het adres van "arr[2][2]" 1044 is.
Voorbeeld 2
Gebruik de dereference pointer om de waarde op het adres op te halen. Laten we deze formule gebruiken om de array te doorlopen met behulp van zijn pointer:
#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 het element van de 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;
}
Output
Wanneer je deze code runt, produceert het de volgende output:
1 2 3 4 5 6 7 8 9 10 11 12
Pointers En Drie-Dimensionale Arrays
Een drie-dimensionale array is een array van twee-dimensionale arrays. Zo'n array wordt gedeclareerd met drie subscripts:
int arr[x][y][j];
Deze array kan beschouwd worden als "x" aantal lagen van tabellen, elke tabel met "x" rijen en "y" aantal kolommen.
Een voorbeeld van een 3D array is:
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} },
};
Een pointer naar de 3D array kan gedeclareerd worden als:
int *ptr = &arr[0][0][0];
Wetende dat de naam van de array zelf het adres is van het 0-de element, kunnen we de pointer van een 3D array schrijven als:
int *ptr = arr;
Elke laag van "x" rijen en "y" kolommen neemt in beslag:
x * y * sizeof(data_type)
Aantal bytes. Aannemend dat het geheugen toegewezen aan de 3D array "arr" zoals hierboven gedeclareerd begint op adres 1000, begint de tweede laag (met "i = 1") op 1000 + (3 * 3) * 4 = 1036 byte positie.
ptr = Basisadres van 3D array arr
Als JMAX het aantal rijen is en KMAX het aantal kolommen, dan is het adres van het element op de 0-de rij en 0-de kolom van de 1e slice:
arr[1][0][0] = ptr + (1 * JMAX * KMAX)
De formule om de waarde van een element op de j-de rij en k-de kolom van de i-de slice te verkrijgen kan gegeven worden als:
arr[i][j][k] = *(ptr + (i * JMAX*KMAX) + (j*KMAX + k))
Voorbeeld: Een 3D Array Printen Met Pointer Dereferencing
Laten we deze formule gebruiken om de 3D array te printen met behulp van pointer dereferencing:
#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;
}
Output
Wanneer je deze code runt, produceert het de volgende output:
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
In het algemeen is het benaderen van een array met een pointer vrij vergelijkbaar met het benaderen van een array met subscript notatie. Het belangrijkste verschil tussen de twee is dat de subscripted declaratie van een array het geheugen statisch alloceert, terwijl we pointers kunnen gebruiken voor dynamische geheugentoewijzing.
Om een multidimensionale array aan een functie door te geven, moet je pointers gebruiken in plaats van subscripts. Echter, het gebruik van een subscripted array is gemakkelijker dan het gebruik van pointers, wat voor nieuwe leerders lastig kan zijn.
C Taal
- Arrays doorgeven aan functies in C++: een praktische gids
- C++ break statement: loop controle onder de knie
- C++ Programmeerbasics: Wat is C++ en Waarom Het Ertoe Doet
- Data Abstractie in C++ Beheersen: Ontwerp Vereenvoudigen met Interface-Implementatie Scheiding
- Efficiënt geheugengebruik met C-bitvelden
- C++ Class Templates Beheersen: Een Praktische Gids
- C++ Switch‑Case Onder de Knie: Syntaxis, Gebruik en Praktische Voorbeelden
- C++ Overervingsmodellen: Meervoudig, Multilevel, Hiërarchisch
- PowerShell Beheersen: Beginnersgids voor Krachtig Scripten
- C# Multidimensionale Arrays: 2D Arrays Uitgelegd met Codevoorbeelden
- C Typecasting: Impliciete en Expliciete Conversies Beheersen met Codevoorbeelden