Liste simplement chainée

Liste simplement chainée - C++ - Programmation

Marsh Posté le 30-01-2013 à 17:43:32    

Bonjour  
J'ai du mal à comprendre ce programme , pouvez vous m'expliquer s'il vous plait chaque instruction à part si vous avez un peu de temps ? Je fais de l'auto formation et j'essaie de comprendre pour étre préte pour le cours et je n'ai aucun moyen de comprendre à part votre aide    :(  
 
struct MAILLON  
{
int chiffre;
MAILLON * suivant;
};
 
typedef MAILLON * LISTE;
 
MAILLON * preparerMaillon(int v){
 
MAILLON * newMaillon = new MAILLON;
if(newMaillon!=NULL){
newMaillon->chiffre=v;
newMaillon->suivant=NULL;
return newMaillon;  
}
else  
return NULL;
}
 
MAILLON * ajouterMaillon(int v, MAILLON * pt){
 
MAILLON * m_nouveau = preparerMaillon(v);
if(m_nouveau!=NULL)
{
m_nouveau->suivant=pt;
return m_nouveau;
}
else
{
return NULL;
}
}
int Supprimer(LISTE * lst){
 
// (*lst)=  
LISTE * pt;
int chiffreARetourner=(*lst)->chiffre;
pt=lst;
(*lst)=(*lst)->suivant;
free(pt);
return chiffreARetourner;
}
 
 
 
Merci  :)

Reply

Marsh Posté le 30-01-2013 à 17:43:32   

Reply

Marsh Posté le 30-01-2013 à 18:17:45    

Utiliser un free en C++ quoi [:petrus75]
 
Sinon, commence par lire des cours sur les pointeurs, et sur les structures.
Là on aura beau t'expliquer, si tu n'a pas ces bagages là c'est perdu d'avance.


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 30-01-2013 à 18:49:53    

Merci bcp pour ta réponse ^^  
Je les ai , mais malgré ça j'ai du mal à comprendre , je suis faible dans ce domaine , il me faut bcp d'aide :(

Reply

Marsh Posté le 30-01-2013 à 19:37:44    

Terminapor a écrit :

Utiliser un free en C++ quoi [:petrus75]
 
Sinon, commence par lire des cours sur les pointeurs, et sur les structures.
Là on aura beau t'expliquer, si tu n'a pas ces bagages là c'est perdu d'avance.


 
 
Et si tu disais pourquoi ne pas utiliser de free plutot que te remballer à tout vas ? Sa serais déja un plus constructif pour aider asouma et ceux qui passent par là...

Reply

Marsh Posté le 30-01-2013 à 19:42:47    

joe'ss a écrit :

 


Et si tu disais pourquoi ne pas utiliser de free plutot que te remballer à tout vas ? Sa serais déja un plus constructif pour aider asouma et ceux qui passent par là...


Parce que visiblement, l'OP n'a pas un niveau suffisant pour comprendre exactement les enjeux de la distinction.

 

Ensuite, apprendre un langage en commençant par lire du code aussi verollé, c'est choisir de se tirer une balle dans chaque pied.


Message édité par theShOcKwAvE le 30-01-2013 à 19:42:56

---------------
last.fm
Reply

Marsh Posté le 30-01-2013 à 19:46:43    

J'ai déja bien lu mes cours ...

Reply

Marsh Posté le 30-01-2013 à 19:50:30    

Ce code, il sort d'où ?
 
Tu pourrais décrire avec tes mots ce que tu comprends d'une variable, d'un pointeur, d'une structure et d'un objet ?
(histoire de donner une idée de ce que tu as compris des cours que tu as eus, je ne sais même pas ce qu'ils ont pu couvrir)


---------------
last.fm
Reply

Marsh Posté le 30-01-2013 à 20:26:06    

une variable : un espace mémoire où on enregistre des données .
un pointeur : servent à la manipulation des adresses , déclaration ou reservation en mémoire ( je ne maitrise pas trés bien la notion du pointeur .. :) )  
une structure : un type qui contient plusieurs variables de plusieurs types  
 Je suis faible , comprendre les notions ne m'aide pas bcp à comprendre les instructions d'un code :)  
 

