Initialisation aisée des tableaux de pointeurs en C : Astuces & meilleures pratiques
Un pointeur est une variable qui stocke l'adresse d'une autre variable. Le nom de la variable pointeur doit être préfixé par le symbole «*». Tout comme dans le cas d'une variable normale, on peut aussi déclarer un « tableau de pointeurs », où chaque indice du tableau contient l'adresse d'un type tableau.
Comment initialiser un tableau de pointeurs en C ?
Une variable pointeur peut être initialisée au moment de la déclaration, en lui affectant l'adresse d'une variable existante. L'extrait suivant montre comment initialiser un pointeur −
int x = 10; int *y = &x;
Par défaut, toutes les variables, y compris les variables pointeur, appartiennent à la « classe de stockage auto ». Cela signifie qu'une variable pointeur stockera une adresse mémoire imprévisible, aléatoire, poubelle, ce qui peut mener à un comportement indéfini et des risques potentiels pour un programme, comme des erreurs de segmentation. Donc, elle devrait être initialisée à NULL si on n'a pas de valeur spécifique à stocker au moment de la déclaration.
int *ptr = NULL;
Un « tableau de pointeurs » stocke l'adresse dans chaque élément. Le type du tableau doit correspondre au type de la variable cible.
Initialiser un tableau de pointeurs avec le mot-clé static
Vous pouvez aussi utiliser le mot-clé static pour initialiser un tableau de pointeurs afin de stocker « 0 » dans chaque indice.
Exemple
#include <stdio.h>
int main(){
static int *ptr[5];
for (int i = 0; i < 5; i++){
printf("ptr[%d] = %d\n", i, ptr[i]);
}
return 0;
}
Sortie
Exécutez le code et vérifiez sa sortie −
ptr[0]= 0 ptr[1]= 0 ptr[2]= 0 ptr[3]= 0 ptr[4]= 0
Initialiser un tableau de pointeurs d'entiers
Ici, on déclare un tableau de pointeurs d'entiers et on stocke les adresses de trois variables entières.
Exemple
#include <stdio.h>
int main(){
int a = 10, b = 20, c = 30;
int *ptr[3] = {&a, &b, &c};
for (int i = 0; i < 3; i++){
printf("ptr[%d]: address: %d value: %d\n", i, ptr[i], *ptr[i]);
}
return 0;
}
Sortie
Exécutez le code et vérifiez sa sortie −
ptr[0]: address: 6422040 value: 10 ptr[1]: address: 6422036 value: 20 ptr[2]: address: 6422032 value: 30
Initialiser un tableau de pointeurs par adresses directes
On peut stocker l'adresse de chaque élément d'un tableau normal dans l'élément correspondant d'un tableau de pointeurs.
Exemple
#include <stdio.h>
int main(){
int arr[] = {10, 20, 30};
int *ptr[3] = {&arr[0], &arr[1], &arr[2]};
for (int i = 0; i < 3; i++){
printf("ptr[%d]: address: %d value: %d\n", i, ptr[i], *ptr[i]);
}
return 0;
}
Sortie
Exécutez le code et vérifiez sa sortie −
ptr[0]: address: 6422032 value: 10 ptr[1]: address: 6422036 value: 20 ptr[2]: address: 6422040 value: 30
Parcourir un tableau avec son adresse de base
Quand on obtient l'adresse de base d'un tableau (dans ce cas « &arr[0] »), on peut obtenir les adresses de ses éléments subséquents, sachant que le pointeur s'incrémente de la taille du type de données.
Aussi, juste avec l'adresse de base (le nom du tableau est la même que l'adresse de l'élément 0), on peut parcourir un tableau.
Exemple 1
Regardez l'exemple suivant −
#include <stdio.h>
int main(){
int arr[] = {10, 20, 30};
int *ptr=arr;
for (int i = 0; i < 3; i++){
printf("ptr[%d]: address: %d value: %d\n", i,ptr+i, *(ptr+i));
}
return 0;
}
Sortie
Exécutez le code et vérifiez sa sortie −
ptr[0]: address: 6422020 value: 10 ptr[1]: address: 6422024 value: 20 ptr[2]: address: 6422028 value: 30
Exemple 2 : Parcours d'un tableau 2D en utilisant un tableau de pointeurs
Dans cet exemple, on a un tableau 2D. L'adresse de l'élément 0 de chaque ligne est stockée dans un tableau de pointeurs. Lors du parcours, l'adresse stockée dans chaque élément du tableau de pointeurs, qui pointe vers l'élément 0 de la ligne correspondante, est incrémentée pour récupérer les valeurs de chaque ligne.
#include <stdio.h>
int main(){
// tableau 2d
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
};
int ROWS = 2, COLS = 4;
int i, j;
// pointeur
int (*ptr)[4] = arr;
// afficher les éléments du tableau via le pointeur ptr
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%d ", *(ptr[i]+j));
}
printf("\n");
}
return 0;
}
Sortie
Quand vous exécutez ce code, il produit la sortie suivante −
1 2 3 4 5 6 7 8
Exemple 3
On n'a pas vraiment besoin d'un tableau de pointeurs ici, car on peut utiliser le nom de ce tableau 2D comme son pointeur de base, et l'incrémenter ligne par ligne et colonne par colonne pour récupérer les éléments dans le tableau 2D donné −
#include <stdio.h>
int main(){
// tableau 2d
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
};
int ROWS = 2, COLS = 4;
int i, j;
// pointeur
int *ptr = arr;
// afficher les éléments du tableau via le pointeur ptr
for (i = 0; i < ROWS; i++){
for (j = 0; j < COLS; j++){
printf("%d ", *(ptr + i * COLS + j));
}
printf("\n");
}
return 0;
}
Sortie
La sortie ressemble à celle du code précédent −
1 2 3 4 5 6 7 8
Initialisation d'un tableau de pointeurs de caractères (Chaînes)
En programmation C, une chaîne est un tableau de type de données char. Puisque le nom d'un tableau représente aussi l'adresse de son élément 0, une chaîne peut être déclarée comme −
char arr[] = "Hello";
En utilisant la notation pointeur, une chaîne est affectée à un pointeur char comme −
char *arr = "Hello";
On peut alors déclarer un tableau de pointeurs char pour stocker plusieurs chaînes comme suit −
char *arr[3] = {"string1", "string2", "string3", ... };
Exemple
L'exemple suivant a un tableau de pointeurs char utilisé pour stocker les noms de langages informatiques −
#include <stdio.h>
int main(){
char *langs [10] = {
"PYTHON", "JAVASCRIPT", "PHP", "NODE JS", "HTML",
"KOTLIN", "C++", "REACT JS", "RUST", "VBSCRIPT"
};
for(int i = 0; i < 10; i++)
printf("%s\n", langs[i]);
return 0;
}
Sortie
Quand vous exécutez ce code, il produit la sortie suivante −
PYTHON JAVASCRIPT PHP NODE JS HTML KOTLIN C++ REACT JS RUST VBSCRIPT
Dans ce programme, « langs » est un pointeur vers un tableau de 10 chaînes. Donc, si « langs[0] » pointe vers l'adresse 5000, alors « langs + 1 » pointera vers l'adresse 5004 qui stocke le pointeur vers la deuxième chaîne.
Aussi, on peut utiliser la variation suivante de la boucle pour afficher le tableau de chaînes −
for (int i = 0; i < 10; i++){
printf("%s\n", *(langs + i));
}
Initialisation d'un tableau dynamique de pointeurs
Vous pouvez utiliser la fonction malloc() pour déclarer et initialiser un tableau de pointeurs de façon dynamique.
Exemple
Regardez l'exemple suivant −
#include <stdio.h>
#include <stdlib.h>
int main(){
int *arr = (int *)malloc (sizeof (int) * 5);
for(int i = 0; i < 5; i++){
arr[i] = i;
}
for (int x = 0; x < 5; x++){
printf("%d %d\n", x, arr[x]);
}
return 0;
}
Sortie
Quand vous exécutez ce code, il produit la sortie suivante −
0 0 1 1 2 2 3 3 4 4
Vous pouvez même demander une entrée utilisateur et affecter les valeurs aux éléments dans le tableau de pointeurs −
for(i = 0; i < 5; i++){
scanf("%d", &x);
arr[i] = x;
}
Langue C
- Maîtriser la syntaxe de base du C : Jetons, structure et points-virgules
- Comprendre Switch-Case en C : Syntaxe, exemples et bonnes pratiques
- Maîtriser la gestion d'exceptions en C# : stratégies et bonnes pratiques
- Maîtriser les attributs en C# : enrichir le code avec des métadonnées
- Maîtriser les directives de préprocesseur C# : compilation conditionnelle
- Les unions en C : Gestion mémoire efficace pour types multiples
- Quatre modèles éprouvés pour les fonctions définies par l'utilisateur en C
- Maîtriser les entrées/sorties en C : Fonctions standards et fichiers
- Maîtriser les arguments de ligne de commande en C : Guide pratique