logo

Punter a una matriu | Apuntador de matriu

Prerequisit: Introducció de punters

Considereu el programa següent:



C






#include> int> main()> {> >int> arr[5] = { 1, 2, 3, 4, 5 };> >int> *ptr = arr;> >printf>(>'%p '>, ptr);> >return> 0;> }>



>

>

En el programa anterior, tenim un punter ptr que apunta al 0thelement de la matriu. De la mateixa manera, també podem declarar un punter que pot apuntar a tota la matriu en lloc d'un sol element de la matriu. Aquest punter és útil quan es parla de matrius multidimensionals.

Sintaxi:

data_type  (* var_name ) [size_of_array];>

Aquí:

    data_type és el tipus de dades que conté la matriu. nom_var és el nom de la variable punter. size_of_array és la mida de la matriu a la qual apuntarà el punter.

Exemple

int (*ptr)[10];>

Aquí ptr és un punter que pot apuntar a una matriu de 10 nombres enters. Com que els subíndexs tenen una prioritat més alta que la indirecta, cal incloure l'operador d'indirecció i el nom del punter entre parèntesis. Aquí el tipus de ptr és 'punter a una matriu de 10 nombres enters'.

Nota: el punter que apunta al 0thelement de matriu i el punter que apunta a tota la matriu són totalment diferents. El programa següent ho mostra:

C




// C program to understand difference between> // pointer to an integer and pointer to an> // array of integers.> #include> int> main()> {> >// Pointer to an integer> >int> *p;> > >// Pointer to an array of 5 integers> >int> (*ptr)[5];> >int> arr[5];> > >// Points to 0th element of the arr.> >p = arr;> > >// Points to the whole array arr.> >ptr = &arr;> > >printf>(>'p = %p, ptr = %p '>, p, ptr);> > >p++;> >ptr++;> > >printf>(>'p = %p, ptr = %p '>, p, ptr);> > >return> 0;> }>

>

>

Sortida

p = 0x7fff6463e890, ptr = 0x7fff6463e890 p = 0x7fff6463e894, ptr = 0x7fff6463e8a4>

Aquí, pàg és el punter a 0thelement de la matriu arr , mentre ptr és un punter que apunta a tota la matriu arr .

  • El tipus base de pàg és int mentre que el tipus base de ptr és 'una matriu de 5 nombres enters'.
  • Sabem que l'aritmètica del punter es realitza en relació amb la mida base, de manera que si escrivim ptr++, aleshores el punter ptr es desplaçarà cap endavant 20 bytes.

La figura següent mostra el punter p i ptr. La fletxa més fosca indica un punter a una matriu.

En desreferenciar una expressió de punter, obtenim un valor al qual apunta aquesta expressió de punter. El punter a una matriu apunta a una matriu, de manera que en desreferenciar-la, hauríem d'obtenir la matriu i el nom de la matriu denota l'adreça base. Així, cada vegada que un punter a una matriu és desreferenciat, obtenim l'adreça base de la matriu a la qual apunta.

C




// C program to illustrate sizes of> // pointer of array> #include> int> main()> {> >int> arr[] = { 3, 5, 6, 7, 9 };> >int> *p = arr;> >int> (*ptr)[5] = &arr;> > >printf>(>'p = %p, ptr = %p '>, p, ptr);> >printf>(>'*p = %d, *ptr = %p '>, *p, *ptr);> > >printf>(>'sizeof(p) = %lu, sizeof(*p) = %lu '>,> >sizeof>(p),>sizeof>(*p));> >printf>(>'sizeof(ptr) = %lu, sizeof(*ptr) = %lu '>,> >sizeof>(ptr),>sizeof>(*ptr));> >return> 0;> }>

>

>

Sortida

p = 0x7fff55adbff0, ptr = 0x7fff55adbff0 *p = 3, *ptr = 0x7fff55adbff0 sizeof(p) = 8, sizeof(*p) = 4 sizeof(ptr) = 8, sizeof(*ptr) = 20>

Punter a matrius multidimensionals

1. Punters i matrius bidimensionals

En una matriu bidimensional, podem accedir a cada element mitjançant dos subíndexs, on el primer subíndex representa el número de fila i el segon subíndex representa el número de columna. També es pot accedir als elements de la matriu 2D amb l'ajuda de la notació de punter. Suposem que arr és una matriu 2-D, podem accedir a qualsevol element arr[i][j] de la matriu utilitzant l'expressió de punter *(*(arr + i) + j) . Ara veurem com es pot derivar aquesta expressió.
Prenem una matriu bidimensional arr[3][4] :

int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };>

Com que la memòria d'un ordinador està organitzada de manera lineal, no és possible emmagatzemar la matriu 2-D en files i columnes. El concepte de files i columnes és només teòric, de fet, una matriu 2-D s'emmagatzema en l'ordre principal de les files, és a dir, les files es col·loquen una al costat de l'altra. La figura següent mostra com s'emmagatzemarà la matriu 2-D anterior a la memòria.

Cada fila es pot considerar com una matriu 1-D, de manera que una matriu bidimensional es pot considerar com una col·lecció de matrius unidimensionals que es col·loquen una darrere l'altra. En altres paraules, podem dir que les matrius dimensionals 2-D que es col·loquen una darrere l'altra. Així que aquí arr és una matriu de 3 elements on cada element és una matriu 1-D de 4 nombres enters.
Sabem que el nom d'una matriu és un punter constant que apunta a 0thMatriu 1-D i conté l'adreça 5000. Des de arr és un 'punter a una matriu de 4 nombres enters', segons l'aritmètica del punter, l'expressió arr + 1 representarà l'adreça 5016 i l'expressió arr + 2 representarà l'adreça 5032.
Així ho podem dir arr apunta al 0thmatriu 1-D, arr + 1 apunta a l'1stmatriu 1-D i arr + 2 apunta al 2ndMatriu 1-D.

