Problème pointeurs en C

Résolu
blanccc Messages postés 23 Date d'inscription mercredi 7 décembre 2005 Statut Membre Dernière intervention 9 juin 2006 - 22 mai 2006 à 11:53
blanccc Messages postés 23 Date d'inscription mercredi 7 décembre 2005 Statut Membre Dernière intervention 9 juin 2006 - 22 mai 2006 à 15:56
Bonjour à tous, voila je débute en C et j'aurais besoin de votre aide sur un truc qui va vous paraitre tout bete je pense :

j'ai créé un type de variable appelé 't_Sommet' de la façon suivante :
typedef struct {
int Numero;
float Abscisse;
float Ordonnee;
} t_Sommet;

ensuite j'ai créé la liste chainée associée de façon classique :
typedef struct {
t_Sommet S;
struct pSommet *prec;
} pSommet;

admettons maintenant que j'ai plusieurs sommets dans ma liste et que je veuille modifier les coordonnées d'un de ces sommets. Ma question est simple : comment je dois faire ?

j'ai une fonction que j'ai créé qui pourrait peut-être vous aider :
t_Sommet Sommet_Numero(pSommet *Sommets, int i) {
t_Sommet Si;
while(Sommets!=NULL) {
Si = Sommets->S;
if (Si.Numero == i) {
return *Si;
}
if (Si.Numero != i) {
Sommets = Sommets->prec;
}
}
}

Le problème avec cette fonction c'est que si je fais :
Sommet1 = Sommet_Numero(*ListeSommets, i);
je me retrouve avec Sommet1 qui vaut le ième sommet de ma liste chainée mais, si je modifie ensuite Sommet1, ça ne modifie pas celui de ma liste or c'est ce que je voudrais faire :
modifier un élément de type 't_Sommet' dans ma liste dont l'attribut 'Numero' vaut i (je sais pas si c'est le bon terme 'attribut'). En fait c'est les valeurs des attributs 'Abscisse' et 'Ordonnee' que je veux modifier.

J'espère avoir réussi à me faire comprendre. N'hésitez pas à me poser des questions si vous avez besoin de plus de détails. Merci d'avance ;)

Cédric, un stagiaire en galère... lol

6 réponses

blanccc Messages postés 23 Date d'inscription mercredi 7 décembre 2005 Statut Membre Dernière intervention 9 juin 2006
22 mai 2006 à 15:56
c'est bon, j'ai fait autrement en me basant sur ce que tu as fait :

t_Sommet *Adresse_Sommet_Numero(pSommet *Sommets, int i) {
pSommet *current = Sommets;
t_Sommet Si;
while (current!=NULL) {
Si = current->S;
if (Si.Numero == i) {
return &(current->S);
}
current = current->prec;
}
return NULL; /* si jamais le Numero n'existe pas */
}

et ensuite, dans le corps de mon prog j'ai une variable que je déclare : t_Sommet *Sommet3
puis je fais :

Sommet3 = Adresse_Sommet_Numero(Sommets, i);
Sommet3->Numero = i;
Sommet3->Abscisse = x;
Sommet3->Ordonnee = y;

Seul problème maintenant, c'est que Sommet3 pointe toujours vers le même sommet. Comment faire pour dire que Sommet3 ne pointe plus vers rien ou qu'il pointe vers un autre Sommet ?

Merci pour ton aide en tous, elle m'aura été bien précieuse !

Cédric
3
Bel0 Messages postés 71 Date d'inscription mercredi 14 avril 2004 Statut Membre Dernière intervention 14 septembre 2007
22 mai 2006 à 13:44
D'après ce que j'ai compris de tes explications et en lisant ton code, je vois un petit truc scabreux dans cette affaire. En gros, tu voudrais pouvoir modifier ton sommet tout en le laissant dans ta liste. Le plus facile pour ça, c'est de retourner une référence vers le sommet en question. Je suppose que c'est ce que tu as voulais faire en faisant: "return *Si;" Mais ca ne fonctionnera pas. Au mieux tu retournes une copie du sommet, au pire ca ne compile meme pas étant donné que Si n'est pas un pointeur. Je te propose donc de modifier t'as source de la façon suivante:

t_Sommet *Sommet_Numero(pSommet *Sommets, int i) {
t_Sommet *current = Sommets;
while(current != NULL) {
if (current.Numero == i)
return &(current->S);

current = current->prec;
}

return NULL; // si le sommet n'est pas trouvé
}

De cette façon, tu reçois un pointeur vers le sommet que tu cherchais ou NULL si la valeur n'existe pas dans la liste. L'adresse retournée par la fonction restera bonne tant que la liste n'est pas libérée ou que l'entrée contenant le sommet en question n'est pas libérée. Avec cette méthode, comme tu utilises un pointeur vers le sommet, tu modifies bien celui qui est dans la liste.

Belo
0
blanccc Messages postés 23 Date d'inscription mercredi 7 décembre 2005 Statut Membre Dernière intervention 9 juin 2006
22 mai 2006 à 13:57
Salut BalO, merci pour tes conseils. Donc si j'ai bien compris, je fais qqch du genre :

t_Sommet *Sommet1;
t_Sommet Sommet2;
Sommet1 = Sommet_Numero(*ListeSommets, i);
Sommet2.Numero = i;
Sommet2.Abscisse = x;
Sommet2.Ordonnee = y;
Sommet1->S = Sommet2;

C'est ça ? désolé si je met du temps à comprendre, j'ai vraiment du mal avec les passages de données par valeur et par référence... lol

merci en tous cas (^_^)
0
blanccc Messages postés 23 Date d'inscription mercredi 7 décembre 2005 Statut Membre Dernière intervention 9 juin 2006
22 mai 2006 à 15:12
désolé BalO mais ça ne compile pas ton truc !!! j'ai bien fait gaffe aux accolades (tu en as oublié pour le 'if'). Merci quand même et, si tu as une autre idée, fais-moi signe...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bel0 Messages postés 71 Date d'inscription mercredi 14 avril 2004 Statut Membre Dernière intervention 14 septembre 2007
22 mai 2006 à 15:29
Pour l'utilisation du code .. pas besoin de faire si compliqué. Il suffit simplement de faire:

t_Sommet *Sommet1;
Sommet1 = Sommet_Numero(*ListeSommets, i);
Sommet1->Numero = i;
Sommet1->Abscisse = x;
Sommet1->Ordonnee = y;

pour changer les informations contenues dans le sommet (ca n'est pas fait pour ajouter un nouveau noeud !!).

Euh, j'ai pas encore un compilateur intégré, mais je vois quelle erreur il pourrait y avoir dans le code. Si tu pouvais copier l'erreur renvoyée par le compilateur, ca pourrait être util pour t'aider.

Belo
0
Bel0 Messages postés 71 Date d'inscription mercredi 14 avril 2004 Statut Membre Dernière intervention 14 septembre 2007
22 mai 2006 à 15:31
oops parlé trop vite sur ce coup.

Essaye de remplacer "if (current.Numero i)" par "if (current->Numero i)"

Belo
0
Rejoignez-nous