pointeur de liste

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: pointeur de liste

Message par Zorro »

surtout qu'on peut sauter au bon element d'une list avec

Code : Tout sélectionner

*Resultat = SelectElement(Liste(), Position)
inutile d'utiliser une boucle , cette fonction en inclue une de façon implicite :)

Code : Tout sélectionner

NewList MaListe.l()

  AddElement(MaListe()) : MaListe() = 23
  AddElement(MaListe()) : MaListe() = 56
  AddElement(MaListe()) : MaListe() = 12
  AddElement(MaListe()) : MaListe() = 73

  SelectElement(MaListe(), 0) ; recup l'element 1 <<<< faute de frappe
  MessageRequester("Position", "A la position 0, la valeur est "+Str(MaListe()),0)

  SelectElement(MaListe(), 2) ; recup l'element 3
  MessageRequester("Position", "A la position 2, la valeur est "+Str(MaListe()),0)

  SelectElement(MaListe(), 1) ; recup l'element 2
  MessageRequester("Position", "A la position 1, la valeur est "+Str(MaListe()),0)

  SelectElement(MaListe(), 3) ; devine ??
  MessageRequester("Position", "A la position 3, la valeur est "+Str(MaListe()),0)
; non seulement ça permet de recuperer un element de la list
; mais ça positionne le pointeur de list sur cet element !
; donc, on peut aussi le modifier .... 
; considérer  SelectElement() comme une façon de bouger le pointeur de la list ou on veux

; on peut utiliser  cette fonction comme Pointeur de code (PC) dans une pile (la liste) d'instructions pour un interpreteur :)

Dernière modification par Zorro le lun. 23/avr./2018 19:08, modifié 1 fois.
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: pointeur de liste

Message par Ollivier »

Je comprends mal ce que vous dites...

ArS indique qu'une Map, ça fait l'affaire.
Falsam mélange définition de pointeur et d'index.
Comtois s'interroge sur le pourquoi du global.
Djes évoque l'utilisation des pointeurs puis, finalement, conseille les index.
Nico semble trouver les pointeurs assez lourds.
Zorro dégage le tout et sort un code sans sélection, où les commentaires sont incohérents (0 équivaut à 0 tandis que 2 équivaut à 3, ...).

Pourtant, la question de notre "débutant", elle est claire et les réponses en code source, à moins de transporter en SpiderBasic, sont franchement bien, et montre des possibilités de simplicité de programmation et de performance indémodables.

J'ai dû looper un train quelquepart...
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: pointeur de liste

Message par nico »

C'est à dire que la demande n'est pas simple puisqu'elle consiste à utiliser une ressource (ici une NewList) qui doit être accessible depuis deux variables structurées et le code doit manipuler cette liste sans faire appel à la variable de cette liste.

Il m'est déjà arrivé de vouloir réaliser cela mais c'était pas avec une NewList, j’encapsulais alors les données dans des procédures.
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: pointeur de liste

Message par Zorro »

Ollivier a écrit :où les commentaires sont incohérents (0 équivaut à 0 tandis que 2 équivaut à 3, ...).
mes commentaires ne sont pas incohérent ........... (et là , je me modere :lol: parceque pour le coup c'est l'hopital qui se fout de la charité )

les elements d'une list chainée commencent a 0 , donc l'element 3 est a la position 2

j'ai repris l'exemple de la Doc , qui parle de "position" du pointeur de liste
et celui ci pointe un elements de la liste , et comme l'element commence a 0 , il y a forcement un decalage

entre le pointeur a la position 2 (c'est ce chiffre que tu mets dans la fonction selectElement() ) , mais
c'est bien le 3 em elements de la liste que tu pointes !!


bref le B a Ba de la programmation, c'est deja (et c'etait deja ) comme ça avec les tableaux
il existait meme une commande Basic pour ça "OptionBase" ...... a l'epoque des dynosaure

la fonction permet de "sauter" directement a une element, c'etait une reponse a Falsam et sa boucle ForEach

maintenant je plussoie, tu declares la list en Global , et elle est accessible par tout le monde ....
c'est meme le principe du "Global"

