Les pointeurs sont un concept fondamental en langage C, qui permet de manipuler directement la mémoire. Ils offrent un moyen puissant et flexible d’accéder aux données, mais ils nécessitent une bonne compréhension pour éviter des erreurs comme les fuites de mémoire ou les accès mémoire invalides.
Un pointeur est une variable qui contient l’adresse mémoire d’une autre variable. Au lieu de stocker une valeur, un pointeur stocke l’emplacement en mémoire où cette valeur est située.
Pour déclarer un pointeur, il faut spécifier le type de données vers lequel il pointe, suivi d’un astérisque (*
), qui indique que la variable est un pointeur.
Exemple de déclaration :
int *ptr; // ptr est un pointeur vers un entier
Ici, ptr
est un pointeur qui peut contenir l’adresse d’une variable de type int
.
&
et déréférencement *
&
) : Il permet de récupérer l’adresse mémoire d’une variable.*
) : Il permet d’accéder à la valeur contenue à l’adresse pointée par un pointeur.Exemple d’utilisation :
int a = 10; // Une variable entière
int *ptr = &a; // ptr contient l'adresse de la variable a
printf("La valeur de a : %d\n", a); // Affiche 10
printf("L'adresse de a : %p\n", &a); // Affiche l'adresse mémoire de a
printf("La valeur à laquelle ptr pointe : %d\n", *ptr); // Affiche 10
Dans cet exemple :
&a
donne l’adresse de la variable a
et l’assigne au pointeur ptr
.*ptr
déréférence le pointeur et accède à la valeur stockée à l’adresse à laquelle ptr
pointe, soit 10
.En C, les tableaux et les pointeurs sont étroitement liés. Le nom d’un tableau est en fait un pointeur vers le premier élément du tableau.
Exemple :
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // ptr pointe vers le premier élément du tableau
printf("%d\n", *ptr); // Affiche 1, premier élément du tableau
printf("%d\n", *(ptr + 1)); // Affiche 2, deuxième élément du tableau
Dans cet exemple, arr
est un pointeur vers le premier élément du tableau, et *(ptr + 1)
permet d’accéder au deuxième élément du tableau en utilisant l’arithmétique des pointeurs.
Les pointeurs supportent l’arithmétique. Vous pouvez ajouter ou soustraire des entiers à un pointeur, ce qui déplace le pointeur vers d’autres emplacements en mémoire.
Exemple :
int arr[3] = {10, 20, 30};
int *ptr = arr; // ptr pointe vers arr[0]
printf("%d\n", *ptr); // Affiche 10
printf("%d\n", *(ptr + 1)); // Affiche 20
printf("%d\n", *(ptr + 2)); // Affiche 30
Ici, ptr + 1
pointe vers l’élément suivant du tableau. En termes d’arithmétique des pointeurs, lorsqu’un pointeur de type int
est incrémenté de 1, il saute de 4 octets (la taille d’un int
sur la plupart des systèmes) pour pointer vers le prochain entier.
NULL
)Un pointeur peut ne pas pointer vers une adresse valide. Dans ce cas, il est souvent initialisé à une valeur spéciale : NULL
, qui signifie que le pointeur ne pointe vers aucune adresse en mémoire.
Exemple :
int *ptr = NULL; // ptr ne pointe vers rien
Il est important de vérifier qu’un pointeur n’est pas nul avant de l’utiliser pour éviter des erreurs d’exécution.
Les pointeurs sont souvent utilisés pour passer des arguments à des fonctions par référence, permettant à la fonction de modifier la valeur d’une variable en dehors de son propre contexte.
Exemple :
void increment(int *ptr) {
(*ptr)++; // Déréférence et incrémente la valeur
}
int main() {
int a = 5;
increment(&a); // Passe l'adresse de a à la fonction
printf("%d\n", a); // Affiche 6, car a a été modifié
return 0;
}
Dans cet exemple, la fonction increment
reçoit un pointeur vers la variable a
et modifie sa valeur directement.
Un pointeur peut également pointer vers un autre pointeur. C’est ce qu’on appelle un pointeur de pointeur.
Exemple :
int a = 10;
int *ptr = &a; // ptr pointe vers a
int **pptr = &ptr; // pptr pointe vers ptr
printf("La valeur de a : %d\n", **pptr); // Affiche 10
Dans ce cas, pptr
est un pointeur qui contient l’adresse de ptr
, et **pptr
permet d’accéder à la valeur de a
.
Les pointeurs en C sont très puissants, mais ils peuvent aussi être dangereux s’ils sont mal utilisés :
malloc
) et que vous oubliez de la libérer (avec free
), vous pouvez provoquer des fuites de mémoire.👉 Les pointeurs en C sont une fonctionnalité puissante qui permet une gestion fine de la mémoire et des performances élevées. Cependant, leur utilisation correcte exige une grande prudence pour éviter les erreurs communes, telles que les fuites de mémoire ou les violations d’accès. Maîtriser les pointeurs est une étape clé pour progresser dans la programmation en C.
Voici quelques exercices corrigés sur les pointeurs en langage C, conçus pour renforcer votre compréhension de ce concept fondamental.
Écrivez un programme qui utilise un pointeur pour accéder et modifier la valeur d’une variable entière.
#include <stdio.h>
int main() {
int a = 10;
int *p; // Déclaration du pointeur
p = &a; // Assigner l'adresse de 'a' à 'p'
printf("Valeur initiale de a : %d\n", a); // Affiche 10
printf("Adresse de a : %p\n", p); // Affiche l'adresse de 'a'
printf("Valeur pointée par p : %d\n", *p); // Affiche 10
// Modification de la valeur de 'a' à travers le pointeur
*p = 20;
printf("Nouvelle valeur de a : %d\n", a); // Affiche 20
return 0;
}
Dans cet exercice, un pointeur p
est utilisé pour accéder et modifier la variable a
. En déréférençant le pointeur (*p
), on peut modifier directement la valeur stockée à l’adresse mémoire où se trouve a
.
Écrivez une fonction qui échange les valeurs de deux variables en utilisant des pointeurs.
#include <stdio.h>
void echanger(int *x, int *y) {
int temp;
temp = *x; // Sauvegarde la valeur de x
*x = *y; // Met y dans x
*y = temp; // Met temp dans y
}
int main() {
int a = 5, b = 10;
printf("Avant échange : a = %d, b = %d\n", a, b);
// Appel de la fonction echanger avec les adresses de 'a' et 'b'
echanger(&a, &b);
printf("Après échange : a = %d, b = %d\n", a, b);
return 0;
}
La fonction echanger()
prend en entrée deux pointeurs. Elle échange les valeurs des deux variables en modifiant directement les valeurs à l’adresse des variables fournies en arguments. Cela permet d’effectuer l’échange sans retour de valeur.
Écrivez un programme qui alloue dynamiquement un tableau de 5 entiers, demande à l’utilisateur de saisir ces entiers, puis affiche les entiers saisis.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *tableau;
int i;
// Allocation dynamique d'un tableau de 5 entiers
tableau = (int *)malloc(5 * sizeof(int));
if (tableau == NULL) {
printf("Échec de l'allocation mémoire.\n");
return 1; // Sortir si l'allocation échoue
}
// Saisie des entiers
printf("Entrez 5 entiers :\n");
for (i = 0; i < 5; i++) {
scanf("%d", &tableau[i]);
}
// Affichage des entiers
printf("Vous avez saisi :\n");
for (i = 0; i < 5; i++) {
printf("%d ", tableau[i]);
}
// Libérer la mémoire
free(tableau);
return 0;
}
Dans cet exercice, nous utilisons malloc()
pour allouer dynamiquement un tableau d’entiers. Après la saisie des valeurs par l’utilisateur, les valeurs sont affichées, puis la mémoire allouée est libérée avec free()
.
Écrivez un programme qui utilise un pointeur sur pointeur pour modifier la valeur d’une variable entière.
#include <stdio.h>
int main() {
int a = 50;
int *p;
int **pp; // Pointeur sur pointeur
p = &a; // p pointe vers a
pp = &p; // pp pointe vers p
// Affichage des valeurs
printf("Valeur de a : %d\n", a); // Affiche 50
printf("Valeur de *p (a) : %d\n", *p); // Affiche 50
printf("Valeur de **pp (a) : %d\n", **pp); // Affiche 50
// Modification de a via le pointeur sur pointeur
**pp = 100;
// Affichage après modification
printf("Nouvelle valeur de a : %d\n", a); // Affiche 100
return 0;
}
Ici, nous utilisons un pointeur sur pointeur (pp
) pour modifier la valeur de la variable a
. Le pointeur p
contient l’adresse de a
, et pp
contient l’adresse de p
. En déréférençant deux fois (**pp
), nous modifions directement la valeur de a
.
Écrivez une fonction qui calcule la longueur d’une chaîne de caractères en utilisant uniquement des pointeurs, sans utiliser la fonction strlen()
de la bibliothèque standard.
#include <stdio.h>
int longueur_chaine(const char *str) {
const char *p = str;
while (*p != '\0') {
p++;
}
return p - str;
}
int main() {
char chaine[] = "Bonjour";
printf("Longueur de la chaîne \"%s\" : %d\n", chaine, longueur_chaine(chaine));
return 0;
}
Dans cette fonction, un pointeur p
parcourt la chaîne de caractères jusqu’à rencontrer le caractère de fin de chaîne \0
. La longueur de la chaîne est ensuite calculée comme la différence entre les adresses de fin et de début de la chaîne (p - str
).
Écrivez une fonction qui inverse un tableau d’entiers en place en utilisant des pointeurs.
#include <stdio.h>
void inverser_tableau(int *arr, int taille) {
int *debut = arr;
int *fin = arr + taille - 1;
int temp;
while (debut < fin) {
temp = *debut;
*debut = *fin;
*fin = temp;
debut++;
fin--;
}
}
int main() {
int tableau[] = {1, 2, 3, 4, 5};
int taille = sizeof(tableau) / sizeof(tableau[0]);
printf("Tableau avant inversion :\n");
for (int i = 0; i < taille; i++) {
printf("%d ", tableau[i]);
}
printf("\n");
inverser_tableau(tableau, taille);
printf("Tableau après inversion :\n");
for (int i = 0; i < taille; i++) {
printf("%d ", tableau[i]);
}
printf("\n");
return 0;
}
La fonction inverser_tableau()
utilise deux pointeurs : debut
et fin
. Ces pointeurs parcourent le tableau depuis les deux extrémités vers le milieu, en échangeant les éléments jusqu’à ce qu’ils se rencontrent.
Ces exercices couvrent différentes utilisations des pointeurs en C, allant de la manipulation basique à des usages plus complexes comme les pointeurs sur pointeurs et la gestion de tableaux dynamiques. Ils sont conçus pour vous aider à mieux comprendre et maîtriser les pointeurs, un aspect fondamental et puissant du langage C.
Le commentaire composé est un exercice littéraire qui consiste à analyser un texte en respectant…
Les adjectifs liés en français sont les adjectifs qui s’accordent en genre (masculin/féminin) et en…
Voici une liste étendue de mots piégeux en français, avec leurs genres et des explications…
Apprendre à distinguer le genre des noms en français peut être un véritable défi pour…
1. Informations Générales Nom complet : Charles-Louis de Secondat, Baron de La Brède et de…
Introduction L’Art de la Guerre (Dell’arte della guerra), publié en 1521, est l’un des ouvrages…
This website uses cookies.