Polynome 2
Fermé
scoutantho
Messages postés
50
Date d'inscription
jeudi 10 avril 2014
Statut
Membre
Dernière intervention
25 juillet 2016
-
12 janv. 2016 à 19:28
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 - 16 janv. 2016 à 12:13
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 - 16 janv. 2016 à 12:13
A voir également:
- Polynome 2
- Jdownloader 2 - Télécharger - Téléchargement & Transfert
- 2 comptes whatsapp - Guide
- Epson scan 2 ✓ - Forum Imprimante
- 2 ecran pc - Guide
- Scratch 2 gratuit - Télécharger - Éducatifs
2 réponses
paly2
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
25
13 janv. 2016 à 19:12
13 janv. 2016 à 19:12
Re-bonjour !
En fait, Polynome est indirectement modifié.
Dans ta boucle, temp.suivant correspond en toujours à une adresse contenue dans Polynome. Donc, une modification de temp->suivant (qui s'accèderait dans Polynome par Polynome.premier->suivant->suivant->suivant...) modifie la valeur qu'on pourrait obtenir directement via Polynome, parce que l'adresse reste la même.
Comme dans ta boucle, tu modifies inf->suivant, qui lui-même est une copie de temp est pointe donc vers la même variable que temp->suivant, tu modifies Polynome...
Mais tout ceci, tu sembles l'avoir très bien compris puisque tu fais exactement ce qu'il faut faire dans ta boucle (enfin, il me semble, je n'ai pas testé le programme) !
Là où je veux en venir, c'est qu'il n'est aucun besoin de retourner un polynôme, mais si c'est absolument nécessaire dans l'énoncé, tu peux retourner Polynome (qui aura été modifié).
Et une dernière chose : aie pitié de ta RAM, et fais des free() pour chaque variable allouée par malloc(). Sinon ça s'appelle une fuite de mémoire et la mémoire allouée par malloc() n'est pas désallouée avant le prochain redémarrage de l'ordinateur.
En fait, Polynome est indirectement modifié.
Dans ta boucle, temp.suivant correspond en toujours à une adresse contenue dans Polynome. Donc, une modification de temp->suivant (qui s'accèderait dans Polynome par Polynome.premier->suivant->suivant->suivant...) modifie la valeur qu'on pourrait obtenir directement via Polynome, parce que l'adresse reste la même.
Comme dans ta boucle, tu modifies inf->suivant, qui lui-même est une copie de temp est pointe donc vers la même variable que temp->suivant, tu modifies Polynome...
Mais tout ceci, tu sembles l'avoir très bien compris puisque tu fais exactement ce qu'il faut faire dans ta boucle (enfin, il me semble, je n'ai pas testé le programme) !
Là où je veux en venir, c'est qu'il n'est aucun besoin de retourner un polynôme, mais si c'est absolument nécessaire dans l'énoncé, tu peux retourner Polynome (qui aura été modifié).
Et une dernière chose : aie pitié de ta RAM, et fais des free() pour chaque variable allouée par malloc(). Sinon ça s'appelle une fuite de mémoire et la mémoire allouée par malloc() n'est pas désallouée avant le prochain redémarrage de l'ordinateur.
paly2
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
25
15 janv. 2016 à 10:45
15 janv. 2016 à 10:45
Et voici une fonction DetruitPolynome gratuite qui devrait fonctionner :
ATTENTION ! Si le pointeur suivant du dernier monome n'est pas a NULL, cette fonction tombera dans une boucle infinie d'appel récursif, et comme à chaque appel et prendra un peu plus de place dans la pile, tu vas saturer la mémoire. Donc, bien vérifier que la chaîne de monomes se termine par NULL !
Et au fait, dans ta fonction InserePolynome, il ne faut pas allouer avec malloc() les variables inf, sup, et temp, car tu les fais toutes pointer vers une zone de mémoire déjà allouer. Du coup, si tu utilises free() après, ce ne sera plus la bonne zone que tu désalloueras (il y aura une fuite de mémoire + une désallocation non voulue). Il te suffit donc de les initialiser à NULL (Exemple :
void DetruitMonome(monome* M) {
if (M->suivant != NULL)
DetruitMonome(M->suivant);
free(M);
}
void DetruitPolynome(polynome P) {
DetruitMonome(P.premier);
}
ATTENTION ! Si le pointeur suivant du dernier monome n'est pas a NULL, cette fonction tombera dans une boucle infinie d'appel récursif, et comme à chaque appel et prendra un peu plus de place dans la pile, tu vas saturer la mémoire. Donc, bien vérifier que la chaîne de monomes se termine par NULL !
Et au fait, dans ta fonction InserePolynome, il ne faut pas allouer avec malloc() les variables inf, sup, et temp, car tu les fais toutes pointer vers une zone de mémoire déjà allouer. Du coup, si tu utilises free() après, ce ne sera plus la bonne zone que tu désalloueras (il y aura une fuite de mémoire + une désallocation non voulue). Il te suffit donc de les initialiser à NULL (Exemple :
monome temp = NULL;). Pour le monome nouvel, je te conseille de l'allouer automatiquement (tu remplaceras alors les
nouvel->par des
nouvel.).
scoutantho
Messages postés
50
Date d'inscription
jeudi 10 avril 2014
Statut
Membre
Dernière intervention
25 juillet 2016
15 janv. 2016 à 11:29
15 janv. 2016 à 11:29
ok, merci de tes fonctions et de ton indication sur les free, je le ferais juste apres, en attendant, j'ai résolu une erreur, j'ai remplacé la ligne 24 else { nouvel->suivant = temp; }
par else { nouvel->suivant = Polynome.premier;
Polynome.premier->suivant = NULL;
Polynome.premier = nouvel;
}
car oui, il faut retourner Polynome mais faut bien lui dire que le debut du polynome est le nouvel element pas le milieu comme c'était le cas.
Maintenant j'ai une violation d'écriture sur la deuxième itération à la ligne 43 :
par else { nouvel->suivant = Polynome.premier;
Polynome.premier->suivant = NULL;
Polynome.premier = nouvel;
}
car oui, il faut retourner Polynome mais faut bien lui dire que le debut du polynome est le nouvel element pas le milieu comme c'était le cas.
Maintenant j'ai une violation d'écriture sur la deuxième itération à la ligne 43 :
//problème ici 2 eme itération
if (inf->degre<nouvel->degre && sup->degre>nouvel->degre) //parcours de monome de 1 en 1 pour bien le placer
{
inf->suivant = nouvel;
nouvel->suivant = sup;
}
else if (inf->degre == nouvel->degre /*&& sup->degre>nouvel->degre*/) // cas où coeff ==
{ //j'additione
inf->coef = inf->coef + nouvel->coef;
}
paly2
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
25
Modifié par paly2 le 15/01/2016 à 13:09
Modifié par paly2 le 15/01/2016 à 13:09
Je ne connais pas les violations d'écriture... Ce sont des erreurs de segmentation ?
Fais du pas à pas pour savoir précisément où elle se trouve, vérifie que tous les pointeurs pointent vers des variables que tu connais et que tu as toi-même allouées (dynamiquement ou automatiquement), et qu'ils ne sont pas utilisés avant d'être initialisés.
Fais du pas à pas pour savoir précisément où elle se trouve, vérifie que tous les pointeurs pointent vers des variables que tu connais et que tu as toi-même allouées (dynamiquement ou automatiquement), et qu'ils ne sont pas utilisés avant d'être initialisés.
scoutantho
Messages postés
50
Date d'inscription
jeudi 10 avril 2014
Statut
Membre
Dernière intervention
25 juillet 2016
>
paly2
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
15 janv. 2016 à 13:39
15 janv. 2016 à 13:39
ok, j'ai pas mal avancé, j'ai moin de faute, il me reste les fonctions :
void DetruitPolynome(polynome* p_P);
// Destruction d'un polynome
( la fonction que tu m'a donné tres gentiment, je n'ai pas réussi à l'impléenter dans mon code selon la déclaration qu'on nous a obligé de mettre. ) j'espere que tu pourras m'aider une derniere fois, je dois le rendre pour ce soir 18h, merci à toi en tout cas. ( meem 18h passé je voudrais une solution pour comprendre merci )
polynome DerivePolynome(polynome P);
// Derivee d'un polynome
polynome AdditionPolynome(polynome P1, polynome P2);
// Somme de 2 polynomes
polynome MultiplicationMonome(polynome P, monome M);
// Multiplication d'un polynome par un monome
polynome MultiplicationPolynomes(polynome P1, polynome P2);
//Multiplication des polynomes P1 et P2
void DetruitPolynome(polynome* p_P);
// Destruction d'un polynome
( la fonction que tu m'a donné tres gentiment, je n'ai pas réussi à l'impléenter dans mon code selon la déclaration qu'on nous a obligé de mettre. ) j'espere que tu pourras m'aider une derniere fois, je dois le rendre pour ce soir 18h, merci à toi en tout cas. ( meem 18h passé je voudrais une solution pour comprendre merci )
polynome DerivePolynome(polynome P);
// Derivee d'un polynome
polynome AdditionPolynome(polynome P1, polynome P2);
// Somme de 2 polynomes
polynome MultiplicationMonome(polynome P, monome M);
// Multiplication d'un polynome par un monome
polynome MultiplicationPolynomes(polynome P1, polynome P2);
//Multiplication des polynomes P1 et P2
paly2
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
25
Modifié par paly2 le 16/01/2016 à 12:15
Modifié par paly2 le 16/01/2016 à 12:15
Oups, pardon, pour ta fonction, j'avais oublié le prototype imposé !
Ça fait donc quelque chose comme ça (c'est très simple, il suffit de remplacer les
Note que tu n'es pas obligé de mettre le prototype de la fonction DetruitMonome dans ton .h, tu peux tout à fait la garder comme fonction permettant le fonctionnement de la fonction DetruitPolynome (seule accessible de l'extèrieur). En effet, dans de tels cas, une fonction qui s'appelle elle-même récursivement est très utile pour commencer par détruire le derniere monôme.
Pour les autres fonctions, il faudra toujours une (ou plusieurs) boucle qui se ressemblera avec des opérations à l'intérieur :) (après c'est des maths :p)
Ça fait donc quelque chose comme ça (c'est très simple, il suffit de remplacer les
P.par des
p_P->) :
void DetruitMonome(monome* M) {
if (M->suivant != NULL)
DetruitMonome(M->suivant);
free(M);
}
void DetruitPolynome(polynome *p_P) {
DetruitMonome(p_P->premier);
}
Note que tu n'es pas obligé de mettre le prototype de la fonction DetruitMonome dans ton .h, tu peux tout à fait la garder comme fonction permettant le fonctionnement de la fonction DetruitPolynome (seule accessible de l'extèrieur). En effet, dans de tels cas, une fonction qui s'appelle elle-même récursivement est très utile pour commencer par détruire le derniere monôme.
Pour les autres fonctions, il faudra toujours une (ou plusieurs) boucle qui se ressemblera avec des opérations à l'intérieur :) (après c'est des maths :p)
13 janv. 2016 à 21:10
void AffichagePolynome(polynome P) { monome * temp = P.premier; for (temp; temp != NULL; temp = temp->suivant) { printf("%lf", temp->coef); printf("x^"); printf("%d", temp->degre); printf("+"); } printf("\b\n"); getchar(); }as tu une idée ?
Modifié par paly2 le 14/01/2016 à 10:25
Il faudrait que je teste le programme en entier, peux-tu uploader les fichiers complets stp ?
Et quel est ton problème exactement ?
14 janv. 2016 à 17:14
main :
#include <stdio.h> #include <stdlib.h> #include "Polynome.h" int main(int argc, char *argv[]) { polynome P; P.premier = NULL; //AffichagePolynome(P); InsereMonome(P,2,1); InsereMonome(P, 5, 10); InsereMonome(P, -10, 12); AffichagePolynome(P); polynome P2; P2=SaisiePolynome(); AffichagePolynome(P2); getchar(); }Polynome.h :
//Polynome.h typedef struct monome { double coef; int degre; struct monome* suivant; }monome; typedef struct polynome { monome* premier; }polynome; polynome InsereMonome(polynome P, double coef, int degree); //insere le monome "coef de degre" dans polynome P polynome SaisiePolynome(); //saisi d'un polynome au clavier void AffichagePolynome(polynome P); //affichega d'un polynome P void DetruitPolynome(polynome* p_P); //destruction d'un polynomecode.c :
#include <stdio.h> #include <stdlib.h> #include "Polynome.h" polynome InsereMonome(polynome Polynome, double coeff, int degree) { monome *nouvel = malloc(sizeof(monome)); nouvel->coef = coeff; nouvel->degre = degree; monome * temp = Polynome.premier; if (temp == NULL) { temp = nouvel; } else if (temp->suivant==NULL) //un seul monome { if (temp->degre<nouvel->degre) //degré du nouveau à droite du premier polynome. { temp->suivant = nouvel; } else { nouvel->suivant = temp; } //degré inférieur donc à gauche } else //plusieurs monome, si degré p.premier inf à nouvel { for (temp; temp!=NULL ; temp=temp->suivant ) //parcourir la chaine { monome* inf = malloc(sizeof(monome)); monome*sup = malloc(sizeof(monome)); inf = temp; //on insere temp dans inf sup = temp->suivant; //on insere le suivant dans sup if (inf->degre<nouvel->degre && sup->degre>nouvel->degre) //parcours de monome de 1 en 1 pour bien le placer { inf->suivant = nouvel; nouvel->suivant = sup; } else if (inf->degre==nouvel->degre /*&& sup->degre>nouvel->degre*/) // cas où coeff == { //j'additione inf->coef = inf->coef + nouvel->coef; } } } return Polynome; } polynome SaisiePolynome() { monome *saisie = malloc(sizeof(monome)); int fin; double A; int B; polynome Polynome; Polynome.premier = NULL; do { printf("saisir coefficient \n"); //saisie du coeff et du degrée scanf("%lf", (&A)); printf("saisir degree \n"); scanf("%d", (&B)); //scanf attend une adresse Polynome=InsereMonome(Polynome, A, B); do { printf("veuillez entrer 0 ou 1 \n"); printf("0 : continuer \n"); printf("1 : quitter\n"); scanf("%d", &fin); } while (fin != 0 && fin !=1); } while (fin != 1); return Polynome; } void AffichagePolynome(polynome P) { monome * temp = P.premier; for (temp; temp != NULL; temp = temp->suivant) { printf("%lf", temp->coef); printf("x^"); printf("%d", temp->degre); printf("+"); } printf("\b\n"); getchar(); }14 janv. 2016 à 19:04
14 janv. 2016 à 22:06