Reply

Marsh Posté le 30-01-2013 à 20:44:36    

asouma12 a écrit :


une structure : un type qui contient plusieurs variables de plusieurs types  


 
Normalement non.

Reply

Marsh Posté le 30-01-2013 à 20:47:24    

c'est un ensemble pas un type , un ensemble qui contient plusieurs variables de différents types ... non ? :(

Reply

Marsh Posté le 30-01-2013 à 20:47:24   

Reply

Marsh Posté le 30-01-2013 à 21:00:46    

le pointeur n'est pas lié à la réservation de la mémoire.
en C++, une structure est effectivement un type et peut effectivement contenir des membres de plusieurs types et il y a beaucoup de règles sur la manière dont ces membres sont initialisés (ou non) qu'il faut respecter.
L'allocation d'une structure et son initialisation (ou sa construction, plutôt) sont des choses différentes, et c'est précisément pour cette distinction qu'il faut faire attention à ce que tu utilises. Quand tu fais malloc d'un côté (qui ne fait qu'allouer de l'espace mémoire), tu fais free pour libérer. Si jamais tu utilises new (qui alloue la mémoire et "construit" la structure), tu dois alors libérer via delete (qui "détruit" la structure puis libère la mémoire)
 
Si il te reste suffisamment de temps devant toi, tu devrais tout de même envisager de te trouver un livre là-dessus (un petit coup d'oeil aux bibliolinks devrait te renseigner des recommandations habituelles qu'on fait ici) ... Je ne suis pas prof et je peux manquer de précision dans ce que je dis.
 
Cela dit, est-ce que tu cernes la différence entre allouer sur la pile et sur le tas ?
 


---------------
last.fm
Reply

Marsh Posté le 30-01-2013 à 21:04:48    

Je ne sais pas ce que c'est une pile :(  
 Merci pour les informations :)

Reply

Marsh Posté le 30-01-2013 à 21:14:59    

Ca sert au fonctionnement de base de tes appels de fonction.
Toutes les variables que tu déclares dans le corps d'une fonction sont allouée sur la pile. L'opérateur new quant à lui sert à réserver de la mémoire sur le tas.
 
