Bonjour,
Je me suis mis aux listes chainées, serait-il possible d'avoir des corrections svp ?
J'ai déposé le code ici pour faire plus simple : https://bitbucket.org/vohu/essais/src
Merci d'avance
Bonjour,
Je me suis mis aux listes chainées, serait-il possible d'avoir des corrections svp ?
J'ai déposé le code ici pour faire plus simple : https://bitbucket.org/vohu/essais/src
Merci d'avance
Bonjour,
Une question préliminaire:
Quel est ton avis sur ce que tu as fait?
Salut, merci pour ton aide,
Alors sur les points que je voudrais être sûr tout de suite :
- Je ne suis pas sûr d'avoir bien géré la libération de la mémoire.
- j'aurai voulu ne pas utiliser des pointeurs de pointeurs ou des pointeurs simples selon les fonctions. Mais j'ai pas réussi à faire autrement.
- sans tenir compte de test.c, je ne sais pas quelles vérifications de sécurité je peux ajouter. Car pour l'instant, toutes mes fonctions renvoient 1 (ce qui explique l'absence de tests dans le fichier test.c)..
- les include du fichier .h : je ne sais jamais trop où les mettre. Dans le .c ou le .h
Sur les améliorations que je ferais après être certain qu'il n'y a pas d'incohérences sur ce que j'ai déjà fait :
- j'ai commenté dans le fichier .h "typedef int_element *ilist;" Je me demande s'il est préférable d'utiliser ce type plutôt que d'utiliser un pointeur sur int_element dans le main()
- trouver des noms de fonctions plus adaptés et sans changer de langage une fois sur deux.
Pour savoir si tu as géré la mémoire correctement, il n'y a beaucoup de solution.
Savoir que les manipulations sont toujours bonnes, et toujours à bon escient.
Pour qu'elle soit toujours bonne, je pense qu'il faut deux fonctions: (supposant T le type valeur)
Ces deux fonctions n'ont pas vocations à être fournie à l'utilisateur. Elle servent à la définition des autres fonctions.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 struct T_element { T valeur; struct T_element *suivant; }; typedef struct T_element *T_liste T_liste creer_T_devant(T valeur, struct T_element *suivant); /* libère l'élément pointé et modifie le pointeur pour désigner le suivant de l'élément pointé retourne la valeur contenu dans l'élément pointé. */ T supprimer_devant_T(struct T_element* *liste);
Par exemple:
L'intérêt, c'est de pouvoir utiliser creer_T_devant() dans toutes les fonctions ajoutant un élément.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 T_liste creer_T_devant(T valeur, T_liste suivant) { T_element *p = malloc( sizeof(struct T_element) ); struct T_element source = {valeur, suivant}; *p = source;//je fais en deux parties, je ne sais plus si en une seule ligne, ca compile return p; }
par exemple:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 T_liste* back_T(T_liste* liste) { if (!liste) return liste; return (liste->suivant) ? back_T(liste->suivant) : liste; } void push_back_T(T_liste* liste, T valeur) { back_T(liste).suivant = creer_T_devant(valeur, 0); } T pop_back_T(T_liste* liste) { if (!liste) return 0;//je n'ai pas vu mieux. à toi de gérer comme tu veux return supprimer_devant_T(back_T(liste).suivant); }
Pour que les manipulations soient faites à bon escient, il suffit de décider ce qui revient au créateur du type liste, et ce qui revient à son utilisateur.
Si la mémoire est intégralement à l'intention du manipulateur, il faut que l'interface des fonctions utilise un liste_type, par pointeur s'il y a modification.
Si l'utilisateur peut être avoir usage de la représentation concrete de la liste (un pointeur de T_element), il est possible de l'utiliser dans les fonctions.
Par exemple tu pourrais avoir dans le liste_T.h
et dans ton liste_T.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 /*#ifndef ...*/ #include "T.h" struct T_element; typedef struct T_element* T_liste; T_liste* back_T(T_liste* liste); void push_back_T(T_liste* liste, T valeur); T pop_back_T(T_liste* liste);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include "liste_T.h" struct T_element { T valeur; struct T_element *suivant; }; T_liste creer_T_devant(T valeur, struct T_element *suivant) { ... } /* libère l'élément pointé et modifie le pointeur pour désigner le suivant de l'élément pointé retourne la valeur contenu dans l'élément pointé. */ T supprimer_devant_T(struct T_element* *liste) { ... } /* implémentation des fonctions publiques*/
Mais tu as regardé ce que j'ai fait ?
Oui, et c'est pour ca que je te montre ce que j'aurais fait.
Par ailleurs, tu es parti sur un retour de code d'erreur. C'est un choix, mais il faut s'y tenir.
append_f ne doit pas appeler exit, mais retourner un code signifiant l'erreur.
De même pop_f ne vérifie pas si l'argument est nul, ou pointe sur nul. (deux étoiles, deux vérifications).
Partager