Page 1 sur 3

pointeur de liste

Publié : mer. 18/avr./2018 21:04
par ymerdy
Bonjour,

je souhaite creer une structure dont l'un des champs serait une liste chainee.

j'ai besoin que cette liste soit globale, pour pouvoir etre commune a plusieurs variables du type de ma structure.

j'ai essayé de faire pointer la liste de chaque variable vers le 1er element de la liste globale, mais cela ne fonctionne pas.

Est-il possible d'avoir un champ de structure qui soit un pointeur vers une liste globale?
et qui permette d'utiliser les fonctions des listes (NextElement, listSize, FirstElement, etc...)?

Code : Tout sélectionner

Structure mystruct
  id.i
  name.s
  List lnum.i()
EndStructure

; Declare une liste globale de 10 elements
; initialisés avec les valeurs de 1 a 10
Global NewList glnum.i()
For i=1 To 10
  AddElement(glnum())
  glnum() = i
Next

ForEach glnum()
  Debug "liste globale:"+glnum()
Next
; Declare 2 objets
Define obj1.mystruct
Define obj2.mystruct

; initialise leurs valeurs
obj1\id = 11
obj1\name = "objet 1"

obj2\id = 22
obj2\name = "objet 2"

; fait pointer leur liste vers la liste globale (partagee entre les 2 objets)
obj1\lnum() = FirstElement(glnum()) ;=> ici erreur, la liste chainee ne contient aucun element
obj2\lnum() = FirstElement(glnum())

ForEach obj1\lnum()
  Debug "liste obj1:"+obj1\lnum()
Next

ForEach obj1\lnum()
  Debug "liste obj2:"+obj1\lnum()
Next

Re: pointeur de liste

Publié : mer. 18/avr./2018 22:32
par Ar-S
Bonjour, primo, si tu es un bot, tu as fait de sacrés progrès ^^
Sinon :
Ce que tu cherches à faire me parait un peu tordu.
Utiliser les "map" ne serait pas plus adéquat ?

ex de la doc avec une structure:

Code : Tout sélectionner

Structure Voiture
    Poids.l
    Vitesse.l
    Prix.l
  EndStructure

  NewMap Voitures.Voiture()
  
  ; Ici, nous utilisons l'élément courant après l'insertion du nouvel élément
  ;
  Voitures("Ferrari F40")\Poids = 1000
  Voitures()\Vitesse = 320
  Voitures()\Prix = 500000
  
  Voitures("Lamborghini Gallardo")\Poids = 1200
  Voitures()\Vitesse = 340
  Voitures()\Prix = 700000

  ForEach Voitures()
    Debug "Nom de la Voiture: "+MapKey(Voitures())
    Debug "Poids: "+Str(Voitures()\Poids)
  Next
Remplace "Ferrari F40" par Obj1 et "Lamborghini Gallardo" par Obj2 et sa semble coller à ton projet non ?

Re: pointeur de liste

Publié : jeu. 19/avr./2018 12:56
par ymerdy
Bonjour,
Merci Ar,-S pour ta reponse!
Malheureusement, je ne vois pas trop le lien avec mon probleme.
Tu me proposes de mettre mes 2 variables obj1 et obj2 dans une map, mais cela ne permet pas de partager une donnee membre entre obj1 et obj2.
Pour que cela soit plus concret, je cree des objets graphe dont la structure de donnees comporte, entre autres, une liste de valeurs, une liste de couleurs, etc...
J'ai besoin que plusieurs graphes puissent avoir le meme jeu de donnees et les memes couleurs, d'ou l'idee d'utiliser des pointeurs de listes, plutot que des listes.

J'ai fait un autre essai en initialisant les listes de obj1 et obj2 avec ChangeCurrentElement().
L'initialisation.fonctionne, mais les listes sont vides pour PB (listsize=0)
J'imagine que PB gere lis listes chainees avec les infos de la liste stoquees quelque part, en 0lus des pointeurs *next et *previous, mais je n'arrive pas a trouver ou en observant la memoire...

Code : Tout sélectionner

Structure mystruct
  id.i
  name.s
  List lnum.i()
EndStructure

; Declare une liste globale de 10 elements
; initialisés avec les valeurs de 1 a 10
Global NewList glnum.i()
For i=1 To 10
  AddElement(glnum())
  glnum() = i
Next

ForEach glnum()
  Debug "liste globale:"+glnum()
