Skip to content

2e année – TP14

21 février 2012

Voici l’énoncé et ma solution du TP N°14, intitulé « Manipulation des piles (représentation chaînée) :

TP14 Manipulation des piles (représentation chainée)

tp14 : solution par nh2

Mon fils de 9 ans m’a prêté ses cartes à jouer pour tester l’algorithme (que j’avais du mal à comprendre au début sans ça) et il m’a suggéré une modification : après avoir dépilé un nombre de A pour le rempiler sur B, il vaut mieux ne pas transférer tous les nombres qui sont sur C vers la pile B mais seulement ceux qui sont supérieurs au sommet de A. Ainsi on évite de les retransférer vers C à la prochaine itération et on gagne beaucoup d’étapes !

Voici donc la solution avec l’algorithme modifié (seul un test a été ajouté en lignes 103-104) :

tp14 par nh2 avec algorithme modifié

Et voici une version améliorée qui montre le contenu des 3 piles à chaque étape. Elle comporte aussi une fonction deplace() assez intéressante à mon avis :

tp14_v3_nh2

Publicités
6 commentaires
  1. merci bien monsieur :)

    J'aime

  2. j’ai vraiment aimé votre solution monsieur, et j’ai quelque questions..
    – j’ai pas compris l’idée d’affichage des messages erreurs, vous avez déclaré trois constantes , chacune avec un entier correspondant, l’entier erreur initialiser par 0 (aucun erreur) et le tableau des chaines de caractères: chaque indice du chaine repère à la valeur du constant d’erreur déclaré précédement, l’affichage sera enfin de l’excution du programme, alors cet affichage sera seulement pour le dernier erreur?
    – la différence entre l’utilisation de la fonction fprintf et printf?
    – j’ai pas compris l’utilité des lignes 45 et 46 (vous avez comparis un entier avec NULL?)
    – à quoi il serve le  » return 666  » ligne 81 (erreur, mais vous avez envoyé un entier!)
    – le role du EXIT_FAILURE et EXIT_SUCCESS
    et quelle merveilleuse utilisation du test linéaire dans le printf (ligne 58) :-)

    J'aime

    • Merci pour tes commentaires. Ça me fait très plaisir de voir que tu as étudié le code source et essayé de le comprendre.
      Quant à tes questions :
      – j’ai fait dans le programme une gestion rudimentaire des erreurs, pas très bien élaborée, juste pour m’aider à déboguer (elle m’a été utile lors des premiers essais). Ta remarque est très juste : si plusieurs erreurs se produisent, seule la dernière sera signalée, à la fin, ce qui n’est pas une très bonne solution… J’y ai pensé aussi mais je n’ai pas pris le temps d’améliorer cela. Il faudrait peut-être utiliser des instructions exit(EXIT_FAILURE) dès que l’erreur se produit pour interrompre l’exécution (voir l’explication avec la commande man 3 exit)… Quoi qu’il en soit c’est à revoir !
      – fprintf permet d’écrire dans n’importe quel fichier (ou flux) alors que printf ne permet d’écrire que dans la sortie standard (stdout). J’ai utilisé fprintf pour diriger les messages d’erreur vers l’erreur standard (stderr), qui est faite pour les erreurs… Voir : http://fr.wikipedia.org/wiki/Flux_standard
      – lignes 45 et 46 : elles permettent d’appeler la fonction depiler() avec pour 2e paramètre la valeur NULL. C’est une pratique courante en C : certains paramètres de type pointeur peuvent être rendus « optionnels », en quelque sorte, en permettant de leur passer NULL quand par exemple on n’a pas besoin que la fonction nous renvoie une valeur par ce paramètre. C’est le cas ici quand j’appelle depiler() juste pour vider la pile et la « détruire », sans utiliser les valeurs qu’elle contient (regarde la fonction detruire_pile()).
      – 666 c’est le nombre de Satan ! :-D Sérieusement, c’est juste parce qu’il faut retourner quelque chose et la valeur 0 semble trop « normale ». Si j’avais utilisé un exit() en cas d’erreur, je n’aurais pas eu besoin de le faire.
      – EXIT_FAILURE et EXIT_SUCCESS sont des constantes déclarées dans stdlib.h standard utilisées comme valeur de retour de main() et donc de ton programme, voir http://www.levenez.com/lang/c/faq/fclc009.html#q_4 . Cette valeur peut être reçue par le programme qui appelle ton programme pour savoir si l’exécution s’est déroulée correctement ou pas. Par exemple, dans le shell, tu peux connaître la valeur de retour du programme après qu’il se termine en tapant la commande echo $? et en général si c’est 0 (qui correspond à la valeur de EXIT_SUCCESS) c’est qu’il n’y a pas eu d’erreur. On utilise EXIT_SUCCESS et EXIT_FAILURE au lieu de 0 et 1 par souci de portabilité, au cas où ton programme serait un jour compilé sur un système d’exploitation sur lequel la convention serait que 0 correspond à une erreur (il aurait un stdlib.h différent alors)…
      – merci pour le compliment concernant le test avec l’opérateur ternaire (je rougis :o) )… il faut bien l’utiliser de temps en temps même s’il peut nuire à la lisibilité du code… je l’utilise surtout pour les instructions du genre printf("%d objet%s", n, n>1?"s.":"."); c’est plus rapide à écrire qu’un if avec deux printf(). On aurait pu écrire aussi printf("%de%c nombre : ",i,' '+(i==1)*('r'-' ')); si l’opérateur ternaire n’existait pas (j’ai appris à faire ce genre de trucs avec un BASIC limité). J’ai d’ailleurs utilisé une astuce comme ça en lignes 100 et 102 dans la fonction afficher_3_piles() de la dernière version.
      Voilà ! Si je t’ai appris quelque chose, eh bien ça me fait vraiment plaisir, car c’est mon but en tant qu’enseignant, et puis j’en apprends toujours grâce à vous alors n’hésitez pas à me parler de ce que vous avez compris ou pas… et là je ne te vouvoie pas, j’écris aussi aux autres étudiants qui me lisent, s’il y en a !

      J'aime

    • de rien :-) (je sais, je réponds très en retard : c’est mon fils qui m’a rappelé qu’il est impoli de ne pas répondre !)

      J'aime

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :