Page 1 sur 1

NewList ===> Pointeur =?=> NewList

Publié : sam. 21/avr./2007 20:10
par kuroyi
Comment utiliser un pointeur d'une NewList avec les instructions AddElement, et cie ? D'après le tutorial sur les pointeurs, j'ai cru comprendre que l'on obtenait l'adresse des éléments (en l'occurrence de celui en cours). Comment est-il possible d'utiliser le pointeur en lieu est place d'une variable de type NewList ou de produire une variable de type NewList à l'aide d'un pointeur.
L'objet de la question : je récupère d'une DLL un bloc mémoire structuré comme une NewList (avec *next,*previous,value, etc.) et souhaite pouvoir le manipuler.

ex.
NewList exemple.l()
AddElement(exemple())
*pointeur.l=@exemple()
AddElement(*pointeur) => non
AddElement(*pointeur()) => non
???

Je souhaite faire l'équivalent de AddElement(exemple()) mais avec le pointeur.

Important : *pointeur.l=@exemple() ne passe pas si la liste n'a aucun élément, donc il pointe bien sur l'élément et pas la liste.

Publié : ven. 27/avr./2007 15:00
par brossden
Je ne sais pas si je répond à ta question mais :

Code : Tout sélectionner


NewList exemple.l()

Toto.S = "Phrase1"
Tata.S = "Phrase2"
Tutu.S = "Phrase n-1"
Titi.S = "Phrase n"
 
AddElement(exemple())
exemple()= @Toto
AddElement(exemple())
exemple()= @Tata
AddElement(exemple())
exemple()= @Tutu
AddElement(exemple())
exemple()= @Titi

ForEach exemple()
  Debug PeekS(exemple(),20)
  
Next

Publié : ven. 27/avr./2007 18:17
par kuroyi
Merci de l'attention.
C'est la liste chainée elle-même que je souhaite manipuler à partir d'un pointeur.
(je sais déjà y référencer des éléments par pointeur).
En gros comment faire à la même chose avec le pointeur : *pointeur.l=@exemple() ?
AddElement(*pointeur)
*pointeur= @Toto
ne marche pas...

Publié : ven. 27/avr./2007 19:53
par Backup
kuroyi a écrit :Merci de l'attention.
C'est la liste chainée elle-même que je souhaite manipuler à partir d'un pointeur.
(je sais déjà y référencer des éléments par pointeur).
En gros comment faire à la même chose avec le pointeur : *pointeur.l=@exemple() ?
AddElement(*pointeur)
*pointeur= @Toto
ne marche pas...
n'etant pas un adepte des pointeur, il me semble pourtant
avoir vu que l'on pouvait faire une truc du genre

*pointeur= @@Toto
ou *pointeur= **Toto

enfin un truc dans le genre 8O

Publié : ven. 27/avr./2007 20:02
par brossden
à mon avis cela n'a aucun sens ton code !

mais je peux me tromper !

Pour moi tu crées une liste de personnes, tu voudrais avoir l'adresse ou se trouve la liste, tu voudrais prendre l'adresse suivante et placer à cette adresse l'adresse d'un nouvelle persone ???

Désolé pige pas !

Publié : ven. 27/avr./2007 20:33
par tmyke
Voila qui correspond a ce que tu cherches, comment acceder aux
éléments de ta liste par des pointeurs..
(merci a Comtois qui ma éclairé, pour d'autre raisons, sur le fonctionnement de List avec PB)

Code : Tout sélectionner

Structure MaStructure
  Champ1.f
  Champ2.s
EndStructure

;PureBasic ajoute lui-même le Next et le Previous
NewList Maliste.MaStructure() ;Déclare une liste chainée



;Ensuite tu peux ajouter un élément à la liste
AddElement(Maliste())
Maliste()\Champ1 = 34.23
Maliste()\Champ2 = "Salut"
;Ajoute un autre élément
*pointeur.MaStructure  = AddElement(Maliste())
Maliste()\Champ1 = 87.81
Maliste()\Champ2 = "au revoir"



;tu peux visualiser le contenu de ta liste
ForEach Maliste()
  Debug Maliste()\Champ1
  Debug Maliste()\Champ2
  Debug "***********"
Next


; partie de manipulation des pointeurs

*pointeur = PeekL(*pointeur+4) ; recupère le pointeur vers la précédente structure
Debug PeekF(*pointeur+8) ; affiche la première donné
; si on veut passer par les champ, faut ajouter au pointeur les
; 2x4 octets des deux Next/Previous ajouté par PB dans ta structure
*champ.MaStructure = *pointeur+8 
Debug *champ\Champ1 ; et on peut lire les champs
Debug *champ\Champ2
Debug "============"

; meme principe pour le suivant
*pointeur = PeekL(*pointeur) ; récupère le suivant cette fois
Debug PeekF(*pointeur+8)  ; affiche la première donné
*champ.MaStructure = *pointeur+8 
Debug *champ\Champ1 ; et on peut lire les champs
Debug *champ\Champ2
Debug "============"

Publié : ven. 27/avr./2007 21:57
par kuroyi
Merci tmyke, cela correspond d'avantage à ce que je souhaite faire.
La dernière partie de ma question est : si je passe ce pointeur à une procédure par exemple comment je peux retransfomer celui en liste chainée pour manipuler le contenu pointé avec les instructions standard (AddElement, etc.)

En fait, cela me permet d'inclure des listes chaînées (ou plutôt des pointeurs vers des listes chainées) dans des structures. La seconde partie du problème consiste à exploiter ces pointeurs avec les instructions standard (c'est à dire faire l'opération inverse car avec les pointeurs c'est coton).

