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   -
Bonjour,
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:

2 réponses

paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
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.
0
scoutantho Messages postés 50 Date d'inscription   Statut Membre Dernière intervention  
 
Merci encore de ta réponse, du coup mon problème se situe ailleurs, du coup dans cette fonction :
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 ?
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
Euh... Cette fonction semble juste pourtant, mais pourquoi fais-tu un getchar() à la fin ?
Il faudrait que je teste le programme en entier, peux-tu uploader les fichiers complets stp ?

Et quel est ton problème exactement ?
0
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  
 
ça ne m'affiche pas les polynomes
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 polynome

code.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();
}
0
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  
 
est ce que je t'ai répondu ?
0
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  
 
en faisant du pas à pas, j'ai trouvé un problème, c'est au niveau du 1er if de inseremonome, il ne fais que cette boucle
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
Et voici une fonction DetruitPolynome gratuite qui devrait fonctionner :
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.
).
0
scoutantho Messages postés 50 Date d'inscription   Statut Membre Dernière intervention  
 
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 :
//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;
}
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
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.
0
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  
 
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
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
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
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)
0