Blog ENI : Toute la veille numérique !
💥 Un livre PAPIER acheté
= La version EN LIGNE offerte pendant 1 an !
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. Développement informatique
  3. Les pointeurs
Extrait - Développement informatique Apprenez à concevoir avant de programmer
Extraits du livre
Développement informatique Apprenez à concevoir avant de programmer
3 avis
Revenir à la page d'achat du livre

Les pointeurs

Objectifs du chapitre

Développer des applications utilisant des pointeurs.

Développer des applications utilisant l’allocation dynamique de mémoire.

Définition

Un pointeur est une variable destinée à contenir une adresse. Une adresse étant un entier, un pointeur est une variable de type entier.

Exemples

1. Pointeur sur un entier

La déclaration int* p réserve un entier en mémoire destiné à contenir l’adresse d’une variable de type entier.

L’écriture int* p (l’étoile collée à int) suggère que la variable p est du type pointeur sur un entier. On pourrait aussi écrire int *p (l’étoile collée au p), qui suggère que la variable *p est du type entier, ce qui est aussi vrai.

  • La déclaration int n réserve un entier en mémoire.


int main() 
{ 
   int* p;            
   int n;
 
images/01033a.png

   n = 17; 
   printf("n  = %d\n\n", n);
 
images/01033b.png

L’instruction suivante met l’adresse de la variable n dans p (l’opérateur & retourne l’adresse de n). On dit que p pointe sur n.


   p = &n;  
   printf("p  = %p\n\n", p);
 
images/01033c.png

Le format %p du printf permet d’afficher l’entier p en hexadécimal.

Affichage de la valeur pointée par p :


   printf("*p = %d\n\n", *p);
 

Incrémentation de la valeur pointée par p, c’est-à-dire n :


   (*p)++; 
   printf("n  = %d\n\n", n); 
 
   return 0; 
}
 

Voici le résultat de l’exécution de ce programme :

images/01033d.png

L’opérateur & retourne...

Pointeurs : une erreur classique 

L’utilisation directe d’adresses mémoire peut être dangereuse et demande de l’attention au programmeur. L’exemple suivant illustre ce danger.


int main() 
{ 
    int* p;
 

L’instruction suivante met l’adresse 0 dans le pointeur. Cette adresse est en général réservée à des programmes du système.


    p = 0;
 

L’instruction suivante essaie de mettre la valeur 10 à l’adresse 0, donc d’écraser un morceau de programme système (ici, Windows) :


    *p = 10; 
 
    return 0; 
}
 

Windows se défend et affiche une belle petite fenêtre d’information :

images/01034a.png

Cette erreur est qualifiée d’Access Violation.

Allocation dynamique d’un tableau

L’allocation dynamique de mémoire consiste à réserver de l’espace mémoire pour des variables au cours de l’exécution du programme. Par exemple, l’allocation dynamique d’un tableau peut être utile si sa dimension n’est pas connue en début de programme.

1. Tableau à une dimension

Les déclarations suivantes réservent deux zones mémoires pouvant contenir un entier. 


int main() 
{ 
    double* tableau; 
    int i;
 
images/01035a.png

La fonction calloc() réserve en mémoire un nombre d’octets égal au produit de ses paramètres.


    tableau = (double*) calloc(3, sizeof(double)); 
    printf("tableau  = %p\n\n", tableau);
 

Ici : 3 * sizeof(double), c’est-à-dire 3 * 8 = 24 octets, c’est-à-dire l’espace correspondant à trois variables de type double.

La fonction calloc() retourne une adresse non typée (void*). Le « cast » en double* assure une cohérence avec la déclaration du pointeur tableau. L’adresse retournée par calloc() est stockée dans tableau, qui pointe sur la zone de mémoire allouée :

images/01035b.png

Le tableau s’utilise désormais comme un tableau normal :


    tableau[0] = 5.1; 
    tableau[1]...

Travail pratique : triangle de Pascal

1. Objectif

Constituer un tableau contenant le triangle de Pascal, en utilisant l’allocation dynamique de tableaux.

2. Sujet

La correction du travail pratique : triangle de Pascal (cf. chapitre Les tableaux), propose une solution utilisant deux tableaux à une dimension. Reprendre ce programme en allouant dynamiquement les deux tableaux.

images/01036a.png

3. Triangle de Pascal : proposition de correction

Cette solution reprend la solution avec deux tableaux d’une ligne. Les tableaux sont alloués dynamiquement. Les variables l1 et l2 sont déclarées en pointeurs :


int main() 
{  
    int* l1; 
    int* l2; 
    int* permut; 
    int lig,col; 
    int nbl; 
 
    printf("Entrez le nombre de ligne(s) du tableau : "); 
    scanf("%d", &nbl);
 

Allocation dynamique des deux tableaux :

    l1 = (int*) calloc(nbl, sizeof(int)); 
    l2 = (int*) calloc(nbl, sizeof(int)); 

Le nombre de lignes du triangle de Pascal n’est plus limité à 16.


    l1[0] = 1; 
    printf("%-5d\n", l1[0]); 
 
    for (lig = 1; lig < nbl; lig++) 
    { 
        l2[0] = 1; 
        printf("%-5d", l2[0]); 
 
        for (col = 1; col < lig; col++) 
        { 
            l2[col] = l1[col] + l1[col - 1]; 
            printf("%-5d", l2[col]); ...