Beheersing van pointers en multidimensionale arrays in C
In de C-taal is een array een verzameling waarden van hetzelfde type, opgeslagen op doorlopende geheugenlocaties. Elk element in een array (eendimensionaal of multidimensionaal) wordt geïdentificeerd door een of meer unieke gehele indices.
Een pointer daarentegen slaat het adres van een variabele op. Het adres van het nulde element in een array is de pointer van de array. U kunt de "dereference-operator" gebruiken om toegang te krijgen tot de waarde waarnaar een pointer verwijst.
U kunt een eendimensionale, tweedimensionale 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.
Aanwijzers en eendimensionale arrays
In een eendimensionale array wordt elk element geïdentificeerd door een enkel geheel getal:
int a[5] = {1, 2, 3, 4, 5};
Hier staat het getal "1" op de 0e index, "2" op index 1, enzovoort.
Een variabele die het adres van het 0e element opslaat, is de pointer −
int *x = &a[0];
Simpel gezegd verwijst de naam van de array ook naar het adres van het 0e element. Je kunt dus ook deze uitdrukking gebruiken −
int *x = a;
Voorbeeld
Omdat de waarde van de pointer toeneemt met de grootte van het gegevenstype, 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;
}
Uitvoer
Wanneer u deze code uitvoert, zal deze de volgende uitvoer produceren −
arr[0]: 1 arr[1]: 2 arr[2]: 3 arr[3]: 4 arr[4]: 5
Aanwijzers en tweedimensionale arrays
Als een eendimensionale array op een lijst met elementen lijkt, lijkt een tweedimensionale array op een tabel of een matrix.
De elementen in een 2D-array kunnen worden beschouwd als logisch gerangschikt in rijen en kolommen. Daarom wordt de locatie van elk element bepaald door twee indices:het rijnummer en het kolomnummer. Zowel de rij- als kolomindexen beginnen vanaf "0".
int arr[2][2];
Zo'n array wordt weergegeven als −
Opgemerkt kan worden dat de tabelindeling slechts een logische representatie is. De compiler wijst een blok van continue bytes toe. In C wordt de arraytoewijzing gedaan op een rij-majeur-manier, wat betekent dat de elementen rijsgewijs in de array worden ingelezen.
Hier declareren we een 2D-array met drie rijen en vier kolommen (het getal tussen de eerste vierkante haakjes 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 rijen volgorde toewijzen. Ervan uitgaande dat het eerste element van de array zich op adres 1000 bevindt en de grootte van het type "int" 4 bytes is, krijgen de elementen van de array de volgende toegewezen geheugenlocaties −
We zullen het adres van het eerste element van de array num aan de pointer ptr toewijzen met behulp van de operator &.
int *ptr = &arr[0][0];
Voorbeeld 1
Als de wijzer met 1 wordt verhoogd, gaat deze naar het volgende adres. Alle 12 elementen in de "34"-array zijn als volgt in een lus toegankelijk −
#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;
}
Uitvoer
Wanneer u deze code uitvoert, zal deze de volgende uitvoer produceren −
1 2 3 4 5 6 7 8 9 10 11 12
Over het algemeen wordt voor het adres van elk element van de array de volgende formule gebruikt −
add of element at ith row and jth col = baseAddress + [(i * no_of_cols + j) * sizeof(array_type)]
In onze 34-array
add of arr[2][4] = 1000 + (2*4 + 2)*4 = 1044
U kunt de bovenstaande afbeelding raadplegen en deze bevestigt dat het adres van "arr[3][4]" 1044 is.
Voorbeeld 2
Gebruik de dereferentiewijzer om de waarde op het adres op te halen. Laten we deze formule gebruiken om de array te doorkruisen met behulp van de aanwijzer −
#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;
}
Uitvoer
Wanneer u deze code uitvoert, zal deze de volgende uitvoer produceren −
1 2 3 4 5 6 7 8 9 10 11 12
Aanwijzers en driedimensionale arrays
Een driedimensionale array is een array van tweedimensionale arrays. Zo'n array wordt gedeclareerd met drie subscripts −
int arr [x] [y] [j];
Deze array kan worden beschouwd als een "x" aantal lagen met tabellen, waarbij elke tabel "x" rijen en "y" aantal kolommen heeft.
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 verwijzing naar de 3D-array kan worden gedeclareerd als −
int * ptr = &arr[0][0][0];
Wetende dat de naam van de array zelf het adres is van het 0e element, kunnen we de pointer van een 3D-array schrijven als −
int * ptr = arr;
Elke laag van "x" rijen en "y" kolommen beslaat −
x * y * sizeof(data_type)
Aantal bytes. Ervan uitgaande dat het geheugen dat is toegewezen aan de 3D-array "arr", zoals hierboven aangegeven, begint vanaf adres 1000, begint de tweede laag (met "i =1") op 1000 + (3 3) 4 =1036 bytepositie.
ptr = Base address of 3D array arr
Als JMAX het aantal rijen is en KMAX het aantal kolommen, dan is het adres van het element op de 0e rij en de 0e kolom van het eerste segment −
arr[1][0][0] = ptr + (1 * JMAX * KMAX)
De formule om de waarde van een element in de j-de rij en de k-de kolom van het i-de segment te verkrijgen, kan worden gegeven als −
arr[i][j][k] = *(ptr + (i * JMAX*KMAX) + (j*KMAX + k))
Voorbeeld:een 3D-array afdrukken met behulp van Pointer Dereferencing
Laten we deze formule gebruiken om de 3D-array af te drukken met behulp van de pointer-dereferentie −
#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;
}
Uitvoer
Wanneer u deze code uitvoert, zal deze de volgende uitvoer produceren −
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
Over het algemeen lijkt het benaderen van een array met een pointer sterk op het benaderen van een array met subscriptrepresentatie. Het belangrijkste verschil tussen de twee is dat de subscriptdeclaratie van een array het geheugen statisch toewijst, 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. Het gebruik van een subscripted array is echter handiger dan het gebruik van pointers, wat lastig kan zijn voor nieuwe leerlingen.
C Taal
- C# - Nullables
- Typen C++-variabelen
- C++ Opmerkingen
- C# Array-zelfstudie:maken, declareren, initialiseren
- C++-referenties
- C# if, if...else, if...else if en Nested if Statement
- C++ Meerdere, meerdere niveaus en hiërarchische overerving
- Verschil tussen C en C ++
- C++ Exception Handling:Try, Catch, Throw Voorbeeld
- C++-bestanden en -streams
- Bestandsafhandeling in C#:I/O-bewerkingen [voorbeelden]