En general podem escriure:

 arr + i Points to ith element of arr ->Apunta a la matriu 1-D>>> 
  • Com que arr + i apunta a ithelement de arr , en desreferenciar-lo obtindrà ithelement de arr que és, per descomptat, una matriu 1-D. Així l'expressió *(arr + i) ens dóna l'adreça base de ithMatriu 1-D.
  • Ho sabem, l'expressió del punter *(arr + i) és equivalent a l'expressió de subíndex arr[i] . Tan *(arr + i) que és el mateix que arr[i] ens dóna l'adreça base de ithMatriu 1-D.
  • Per accedir a un element individual de la nostra matriu 2-D, hauríem de poder accedir a qualsevol jthelement de ithMatriu 1-D.
  • Atès que el tipus base de *(arr + i) és int i conté l'adreça 0thelement de ithMatriu 1-D, podem obtenir les adreces dels elements posteriors al fitxer ithMatriu 1-D afegint valors enters a *(arr + i) .
  • Per exemple *(arr + i) + 1 representarà l'adreça de 1stelement de 1stelement de ithmatriu 1-D i *(arr+i)+2 representarà l'adreça de 2ndelement de ithMatriu 1-D.
  • De la mateixa manera *(arr + i) + j representarà l'adreça de jthelement de ithMatriu 1-D. En desreferenciar aquesta expressió podem obtenir la jthelement de la ithMatriu 1-D.

Punters i matrius tridimensionals

arr es pot considerar com una matriu formada per dos elements on cada element és una matriu 2-D. El nom de la matriu arr és un punter al 0thMatriu 2-D.

Així l'expressió del punter *(*(*(arr + i ) + j ) + k) és equivalent a l'expressió de subíndex arr[i][j][k].
Sabem que l'expressió *(arr + i) és equivalent a arr[i] i l'expressió *(*(arr + i) + j) és equivalent a arr[i][j]. Així que podem dir que arr[i] representa l'adreça base de ithMatriu 2-D i arr[i][j] representa l'adreça base de la jthMatriu 1-D.

Exemple

desactivar el mode de desenvolupador d'Android

L'exemple següent mostra el programa per imprimir elements de matriu 3D mitjançant punters.

C




// C program to print the elements of 3-D> // array using pointer notation> #include> int> main()> {> >int> arr[2][3][2] = {> >{> >{5, 10},> >{6, 11},> >{7, 12},> >},> >{> >{20, 30},> >{21, 31},> >{22, 32},> >}> >};> >int> i, j, k;> >for> (i = 0; i <2; i++)> >{> >for> (j = 0; j <3; j++)> >{> >for> (k = 0; k <2; k++)> >printf>(>'%d '>, *(*(*(arr + i) + j) +k));> >printf>(>' '>);> >}> >}> >return> 0;> }>

>

>

Sortida

5 10 6 11 7 12 20 30 21 31 22 32>

La figura següent mostra com s'emmagatzema a la memòria la matriu 3D utilitzada al programa anterior.

Subscripting punter a una matriu

Suposem arr és una matriu 2-D amb 3 files i 4 columnes i ptr és un punter a una matriu de 4 nombres enters, i ptr conté l'adreça base de la matriu arr .

int arr[3][4] = {{10, 11, 12, 13}, {20, 21, 22, 23}, {30, 31, 32, 33}}; int (*ptr)[4]; ptr = arr;>

Des de ptr és un punter a la matriu 2-D de la primera fila, és a dir, una matriu de 4 nombres enters, ptr + i assenyalarà ithfila. Sobre la desreferenciació ptr + i , obtenim l'adreça base de ithfila. Per accedir a l'adreça de jthelement de ithfila podem afegir j a l'expressió del punter *(ptr + i) . Per tant, l'expressió del punter *(ptr + i) + j dóna l'adreça de jthelement de ithfila i l'expressió del punter *(*(ptr + i)+j) dóna el valor de la jthelement de ithfila.
Sabem que l'expressió de punter *(*(ptr + i) + j) és equivalent a l'expressió de subíndex ptr[i][j]. Així, si tenim una variable de punter que conté l'adreça base de la matriu 2-D, podem accedir als elements de la matriu fent doble subíndex d'aquesta variable de punter.

Exemple

C




// C program to print elements of a 2-D array> // by scripting a pointer to an array> #include> int> main()> {> >int> arr[3][4] = {> >{10, 11, 12, 13},> >{20, 21, 22, 23},> >{30, 31, 32, 33}> >};> >int> (*ptr)[4];> >ptr = arr;> >printf>(>'%p %p %p '>, ptr, ptr + 1, ptr + 2);> >printf>(>'%p %p %p '>, *ptr, *(ptr + 1), *(ptr + 2));> >printf>(>'%d %d %d '>, **ptr, *(*(ptr + 1) + 2), *(*(ptr + 2) + 3));> >printf>(>'%d %d %d '>, ptr[0][0], ptr[1][2], ptr[2][3]);> >return> 0;> }>

>

>

Sortida

0x7ffc9556b790 0x7ffc9556b7a0 0x7ffc9556b7b0 0x7ffc9556b790 0x7ffc9556b7a0 0x7ffc9556b7b0 10 22 33 10 22 33>