2 Partie C de l'examen
L'application d'une formule à une liste de variables (par exemple les
temps CPU et nombres d'entrées/sorties) met en jeu des coefficients
pour produire une valeur (le coût).
Les variables sont représentées par des noms dans les formules. Les
coefficients sont entiers.
On suppose défini dans une bibliothèque ad hoc le type
value_t et les fonctions de manipulation (entrée, sortie,
calcul) sur ce type. L'interface de cette bibliothèque est donnée par
le fichier val.h suivant
#ifndef _VAL_H_
#define _VAL_H_
typedef float value_t;
/* entrées/sorties */
void read_value(value_t *val);
void write_value(value_t val);
/* conversion depuis une chaîne de caractères */
void a_to_value(value_t *val, const char *s);
/* calcul */
void sum_value(value_t n1, value_t n2, value_t *r); /* *r = n1 + n2 */
void mul_value(value_t n, int coeff, value_t *r); /* *r = n * c */
void div_value(value_t n, int coeff, value_t *r); /* *r = n / c */
#endif
On ne devra jamais faire de calcul directement sur les valeurs mais
systématiquement utiliser les fonctions de la bibliothèque
val.
Une formule est caractérisée par les éléments suivants :
-
le résultat d'une formule est une valeur ;
- une formule peut être la somme de deux formules ;
- une formule peut être une formule multipliée ou divisée par un
coefficient ;
- une formule peut se résumer à la valeur d'une variable.
On utilisera les définitions suivantes disponibles dans le fichier
formula_t.h :
#ifndef _FORMULA_T_H_
#define _FORMULA_T_H_
#define NAME_LG 16
enum op_e {SUM_OP, MUL_OP, DIV_OP, VAL_OP};
struct var_s {
char var_name[NAME_LG]; /* nom de la variable */
value_t var_val; /* valeur de cette variable */
struct var_s *var_next; /* chaînage de toutes les variables */
};
struct form_elem_s {
enum op_e fe_operator;
union {
struct var_s *fe_var;
struct form_elem_s *fe_form;
int fe_coeff;
} fe_operand1,
fe_operand2;
};
#endif
Chaque élément de type struct var_s réalise l'association
d'une valeur à un nom de variable. Toutes les variables utilisées dans
une formule sont chaînées dans une liste en utilisant le champs
var_next.
Le type des champs fe_operand1 et fe_operand2
dépend de la valeur du champ fe_operator, il est cohérent
avec les propriétés des formules :
valeur de fe_operator |
type de fe_operand1 |
type de fe_operand2 |
SUM_OP |
(struct form_elem_s *) |
(struct form_elem_s *) |
MUL_OP ou DIV_OP |
(struct form_elem_s *) |
int |
VAL_OP |
(struct var_s *) |
champ non utilisé |
Chaque élément de type struct form_elem_s représente une
formule que l'on supposera correcte. Par exemple, la formule
(a*2+b+c) /4 + c
peut être accessible par deux variables déclarées
struct form_elem_s *formule;
struct var_s *liste_vars;
et peut être représentée comme à la figure 1.
Figure 1 : Représentation possible de la formule
La fonction
void input_values(struct var_s *list, char *argv[]);
remplit les valeurs des variables de la liste list avec les
chaînes de caractères du tableau argv. L'extrait de code C
suivant illustre l'utilisation de cette fonction ;
int
main(int argc, char *argv[])
{
struct form_elem_s *formule;
struct var_s *liste_vars;
/* creation de la formule et de la liste des variables */
...
/* affectation des variables */
input_values(liste_vars, argv+1);
/* ... */
La commande suivante est un exemple d'utilisation du programme issu de
ce code qui va affecter les trois variables de la liste :
% ./a.out 10.0 8.0 12.0
Exercice 5 [fonction input_values()]
Donnez le principe et le code C de la fonction
input_values().
La fonction
void print_formula(struct form_elem_s *formula);
calcule la valeur d'une formule en utilisant les valeurs déjà
associées aux variables ; la valeur résultante de la formule est
ensuite affichée.
Exercice 6 [fonction print_formula()]
Donnez l'algorithme et le code C de la fonction
print_formula().
On suppose que tous les éléments de type struct var_s et de
type struct form_elem_s ont été alloués dynamiquement
malloc(). La fonction
void free_formula(struct form_elem_s **formula,
struct var_s **var_list);
désalloue tous ces éléments et réinitialise à zéro ses paramètres.
Exercice 7 [fonction free_formula()]
Donnez le principe et le code C de la fonction
free_formula().
Exercice 8 [bibliothèque formula]
Les fonctions des exercices précédents utilisent possiblement
d'autres fonctions que vous avez définies.
Donnez le source C d'un fichier qui une fois compilé séparément
produit une bibliothèque qui fournit exactement (ni plus, ni
moins) les trois fonctions définies par
#ifndef _FORMULA_H_
#define _FORMULA_H_
#include "formula_t.h"
void input_values(struct var_s *list, char *argv[]);
void print_formula(struct form_elem_s *formula);
void free_formula(struct form_elem_s **formula,
struct var_s **var_list);
#endif
Bien entendu, ne réécrivez pas entièrement le corps de vos
fonctions mais abrégez en ne recopiant que l'essentiel.