Polynome 2
scoutantho
Messages postés
50
Date d'inscription
Statut
Membre
Dernière intervention
-
paly2 Messages postés 254 Date d'inscription Statut Membre Dernière intervention -
paly2 Messages postés 254 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
mon problème sur les polynomes se trouve désormais sur mon retour de ma fonction "insere_monome".
Peut-on m'aider ? je dois retourner un polynome, mais pas le "temp" mais pas le "Polynome" car il n'est pas modifié.
Merci de votre gentillesse
mon problème sur les polynomes se trouve désormais sur mon retour de ma fonction "insere_monome".
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 ??; }
Peut-on m'aider ? je dois retourner un polynome, mais pas le "temp" mais pas le "Polynome" car il n'est pas modifié.
Merci de votre gentillesse
A voir également:
- Polynome 2
- Supercopier 2 - Télécharger - Gestion de fichiers
- 2 ecran pc - Guide
- Faire 2 colonnes sur word - Guide
- Whatsapp 2 - Guide
- Word numéro de page 1/2 - Guide
2 réponses
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.
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.).
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;
}
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.
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
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)
as tu une idée ?
Il faudrait que je teste le programme en entier, peux-tu uploader les fichiers complets stp ?
Et quel est ton problème exactement ?
main :
Polynome.h :
code.c :