Pointeur vers un tableau | Pointeur de tableau

Pointeur vers un tableau | Pointeur de tableau

Prérequis : Introduction aux pointeurs

Considérons le programme suivant :

C




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

Dans le programme ci-dessus, nous avons un pointeur ptr qui pointe vers le 0 ème élément du tableau. De même, nous pouvons également déclarer un pointeur pouvant pointer vers l’ensemble du tableau au lieu d’un seul élément du tableau. Ce pointeur est utile lorsqu’on parle de tableaux multidimensionnels.

Syntaxe:

data_type  (* var_name ) [size_of_array]; 

Ici:

    data_type est le type de données contenues dans le tableau. var_name est le nom de la variable pointeur. size_of_array est la taille du tableau vers lequel pointe le pointeur.

Exemple

int (*ptr)[10]; 

Ici ptr est un pointeur qui peut pointer vers un tableau de 10 entiers. Étant donné que l'indice a une priorité plus élevée que l'indirection, il est nécessaire de mettre l'opérateur d'indirection et le nom du pointeur entre parenthèses. Ici, le type de ptr est « pointeur vers un tableau de 10 entiers ».

Remarque : Le pointeur qui pointe vers le 0 ème L'élément du tableau et le pointeur qui pointe vers l'ensemble du tableau sont totalement différents. Le programme suivant le montre :

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;> }>

Sortir

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

Ici, p est un pointeur vers 0 ème élément du tableau arr , alors que ptr est un pointeur qui pointe vers l'ensemble du tableau arr .

  • Le type de base de p est un entier alors que le type de base de ptr est « un tableau de 5 entiers ».
  • Nous savons que l’arithmétique du pointeur est effectuée par rapport à la taille de base, donc si nous écrivons ptr++, alors le pointeur ptr sera décalé de 20 octets.

La figure suivante montre les pointeurs p et ptr. La flèche la plus sombre désigne un pointeur vers un tableau.

En déréférençant une expression de pointeur, nous obtenons une valeur pointée par cette expression de pointeur. Le pointeur vers un tableau pointe vers un tableau, donc en le déréférençant, nous devrions obtenir le tableau, et le nom du tableau indique l'adresse de base. Ainsi, chaque fois qu'un pointeur vers un tableau est déréférencé, nous obtenons l'adresse de base du tableau vers lequel il pointe.

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;> }>

Sortir

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

Pointeur vers des tableaux multidimensionnels

1. Pointeurs et tableaux bidimensionnels

Dans un tableau bidimensionnel, nous pouvons accéder à chaque élément en utilisant deux indices, le premier indice représentant le numéro de ligne et le deuxième indice représentant le numéro de colonne. Les éléments du tableau 2D sont également accessibles à l'aide de la notation du pointeur. Supposons que arr soit un tableau 2D, nous pouvons accéder à n'importe quel élément arr[i][j] du tableau en utilisant l'expression de pointeur *(*(arr + i) + j) . Nous allons maintenant voir comment cette expression peut être dérivée.
Prenons un tableau à deux dimensions arr[3][4] :

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

Étant donné que la mémoire d'un ordinateur est organisée de manière linéaire, il n'est pas possible de stocker le tableau 2D en lignes et en colonnes. Le concept de lignes et de colonnes n'est que théorique. En fait, un tableau 2D est stocké dans l'ordre des lignes principales, c'est-à-dire que les lignes sont placées les unes à côté des autres. La figure suivante montre comment le tableau 2D ci-dessus sera stocké en mémoire.

Chaque ligne peut être considérée comme un tableau 1D, de sorte qu'un tableau bidimensionnel peut être considéré comme une collection de tableaux unidimensionnels placés les uns après les autres. En d’autres termes, nous pouvons dire que des tableaux bidimensionnels sont placés les uns après les autres. Alors ici arr est un tableau de 3 éléments où chaque élément est un tableau 1D de 4 entiers.
Nous savons que le nom d'un tableau est un pointeur constant qui pointe vers 0 ème Tableau 1-D et contient l'adresse 5000. Depuis arr est un « pointeur vers un tableau de 4 entiers », selon l’arithmétique du pointeur, l’expression arr + 1 représentera l’adresse 5016 et l’expression arr + 2 représentera l’adresse 5032.
On peut donc dire que arr pointe vers le 0 ème tableau 1-D, arrivée + 1 pointe vers le 1 St Tableau 1D et arrivée + 2 pointe vers le 2 sd Tableau 1D.

