mardi 9 septembre 2014

Mise à niveau informatique (module INF3036) (cours 2)

Fin du jeu de pendu 


Le prochain cours à lieu le 16 septembre. D'ici là vous devrez essayer de finaliser le jeu de pendu par vous même.

Je ne passerai qu'une 1/2 h pour répondre à vos question et présenter le dernier point qui est  "comment déterminer la fin de la partie?".

Maintenant qu'on a revu , par la pratique les éléments de base de la programmation (structure d'un programme, structures de contrôles variables simples et tableaux), nous allons passer au programme de deuxième année.

La leçon d'aujourd'hui portera sur ...

L'allocation mémoire

Pour comprendre la manière dont la mémoire est gérée par l'ordinateur (et en particulier dans un programme en langage C), nous allons faire une série "d'expériences", à l'issue desquelles je vous donnerai des informations permettant d'expliquer les comportements observés.

Expérience 0

Écrivez un programme qui alloue un tableau de 100 cases de valeurs entière et qui met la valeur 12 dans chacune des cases,puis affichez le contenu de la dernière case.
Cette "expérience" ne devrait normalement vous poser aucun problème et le résultat est , normalement, tout à fait prévisible, et sans surprise.

Expérience 1

Augmentez la taille du tableau du programme précédent, passez de 100 cases à 1000, et re-testez le.
Puis 10000, puis 100000, etc.... et testez votre programme à chaque fois.
À un moment ce programme ne marchera plus...
Pourquoi ? (quelle est la taille de la mémoire disponible?)

Après une explication nous verrons le fonctionnement de la fonction malloc.

Expérience 2

Re-écrivez le programme précédent en utilisant la fonction malloc pour faire une allocation "manuelle" en lieu et place de l'allocation "automatique" précédente.
Est-ce que ça marche mieux ? Pourquoi ?

Expérience 3

Maintenant que vous arrivez compris qu'une allocation ne marche pas forcément à tous les coup, écrivez un test vous permettant de savoir si l'allocation à réussi, avant d'écrire en mémoire...

Expérience 4

Maintenant que vous savez réserver des zones mémoire, essayez de vous accaparer  un maximum de mémoire. C'est a dire allouer et utiliser un maximum de mémoire. Pour cela utilisez une boucle infinie. Grâce au programme "top" mesurez quel pourcentage de la mémoire vous arrivez à utiliser. Essayez (par tout les moyens que vous trouverez raisonnable) d'en avoir le plus possible.
Quelle quantité arrivez vous à obtenir ? Que se passe-t-il quand l'ordinateur commence à manquer de mémoire ?

Expérience 5

Vous comprenez maintenant qu'il nous faut donc une instruction pour rendre la mémoire au système, une fois qu'on en a plus besoin... Cela se fait via l'instruction free.
Modifiez votre dernier programme de manière à ce qu'il libère les zones mémoire qu'il n'utilise plus. Voyez la différence de comportement de l'ordinateur lors de l'exécution de cette nouvelle version du programme.
Pour encore mieux percevoir l'état de l'ordinateur, utilisez un "moniteur système" (ou "system load indicator") que vous trouverez via la barre d'applications. Un peu comme le compte tour ou la mesure de température d'un moteur de voiture, un "moniteur système" vous indique votre consommation des ressources de l'ordinateur.
Bien sûr plus un programme est économe, mieux c'est.

Expérience 6

Relancez l'"expérience 4", tout en surveillant votre moniteur système pour mieux comprendre/voir ce qu'il se passe.
À quoi peuvent servir les autres mesures du moniteur système ? ("load", "disk", "net") ?

Expérience 7

Reprenez votre programme de jeu de pendu, et remplacez toutes les allocations "automatique" (avec l'opérateur []), par une allocation "manuelle" (via la fonction malloc). Pensez aussi que pour faire un bon programme vous devrez aussi libérer ces zones mémoire via free (une fois que vous n'avez plus besoin des données correspondantes). Testez à nouveau votre programme pour vérifier que ces modifications n'ont pas généré de bug.

Profitez aussi de cette reprise en main du programme de jeu de pendu pour commenter votre code.
Pour rappel; commenter un code veux dire ajouter des annotations en langage naturel facilitant la compréhension du programme. Pour éviter que le compilateur lise ces information utilisez la suite de symbole // pour signifier au compilateur de ne pas lire ce qui suit.
exemple :  
   printf("hello world!\n"); // ceci est un commentaire

Conclusion

Listez toutes les propriétés et informations importantes concernant la mémoire que vous avez appris aujourd'hui.

Travail personnel

Votre programme de jeu de pendu est fonctionnel, mais très vraisemblablement vous avez mis un certain temps pour faire l'"expérience 7", car vous avez , naturellement mis du temps à comprendre à nouveau ce que fait chaque ligne du programme.

Pour éviter cela il est bon d'organiser son code avec des fonctions. Vous allez donc découper l'ensemble du code du jeu de pendu en fonctions qui s'occuperons de différents aspects du jeu.
Par exemple (il y a des tas de manière différentes de faire ce découpage) :
  • Allocation de tableaux de caractère (utilisé pour le "mot secret" et "le mot masque")
  • Initialisation du mot masque
  • Tester si la lettre proposée est présente, ou non, dans le mot secret (et modification éventuelle du mot masque)
Bien sur une fois ces fonctions crées il vous faudra modifier le code dans le main pour qu'il utilise ces fonctions. Idéalement le code qui reste dans le main n'est plus que des appels de fonctions. Si le nom des fonctions et des variables ont bien été choisit , ce code devient alors très facile à lire.