đ DĂ©bogage et trace d'exĂ©cution
đŻ Objectifâ
Utiliser le débogueur de Visual Studio de façon systématique et réaliser une trace d'exécution pour comprendre et corriger un programme qui contient des boucles et des tableaux.
Jusqu'ici, tu as surtout tracé du code simple (variables, if) au cours 2.2. Maintenant que tes programmes contiennent des boucles for imbriquées et des tableaux 2D, les lire de haut en bas ne suffit plus : il faut observer le programme pendant qu'il s'exécute.
1ïžâŁ Les trois familles d'erreursâ
Avant de déboguer, il faut savoir quel type d'erreur on a devant soi.
| Type d'erreur | Quand ? | Exemple | Comment la trouver ? |
|---|---|---|---|
| Compilation (syntaxe) | Avant l'exécution | Consol.WriteLine(...), ; manquant | Visual Studio le souligne en rouge et refuse de compiler |
| ExĂ©cution (exception) | Pendant l'exĂ©cution | IndexOutOfRangeException, FormatException | Le programme plante et Visual Studio s'arrĂȘte sur la ligne fautive |
| Logique | Pendant l'exĂ©cution | Le total affichĂ© est 0, la grille est dĂ©calĂ©e | â Le programme fonctionne, mais le rĂ©sultat est faux â c'est ici que le dĂ©bogueur devient indispensable |
Un programme qui compile et qui ne plante pas n'est pas un programme correct. C'est toi qui dois vérifier que le résultat est le bon.
2ïžâŁ La boĂźte Ă outils du dĂ©bogueurâ
đŽ Le point d'arrĂȘt (breakpoint)â
Un point d'arrĂȘt dit au programme : « arrĂȘte-toi juste avant d'exĂ©cuter cette ligne ».
- Clique dans la marge grise à gauche du numéro de ligne, ou appuie sur
F9. - Un cercle rouge apparaĂźt. Lance le programme avec
F5: il s'arrĂȘte sur la ligne (surlignĂ©e en jaune). - La ligne jaune n'est pas encore exĂ©cutĂ©e.
Sur la premiÚre ligne du bloc que tu soupçonnes, pas au tout début de Main. Si le total d'une boucle est faux, place-le sur la ligne de la boucle, pas 40 lignes plus haut.
âšïž Les touches pour avancerâ
| Touche | Nom | Ce que ça fait |
|---|---|---|
F5 | Continuer | Repart et court jusqu'au prochain point d'arrĂȘt |
F10 | Pas Ă pas principal (Step Over) | ExĂ©cute la ligne courante au complet et s'arrĂȘte Ă la suivante |
F11 | Pas à pas détaillé (Step Into) | Entre à l'intérieur de la fonction appelée sur cette ligne |
Maj + F11 | Pas Ă pas sortant (Step Out) | Termine la fonction courante et revient Ă l'appelant |
Maj + F5 | ArrĂȘter | Termine la session de dĂ©bogage |
F10 ou F11 ?Utilise F10 pour parcourir ton code ligne par ligne. Utilise F11 seulement quand tu veux voir ce qui se passe dans une de tes fonctions. Sur un Console.WriteLine(...), F11 ne sert Ă rien : c'est du code de Microsoft.
đ Observer les variablesâ
Pendant que le programme est arrĂȘtĂ©, plusieurs façons de voir les valeurs :
- Survoler une variable avec la souris â une infobulle affiche sa valeur.
- FenĂȘtre Variables locales (Locals) â toutes les variables du bloc courant.
- FenĂȘtre Automatique (Autos) â seulement les variables des lignes autour.
- FenĂȘtre Espion (Watch) â tu y ajoutes ce que tu veux suivre, y compris une expression.
Dans la fenĂȘtre Espion, tu peux Ă©crire une expression complĂšte et la voir se mettre Ă jour Ă chaque F10 :
grille[rangee, colonne]â la case courantegrille.GetLength(0)â le nombre de rangĂ©estotal / nbNotesâ vĂ©rifier un calcul avant qu'il soit faux
Menu : DĂ©boguer â FenĂȘtres â Espion â Espion 1 (Ctrl + Alt + W, 1).
đ DĂ©plier un tableauâ
Dans Variables locales, clique sur la ➠à gauche d'un tableau pour voir toutes ses cases. Pour un tableau 2D, les cases sont affichées sous la forme [0, 0], [0, 1], [1, 0]⊠C'est le moyen le plus rapide de voir qu'une rangée est restée vide (0 partout).
3ïžâŁ Trace d'exĂ©cution d'une boucleâ
La trace d'exĂ©cution est la version papier du dĂ©bogueur : on suit le programme instruction par instruction en notant l'Ă©volution des variables. Tu en as besoin Ă l'examen, oĂč il n'y a pas de Visual Studio.
Exemple 1 â Boucle for avec accumulateurâ
1. int[] notes = { 80, 90, 70 };
2. int total = 0;
3. for (int i = 0; i < notes.Length; i++)
4. {
5. total = total + notes[i];
6. }
7. Console.WriteLine(total);
| Instruction exécutée | i | notes[i] | total | Affichage |
|---|---|---|---|---|
| 2 | â | â | 0 | â |
| 3 | 0 | 80 | 0 | â |
| 5 | 0 | 80 | 80 | â |
| 3 | 1 | 90 | 80 | â |
| 5 | 1 | 90 | 170 | â |
| 3 | 2 | 70 | 170 | â |
| 5 | 2 | 70 | 240 | â |
| 3 | 3 | â n/a | 240 | â |
| 7 | 3 | â | 240 | 240 |
Remarque l'avant-derniĂšre ligne : i vaut 3, le test i < 3 est false, on sort de la boucle. C'est exactement ce que tu verras en appuyant sur F10 une fois de trop.
Exemple 2 â Boucles imbriquĂ©es sur un tableau 2Dâ
1. int[,] grille = { { 1, 2 },
{ 3, 4 } };
2. int somme = 0;
3. for (int rangee = 0; rangee < grille.GetLength(0); rangee++)
4. {
5. for (int colonne = 0; colonne < grille.GetLength(1); colonne++)
6. {
7. somme = somme + grille[rangee, colonne];
8. }
9. }
| Instruction exécutée | rangee | colonne | grille[rangee, colonne] | somme |
|---|---|---|---|---|
| 2 | â | â | â | 0 |
| 3 | 0 | â | â | 0 |
| 5 | 0 | 0 | 1 | 0 |
| 7 | 0 | 0 | 1 | 1 |
| 5 | 0 | 1 | 2 | 1 |
| 7 | 0 | 1 | 2 | 3 |
| 5 | 0 | 2 | â n/a | 3 |
| 3 | 1 | â | â | 3 |
| 5 | 1 | 0 | 3 | 3 |
| 7 | 1 | 0 | 3 | 6 |
| 5 | 1 | 1 | 4 | 6 |
| 7 | 1 | 1 | 4 | 10 |
| 5 | 1 | 2 | â n/a | 10 |
| 3 | 2 | â | â | 10 |
colonne est redéclarée à 0 à chaque tour de la boucle extérieure. La boucle intérieure fait donc tous ses tours pour chaque rangée : 2 rangées à 2 colonnes = 4 passages par la ligne 7.
4ïžâŁ Les bogues classiques (et comment les repĂ©rer)â
â IndexOutOfRangeExceptionâ
int[] notes = { 80, 90, 70 };
for (int i = 0; i <= notes.Length; i++) // đ„ <= au lieu de <
{
Console.WriteLine(notes[i]);
}
Un tableau de 3 Ă©lĂ©ments a les indices 0, 1, 2. Avec <=, on essaie de lire notes[3] â đ„
đ Au dĂ©bogueur : le programme s'arrĂȘte sur la ligne fautive. Survole i et notes.Length : tu verras 3 et 3.
â Les dimensions inversĂ©esâ
for (int rangee = 0; rangee < grille.GetLength(1); rangee++) // đ„ (1) au lieu de (0)
Sur une grille carrée (3 à 3), ce bogue ne plante jamais et ne se voit pas. Sur une grille 2 à 5, il plante ou saute des cases.
đ Au dĂ©bogueur : ajoute grille.GetLength(0) et grille.GetLength(1) dans la fenĂȘtre Espion.
â L'accumulateur rĂ©initialisĂ© dans la boucleâ
for (int i = 0; i < notes.Length; i++)
{
int total = 0; // đ„ remis Ă 0 Ă chaque tour
total = total + notes[i];
}
đ Au dĂ©bogueur : place un point d'arrĂȘt sur la ligne du total et appuie sur F10 plusieurs fois. Tu verras total retomber Ă 0 Ă chaque tour au lieu de grandir.
â Le WriteLine au mauvais endroitâ
Un affichage dans la boucle intérieure au lieu de la boucle extérieure (ou l'inverse) donne une grille en une seule colonne, ou toutes les valeurs collées sur une ligne.
đ Au dĂ©bogueur : F10 pas Ă pas en gardant la fenĂȘtre Console visible Ă cĂŽtĂ© de Visual Studio pour voir quand chaque caractĂšre est Ă©crit.
5ïžâŁ Une mĂ©thode en 5 Ă©tapesâ
Devant un programme qui ne fonctionne pas, ne modifie pas le code au hasard đČ
- Reproduire â quelles entrĂ©es provoquent le problĂšme, Ă tous les coups ?
- Situer â quelle est la derniĂšre ligne dont tu es certain qu'elle est correcte ? Place ton point d'arrĂȘt lĂ .
- Formuler une hypothĂšse â « je pense que
colonnene revient pas Ă 0 ». - VĂ©rifier â
F10pas Ă pas, en lisant les Variables locales ou l'Espion. L'hypothĂšse est confirmĂ©e ou Ă©liminĂ©e. - Corriger, puis retester â et relancer aussi les cas qui fonctionnaient avant la correction.
« Ăa devrait marcher » n'est pas un diagnostic. Le dĂ©bogueur te donne la vraie valeur de chaque variable : sers-t'en au lieu de supposer.
Vous devez réaliser le laboratoire suivant :