Les variables qui sont déclarées à l'intérieur de ta fonction ont une durée de vie limitée à l'appel de ta fonction. Pour faire simple, quand ton programme est exécuté et que ton processeur "rentre" dans une fonction (c'est un bel abus de langage), il va réserver de l'espace pour les variables qui sont dans cette fonction sur la pile. Quand il sort de la fonction, il libère cet espace. Tu ne peux donc plus t'en servir.
 
Le lien avec ton éxercice est que tu veux que plusieurs fonctions indépendantes te servent à manipuler une liste chaînée. Pour ne pas être lié à tes fonctions, les portions qui composent cette liste chaînée en mémoire (les maillons dans ton exemple) doivent être allouées sur le tas (donc dans notre cas, avec l'opérateur new)
 
La manipulation de données sur le tas passe obligatoirement par la manipulation de pointeurs (les références, si tu les as déjà croisées, ne sont que des pointeurs déguisés pour des facilités d'écriture)
 
Le plus important quand on écrit un programme, c'est d'arriver à décrire avec tes mots la manière dont tu veux faire les choses, du plus haut niveau d'abstraction jusqu'au plus près de la machine. Là, en construisant une liste chaînée, tu te retrouves assez proche de la machine, il faut que tu comprennes comment tu vas organiser ta mémoire pour t'assurer que tu pourras toujours utiliser toutes tes informations.
 
Je ne sais pas à quel point ces choses sont claires pour toi.
Pourquoi le maillon a cette structure là ?
Comment on représente une liste vide ?
Comment on identifie un élément à l'intérieur de ta liste pour agir dessus ?
 


---------------
last.fm
Reply

Marsh Posté le 30-01-2013 à 21:21:51    

Le maillon est l 'élément de base de ma liste , il contient un chiffre et un pointeur vers un maillon suivant  qu'on ajoutera par la suite si on veut , sinon si il y ' a pas un autre maillon qui suit , notre pointeur pointera sur NULL .  
J'ai pas compris la dernière question :(

Reply

Marsh Posté le 30-01-2013 à 21:33:52    

Dans ton exemple, rien ne t'empèche d'avoir une liste qui contient, dans l'ordre : 1, 5, 3, 7, 2, 1, 6
 
Si tu veux supprimer le deuxième 1, comment fais-tu ?
C'est pour ce genre de question que je parle d'identifier un maillon. En C++, dans les conteneurs standards, ce sont les itérateurs qui servent à identifier de quel "maillon" on parle.
 
Techniquement, la structure que représente ton code n'est pas ce qu'on appelle une liste, mais c'est en fait une "pile" (tes éléments sont stockés dans l'ordre inverse de leur ajout)
 
(attention à ne pas confondre "la pile" et le concept de pile :o ... ce qu'on appelle "la pile" est quelque chose qui fonctionne comme une pile et qui sert au fonctionnement de ton langage, j'espère que je ne t'ai pas embrouillé)
 
Bref, je vois que dans ta dernière fonction, il est question d'un type LISTE. Quel est-il ?
 
Tu n'as pas répondu à ma question précédente, sinon ... Comment représentes-tu une liste vide ?


---------------
last.fm
Reply

Marsh Posté le 30-01-2013 à 21:50:54    

Le chiffre on l'initialise avec 0 et le pointeur sur NULL non ?

Reply

Marsh Posté le 30-01-2013 à 21:52:59    

LISTE est equivalente à  MAILLON* , c'est pour ça c'est écrit  
 typedef MAILLON * LISTE;  

Reply

Marsh Posté le 30-01-2013 à 21:53:38    

et MAILLON* est un pointeur sur type MAILLON

Reply

Marsh Posté le 30-01-2013 à 22:35:09    

l'ecriture LISTE*pt est equivalente à MAILLON**pt , c'est un pointeur sur pointeur , qu'est ce que ça signifie s'il vous plait ?

Reply

Marsh Posté le 31-01-2013 à 08:34:06    

Un pointeur sur pointeur, c'est simplement un pointeur qui pointe sur une adresse :D
 
En gros, ici c'est requit parce qu'on supprime le 1ère élément, donc il faut mettre à jour la liste, celle sur laquelle on veut supprimer une valeur :  
 

Code :
  1. int main()
  2. {
  3.     Liste L;
  4.     ajouterMaillon(10,L);
  5.     ajouterMaillon(20,L);
  6.     ajouterMaillon(30,L);
  7.    // Ici, la liste doit être ordonnée comme ça :  
  8.   // [30]  -> [20] -> [10]-> [ ]
  9.   // donc L pointe sur le dernier élément
  10.  
  11.  
  12.    Supprimer(&L);
  13.    // Ici, on a supprimer le 1ère élément, donc forcément L doit être modifié, c'est pourquoi on y fait passer son adresse, comme ça
  14.   // on modifie directement sa valeur dans la fonction sans avoir à passer par un return.
  15.   // L :
  16.   // [20] -> [10]-> [ ]
  17. }


 
Mais sauf que ton code là, c'est du C (avec un new [:petrus75]), pas du C++ faudrait juste que tu précises, tu dois faire du C ou du C++ ?


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 31-01-2013 à 10:32:52    

asouma12 a écrit :

LISTE est equivalente à  MAILLON* , c'est pour ça c'est écrit  
 typedef MAILLON * LISTE;  


 
okay, effectivement, j'avais raté le typedef, au temps pour moi.
 
Il faut que tu comprennes qu'un pointeur est un type au même titre qu'un entier.
Tu peux avoir un entier quelque part en mémoire et manipuler un pointeur qui pointe dessus.
Tu peux avoir un pointeur sur cet entier quelque part en mémoire et manipuler un pointeur sur ce pointeur.
 
Techniquement, il n'y a pas de limite sur le nombre d'indirections qu'il te faut pour obtenir le type final sur lequel tu pointes. Cela étant dit, c'est plutôt rare d'avoir besoin de plus de deux niveaux d'indirection.
 
Un bon éxercice pour t'aider à comprendre ton programme est de faire un tableau avec les variables que tu touches en colonnes. Chaque nouvelle ligne correspond à une instruction.


---------------
last.fm
Reply

Marsh Posté le 31-01-2013 à 17:47:45    

Merci pour vos réponses  
J'ai vu Cin , cout  donc j'ai cru  que c'est du C++ j'ai pas fait attention au new , je crois que j'aurai besoin de le comprendre en C :)

Reply

Marsh Posté le 31-01-2013 à 17:57:10    

ça veut dire quoi svp exactement l 'instruction  element!=NULL   sachant que element est un pointeur sur type MAILLON  ?

Reply

Marsh Posté le 31-01-2013 à 18:56:03    

en C, il n'y a pas de new.

 

ton pointeur peut être NULL
!= est l'opérateur pour tester la différence, donc cet opérateur te retournera vrai si ses deux opérandes sont différentes.
Ici, il te retournera donc "true" si element ne pointe pas à l'adresse "nulle" de ton système.


Message édité par theShOcKwAvE le 31-01-2013 à 18:56:36

---------------
last.fm
Reply

Marsh Posté le 31-01-2013 à 20:34:15    

et ça veut dire quoi un pointeur NULL ?

Reply

Marsh Posté le 31-01-2013 à 20:48:24    

et ça veut dire quoi svp l'expression void* element

Reply

Marsh Posté le 31-01-2013 à 20:49:15    

Je m'excuse je pose trop de questions mais j'ai vraiment besoin de comprendre pour m'améliorer :(

Reply

Marsh Posté le 01-02-2013 à 10:42:31    

En C, on utilise int* a = malloc(sizeof(int)); pour allouer de la mémoire et free a; pour la libérer
En C++ on utilise int* a = new(int); pour allouer et delete a; pour libérer
En C++ on peut également utiliser malloc/free, mais il ne faut surtout pas mixer avec new/delete (pas de int* a = new(int); puis free a; ou inversement)

 

Un pointeur NULL est un pointeur qui ne pointe sur aucune case mémoire, autrement dit il ne contient pas d'adresse valide : il contient l'adresse 0 qui n'existe pas, d'où "NULL"

  

Je suis pas très sûr du void* : Il me semble qu'il s'agit de l'adresse d'une variable dont tu ne définis/connais pas le type. Il faut la caster en un type connu pour pouvoir lire sa valeur correctement (exemple de cast: int a = 5;  void* b = &a;  printf("%d", *((int*)b) );//Affiche 5       )
(Si quelqu'un pouvait confirmer mes dires sur ce sujet, ça serait sympa ^^)

EDIT Faux/pas correct, lire plus bas le post de theshockwave


Message édité par crom29 le 01-02-2013 à 12:56:21

---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
Reply

Marsh Posté le 01-02-2013 à 12:50:56    

en écrivant :

Code :
  1. void* element;


tu déclares une variable (ou un membre, suivant dans quel contexte tu écris ca) element qui est un pointeur sur un type inconnu.
Les void* sont à éviter autant que possible.
 
un pointeur NULL, c'est un pointeur sur une adresse invalide. Tout système a une adresse invalide. Parfois, c'est l'adresses 0, parfois pas. On s'y réfère en parlant simplement de pointeur NULL. Il est illégal de tenter de consulter ce qui se trouve à cette adresse (ca causera une erreur et ton programme s'arrêtera immédiatement si ca arrive)
 
Ca sert très souvent de mettre un pointeur à NULL.
un exemple simple :

Code :
  1. void DoSomething( int param, int* optionalResult )
  2. {
  3.   // blah blah ...  
  4.   if( optionalResult != NULL )
  5.   {
  6.     optionalResult = param*3;
  7.   }
  8. }


 
Ici, par exemple, c'est une fonction avec un paramètre optionnel. Si tu n'es pas intéressé par la valeur en question, au moment de ton appel, tu passes NULL comme paramètre.
 
C'est aussi une bonne pratique, une fois que tu as libéré la mémoire d'un pointeur de le mettre à NULL pour t'assurer que personne ne risque de tenter d'accéder à la zone mémoire que tu as libérée.
 
 
Crom29 : attention à tes casts automatiques de int* vers void* : C et C++ ne se comportent pas de la même manière ici. Si tu n'es pas sur de toi évite d'embrouiller quelqu'un qui apprend :)
 
Edit : Dans ton exemple ci-dessus, le pointeur à NULL sert aussi à dire que tu n'as pas encore créé ta donnée. Donc une liste par défaut vaut NULL et ca représente le fait qu'il n'y a aucun maillon dedans. Cela dit, c'est le genre de détail d'implémentation que l'utilisateur de ton type LIST ne devrait pas avoir à connaître.


Message édité par theShOcKwAvE le 01-02-2013 à 12:58:34

---------------
last.fm
Reply

Marsh Posté le 01-02-2013 à 12:54:38    

message édité, merci de ta réponse :)


---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
Reply

Marsh Posté le 01-02-2013 à 16:31:19    

JE vous remercie amplement pour vos réponses :) plus spécialement theshockwave :)

Reply

Marsh Posté le 01-02-2013 à 16:46:32    

Il y a tout de même quelques approximations. Je te conseille de vite choisir si tu veux faire du C++ ou du C et de savoir à quelle version tu seras confronté.
Ca permettrait de t'orienter vers de meilleure façons de faire suivant le langage quand tu poses des questions.
 
(Exemple d'approximation que j'ai utilisée : pour NULL ... en fait, c'est plus compliqué :
Le C utilise NULL
En C++ avant C++11, les pointeurs ont un comportement spécial qui fait qu'ils prennent l'adresse nulle du système si tu leur affectes 0. NULL existe pour la compatibilité avec le C seulement
Le C++11 utilise nullptr)


---------------
last.fm
Reply

Marsh Posté le 01-02-2013 à 16:52:18    

J'essaye de l'apprendre en C plutôt qu'en C++ , je ne m'y connais pas trés bien en C++ :(

Reply

Marsh Posté le 01-02-2013 à 17:02:21    

ok, C est plus facile à appréhender que C++. Du coup, tu peux oublier les new/delete ... Tu fonctionnes avec malloc, free et NULL :)


---------------
last.fm
Reply

Marsh Posté le 01-02-2013 à 17:04:30    

Et pour le "'!=" ça retourne réellement un booléen ou pas ?
Parce que de mémoire faut faire un include pour les booléen.
Amoins que mais j'y connais rien.

Reply

Marsh Posté le 01-02-2013 à 17:05:29    

Parfait :) Merci bcp  ^^

Reply

Marsh Posté le 01-02-2013 à 17:33:38    


 
le type bool n'existait pas encore dans mon compilateur quand j'ai appris le C mais il semblerait qu'il existe maintenant.
 
Cela dit, vu la manière dont il est fait, je soupçonne que le fonctionnement du langage n'aie pas changé et qu'il utilise en fait toujours des entiers (int) au lieu de booléens.
Donc techniquement, je parierais que != retourne un int  encore maintenant :)
 


---------------
last.fm
Reply

Marsh Posté le 01-02-2013 à 17:34:47    

Merci !

Reply

Marsh Posté le 01-02-2013 à 22:47:41    

A quoi sert la bibliothéque cstdlib svp ?

Reply

Marsh Posté le 01-02-2013 à 22:56:30    

A utiliser en C++ l'équivalent de la bibliothèque stdlib du langage C
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed