Pointeurs et tableaux en langage C
Lorsqu'un tableau est déclaré, le compilateur alloue une quantité de mémoire suffisante pour contenir tous les éléments du tableau. L'adresse de base, c'est-à-dire l'adresse du premier élément du tableau, est également attribuée par le compilateur.
Supposons que nous déclarions un tableau,
int Tab[4]= {3,2,7,9};
En supposant que l'adresse de base de tab soit 2000 et que chaque entier nécessite deux octets, les quatre éléments seront stockés comme suit:
Ici, la variable Tab donnera l'adresse de base, qui est un pointeur constant pointant vers le premier élément du tableau, Tab [0]. Ainsi, Tab contient l'adresse de Tab [0] c'est-à-dire 2000. En bref, Tab a deux objectifs: il s'agit du nom du tableau et il agit comme un pointeur pointant vers le premier élément du tableau.
Nous pouvons également déclarer un pointeur de type int pour pointer vers le tableau Tab.
int Tab[4]= {3,2,7,9}; int *p; p = Tab; // ou p = &Tab[0]; les deux déclarations sont équivalentes.
Nous pouvons maintenant accéder à chaque élément du tableau Tab en utilisant p++ pour passer d'un élément à un autre.
Pointeur vers un tableau (1D)
Comme nous l'avons vu précédemment, nous pouvons utiliser un pointeur pour pointer sur un tableau, puis utiliser ce pointeur pour accéder aux éléments du tableau.
Exemple 1 :
#include < stdio.h> int main(void){ int Tab[4] = {3, 2, 7, 9}, i; int *p; p = Tab; for (i = 0; i < 4; i++){ printf("%d \n", *p); p++; } return 0; }
2
7
9
Dans le programme ci-dessus, le pointeur *p affichera une par une toutes les valeurs stockées dans le tableau. Nous pouvons également utiliser l'adresse de base (Tab dans le cas précédent) pour agir en tant que pointeur et afficher toutes les valeurs, comme dans l'exemple suivant.
Exemple 2 :
#include < stdio.h> int main(void){ int Tab[4] = {3, 2, 7, 9}, i; int *p; p = Tab; for (i = 0; i < 4; i++){ printf("%d \n", *(Tab + i)); } return 0; }
2
7
9
La forme généralisée pour utiliser un pointeur avec un tableau,
*(Tab+i)
Est identique à:
Tab[i]
Pointeur sur un tableau multidimensionnel
Un tableau multidimensionnel est de forme, Tab [i] [j]. Voyons comment nous pouvons faire pointer un pointeur vers un tel tableau. Comme nous le savons maintenant, le nom du tableau donne son adresse de base. Dans Tab[i][j], Tab donnera l'adresse de base de ce tableau. Même Tab+0+0 donnera également l'adresse de base, c'est-à-dire l'adresse de l'élément Tab[0][0].
Exemple 3 :
#include < stdio.h> int main(void) { int i, j; int Tab[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int *p; p = Tab; for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { printf("Tab[%d][%d] = %d \n", i, j, *(p + (i * 4) + j)); } } return 0; }
Tab[0][1] = 2
Tab[0][2] = 3
Tab[0][3] = 4
Tab[1][0] = 5
Tab[1][1] = 6
Tab[1][2] = 7
Tab[1][3] = 8
Tab[2][0] = 9
Tab[2][1] = 10
Tab[2][2] = 11
Tab[2][3] = 12
Voici la forme généralisée d'utilisation du pointeur avec des tableaux multidimensionnels.
*(p + (i x nb_colonnes + j))
Où, p contient l'adresse du premier élément du tableau, i et j désignent la ième ligne et la jième colonne du tableau.
Et nb_colonnes indique le nombre total de colonnes dans la ligne du tableau.
Nous pouvons également utiliser l'adresse de base (Tab dans le cas précédent) pour agir en tant que pointeur et afficher toutes les valeurs, comme dans l'exemple suivant.
Exemple 4 :
#include < stdio.h> int main(void) { int i, j; int Tab[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int *p; p = Tab; for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { printf("Tab[%d][%d] = %d \n", i, j, *(*(Tab + i) + j)); } } return 0; }
Tab[0][1] = 2
Tab[0][2] = 3
Tab[0][3] = 4
Tab[1][0] = 5
Tab[1][1] = 6
Tab[1][2] = 7
Tab[1][3] = 8
Tab[2][0] = 9
Tab[2][1] = 10
Tab[2][2] = 11
Tab[2][3] = 12
Voici la forme généralisée
*(*(Tab + i) + j) // Equivalente à Tab[i][j]
Tableau de pointeurs
Tout comme nous pouvons déclarer un tableau d'int, float ou char, etc., nous pouvons également déclarer un tableau de pointeurs, voici la syntaxe pour faire la même chose.
type_donnees *nom_tab[taille];
Exemple 5 :
int *Tab[5];
Ici, Tab est un tableau de 5 pointeurs entiers. Cela signifie que ce tableau peut contenir l'adresse de 5 variables entières. En d'autres termes, vous pouvez affecter 5 variables de type pointeur vers int, aux éléments de ce tableau.
Exemple 6 :
#include < stdio.h> int main(void) { int i, a = 3, b = 7, c = 1; int *Tab[3]; Tab[0] = &a; Tab[1] = &b; Tab[2] = &c; for (i = 0; i < 3; i++) { printf("Adresse = %d \t Valeur = %d \n", Tab[i], *Tab[i]); } return 0; }
Adresse = -276735280 Valeur = 7
Adresse = -276735284 Valeur = 1
Vous pouvez également utiliser un tableau de pointeurs sur un caractère pour stocker une liste de chaînes comme suit:
Exemple 7 :
#include < stdio.h> int main(void) { int i = 0; char *noms[4] = { "ESSADDOUKI Mostafa", "KAYOUH Mohamed", "ESSADDOUKI Ismail", "SEKHRA Omar"}; for (i = 0; i < 4; i++) { printf("noms[%d] = %s\n", i, noms[i]); } return 0; }
noms[1] = KAYOUH Mohamed
noms[2] = ESSADDOUKI Ismail
noms[3] = SEKHRA Omar
Vous pouvez également utiliser un tableau de pointeurs pour stocker un tableau 2D
Exemple 8 :
#include < stdio.h> #include < stdlib.h> int main(void) { int i, j; int *Tab[3]; // allocation de la mémoire pour chaque élément de Tab for (i = 0; i < 3; i++) { Tab[i] = (int *)malloc(4 * sizeof(int)); // chaque ligne contient 4 colonnes de type entier } // remplir le tableau par (i*j) for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { *(*(Tab + i) + j) = i * j; } } // afficher les éléments du Tab for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { printf("Tab[%d][%d] = %d \n", i, j, *(*(Tab + i) + j)); } } return 0; }
Tab[0][1] = 0
Tab[0][2] = 0
Tab[0][3] = 0
Tab[1][0] = 0
Tab[1][1] = 1
Tab[1][2] = 2
Tab[1][3] = 3
Tab[2][0] = 0
Tab[2][1] = 2
Tab[2][2] = 4
Tab[2][3] = 6