Merci à tous pour votre assistance, j'avance à petits pas, mais j'avance.

Publié : sam. 28/avr./2007 8:28
par tmyke
kuroyi a écrit :Merci tmyke, cela correspond d'avantage à ce que je souhaite faire.
La dernière partie de ma question est : si je passe ce pointeur à une procédure par exemple comment je peux retransfomer celui en liste chainée pour manipuler le contenu pointé avec les instructions standard (AddElement, etc.)
je viens d'essayer un truc comme cela, j'ai pas poussé plus les essais

Code : Tout sélectionner

Structure MaStructure
  Champ1.f
  Champ2.s
EndStructure

;PureBasic ajoute lui-même le Next et le Previous
NewList Maliste.MaStructure() ;Déclare une liste chainée



Declare TestList(*ptr)

;Ensuite tu peux ajouter un élément à la liste
AddElement(Maliste()) 
; mémorise le point de la liste créée
*liste = @Maliste()
Maliste()\Champ1 = 34.23
Maliste()\Champ2 = "Salut"
;Ajoute un autre élément
*pointeur.MaStructure  = AddElement(Maliste())
Maliste()\Champ1 = 87.81
Maliste()\Champ2 = "au revoir"


TestList(*liste)

; partie de manipulation des pointeurs

*pointeur = PeekL(*pointeur+4) ; recupère le pointeur vers la précédente structure
Debug PeekF(*pointeur+8) ; affiche la première donné
; si on veut passer par les champ, faut ajouter au pointeur les
; 2x4 octets des deux Next/Previous ajouté par PB dans ta structure
*champ.MaStructure = *pointeur+8
Debug *champ\Champ1 ; et on peut lire les champs
Debug *champ\Champ2
Debug "============"



; meme principe pour le suivant
*pointeur = PeekL(*pointeur) ; récupère le suivant cette fois
Debug PeekF(*pointeur+8)  ; affiche la première donné
*champ.MaStructure = *pointeur+8
Debug *champ\Champ1 ; et on peut lire les champs
Debug *champ\Champ2
Debug "============"



;tu peux visualiser le contenu de ta liste
  Debug "***********"
ForEach Maliste()
  Debug Maliste()\Champ1
  Debug Maliste()\Champ2
  Debug "***********"
Next



; procedure quelconque 
Procedure TestList(*ptr)
  Protected NewList Uneliste.MaStructure()

  ChangeCurrentElement(Uneliste(), *ptr)
  
  AddElement(UneListe())
  UneListe()\Champ1 = 66.23
  UneListe()\Champ2 = "Trois"
  
  
EndProcedure

