logo

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èmeL'é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èmeTableau 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èmetableau 1-D, arrivée + 1 pointe vers le 1StTableau 1D et arrivée + 2 pointe vers le 2sdTableau 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èmeTableau 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èmeTableau 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èmeTableau 1D.
  • Depuis le type de base de *(arr + je) est int et il contient l'adresse de 0èmeélément de jeèmeTableau 1-D, nous pouvons obtenir les adresses des éléments suivants dans le ièmeTableau 1D en ajoutant des valeurs entières à *(arr + je) .
  • Par exemple *(arr + je) + 1 représentera l'adresse de 1Stélément de 1Stélément de jeèmeTableau 1D et *(arr+je)+2 représentera l'adresse de 2sdélément de jeèmeTableau 1D.
  • De même *(arr + i) + j représentera l'adresse de jèmeélément de jeèmeTableau 1D. En déréférençant cette expression, nous pouvons obtenir le jèmeélément du jeèmeTableau 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èmeTableau 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èmeTableau 2D et arr[i][j] représente l'adresse de base du jèmeTableau 1D.

Exemple

inconvénients d'Internet

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èmerangée. Sur le déréférencement ptr + je , nous obtenons l'adresse de base de ièmerangée. Pour accéder à l'adresse de jèmeélément de jeèmeligne, 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èmeligne et l'expression du pointeur *(*(ptr + i)+j) donne la valeur du jèmeélément de jeèmerangé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>