En général on peut écrire :

 arr + i Points to ith element of arr ->Pointe vers le tableau 1-D 
  • Puisque arr + i pointe vers i ème élément de arr , en déréférençant, j'obtiendrai ème élément de arr qui est bien sûr un tableau 1D. Ainsi l'expression *(arr + je) nous donne l'adresse de base de moi ème Tableau 1D.
  • Nous savons, l'expression du pointeur *(arr + je) est équivalent à l'expression en indice arr[je] . Donc *(arr + je) ce qui est identique à arr[je] nous donne l'adresse de base de moi ème Tableau 1D.
  • Pour accéder à un élément individuel de notre tableau 2D, nous devrions pouvoir accéder à n'importe quel j ème élément de je ème Tableau 1D.
  • Depuis le type de base de *(arr + je) est int et il contient l'adresse de 0 ème élément de je ème Tableau 1-D, nous pouvons obtenir les adresses des éléments suivants dans le i ème Tableau 1D en ajoutant des valeurs entières à *(arr + je) .
  • Par exemple *(arr + je) + 1 représentera l'adresse de 1 St élément de 1 St élément de je ème Tableau 1D et *(arr+je)+2 représentera l'adresse de 2 sd élément de je ème Tableau 1D.
  • De même *(arr + i) + j représentera l'adresse de j ème élément de je ème Tableau 1D. En déréférençant cette expression, nous pouvons obtenir le j ème élément du je ème Tableau 1D.

Pointeurs et tableaux tridimensionnels

int arr[2][3][2] = { {{5, 10}, {6, 11}, {7, 12}}, {{20, 30}, {21, 31}, {22, 32}} }; 

Dans un tableau tridimensionnel, nous pouvons accéder à chaque élément en utilisant trois indices. Prenons un tableau 3D. Nous pouvons considérer un tableau tridimensionnel comme un tableau de tableau 2D, c'est-à-dire que chaque élément d'un tableau 3D est considéré comme un tableau 2D. Le tableau 3D arr peut être considéré comme un tableau composé de deux éléments où chaque élément est un tableau 2D. Le nom du tableau arr est un pointeur vers le 0 ème Tableau 2D.

Ainsi l'expression du pointeur *(*(*(arr + i ) + j ) + k) est équivalent à l'expression d'indice arr[i][j][k].
Nous savons que l'expression *(arr + i) est équivalente à arr[i] et l'expression *(*(arr + i) + j) est équivalente à arr[i][j]. On peut donc dire que arr[i] représente l'adresse de base de i ème Tableau 2D et arr[i][j] représente l'adresse de base du j ème Tableau 1D.

Exemple

L'exemple ci-dessous montre le programme permettant d'imprimer des éléments d'un tableau 3D à l'aide de pointeurs.

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;> }>

Sortir

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

La figure suivante montre comment le tableau 3D utilisé dans le programme ci-dessus est stocké en mémoire.

Pointeur d'abonnement vers un tableau

Supposer arr est un tableau 2D avec 3 lignes et 4 colonnes et ptr est un pointeur vers un tableau de 4 entiers, et ptr contient l'adresse de base du tableau arr .

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

Depuis ptr est un pointeur vers le tableau 2D de la première ligne, c'est-à-dire un tableau de 4 entiers, ptr + je je vais me montrer ème rangée. Sur le déréférencement ptr + je , nous obtenons l'adresse de base de i ème rangée. Pour accéder à l'adresse de j ème élément de je ème ligne, nous pouvons ajouter j à l'expression du pointeur *(ptr + i) . Donc l'expression du pointeur *(ptr + je) + j donne l'adresse de j ème élément de je ème ligne et l'expression du pointeur *(*(ptr + i)+j) donne la valeur du j ème élément de je ème rangée.
Nous savons que l'expression du pointeur *(*(ptr + i) + j) est équivalente à l'expression d'indice ptr[i][j]. Ainsi, si nous avons une variable de pointeur contenant l'adresse de base du tableau 2D, nous pouvons alors accéder aux éléments du tableau en inscrivant deux fois cette variable de pointeur.

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;> }>

Sortir

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