Publié : sam. 28/avr./2007 12:31
par Gratteur
J'ai programmé ce petit truc l'année dernière pour faire mumuze avec les listes et les pointeurs. En gros ça permet de créer plein de listes de structure identique dans une seule (ce qui peut être pratique par exemple pour utiliser une liste dans une autre liste ou une dans chaque élément d'un tableau).

Le but du jeu était de programmer ça vite fait à partir des listes Purebasic et sans utiliser de buffer.
Je n'ai pas commenté car ce n'était pas destiné à être posté ici mais je pense que l'exemple parle de lui-même et montre différentes façons d'utiliser la Gliste, ça mange pas de pain mais j'espère que ça te sera utile.

Code : Tout sélectionner

Procedure InitGList()
  Structure Glist
    id.l
    type.l
  EndStructure
  Global NewList Glist.Glist()
  Structure Gindex
    index.l
    elementcourant.l
    nbelements.l
  EndStructure
  Global NewList Gindex.Gindex()
EndProcedure

Procedure RazGList()
  ClearList(Gindex())
  ClearList(Glist())
EndProcedure

Procedure NewGList()
  LastElement(Gindex())
  AddElement(Gindex())
  LastElement(Glist())
  AddElement(Glist())
  Gindex()\index = @Glist()
  Gindex()\elementcourant = @Glist()
  ProcedureReturn @Gindex()
EndProcedure

Procedure IsGList(list)
  Protected resultat
  ForEach Gindex() 
    If list = @Gindex()
      resultat = @Gindex()
    EndIf
  Next
  ProcedureReturn resultat
EndProcedure

Procedure UseGList(list)
  ChangeCurrentElement(Gindex(), list)
  ChangeCurrentElement(Glist(), Gindex()\elementcourant)
EndProcedure

Procedure CountGListe(list)
  ChangeCurrentElement(Gindex(), list)
  ChangeCurrentElement(Glist(), Gindex()\elementcourant)
  ProcedureReturn Gindex()\nbelements
EndProcedure

Procedure IndexGList(list)
  Protected resultat
  ChangeCurrentElement(Gindex(), list)
  ChangeCurrentElement(Glist(), Gindex()\index)
  resultat = ListIndex(Glist())+1
  ChangeCurrentElement(Glist(), Gindex()\elementcourant)
  resultat = ListIndex(Glist())-resultat
  ProcedureReturn resultat
EndProcedure

Procedure SelectGList(list, position)
  Protected resultat
  ChangeCurrentElement(Gindex(), list)
  If position >= 0 And position < Gindex()\nbelements
    ChangeCurrentElement(Glist(), Gindex()\index)
    SelectElement(Glist(), ListIndex(Glist())+1+position)
    Gindex()\elementcourant = @Glist()
    resultat = @Glist()
  EndIf
  ProcedureReturn resultat
EndProcedure

Procedure ChangeGList(list, *element)
  ChangeCurrentElement(Gindex(), list)
  ChangeCurrentElement(Glist(), *element)
  Gindex()\elementcourant = @Glist()
EndProcedure

Procedure SwapGList(list, *element1, *element2)
  ChangeCurrentElement(Gindex(), list)
  ChangeCurrentElement(Glist(), Gindex()\elementcourant)
  SwapElements(Glist(), *element1, *element2)
EndProcedure

Procedure AddGList(list, *valeur.Glist=0)
  ChangeCurrentElement(Gindex(), list)
  If Gindex()\nbelements
    ChangeCurrentElement(Glist(), Gindex()\elementcourant)
  Else
    ChangeCurrentElement(Glist(), Gindex()\index)
  EndIf
  AddElement(Glist())
  Gindex()\elementcourant = @Glist()
  Gindex()\nbelements+1
  If *valeur
    CopyMemory(*valeur, @Glist(), SizeOf(Glist))
  EndIf
  ProcedureReturn @Glist()
EndProcedure

Procedure InsertGList(list, *valeur.Glist=0)
  Protected resultat
  ChangeCurrentElement(Gindex(), list)
  If Gindex()\nbelements
    ChangeCurrentElement(Glist(), Gindex()\elementcourant)
    InsertElement(Glist())
  Else
    ChangeCurrentElement(Glist(), Gindex()\index)
    AddElement(Glist())
  EndIf
  Gindex()\elementcourant = @Glist()
  Gindex()\nbelements+1
  If *valeur
    CopyMemory(*valeur, @Glist(), SizeOf(Glist))
  EndIf
  ProcedureReturn @Glist()
EndProcedure

Procedure DelGList(list) 
  ChangeCurrentElement(Gindex(), list)
  If Gindex()\nbelements
    ChangeCurrentElement(Glist(), Gindex()\elementcourant)
    DeleteElement(Glist())
    Gindex()\elementcourant = @Glist()
    Gindex()\nbelements-1
  EndIf
EndProcedure

Procedure ClearGList(list)
  ChangeCurrentElement(Gindex(), list)
  ChangeCurrentElement(Glist(), Gindex()\index)
  While Gindex()\nbelements
    NextElement(Glist())
    DeleteElement(Glist())
    Gindex()\nbelements-1
  Wend
  Gindex()\elementcourant = @Glist()
EndProcedure

Procedure ResetGList(list)
  ChangeCurrentElement(Gindex(), list)
  ChangeCurrentElement(Glist(), Gindex()\index)
  Gindex()\elementcourant = @Glist()
EndProcedure

Procedure FirstGList(list)
  Protected resultat
  ChangeCurrentElement(Gindex(), list)
  If Gindex()\nbelements
    ChangeCurrentElement(Glist(), Gindex()\index)
    NextElement(Glist())
    Gindex()\elementcourant = @Glist()
    resultat = @Glist()
  EndIf
  ProcedureReturn resultat
EndProcedure

Procedure LastGList(list)
  Protected resultat
  ChangeCurrentElement(Gindex(), list)
  If Gindex()\nbelements
    If NextElement(Gindex()) = 0
      LastElement(Glist())
    Else
      ChangeCurrentElement(Glist(), Gindex()\index)
      PreviousElement(Glist())
    EndIf
    ChangeCurrentElement(Gindex(), list)
    Gindex()\elementcourant = @Glist()
    resultat = @Glist()
  EndIf
  ProcedureReturn resultat
EndProcedure

Procedure NextGList(list)
  Protected resultat
  ChangeCurrentElement(Gindex(), list)
  If Gindex()\nbelements
    ChangeCurrentElement(Glist(), Gindex()\index)
    resultat = ListIndex(Glist())
    ChangeCurrentElement(Glist(), Gindex()\elementcourant)
    If ListIndex(Glist())-resultat = Gindex()\nbelements
      ChangeCurrentElement(Glist(), Gindex()\index)
      resultat = 0
    Else
      NextElement(Glist())
      resultat = @Glist()
    EndIf
    Gindex()\elementcourant = @Glist()
  EndIf
  ProcedureReturn resultat
EndProcedure

Procedure PreviousGList(list)
  Protected resultat
  ChangeCurrentElement(Gindex(), list)
  If Gindex()\nbelements
    ChangeCurrentElement(Glist(), Gindex()\elementcourant)
    PreviousElement(Glist())
    Gindex()\elementcourant = @Glist()
    If Gindex()\index <> @Glist()
      resultat = @Glist()
    EndIf
  EndIf
  ProcedureReturn resultat
EndProcedure

Procedure ValList(list, *valeur.Glist)
  ChangeCurrentElement(Gindex(), list)
  ChangeCurrentElement(Glist(), Gindex()\elementcourant)
  CopyMemory(*valeur, @Glist(), SizeOf(Glist))
EndProcedure

InitGList()
list = NewGList()
AddGList(list)
Glist()\id = 2
val.Glist
val\id = 1
InsertGList(list, val)
list2 = NewGList()

Debug "Test 1 :"
ResetGList(list)
While NextGList(list)
  Debug GList()\id
Wend

LastGList(list)
val\id = 3
ValList(list, val)
PreviousGlist(list)
val\id = 2
ValList(list, val)

Debug "Test 2 :"
ResetGList(list)
While NextGList(list)
  Debug GList()\id
Wend

FirstGList(list)
GList()\id = 3
NextGList(list)
GList()\id = 4

Debug "Test 3 :"
ResetGList(list)
While NextGList(list)
  Debug GList()\id
Wend

Publié : sam. 28/avr./2007 12:54
par Gratteur
Pour l'utilisation c'est simple :

InitGList() : Initialise la Glist(), la structure Glist peut être modifiée
RazGList() : Supprime toutes les Glist() créées
NewGList() : Crée une nouvelle Glist() et rend en résultat son identifiant listid
IsGList(listid) : Le résultat est différent de 0 si la Glist() existe
UseGList(listid) : Se place sur l'élément courant de la liste
CountGListe(listid) : Le nombre d'éléments de la liste
IndexGList(listid) : La position de l'élément courant de la liste
SelectGList(listid, position) : Sélectionne l'élément de la liste à partir de sa position
ChangeGList(listid, *element) : Change l'élément de la liste par son pointeur
SwapGList(listid, *element1, *element2) : Echange deux elements de la liste par leurs pointeurs
AddGList(listid, *valeur.Glist=0) : Ajoute un élément à la liste
InsertGList(listid, *valeur.Glist=0) : Insert un élément à la liste
DelGList(listid) : Efface un élément à la liste
ClearGList(listid) : Efface la liste
ResetGList(listid) : Se place juste avant la liste
FirstGList(listid) : Le premier élément de la liste
LastGList(listid) : Le dernier élément de la liste
NextGList(listid) : L'élément suivant de la liste
PreviousGList(listid) : L'élément précédent de la liste
ValList(list, *valeur.Glistid) ; Change la valeur de l'élément courant la liste

De façon générale les valeurs retour sont équivalentes à celles des fonctions Purebasic (par exemple NextElement() renvoit 0 si il n'y a pas délément suivant). Il faut aussi savoir que les fonctions qui renvoient une adresse mémoire renvoient l'adresse de l'élément courant si possible.

Voila.

Publié : sam. 28/avr./2007 19:14
par kuroyi
Formidable. Merci à tous. J'épluche et vous tiens au courant. Merci beaucoup.

Publié : mer. 02/mai/2007 21:23
par lionel_om
J'ai fait une Lib (pas encore en version PB4, mais y'a les sources pour modifier toi même) qui permet de gérer des listes de Strings, Entiers (long) ou de structures : Lib Vector. L'aide est fournie avec pour avoir toutes les fonctions (et leur description + syntaxe) disponible !

Lionel