Programmation • IoT

Chapitre 4 – Les pointeurs

Document réservé

Vous consultez actuellement la présentation publique de ce chapitre.

Les documents PDF complets, comprenant les développements théoriques, les exemples détaillés et les exercices, sont disponibles sur demande.

Pour obtenir un accès, contactez-moi via la page Contact en indiquant les domaines qui vous intéressent (C++, ESP-IDF, électronique, etc.).

4.1 Prérequis, nouvelles notions et objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Programme 1 — Une adresse est une valeur . . . . . . . . . . . . . . . . . . . . . . . 4.4.1 Modifier une variable à travers un pointeur . . . . . . . . . . . . . . . . . . . . 4.4.2 Un pointeur est une variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.9 Réponses aux questions de réflexion . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Accueil
Prérequis, nouvelles notions et objectifs 2. Adresse mémoire. 2. Opérateur de déréférencement (∗). 3. Pointeur nul (nullptr). • Qu’est-ce qu’un pointeur ? • Que contient un pointeur ? • Quelle est la différence entre une valeur et une adresse ? • Que signifie l’opérateur ∗ ? • Que signifie l’opérateur & ? • Qu’est-ce que le déréférencement ? • À quoi sert un pointeur ? Programme 1 — Une adresse est une valeur Code 4.1 – Pointeur Exp 1 std::cout << « a =  » << a << ’\n’; std::cout << « &a =  » << &a << ’\n’; std::cout << ’\n’; Code 4.2 – Sortie du programme Que s’est-il passé ? Dans le chapitre précédent, nous avons vu qu’une variable possède une adresse mémoire. Par exemple, si l’on écrit : l’objet a possède la valeur 10 mais également une adresse mémoire que l’on peut faire imprimer avec std::cout << &a << \n; Cette valeur est une adresse mémoire. Jusqu’à présent, nous nous sommes contentés de l’afficher. Mais une question se pose naturellement : Peut-on conserver cette adresse dans une variable ? La réponse est oui. C’est précisément le rôle des pointeurs. Qu’est-ce qu’un pointeur ? Un pointeur est une variable dont la valeur est une adresse mémoire. La déclaration du pointeur p qui prend comme valeur l’adresse de a se fait par int∗ signifie je déclare une variable capable de contenir l’adresse d’un objet de type int. p est le nom de cette variable qui est initialisée avec la valeur &a qui est l’adresse mémoire de a.
Accueil
Pourquoi écrit-on int∗ p et non int ∗p ? Les deux notations sont équivalentes et le compilateur ne fait aucune différence. Dans ce cours, j’utiliserai de préférence l’écriture int ∗p, voici pourquoi. Soient les déclarations : Les deux sont acceptées par le compilateur. Je préfère la seconde car elle dit : On travaille avec des objets qui sont de type entiers. On définit un pointeur ∗p sur un entier qui recevra une adresse et une variable q qui recevra elle une valeur entière. La première notation, int∗ p,q; peut sembler vouloir dire que l’on déclare deux pointeurs ∗p et ∗q ce qui bien sûr n’est pas le cas. Finalement le mieux est de donner ces déclarations sur deux lignes, tout le monde est alors content : Le déréférencement Code 4.3 – Déréférencement //ou encore int* p = &a Code 4.4 – Programme C++ vraiment minimal
Accueil
Nous savons maintenant que la variable p contient l’adresse mémoire de l’objet a. Cependant, dans de nombreuses situations, ce n’est pas l’adresse qui nous intéresse mais la valeur stockée à cette Pour accéder à cette valeur, le langage C++ utilise l’opérateur de déréférencement ∗. « la valeur contenue à l’adresse mémorisée dans le pointeur p ». Autrement dit, le compilateur suit l’adresse contenue dans le pointeur puis accède à l’objet situé à Modifier une variable à travers un pointeur Code 4.5 – Programme C++ vraiment minimal std::cout << « Avant\n »; std::cout << « a =  » << a << ’\n’; std::cout << « \nApres\n »; std::cout << « a =  » << a << ’\n’; Le pointeur ne permet pas seulement de lire la valeur située à une adresse ; il permet également de la modifier.
Accueil
Un pointeur est une variable Un pointeur étant une variable, sa valeur peut varier ! Code 4.6 – Un pointeur peut varier std::cout << *p << ’\n’; p = &b; // On affecte une autre adresse a p std::cout << *p << ’\n’; Contrairement à une référence, un pointeur peut être réaffecté. On remarque dans cet exemple que la forme de déclaration est peut-être plus logique que vu que lors de la réaffectation on écrit Un poonteur peut exister sans désigner d’objet. C’est justement une différence avec les références. On définit le pointeur nul avec la commande :
Accueil
n’a aucun sens, Il tente d’accéder un objet qui n’exsiste pas. Pointeurs et mémoire Code 4.7 – Programme C++ vraiment minimal On peut représenter ces deux déclaration par le dessin suivant : Fig. 4.1 – Pointeurs et mémoire Les flèches représentent des valeurs. La case mémoire de p contient simplement le nombre 0x1000 qui est interprété comme une adresse. Il faut retenir ce tableau résumant la différence entre les pointeurs et les références : Toujours liée à un objet Peut être nul (nullptr) Alias d’un objet existant Variable contenant une adresse Table 4.1 – Comparaison entre une référence et un pointeur. L’opérateur ∗ possède deux significations différentes en C++. Lors d’une déclaration, il indique que la variable est un pointeur. En dehors d’une déclaration, il représente l’opérateur de déréférencement.
Accueil
• Un pointeur est une variable dont la valeur est une adresse mémoire. • L’opérateur & permet d’obtenir l’adresse d’un objet. • L’opérateur ∗ permet d’accéder à l’objet situé à l’adresse contenue dans un pointeur. • Un pointeur possède sa propre case mémoire et donc sa propre adresse. • Un pointeur peut être réaffecté pour désigner un autre objet. • Un pointeur peut être nul (nullptr) et ne désigner alors aucun objet. Questions de réflexion 1. Quelle est la différence entre une valeur et une adresse mémoire ? 2. Pourquoi dit-on qu’un pointeur est une variable comme les autres ? 3. Quelle est la différence entre p, ∗p et &p ? 4. Pourquoi est-il dangereux de déréférencer un pointeur nul ? 5. Quelle est la principale différence entre une référence et un pointeur ? Réponses aux questions de réflexion 1. Une valeur représente une information (par exemple un entier ou un caractère), tandis qu’une adresse mémoire indique l’endroit où cette information est stockée dans la mémoire de l’ordinateur. 2. Comme toute variable, un pointeur possède sa propre case mémoire, sa propre adresse et une durée de vie. Sa particularité est que la valeur qu’il contient est une adresse mémoire. 3. Le symbole p représente le pointeur lui-même, c’est-à-dire la variable qui contient une adresse. L’expression ∗p représente l’objet situé à cette adresse. L’expression &p représente l’adresse mémoire du pointeur lui-même. 4. Un pointeur nul ne désigne aucun objet. Tenter d’accéder à l’objet qu’il est censé désigner conduit à un comportement indéfini. Il est donc indispensable de vérifier qu’un pointeur est valide avant de le déréférencer. 5. Une référence est un alias d’un objet existant. Elle doit être initialisée dès sa création et ne peut jamais être réaffectée. Un pointeur est une variable contenant une adresse mémoire. Il peut être réaffecté pour désigner successivement plusieurs objets et peut également ne désigner aucun objet (nullptr). Remarque 4.9.1. Nous savons maintenant manipuler un pointeur désignant un objet unique. Le chapitre suivant montrera que plusieurs objets peuvent être stockés côte à côte en mémoire. Nous découvrirons alors les tableaux et comprendrons pourquoi ils sont si étroitement liés aux pointeurs.
Accueil
Accueil
cpp-Chap4- Les pointeurs
Accueil
Contenu

Inscription

×
Cancel