Next
; Declare 2 objets
Define obj1.mystruct
Define obj2.mystruct

; initialise leurs valeurs
obj1\id = 11
obj1\name = "objet 1"

obj2\id = 22
obj2\name = "objet 2"

; fait pointer leur liste vers la liste globale (partagee entre les 2 objets)
;obj1\lnum() = FirstElement(glnum()) ;=> ici erreur, la liste chainee ne contient aucun element
;obj2\lnum() = FirstElement(glnum())
ChangeCurrentElement(obj1\lnum(),FirstElement(glnum())
ChangeCurrentElement(obj2\lnum(),FirstElement(glnum())

Debug "taille liste de obj1:"+ListSize(obj1\lnum()) ;=> 0!!!
ForEach obj1\lnum()
  Debug "liste obj1:"+obj1\lnum()
Next

Debug "taille liste de obj2:"+ListSize(obj2\lnum());=> 0!!!
ForEach obj2\lnum()
  Debug "liste obj2:"+obj2\lnum()
Next


Re: pointeur de liste

Publié : jeu. 19/avr./2018 15:17
par Ollivier
Bon allez... De tête... Version 'procédure spécifique à Gtodo'

Code : Tout sélectionner


structure todo
 list act.s()
endstructure

global Gtodo.todo

procedure GtodoAjoute(act.s)
 addelement(Gtodo\act() )
 Gtodo\act() = act
endprocedure

GtodoAjoute("remercier Yvonne")
GtodoAjoute("rembourser Yolande")
GtodoAjoute("nettoyer lunette")

ForEach Gtodo\act()
 debug Gtodo\act()
Next

Il te faut une version 'procédure générale' ?
De type

Code : Tout sélectionner

Ajoute(Gtodo, "acheter savon")
Ajoute(Courses, "savon")

Re: pointeur de liste

Publié : jeu. 19/avr./2018 15:33
par ymerdy
Hello,
j'ai peut etre mal exprime mon probleme, mais si on part de ton exemple, comment creer un Gtodo2 de type todo dont la liste act() soit commune avec Gtodo?
Il faut que la liste soit partagee, et pas une copie, de sorte que sij'ajoute un element a la liste, la modif soit vue des 2 objets Gtodo et Gtodo2.

Re: pointeur de liste

Publié : jeu. 19/avr./2018 16:27
par djes
Je suis dans le train mais à voir, il suffit de créer une seule liste (globale dans ce cas, ce serait mieux) et de remplacer (même si tu n'y es pas obligé) le champ liste de ta structure par un pointeur, qu'il faudra forcément initialiser à la première utilisation.

Re: pointeur de liste

Publié : jeu. 19/avr./2018 16:42
par Ollivier
Version 'procédure générale' sur le principe de copie de chaîne (a contrario du principe de copie de pointeurs qui est moins gourmand en mémoire, mais moins simple à comprendre en une fois)

Code : Tout sélectionner

Structure LST
List Act.S()
EndStructure

Global Todo.LST



Procedure Ajouter(Quoi.S, *AQuoi.LST)

AddElement(*AQuoi\Act() )
*AQuoi\Act() = Quoi

AddElement(Todo\Act() )
Todo\Act() = Quoi

EndProcedure



Procedure Lire(*Quoi.LST)

ForEach(*Quoi\Act() )
Debug *Quoi\Act()
Next
Debug " "

EndProcedure



Define Lundi.LST
Define Mardi.LST


Ajouter(">>> TODO <<<", Todo) ; facultatif
Ajouter(">>> LUNDI <<<", Lundi) ; facultatif
Ajouter(">>> MARDI <<<", Mardi) ; facultatif


Ajouter("Courses", Lundi)
Ajouter("Coiffeur", Mardi)
Ajouter("Dentiste", Mardi)

Lire(Todo)
Lire(Lundi)
Lire(Mardi)
@Djes

Je suis à pied, j'espère que mon code ne boguera pas...
(T'as fait comment pour avoir un train, ça fait une semaine que je suis coincé...)

:!: [moderation:falsam] en mp la réponse svp. On ne va pas débattre sur le transport

Re: pointeur de liste

Publié : jeu. 19/avr./2018 17:07
par falsam
Cette question me pertube
ymerdy a écrit :Est-il possible d'avoir un champ de structure qui soit un pointeur vers une liste globale?
Non

- Un pointeur de liste pointe sur un élément de liste et non pas sur la liste entière.
- La boucle ForEach ... Next ne permet pas de démarrer depuis un point précis de ta liste.

Code : Tout sélectionner

obj1\lnum() = FirstElement(glnum()) ;=> ici erreur, la liste chainee ne contient aucun element
Normal cette erreur. Une liste ne peut pas etre le pointeur d'un element d'une liste.

Re: pointeur de liste

Publié : jeu. 19/avr./2018 18:02
par Ollivier
Allez... Version 'sans les dents' : donc j'ai modifié mon code plus haut pour que désormais, ce soit les pointeurs qui soient stockés, et non plus des copies de chaîne.

Ainsi, un bon apprentissage consiste à jouer aux 7 différences entre les 2 codes.

(Si ça bogue, pas de stress)

Code : Tout sélectionner

Structure LST
List Act.S()
EndStructure

Global Todo.LST

Structure LSTPTR
List *Act()
EndStructure

Procedure Ajouter(Quoi.S, *AQuoi.LSTPTR)

AddElement(Todo\Act() ) ; inchangé
Todo\Act() = Quoi

AddElement(*AQuoi\Ptr() )
*AQuoi\Act() = @Todo\Act()

EndProcedure



Procedure Lire(*Quoi.LST)
ForEach(*Quoi\Act() )

ChangeCurrentElement(Todo(), *Quoi\Act() )
Debug Todo\Act()

Next
Debug " "
EndProcedure



Define Lundi.LSTPTR
Define Mardi.LSTPTR

Ajouter("Courses", Lundi)
Ajouter("Coiffeur", Mardi)
Ajouter("Dentiste", Mardi)

ForEach Todo()
Debug Todo()
Next
Debug " "

Lire(Lundi)
Lire(Mardi)

Re: pointeur de liste

Publié : jeu. 19/avr./2018 18:05
par falsam
Et bien ça bug ligne16 !!! Ollivier teste avant de balancer tes codes. Attends au moins d'etre chez toi.

Re: pointeur de liste

Publié : ven. 20/avr./2018 9:09
par comtois
Si ta liste est globale, pourquoi vouloir pointer dessus ?

Tu peux aussi créer tes propres listes, sans utiliser celles de PureBasic, comme ça tu fais comme tu veux (c'est à toi d'allouer l'espace mémoire, de le libérer, mais c'est plus souple).

Re: pointeur de liste

Publié : ven. 20/avr./2018 10:28
par Ollivier
@Falsam

J'ai dit "pas de stress".

remplacer ligne 16

Code : Tout sélectionner

AddElement(*AQuoi\Ptr() )
par

Code : Tout sélectionner

AddElement(*AQuoi\Act() )
3 lettres à remettre en place...

@Comtois
Comtois a écrit :Si ta liste est globale, pourquoi vouloir pointer dessus ?
Et pourquoi pas? :D
Bonjour à toi !

Re: pointeur de liste

Publié : sam. 21/avr./2018 16:24
par Ollivier
Je découvre ça :
Falsam a écrit :- Un pointeur de liste pointe sur un élément de liste et non pas sur la liste entière.
- La boucle ForEach ... Next ne permet pas de démarrer depuis un point précis de ta liste.
Bon... Vous l'aurez deviné : c'est faux pour les deux item ci-dessus...

Bonne soirée les gars...

Re: pointeur de liste

Publié : dim. 22/avr./2018 22:48
par nico
il est possible d'utiliser CopyList, ce qui donnera quelque chose comme ça, mais c'est pas très raisonnable:
; fait pointer leur liste vers la liste globale (partagee entre les 2 objets)
CopyList(glnum(), obj1\lnum())

On peut effectivement utiliser des pointeurs mais du coup autant créer sa propre liste chainée, cela a déjà été fait, notamment pour créer des listes chainées dynamiques (créer des listes a la volée sans avoir a les déclarées auparavant). J'en ai moi même réalisé de mémoire, je ne suis pas le seul.

Je verrais bien aussi une solution avec des interfaces (vtable).

Re: pointeur de liste

Publié : lun. 23/avr./2018 9:00
par djes
En fait, et malgré la réponse apportée par demivec sur le forum anglais, je pense qu'il est plus simple d'utiliser la liste globale, et de mettre le pointeur de position dans la structure. À chaque utilisation des «objets», on se positionne sur l'élément voulu, et voilà, inutile de jongler avec des pointeurs.