L’Arithmétique des Pointeurs en Langage C
L’arithmétique des pointeurs est une fonctionnalité puissante en langage C qui permet de manipuler les adresses mémoire et de naviguer dans des structures de données comme les tableaux en utilisant des pointeurs. Elle repose sur le fait que les pointeurs stockent des adresses, et que ces adresses sont manipulables à l’aide d’opérateurs arithmétiques.
1. Notions de Base
En C, un pointeur ne représente pas seulement une adresse mémoire, il est aussi associé à un type de données (par exemple int*
, char*
, etc.). Cela permet au compilateur de savoir combien d’octets doivent être “sautés” lors des opérations arithmétiques sur ce pointeur. Voici les principales opérations d’arithmétique des pointeurs :
- Incrémentation (
++
) - Décrémentation (
--
) - Addition (
+
) - Soustraction (
-
)
Ces opérations sont couramment utilisées pour parcourir des tableaux ou manipuler des données en mémoire.
2. Incrémentation d’un pointeur (++
)
Lorsque vous incrémentez un pointeur, il ne s’incrémente pas d’un octet mais du nombre d’octets correspondant au type de données vers lequel il pointe.
Exemple :
#include <stdio.h>
int main() {
int tableau[3] = {10, 20, 30};
int *p = tableau; // p pointe vers le premier élément du tableau
printf("Valeur initiale pointée par p : %d\n", *p); // Affiche 10
p++; // Incrémentation du pointeur (il "saute" à l'adresse du prochain entier)
printf("Valeur après incrémentation : %d\n", *p); // Affiche 20
return 0;
}
Explication :
p++
incrémente le pointeurp
pour qu’il pointe vers l’élément suivant du tableau.- Comme
p
est un pointeur vers unint
, et que chaqueint
fait généralement 4 octets, le pointeur “saute” de 4 octets pour pointer vers l’élément suivant.
3. Décrémentation d’un pointeur (--
)
Similaire à l’incrémentation, mais dans le sens inverse : le pointeur est décrémenté pour pointer vers l’élément précédent.
Exemple :
#include <stdio.h>
int main() {
int tableau[3] = {10, 20, 30};
int *p = &tableau[2]; // p pointe vers le dernier élément
printf("Valeur initiale pointée par p : %d\n", *p); // Affiche 30
p--; // Décrémentation du pointeur
printf("Valeur après décrémentation : %d\n", *p); // Affiche 20
return 0;
}
Explication :
p--
fait en sorte que le pointeurp
recule vers l’adresse de l’élément précédent dans le tableau.
4. Addition et soustraction de pointeurs (+
, -
)
En plus des incrémentations et décrémentations unitaires, vous pouvez ajouter ou soustraire des entiers à un pointeur. Cela est utile pour parcourir un tableau ou manipuler des blocs de mémoire.
Exemple : Addition de pointeurs
#include <stdio.h>
int main() {
int tableau[5] = {10, 20, 30, 40, 50};
int *p = tableau; // p pointe vers le premier élément du tableau
printf("Valeur de tableau[3] via arithmétique des pointeurs : %d\n", *(p + 3)); // Affiche 40
return 0;
}
Explication :
*(p + 3)
signifie “l’adresse pointée parp
, plus trois entiers”, ce qui correspond àtableau[3]
. Le pointeur avance de 3 fois la taille d’unint
(généralement 4 octets).
Exemple : Soustraction de pointeurs
#include <stdio.h>
int main() {
int tableau[5] = {10, 20, 30, 40, 50};
int *p = &tableau[4]; // p pointe vers le dernier élément du tableau
printf("Valeur après soustraction de 2 : %d\n", *(p - 2)); // Affiche 30
return 0;
}
Explication :
*(p - 2)
déplace le pointeurp
deux éléments en arrière, ce qui correspond àtableau[2]
(valeur30
).
5. Différence entre deux pointeurs
Lorsque deux pointeurs pointent vers des éléments du même tableau, il est possible de calculer la distance entre eux en utilisant la soustraction. Le résultat est le nombre d’éléments qui séparent les deux pointeurs.
Exemple :
#include <stdio.h>
int main() {
int tableau[5] = {10, 20, 30, 40, 50};
int *p1 = &tableau[1]; // Pointeur sur tableau[1]
int *p2 = &tableau[4]; // Pointeur sur tableau[4]
printf("Distance entre p1 et p2 : %ld\n", p2 - p1); // Affiche 3
return 0;
}
Explication :
p2 - p1
calcule le nombre d’éléments entretableau[1]
ettableau[4]
, ce qui donne3
.
6. Cas des pointeurs de types différents
L’arithmétique des pointeurs dépend du type de données auquel le pointeur fait référence, car chaque type a une taille en mémoire différente. Par exemple, un pointeur vers un char
(1 octet) incrémente de 1 octet, tandis qu’un pointeur vers un int
(4 octets) incrémente de 4 octets.
Exemple avec différents types :
#include <stdio.h>
int main() {
char c = 'A';
int i = 100;
char *p_char = &c;
int *p_int = &i;
printf("Adresse de c : %p, après incrémentation de p_char : %p\n", p_char, p_char + 1);
printf("Adresse de i : %p, après incrémentation de p_int : %p\n", p_int, p_int + 1);
return 0;
}
Explication :
p_char + 1
incrémente l’adresse de 1 octet (carchar
est sur 1 octet).p_int + 1
incrémente l’adresse de 4 octets (carint
est généralement sur 4 octets).
7. Arithmétique interdite sur les pointeurs
Certaines opérations arithmétiques ne sont pas autorisées avec les pointeurs, car elles n’ont pas de sens en termes d’adresses mémoire :
- Multiplication (
*
) et division (/
) : Vous ne pouvez pas multiplier ou diviser des pointeurs. - Addition de deux pointeurs : Vous ne pouvez pas additionner deux pointeurs entre eux.
👉 L’arithmétique des pointeurs permet de manipuler efficacement des structures de données comme les tableaux, en déplaçant les pointeurs pour accéder aux différents éléments. Les opérations les plus courantes incluent l’incrémentation, la décrémentation, l’addition et la soustraction, mais il est important de toujours comprendre ce que vous faites, car une mauvaise manipulation des pointeurs peut entraîner des erreurs graves telles que des dépassements de mémoire ou des accès invalides.
Voici quelques exercices corrigés sur l’arithmétique des pointeurs en C, avec des explications détaillées pour vous aider à comprendre chaque étape.
Exercice 1 : Accéder aux éléments d’un tableau avec un pointeur
Énoncé :
Écrivez un programme qui utilise un pointeur pour accéder et afficher les éléments d’un tableau d’entiers.
Solution :
#include <stdio.h>
int main() {
int tableau[5] = {1, 2, 3, 4, 5};
int *p = tableau; // Pointeur vers le premier élément du tableau
for (int i = 0; i < 5; i++) {
printf("Élément %d : %d\n", i, *(p + i)); // Accès via l'arithmétique des pointeurs
}
return 0;
}
Explication :
- Le pointeur
p
pointe vers le premier élément du tableau (tableau[0]
). *(p + i)
permet d’accéder à chaque élément du tableau en utilisant l’arithmétique des pointeurs.- Le programme parcourt les éléments du tableau et les affiche.
Exercice 2 : Incrémentation d’un pointeur
Énoncé :
Modifiez l’exercice précédent pour afficher les éléments du tableau en incrémentant le pointeur à chaque itération de la boucle.
Solution :
#include <stdio.h>
int main() {
int tableau[5] = {10, 20, 30, 40, 50};
int *p = tableau; // Pointeur vers le premier élément du tableau
for (int i = 0; i < 5; i++) {
printf("Élément %d : %d\n", i, *p); // Affiche la valeur pointée par p
p++; // Incrémentation du pointeur pour pointer vers l'élément suivant
}
return 0;
}
Explication :
p++
incrémente le pointeur pour passer à l’élément suivant dans le tableau.- Le programme affiche successivement les valeurs des éléments du tableau sans avoir besoin d’utiliser d’indices.
Exercice 3 : Soustraction de deux pointeurs
Énoncé :
Écrivez un programme qui calcule la distance entre deux pointeurs dans un tableau.
Solution :
#include <stdio.h>
int main() {
int tableau[6] = {5, 10, 15, 20, 25, 30};
int *p1 = &tableau[1]; // Pointeur vers le deuxième élément
int *p2 = &tableau[4]; // Pointeur vers le cinquième élément
// Calcul de la distance entre les deux pointeurs
int distance = p2 - p1;
printf("Distance entre p1 et p2 : %d éléments\n", distance);
return 0;
}
Explication :
p2 - p1
calcule la distance entre les deux pointeurs en termes d’éléments du tableau.- Le résultat de la soustraction est le nombre d’éléments qui séparent les deux pointeurs dans le tableau, ici 3 (car
tableau[4] - tableau[1] = 3
).
Exercice 4 : Échanger deux valeurs d’un tableau avec des pointeurs
Énoncé :
Écrivez une fonction qui prend deux pointeurs vers des éléments d’un tableau et échange leurs valeurs.
Solution :
#include <stdio.h>
void echanger(int *p1, int *p2) {
int temp = *p1; // Sauvegarde de la valeur pointée par p1
*p1 = *p2; // p1 prend la valeur pointée par p2
*p2 = temp; // p2 prend la valeur temporaire (ancienne valeur de p1)
}
int main() {
int tableau[5] = {10, 20, 30, 40, 50};
// Affichage du tableau avant l'échange
printf("Avant l'échange : %d, %d\n", tableau[1], tableau[3]);
// Appel de la fonction pour échanger tableau[1] et tableau[3]
echanger(&tableau[1], &tableau[3]);
// Affichage du tableau après l'échange
printf("Après l'échange : %d, %d\n", tableau[1], tableau[3]);
return 0;
}
Explication :
- La fonction
echanger()
prend deux pointeurs en argument, qui pointent vers les deux éléments à échanger. - Les valeurs pointées par
p1
etp2
sont échangées à l’aide d’une variable temporaire. - Le programme échange les éléments
tableau[1]
(valeur 20) ettableau[3]
(valeur 40).
Exercice 5 : Inverser un tableau à l’aide de l’arithmétique des pointeurs
Énoncé :
Écrivez un programme qui utilise des pointeurs pour inverser les éléments d’un tableau.
Solution :
#include <stdio.h>
void inverser_tableau(int *arr, int taille) {
int *debut = arr; // Pointeur vers le début du tableau
int *fin = arr + taille - 1; // Pointeur vers la fin du tableau
int temp;
// Inversion des éléments en utilisant des pointeurs
while (debut < fin) {
temp = *debut;
*debut = *fin;
*fin = temp;
debut++; // Avancer le pointeur vers le début
fin--; // Reculer le pointeur vers la fin
}
}
int main() {
int tableau[6] = {1, 2, 3, 4, 5, 6};
// Affichage avant inversion
printf("Avant inversion : ");
for (int i = 0; i < 6; i++) {
printf("%d ", tableau[i]);
}
printf("\n");
// Inversion du tableau
inverser_tableau(tableau, 6);
// Affichage après inversion
printf("Après inversion : ");
for (int i = 0; i < 6; i++) {
printf("%d ", tableau[i]);
}
printf("\n");
return 0;
}
Explication :
- La fonction
inverser_tableau()
utilise deux pointeurs :debut
pour parcourir le tableau depuis le début etfin
depuis la fin. - Les éléments sont échangés jusqu’à ce que les deux pointeurs se rencontrent au milieu du tableau.
- Le programme affiche le tableau avant et après l’inversion.
Exercice 6 : Trouver la plus grande valeur d’un tableau avec des pointeurs
Énoncé :
Écrivez une fonction qui trouve et retourne la plus grande valeur d’un tableau d’entiers en utilisant des pointeurs.
Solution :
#include <stdio.h>
int trouver_max(int *arr, int taille) {
int *p = arr;
int max = *p; // Initialiser le max avec le premier élément
// Parcourir le tableau
for (int i = 1; i < taille; i++) {
p++; // Avancer le pointeur
if (*p > max) {
max = *p; // Mettre à jour le maximum
}
}
return max;
}
int main() {
int tableau[5] = {15, 30, 25, 40, 10};
int max = trouver_max(tableau, 5);
printf("La plus grande valeur du tableau est : %d\n", max);
return 0;
}
Explication :
- La fonction
trouver_max()
parcourt le tableau en utilisant un pointeurp
, en le déplaçant à chaque itération avecp++
. - Le programme compare chaque valeur du tableau avec le
max
actuel et met à jour lemax
si une valeur plus grande est trouvée.
Conclusion
Ces exercices couvrent différentes applications de l’arithmétique des pointeurs en C, depuis l’accès aux éléments de tableaux jusqu’à la manipulation plus complexe de structures de données. En pratiquant ces exemples, vous apprendrez à utiliser les pointeurs pour parcourir et modifier des données en mémoire de manière efficace.