Un problème bien ennuyeux 




Un des plus gros problèmes avec les pointeurs, en plus d'être assez délicats à assimiler pour des débutants, c'est qu'on a du mal à comprendre à quoi ils peuvent bien servir.

Alors bien sûr, je pourrais vous dire : « Les pointeurs sont totalement indispensables, on s'en sert tout le temps, croyez-moi ! », mais je sais que cela ne vous suffira pas.

Je vais donc vous poser un problème que vous ne pourrez pas résoudre sans utiliser de pointeurs. Ce sera en quelque sorte le fil rouge du chapitre. Nous en reparlerons à la fin de ce chapitre et verrons quelle est la solution en utilisant ce que vous aurez appris.

Voici le problème : je veux écrire une fonction qui renvoie deux valeurs. « Impossible » me direz-vous ! En effet, on ne peut renvoyer qu'une valeur par fonction :

 

int fonction()

{

    return valeur;

}



Si on indique int, on renverra un nombre de type int (grâce à l'instruction return).

On peut aussi écrire une fonction qui ne renvoie aucune valeur avec le mot-clé void :


void fonction()

{

  

}



Mais renvoyer deux valeurs à la fois… c'est impossible. On ne peut pas faire deux return.

Supposons que je veuille écrire une fonction à laquelle on envoie un nombre de minutes. Celle-ci renverrait le nombre d'heures et minutes correspondantes :

  1. si on envoie 45, la fonction renvoie 0 heure et 45 minutes ;
  2. si on envoie 60, la fonction renvoie 1 heure et 0 minutes ;
  3. si on envoie 90, la fonction renvoie 1 heure et 30 minutes.


Soyons fous, tentons le coup :

#include <stdio.h>

#include <stdlib.h>

    

/* Je mets le prototype en haut. Comme c'est un tout

petit programme je ne le mets pas dans un .h, mais

en temps normal (dans un vrai programme), j'aurais placé

le prototype dans un fichier .h bien entendu */

   

void decoupeMinutes(int heures, int minutes);

    

int main(int argc, char *argv[])

{

    int heures = 0, minutes = 90;

    

    /* On a une variable minutes qui vaut 90.

    Après appel de la fonction, je veux que ma variable

    "heures" vaille 1 et que ma variable "minutes" vaille 30 */

    

    decoupeMinutes(heures, minutes);

    

    printf("%d heures et %d minutes", heures, minutes);

    

    return 0;

}

     

void decoupeMinutes(int heures, int minutes)

{

    heures = minutes / 60;  // 90 / 60 = 1

    minutes = minutes % 60; // 90 % 60 = 30

}



Résultat :

0 heures et 90 minutes



Zut, zut, zut et rezut, ça n'a pas marché. Que s'est-il passé ? En fait, quand vous « envoyez » une variable à une fonction, une copie de la variable est réalisée. Ainsi, la variable heures dans la fonction decoupeMinutes n'est pas la même que celle de la fonction main ! C'est simplement une copie !

Votre fonction decoupeMinutes fait son job. À l'intérieur de decoupeMinutes, les variables heures et minutes ont les bonnes valeurs : 1 et 30.

Mais ensuite, la fonction s'arrête lorsqu'on arrive à l'accolade fermante. Comme on l'a appris dans les chapitres précédents, toutes les variables créées dans une fonction sont détruites à la fin de cette fonction. Vos copies de heures et de minutes sont donc supprimées. On retourne ensuite à la fonction main, dans laquelle vos variables heures et minutes valent toujours 0 et 90. C'est un échec !


Notez que, comme une fonction fait une copie des variables qu'on lui envoie, vous n'êtes pas du tout obligés d'appeler vos variables de la même façon que dans le main. Ainsi, vous pourriez très bien écrire : void decoupeMinutes(int h, int m).
h pour heures et m pour minutes.
Si vos variables ne s'appellent pas de la même façon dans la fonction et dans le main, ça ne pose donc aucun problème !



Bref, vous aurez beau retourner le problème dans tous les sens… vous pouvez essayer de renvoyer une valeur avec la fonction (en utilisant un return et en mettant le type int à la fonction), mais vous n'arriveriez à renvoyer qu'une des deux valeurs. Vous ne pouvez pas renvoyer les deux valeurs à la fois. De plus, vous ne pouvez pas utiliser de variables globales car, comme on l'a vu, cette pratique est fortement déconseillée.

Voilà, le problème est posé. Comment les pointeurs vont-ils nous permettre de le résoudre ?

Créé avec HelpNDoc Personal Edition: Produire des livres Kindle gratuitement