pointeur ou pas , on s'en fout , ça marche pareil ...
que tu mettes *po=selectElement(x) ou po=selectElement(x)
ça ne change rien au fait que *po ou po aura la position de l'element X

dans un cas c'est un pointeur, dans l'autre une variable , mais l'essentiel c'est d'avoir ce qu'on veux


ps: je viens de voir que tu chipotes sur une faute de frappe , dans un commentaire .... :roll:
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: pointeur de liste

Message par nico »

Voici un exemple de démo utilisant des vtables qui pointent sur des procédures encapsulant la gestion de la liste chaînée, tout est géré à partir des variables structurées, obj1 et obj2.

Code : Tout sélectionner

Interface MaList
    AjouterList(Valeur.i)
    SupprimerList(Valeur.i)
    LireNbList()
    ResetMaList()
    LireSuivantList()
EndInterface

Structure Class
    *Vtable.MaList
EndStructure

Global NewList MaList.Class()

AddElement(MaList())
MaList()\Vtable = ?Vtable

Structure mystruct
    id.i
    name.s
    *Vtable.MaList
EndStructure

Procedure GestionList(index.l, Valeur.i=0)
    Static NewList glnum.i()
    Protected  *pointeur
    
    If index = 0
        *pointeur = AddElement(glnum())
        glnum() = Valeur    
        ProcedureReturn *pointeur
        
    ElseIf index = 1
        *pointeur = DeleteElement(glnum(),1)
        ProcedureReturn *pointeur
        
    ElseIf index =2
        ProcedureReturn ListSize(glnum())
        
    ElseIf index =3
        ProcedureReturn ResetList(glnum())
        
    ElseIf index =4
        NextElement(glnum())
        ProcedureReturn glnum()
    EndIf 
    
EndProcedure

Procedure AjouterList(*This, Valeur.i)
    ProcedureReturn GestionList(0, Valeur)
EndProcedure

Procedure SupprimerList(*This, Valeur.i)
    ProcedureReturn GestionList(1, Valeur)
EndProcedure

Procedure LireNbList(*This)
    ProcedureReturn GestionList(2, Valeur)
EndProcedure

Procedure ResetMaList(*This)
    ProcedureReturn GestionList(3)
EndProcedure

Procedure LireSuivantList(*This)
    ProcedureReturn GestionList(4, Valeur)
EndProcedure

; Declare 2 objets
Define obj1.mystruct
Define obj2.mystruct

; affectation des interfaces aux objets 1 et 2
obj1\Vtable = MaList()
obj2\Vtable = MaList()

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

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

obj1\Vtable\AjouterList(111)
obj1\Vtable\AjouterList(222)

; nombre d'élément de la liste
nombre = obj1\Vtable\LireNbList()
Debug "nombre d'éléments= " + Str(nombre)
Debug "   "

; on affiche toute les valeurs de la liste à partir de l'objet 1
Debug obj1\name
Debug obj1\id

obj1\Vtable\ResetMaList()
For a = 1 To nombre
    Debug "liste obj1:"+ obj1\Vtable\LireSuivantList()
Next

Debug "   "

; on affiche toute les valeurs de la liste à partir de l'objet 2
Debug obj2\name
Debug obj2\id

obj2\Vtable\ResetMaList()
For a = 1 To nombre
    Debug "liste obj2:"+ obj2\Vtable\LireSuivantList()
Next

DataSection
    Vtable:
    Data.i @AjouterList(), @SupprimerList(), @LireNbList(), @ResetMaList(), @LireSuivantList()
EndDataSection
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: pointeur de liste

Message par Ollivier »

Je vais essayer de me faire comprendre pourquoi je m'exclame...

Ce que le compilo a acquis :

Code : Tout sélectionner

Structure ListeDeChaines
 List A.S()
EndStructure
On n'avait pas ça avant. Ça permet d
'avoir une liste pointée comme un buffer.

Code : Tout sélectionner

