TP : premières fonctions

Contenu

TP : premières fonctions#

À faire

2025-2026

  • Leur faire écrire plus de tests automatiques eux-mêmes?

Exercice 1 : renvoyer versus afficher

  1. Les deux cellules suivantes définissent respectivement les fonctions valeurAbsolue et afficheValeurAbsolue; notez les différences entre ces deux fonctions, puis exécutez les cellules.

#include <iostream>
using namespace std;
/** Une fonction qui calcule la valeur absolue
 * @param a un entier
 * @return la valeur absolue de a
 **/
int valeurAbsolue(int a) {
    if (a > 0) {
        return a;
    } else {
        return -a;
    }
}
/** Une fonction qui affiche la valeur absolue
 * @param a, un entier
 **/
void afficheValeurAbsolue(int a) {
    if (a > 0) {
        cout << a << endl;
    } else {
        cout << -a << endl;
    }
}

Exercice 1 (suite)

  1. Observez les appels suivants; y a-t-il une différence entre valeurAbsolue et afficheValeurAbsolue?

valeurAbsolue(-3)
3
type: int
afficheValeurAbsolue(-3)
3
valeurAbsolue(-3);
afficheValeurAbsolue(-3);
3
valeurAbsolue(-3) == 3
true
type: bool
afficheValeurAbsolue(-3) == 3

input_line_20
:
2
:
27
:
 


error
: 


invalid operands to binary expression ('void' and 'int')


 afficheValeurAbsolue(-3) == 3


 ~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~


Interpreter Error: 

Explication

valeurAbsolue renvoie une valeur alors que afficheValeurAbsolue l'affiche. On notera ci-dessus que, avec valeurAbsolue(3);, Jupyter ne montre pas du tout la valeur alors que, avec valeurAbsolue(3), Jupyter montre la valeur avec son type (int). Inversement afficheValeurAbsolue affiche la valeur mais ne la renvoie pas.

Exercice 1 (suite)

  1. Essayez de deviner le résultat des appels suivants puis exécutez pour vérifier :

valeurAbsolue(-5) + valeurAbsolue(3)
8
type: int
afficheValeurAbsolue(-5) + afficheValeurAbsolue(3)

input_line_23
:
2
:
27
:
 


error
: 


invalid operands to binary expression ('void' and 'void')


 afficheValeurAbsolue(-5) + afficheValeurAbsolue(3)


 ~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~


Interpreter Error: 

Exercice 1 (suite)

  1. La seconde cellule vous donne une erreur, comprenez-vous pourquoi?

Exercice 2 : une fonction utilisant une fonction

  1. Complétez la fonction ci-dessous dont on donne la documentation.

    ⚠️ Vous devez utiliser un appel à l'une des deux fonctions précédentes, afficheValeurAbsolue ou valeurAbsolue; laquelle faut-il choisir? Pourquoi? ⚠️

/** Distance de deux points sur une droite
 * @param a un entier: la coordonnée du premier point
 * @param b un entier: la coordonnée du deuxième point
 * @return la valeur absolue de la différence entre a et b
 **/
int distance(int a, int b) {
    /// BEGIN SOLUTION
    return valeurAbsolue(b - a);
    /// END SOLUTION
}

Notes aux enseignants

Malgré les consignes écrites en gras, certains ne font pas appel à valeurAbsolue dans la fonction distance, soit parce qu'ils n'ont pas compris ce qu'est un appel de fonction, soit parce qu'ils ne comprennent pas qu'une fonction peut en appeler une autre. D'autres font un appel, mais très maladroit.

Si vous avez le temps, n'hésitez pas à passer vérifier la fonction valeurAbsolue de tous vos élèves.

Exercice 2 (suite)

  1. Vérifiez le comportement de votre fonction distance sur l'exemple ci-dessous; essayez sur quelques autres exemples; corrigez la fonction si nécessaire :

distance(5,3)
2
type: int

Exercice 2 (suite)

  1. Les tests ci-dessous automatisent partiellement la vérification du comportement de la fonction distance, en spécifiant chaque fois la valeur attendue. Vérifiez que l'on obtient bien true à chaque fois :

distance(5,3) == 2
true
type: bool
distance(-4,2) == 6
true
type: bool
distance(2,-5) == 7
true
type: bool

Exercice 3 : tests automatiques

