Année universitaire 2002-2003 |
Licence d'informatique
|
On peut connaître la taille occupée par un objet obj en utilisant l'une des deux expressions suivantes :
sizeof(obj)
sizeof obj
La valeur de ces deux expressions est le nombre d'octets occupés par l'objet obj dans la mémoire. Elle est utile principalement pour réserver un espace mémoire de la taille souhaitée par le programmeur, à l'aide de la fonction malloc.
L'objet obj peut être :
... struct exemple { ... struct exemple *p_ex; char ch[20]="beta"; ... p_ex=malloc(sizeof(struct exemple)); /* Ligne a. */ p_ex->chaine=malloc(sizeof(ch));/* Ligne b. */ ... |
Dans la Ligne a, on réserve un espace mémoire suffisant pour stocker une variable de type struct exemple. Dans la Ligne b, on réserve un espace permettant de stocker une chaîne de caractères de taille identique à celle de la variable ch (soit 20 octets).
Lorsqu'une action dépend de la valeur d'une expression, il peut être utile d'utiliser une instruction switch plutôt que des instructions if.
L'exemple suivant est issu de la correction de l'exercice 1 de la troisième séance de travaux pratiques :
... switch (compte(m_ancien,i,j)) { case 0 : case 4 : m[i][j]='B'; break; case 2 : m[i][j]='N'; break; default : m[i][j]=m_ancien[i][j]; } ... |
L'instruction break; signale que la prochaine instruction à exécuter se trouve après la prochaine accolade fermante }. Si l'expression passée en paramètre à l'instruction switch apparaît dans un des cas (case) spécifiés, alors la séquence d'instructions qui suit (jusqu'à la prochaine instruction break; ou jusqu'à l'accolade fermante de l'instruction switch) est exécutée. Dans le cas contraire (si l'expression passée en paramètre à l'instruction switch n'apparaît dans aucun des cas spécifiés), alors la séquence d'instructions qui suit default est exécutée.
On désire écrire un programme permettant la gestion d'un agenda. Pour cela, on va créer une liste chaînée, dans laquelle chaque cellule, de type struct fiche, contiendra les informations concernant une personne. On utilisera par conséquent les directives d'inclusion et les définitions suivantes :
La principale difficulté de cet exercice sera l'allocation dynamique de mémoire (cf. la séance 5 de travaux dirigés) pour toute nouvelle cellule de la liste chaînée. Il est demandé de n'utiliser aucune variable globale. On propose de procéder de la manière suivante :
1) Dans le programme principal main, on effectue la déclaration et l'initialisation suivantes :
struct fiche *p_liste=NULL;
Cette variable, qui pointera sur le premier élément de la liste chaînée, sera passée en paramètre aux différentes fonctions, soit par valeur, soit par adresse (auquel cas un des paramètres formels sera de type struct fiche **).
2) Dans le programme principal, on affiche le menu suivant en boucle :
jusqu'à ce que l'utilisateur tape le caractère 0. On gérera les différentes réponses possibles à l'aide d'une instruction d'aiguillage à choix multiple (mot-clé switch, cf. le paragraphe 2).
3) Écrire les fonctions suivantes :
void ajouter(struct fiche **pp_liste)
Cette fonction permet la saisie du nom (40 caractères maximum) et du numéro de téléphone (10 chiffres) d'une personne. Il ne faut pas oublier de faire l'allocation dynamique d'une zone mémoire de taille sizeof(struct fiche), et de stocker l'adresse de cette zone mémoire dans une variable locale, de nom p_nouv.
L'ajout d'une nouvelle personne dans l'agenda se fera selon l'algorithme suivant :
void afficher(struct fiche *p_liste)
Cette fonction affiche à l'écran l'ensemble des personnes inscrites dans l'agenda, en indiquant le nom et le numéro de téléphone d'une personne par ligne.
void quitter(struct fiche **pp_liste)
Cette fonction libère la totalité de l'espace mémoire qui a été alloué dynamiquement pour la création de la liste chaînée. On conseille de commencer par libérer la première cellule de la liste chaînée, et ainsi de suite.
Pour écrire cette fonction, on doit appeler la fonction free autant de fois qu'il y a de personnes dans l'agenda. Il ne suffit pas de libérer l'espace mémoire pointé par *pp_liste !
int compa(char *s,char *t)
Cette fonction permet de comparer deux chaînes de caractères passées en paramètres.
void retirer(struct fiche **pp_liste)
Cette fonction permet de retirer une personne de l'agenda, dans le cas bien sûr où elle s'y trouve. Le nom de cette personne doit être demandé à l'utilisateur à l'intérieur de la fonction. L'espace mémoire occupé par cette personne doit être libéré.
void trier(struct fiche **pp_liste)
Cette fonction modifie le chaînage, de telle sorte que les personnes soient "chaînées" par ordre alphabétique.