Procedure NouvelleListeDeChaines()
Define *Quoi.ListeDeChaines
*Quoi = AllocateMemory(SizeOf(ListeDeChaines) )
InitializeStructure(*Quoi, ListeDeChaines)
ProcedureReturn *Quoi
EndProcedure
Ça, ça permet de faire l'équivalent de NewList.

Code : Tout sélectionner

Procedure SupprimeListeDeChaines(*Quoi.ListeDeChaines)
ClearStructure(*Quoi, ListeDeChaines)
FreeMemory(*Quoi)
EndProcedure
Ça, ça permet un équivalent qui n'existait pas du tout : rayer une liste de "la carte". Plus d'existence...

Maintenant, si on remplace

Code : Tout sélectionner

Global Todo.ListeDeChaines
par

Code : Tout sélectionner

Global *Todo.ListeDeChaines = NouvelleListeDeChaines()
Je dirai qu'elle est là, la subtilité présentée par Demivec.

Notre pointeur *Todo pointe vers la totalité de la liste des actions (à faire à l'avenir, dans le cas d'une "Todo list") sous forme de chaînes. Et cela quelque soit le fond et la forme de nos listes d'appel :

Code : Tout sélectionner

Define Lundi.ListeDePointeurs
Define Mardi.ListeDePointeurs
...
Define Roger.ListeDePointeurs
Define Rachid.ListeDePointeurs
...
Define Voiture.ListeDePointeurs
Define Velo.ListeDePointeurs
Define Train.ListeDePointeurs
...
Par l'intermédiaire de listes d'occurences (je mets un nom juste pour comprendre)

Code : Tout sélectionner

Define CoursesAlimentaires.ListeDePointeurs ; nom abject
regroupées en tableaux de listes

Code : Tout sélectionner

Dim *Occurence(255).ListeDePointeurs
où, par exemple, CoursesAlimentaires serait (au pif : 12) *Occurence(12), on peut faire une "translation" de notre "Todo list", par exemple, obtenir la traduction en anglais de chacune de nos actions, voire, pour chaque action, un commentaire, voir, en s'étalant aux autres types de données, un type descripteur de données.

Le tout, finalement, avec une syntaxe de programmation qui n'est pas très lourde, une vitesse interne égalable à celle des gestions de listes, avec, en plus une gestion de la mémoire complètement étanche.

Là, il n'y a que 3 couches :
1) translateurs (listes temporaires de pointeurs vers le 2 obtenus à partir du 3)
2) attributeurs (lundi, roger, velo, etc... listes de pointeurs vers le 3)
3) données (listes de chaînes, notamment)

Mais la couche 2 peut être "composée" d'une myriade d'étages ou de n'importe quelle forme de schéma fonctionnel.

Ça reste assez simple à programmer, si on garde certains pointeurs en global.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: pointeur de liste

Message par nico »

Mais t'as une idée du temps que ça m'a pris de pondre le code précédent mais t'as raison c'est plus simple, je ne savais pas que l'on pouvais faire comme ça.
Je n'avais pas saisi tes précédents codes à ce sujet.

Il y a bien un petit exemple dans l'aide de Purebasic après recherche.

Donc j'ai refais le code en reprenant le principe que t'explique et voilà:

Code : Tout sélectionner

; La Structure contenant la liste est à part, c'est fait exprès!
Structure liste
    List glnum.i()
EndStructure

Structure mystruct
    id.i
    name.s
    *lnum.liste
EndStructure

; Declare un pointeur de liste globale
; mais c'est pas utile sauf si on souhaite initialiser des valeurs sans passer par obj1 ou obj2
Global *glnum.liste

; InitializeStructure ne sera exécutée qu'une seule fois en réalité
; puis renverra par la suite le pointeur généré
; c'est pour cela qu'il n'y a pas la procédure de suppression de la liste ici
; il n'y a pas de rique d'initialiser plus d'une fois la même liste
Procedure InitStructure(*pointeur)
    Static mem.i=0
    
    If mem = 0
        *pointeur = AllocateMemory(SizeOf(liste))
        InitializeStructure(*pointeur, liste)
        mem = *pointeur
    EndIf 
    
    ProcedureReturn mem
EndProcedure