Dans l'exercice précédent, on a testé la fonction distance. Cependant, il a fallu exécuter les trois cellules de test séparément et s'assurer pour chacune d'entre elles que true était affiché et pas false. Pour n'être averti que s'il y a un problème et savoir d'où il provient, nous allons rassembler les tests en une seule cellule à l'aide de l'infrastructure d'automatisation des tests vue en cours.

  1. Essayez les exemples suivants.

Astuce

Si vous avez une erreur du type no member named 'cerr', vous avez probablement redémarré le noyau en oubliant d'exécuter la première cellule de cette feuille contenant #include <iostream>.

À chaque fois que vous redémarrez le noyau, allez ensuite dans Noyau -> Redémarrer le noyau et exécuter jusqu'à la cellule sélectionnée. Cela exécute toutes les cellules qui sont avant celle où vous vous trouvez. Vous éviterez ainsi de perdre du temps à chercher où sont les cellules qu'il faut ré-exécuter.

CHECK ( 1 < 2 );
CHECK ( 1 > 2 );
Standard Exception: Test failed: 1 > 2

Exercice 3 (suite)

Notez que, si la condition en paramètre de CHECK est vraie, il n'y a aucun affichage. Par contre si la condition est fausse, un message d'erreur indiquant la condition fausse est affiché.

Avec CHECK, les tests de la fonction distance se mettent sous la forme :

CHECK ( distance(5,3)  == 2 );
CHECK ( distance(-4,2) == 6 );
CHECK ( distance(2,-5) == 7 );
// BEGIN HIDDEN TESTS
CHECK ( distance(-5,-2) == 3);
// END HIDDEN TESTS

Exercice 3 (suite)

  1. Exécutez ces tests. Leur exécution ne devrait rien afficher.

  2. Exécutez les deux cellules suivantes pour définir et tester la fonction maxValeurAbsolue. Corrigez la fonction pour qu'elle passe les tests. :::

Exercice 3 (suite)

  1. Ajoutez un test avec les valeurs 5 et -15, dans cet ordre :

/// BEGIN SOLUTION
CHECK( maxValeurAbsolue(5, -3) );
/// END SOLUTION

input_line_35
:
3
:
8
:
 


error
: 


use of undeclared identifier 'maxValeurAbsolue'


CHECK( maxValeurAbsolue(5, -3) );


       ^


Interpreter Error: 

Exercice 4 (à la maison)

Mêmes consignes que pour l'exercice 2 avec la fonction suivante :

/** somme des valeurs absolues (aussi appelée norme L1)
 * @param a un entier
 * @param b un entier
 * @return la somme des valeurs absolues de a et b
 **/
int sommeValeurAbsolue(int a, int b) {
    /// BEGIN SOLUTION
    return valeurAbsolue(a) + valeurAbsolue(b);
    /// END SOLUTION
}
sommeValeurAbsolue(5,-3)
sommeValeurAbsolue(5,-3)  == 8
sommeValeurAbsolue(-4,-2) == 6
sommeValeurAbsolue(2,5) == 7

Exercice 5 : suivre la documentation et les tests

  1. Définissez la fonction nombreSecondes dont la documentation est donnée ci-dessous :

/** Renvoie en secondes la durée décrite en jours, heures, minutes, secondes
 * @param j un entier représentant le nombre de jours
 * @param h un entier représentant le nombre d heures
 * @param m un entier représentant le nombre de minutes
 * @param s un entier représentant le nombre de secondes
 * @return la durée totale en secondes
**/
/// BEGIN SOLUTION
int nombreSecondes(int j, int h, int m, int s) {
    return s + (60 * (m + 60 * (h + 24*j)));
}
/// END SOLUTION

Exercice 5 (suite)

  1. Vérifiez son fonctionnement sur les exemples et tests ci-dessous :

nombreSecondes(1,1,1,1)
CHECK( nombreSecondes(0,0,0,1)  == 1      );
CHECK( nombreSecondes(0,0,1,0)  == 60     );
CHECK( nombreSecondes(0,1,0,0)  == 3600   );
CHECK( nombreSecondes(1,0,0,0)  == 86400  );
CHECK( nombreSecondes(3,2,5,25) == 266725 );

Bilan#

Dans cette feuille, vous vous êtes familiarisés avec les fonctions : distinction entre afficher et renvoyer, fonction appelant des fonctions, documentation, tests, tests automatiques. Vous avez maintenant le bagage requis pour la suite du TP où vous définirez la fonction exponentielle.