tete du loic

 Loïc YON [KIUX]

  • Enseignant-chercheur
  • Référent Formation Continue
  • Responsable des contrats pros ingénieur
  • Référent entrepreneuriat
  • Responsable de la filière F2 ingénieur
  • Secouriste Sauveteur du Travail
mail
loic.yon@isima.fr
phone
(+33 / 0) 4 73 40 50 42
location_on
ISIMA
  • twitter
  • linkedin
  • viadeo

[C] TP 1 : Outils

Date de première publication : 2018/09/24

Dans ce premier TP de C, nous allons introduire les outils dont nous aurons besoin pour travailler en C cette année.

Nous allons tester et corriger le programme suivant :

#include

void essai(int j) 
{
  int i;
  
  while(i<10) 
  {
    printf("%d ", i+j );
    ++i;
  }
}

int main() 
{
  int j;

    for(j=0; j< 10; ++j)  
    {
      essai(j);
      printf("\n");
    }
  
  return 0;
}

Mise en place (git)

Il est possible de récupérer le programme de différentes manières :

Il faut tout d'abord configurer son compte pour utiliser un tel utilitaire. Tapez les commandes suivantes :

git config --global user.name "un_nom"
git config --global user.email "un_mail"

If faut ensuite récupérer le code, cela va créer le répertoire C1A avec le bon fichier dedans :

git clone https://gitlab.com/kiux/C1A.git

Vous pouvez trouver ce qui ne va pas sans les outils mais vous allez les utiliser quand même.

En règle générale, c'est une excellente idée de compiler les programmes en développement avec cette option -g. On enlève cette option lorsque le programme est compilé pour le distribuer à l'utilisateur final.

valgrind

Le premier outil que nous allons utiliser est valgrind. Cet outil simule l'exécution de notre programme et va analyser tout un tas d'informations. Nous allons avons avoir, entre autres, toutes les anomalies mémoire :

valgrind ./executable

Le résultat est le suivant :

==19248== Conditional jump or move depends on uninitialised value(s)
==19248==    at 0x400574: essai (ddd01.c:17)
==19248==    by 0x400593: main  (ddd01.c:30)

==19248== Use --track-origins=yes to see where uninitialised values come from
==19248== ERROR SUMMARY: 800 errors from 7 contexts (suppressed: 0 from 0)

L'exécution suivante peut donner encore plus d'informations :

valgrind --track-origins=yes ./executable

Vous avez le numéro de ligne, c'est facile maintenant de corriger ! Mais ne le faites pas encore...

ddd

Nous allons maintenant utiliser le débogeur gdb au travers de sa surcouche graphique ddd.

ddd nom_executable_a_tester &

L'interface graphique de débogueur se lance alors et ressemble à ça :

fenetre de ddd

Posez un point d'arrêt sur la première instruction de la fonction essai() en double cliquant (Un STOP apparait). Puis exécutez le programme ligne par ligne jusqu'à trouver l'erreur.

Le curseur flèche verte indique la prochaine instruction à être exécutée.

Si vous avez de la "chance", vous verrez tout de suite ce qui se passe et vous pourrez alors corriger !

ddd n'aime pas certains encodages de fichier ou les accents dans les commentaires. Les symptômes : l'affichage graphique des variables qui ne marche pas ou bien un affichage incomplet du code.

Dans le support de cours en ligne C3, vous trouverez les commandes pour utiliser le débogueur en version texte.

Bibliothèque de tests

De nombreux TPs vont se faire en utilisant des "tests unitaires". Le principe est de tester régulièrement le code que l'on est en train d'écrire en le confrontant à ce que l'on veut obtenir. Le développement est réputé "terminé" lorsque tous les tests réussissent. (Bien entendu, dans un mode idéal, où les tests couvrent tous les cas possibles d'exécution et que d'autres types de tests ont été réussis)

Vous devez récupérer les fichiers de code pour cet exercice :

git clone https://gitlab.com/kiux/C1B.git

Pour compiler le tout, vous pouvez faire une commande gcc générale mais vous pouvez aussi simplement lancer la commande :

make

Cela exécute des instructions de compilation (encore appelées règles) contenues dans le fichier Makefile lui-aussi fourni.

Premiers tests

On vous demande de coder la fonction pgcd() qui calcule le plus grand diviseur commun entre deux nombres entiers. Si vous complétez le code de la fonction dans le fichier mon_code.c, les tests seront réussis (OK ou passed) et non plus en echec (KO ou failed) !

main.c:   9 | EXPECT  : 12 == pgcd(36, 24)
main.c:  10 | EXPECT  : 3 == pgcd(96, 81)
main.c:  11 | EXPECT  : 1 == pgcd(17, 1)
main.c:  17 | EXPECT  : 12 == pgcd(24, 36)
main.c:  18 | EXPECT  : 3 == pgcd(81, 96)
main.c:  19 | EXPECT  : 1 == pgcd( 1, 17)
--- teZZT REPORT ---
  6 test(s) failed
  0 test(s) passed

Au passage, le pgcd de deux nombres a et b vautb si le reste de la division entière de a par b est nul sinon c'est le pgcd de b et de ce reste (définition récursive).

Transformer en majuscules

Vous pouvez ensuite décommenter les tests suivants. Il s'agit de tester la fonction majuscules() que vous avez écrite pendant les semaines bloquées (vous pouvez réutiliser ce que vous avez écrit naturellement).

On vérifie ce qu'il se passe quand la chaîne en paramètre est vide, quand elle ne contient que des majuscules, que des minuscules et quand elle contient également des caractères qui ne sont pas des lettres.

TEST(maj4) {
  char s[255] = "aAbB2eDdD!";

  majuscules(s);
 
  CHECK(  0 == strcmp( s, "AABB2EDDD!") );
}

Vous pouvez ajouter des tests complémentaires si vous le désirez.