; initialisation du pointeur de liste
*glnum = InitStructure(*glnum)

; remplissage de la liste avec les valeurs de 1 à 10
For i=1 To 10
    AddElement(*glnum\glnum())
    *glnum\glnum() = i
Next

Debug "Affichage initial de la liste"

ForEach *glnum\glnum()
    Debug "liste globale:"+ *glnum\glnum()
Next

Debug "   "

; Declare les 2 objets + initialisation des pointeurs
Define obj1.mystruct
Define obj2.mystruct
obj1\lnum = InitStructure(obj1\lnum)
obj2\lnum = InitStructure(obj2\lnum)


; initialise les valeurs de obj1
obj1\id = 11
obj1\name = "objet 1"
AddElement(obj1\lnum\glnum())
obj1\lnum\glnum() = 111

; initialise les valeurs de obj2
obj2\id = 22
obj2\name = "objet 2"
AddElement(obj2\lnum\glnum())
obj2\lnum\glnum() = 222

Debug "Affichage de la liste à partir de obj1"

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

Debug "   "

Debug "Affichage de la liste à partir de obj2"

ForEach obj2\lnum\glnum()
    Debug "liste obj2:"+ obj2\lnum\glnum()
Next
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: pointeur de liste

Message par djes »

Ollivier, tu sais que j'aime particulièrement deux choses, la bidouille, et repousser les limites du langage. Mais j'aime aussi l'élégance. Et pour cette question, qui se résume à terme à partager des valeurs communes entre gadgets (table de couleurs, etc.) je pense qu'il faut faire au plus simple, au plus lisible, au plus portable, en utilisant au maximum ce que PureBasic a à offrir.
Et puis les échanges et la diversité des réponses sont une richesse !
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: pointeur de liste

Message par nico »

Je ne comprend pas la solution que tu suggères, elle ne semble pas répondre à la question; tu pourrais poster un code qui illustre complètement ce qui est recherché.
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: pointeur de liste

Message par Marc56 »

; 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
C'est normal, FirstElement() est une fonction, son résultat (pointeur) change donc à chaque appel.
Il ne pointe sur rien tant que la liste ne contient aucun élément. (Le message d'information l'indique bien)

Comme l'a indiqué Zorro, il faut se servir du numéro d'index pour appeler un élément d'une liste.
Dans une liste, le numéro est obtenu par SelectElement car il varie à chaque tri/ajout/supression/déplacement

Pour identifier et partager des propriétés d'objets, il est préférable d'utiliser une map (il est possible aussi de parcourir une map)

Mais bon, il est possible que comme tout le monde ici et sur le forum us, je n'ai probablement pas dû bien comprendre l’énoncé :) :wink:
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

Re: pointeur de liste

Message par case »

je comprend pas l’intérêt d'avoir une liste dans une structure qui ne sera pas utilisée, pour aller lire une autre liste globale.
il suffis d'avoir une liste globale et quand on veux l'utiliser on l'utilise sans passer par une structure ou des pointeurs ou tout autre procédé empreint de magie noire...
c'est vraiment se compliquer le code pour rien.

que la liste soit dans une structure n'apporte rien.

au lieu de faire foreach montruc\maliste()
il suffis de faire foreach maliste()

a chaque fois qu'on veux accéder a la liste commune...
ImageImage
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: pointeur de liste

Message par Zorro »

+1000 :)

un liste peut etre vue comme un simple "endroit" ou l'on fourre des données
en etant global , on peut y acceder de partout en lecture ou ecriture ... plus simple tu meurts :)

ma devise : dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer :)
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: pointeur de liste

Message par Ollivier »

Comme dit le proverbe chinois :

<<
Simplifie sagement le nombre de feuille de Lotus,
Mais pas à en teindre tes doigts aux couleurs de l'anus...
>>

Je vais donner un exemple...
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: pointeur de liste

Message par falsam »

Ollivier le grand a écrit :Je vais donner un exemple...
J'espere qu'on va rire :mrgreen:
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: pointeur de liste

Message par falsam »

@Case @Zorro + 1000 ^-^
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre