Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Langage C++
  3. Pointeurs, utilisations classiques
Extrait - Langage C++ De l'héritage C au C++ moderne (avec programmes d'illustration) (2e édition)
Extraits du livre
Langage C++ De l'héritage C au C++ moderne (avec programmes d'illustration) (2e édition) Revenir à la page d'achat du livre

Pointeurs, utilisations classiques

Introduction

Ce chapitre reprend certains sujets déjà abordés partiellement dans les chapitres précédents afin de fournir des précisions supplémentaires qui concernent des utilisations classiques de pointeurs. Nous revoyons ainsi les pointeurs utilisés en paramètres de fonction, les allocations dynamiques, notamment les allocations dynamiques de tableaux, et également comment associer des classes entre elles avec des pointeurs et constituer des listes.

Pointeur en paramètre (passage par référence)

Pour rappel, les paramètres de fonctions sont des variables locales à la fonction initialisées avec des valeurs au moment de l’appel de la fonction. Si l’on place un pointeur en paramètre, il reçoit au moment de l’appel, selon son type, une adresse mémoire d’objet d’un type correspondant. La fonction peut ensuite accéder à cette adresse mémoire et modifier l’objet source correspondant. C’est ce que l’on appelle un "passage par référence" et il s’agit de la référence d’un objet de n’importe quel type via son adresse mémoire (variable, tableau, objet). En quelque sorte, le paramètre d’entrée de valeur pour la fonction sert aussi de sortie de valeur à la fonction.

1. Expérimentation avec pointeur classique

En C et C++, le passage des arguments se fait toujours par valeur et c’est uniquement la valeur des variables qui est affectée aux paramètres des fonctions. Ce n’est pas la variable elle-même qui deviendrait paramètre de la fonction.

Ci-dessous, une variable v est initialisée avec la valeur 10. La fonction modif() est appelée et la valeur de v est affectée à son paramètre, ce qui donne :

#include <iostream> 
void modif(int e1) 
{ 
    e1 = 50; 
} 
int main() 
{ 
    int v = 10; 
    modif(v); 
    std::cout << v << '\n';   // 10 
 
    std::cin.get(); 
    return 0; 
} 

cout imprime 10 car la variable v, locale au contexte d’appel, vaut toujours 10.

Toutefois, si l’on...

Allocation dynamique et tableaux

L’allocation dynamique consiste pour le programmeur à gérer lui-même des allocations de mémoire et avec elles les libérations correspondantes de la mémoire allouée. Nous l’avons déjà largement expérimentée au chapitre précédent Pointeurs et références dans la classe. Ce chapitre-ci propose quelques précisions à propos des tableaux.

1. Tableau de pointeurs

Le tableau de pointeurs constitue une structure de données très utile. Il repose sur l’utilisation systématique de l’allocation dynamique de chacun de ses éléments.

Soit une classe point :

#include <iostream> 
class point 
{ 
    int x, y; 
public: 
    point(int x, int y):x{x},y{y}{} 
    void affiche() { std::cout << '(' << x << ',' << y << ')'; } 
};  

Dans le main ou ailleurs, nous pouvons déclarer un tableau de pointeurs point* :

int main() 
{ 
    constexpr int nbPoint = 10; 
    point* points[nbPoint]; 

Chaque point du tableau étant un pointeur, il nécessite une allocation dynamique après quoi nous pouvons afficher le point :

    // création et affichage 
    for (int i = 0; i < nbPoint; i++) { 
        points[i] = new point{ rand() % 100,rand() % 100 }; 
        points[i]->affiche(); 
    } 

Une fois que le tableau n’est plus nécessaire, la mémoire allouée pour chaque...

Relier des objets

Un pointeur membre d’une structure ou d’une classe A pointe sur une structure ou une classe B et dans la classe B un pointeur pointe sur A. Dans cette section, nous explorons les relations possibles premièrement entre structures de style C avec l’association de deux structures différentes Pilote et Avion. Dans un deuxième temps, nous associons des classes de même type afin de constituer une liste de personnes. Pour finir, nous proposons une dernière version de fourmilière basée sur une liste de fourmis.

1. Associer deux types structures style C

Un pointeur de structure dans une structure permet de relier ces structures. Par exemple, dans un programme, nous devons avoir d’un côté des pilotes et de l’autre des avions. Chaque pilote peut piloter un avion et chaque avion possède ou non un pilote.

Pour programmer cette situation, nous définissons deux structures : une structure Pilote et une structure Avion. Dans la structure Pilote, nous plaçons un pointeur sur une structure Avion et dans la structure Avion nous plaçons un pointeur sur une structure Pilote. Ainsi, chaque pilote peut être associé à un avion et réciproquement, chaque avion peut être relié à un pilote.

On mesure avec ce programme l’importance de la valeur null. Cette valeur nous permet de savoir si avion et pilote existent, existences qui conditionnent leurs relations et les accès aux données membres.

a. Structures Avion et Pilote

Voici une structure Avion :

struct Pilote;  // déclaration de type incomplet 
struct Avion 
{ 
    Pilote* pilote; // peut pointer sur un pilote  
    std::string type; 
    int num; 
 
}; 

Pour la structure Avion, le compilateur...