[TUTO] Les Structures

Informations pour bien débuter en PureBasic
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

[TUTO] Les Structures

Message par Backup »

ceci est un recapitulatif d'une discution qui a eu lieu sur les structures
un tuto !! je remerci les auteurs respectif au nom de toute l'humanité
pour nous avoir fait partagé leur immense savoir :)

voici:

Une structure, c'est ni plus, ni moins qu'une liste de variables qui peuvent être de différents types.

Code:

Code : Tout sélectionner

Structure RESULTAT
  octet.b
  Mot.w
  Mot_Long.l
  Chaine.s
EndStructure

Info.RESULTAT
Info.RESULTAT : retourne l'adresse de la structure RESULTAT dans Info

Info\Octet = 2 : Tu donnes la valeur de 2 a la variable octet,
en appelant la structure grace à son adresse contenue dans Info

Nombre = Info\Octet : Tu récupères la valeur contenue dans la variable
Octet, en appelant la structure grace à son adresse contenue dans Info

C'est comme si tu appelais des variables.

Par contre, tu peux avoir une variable qui est liée à une autre structure.

Code:

Code : Tout sélectionner

Structure RESULTAT
  octet.b
  Mot.w
  Mot_Long.l
  Chaine.s
  Valeur.AUTRESTRUCTURE <-- Variable liée à une autre structure
EndStructure

Info.RESULTAT
et le "info" c'est arbitraire n'est-ce pas ?
t'aurai pu lui donner n'importe quel nom ?
Tout juste ! Info, c'est le nom de la variable. Tu peux créer autant de variables que tu veux en les déclarant du type "Resultat". C'est exactement comme quand tu fais :
a.l ; variable de type entier long
b.f ; variable de type flotant (nombre à virgule)
est-ce le point entre les deux qui sert d'affectation ?
Oui, sauf que dans ce cas, on utilise pas le terme "affectation" mais "typage". L'affectation, c'est quand tu affecte (donne) une valeur à une variable (a=1). Le typage c'est quand tu décide de quelle sorte de variable il s'agit. (cela dit, on dit parfois "affectation de type" plutôt que "typage").
et les structures peuvent t'elle renfermer des listes ou d'autre structures ??
Oui, comme dit plus haut, une structure est une liste de variables. Chacune de ces variables peut avoir un type différent, y compris un type structure.
en fait si j'ai compris le terme "resultat"dans ton exemple n'est employé que pour la creation de la structure !
on l'affecte a une variable dans ce cas "info" et dorenavant on utilise que "info" on oublie "Resultat" ok ??
C'est ça ! Comme on peut avoir besoin de créer différentes sortes de structures, il faut bien pouvoir leur donner un nom pour pouvoir les utiliser à tour de rôle :
a.struct1
b.struct2
Ensuite, tu utilise a et b comme tu veux.

En fait, tu vois, tu avais tout compris. Le seul point dont tu ne parles pas, c'est comment utiliser ensuite ces variables. Petit exemple ?

Code:

Code : Tout sélectionner

;Création d'une structure : 
Structure Struct1 
  e1.l 
  e2.l 
EndStructure 
; 
; Typage d'une variable et affectation (les deux en même temps) 
var.Struct1\e1 = 1 ; on aurait pu faire "var.Struct1" et à la ligne var\e1 = 1 
; on complète l'affectation 
var\e2 = 2 ; pas la peine de refaire var.Struct1\e2 = 2, le type de var 
                ; a déjà été déclaré, maintenant, PurePasic sait que var est de type Struct1 

debug var\e1 ; ça va afficher "1" 
debug var\e2 ; ça va afficher "2" 
Les structures sont particulièrement pratique quand tu dois créer un tableau de données. Le cas typique, c'est un tableau de points
Code:

Code : Tout sélectionner

Dim pt.point(100) 

;Pas besoin de créer la structure "point", elle existe déjà (PureBasic ;pré-déclare tout un paquet de structures que tu peux voir avec "Structure Viewer"). 
;Dans cet exemple, pt est un tableau à deux dimensions de 100 points qui ;s'utilise comme suit : 

pt(1)\x = 10 
pt(1)\y = 25 
pt(2)\x = 7 
pt(2)\y = 8 
ou, pour créer une courbe : 
For ct = 1 to 100 
pt(ct)\x = ct 
pt(ct)\y = ct*ct 
Next


Par contre, une procedure peut prendre en paramètre un pointeur vers une structure à remplir:

Code:

Code : Tout sélectionner

Structure RESULTAT 
  octet.b 
  Mot.w 
  motlong.l 
  Chaine.s 
EndStructure 

Procedure MaProcedure(*result.resultat) 
  
  *Result\octet   = #True 
  *Result\Mot     = 1234 
  *Result\motlong = 12345678 
  *Result\Chaine  = "Hello World !" 
  ;ProcedureReturn @Result  : du coup, plus besoin de retourner de valeur 
EndProcedure 

Procedure metlesouk() 
  a=7 
  b=9 
  c.f=0.1 
  d$="coucou" 
EndProcedure 

MaProcedure(@Valeur.RESULTAT) 
metlesouk() 
Debug Valeur\octet 
Debug Valeur\Mot 
Debug Valeur\motlong 
Debug Valeur\Chaine 

Voilà
[/quote]

*****************************************************************************************
Structure Union

voici ce qu'est une StructureUnion
c'est le regroupement L'UNION de plusieurs Champs a la meme adresse memoire :

Code : Tout sélectionner

Structure Type
    Name$
    StructureUnion
    Long.l      ; Chaque champ (Long, Float et String) est placé à la
    Float.f     ; meme adresse mémoire.
    String.s    ;  UN SEUL ESPACE MEMOIRE POUR CES 3 CHAMPs
    EndStructureUnion   
EndStructure
; ce qui fait que

type.Type\Long.l  =1
type.Type\Float.f  =1 ; la on viens d'écraser ce qu'on avait attribué a \Long.l

; la preuve
Debug type.Type\Float.f ; c'est bon puisque c'est la dernière valeur entrée
Debug type.Type\Long.l ; ça affiche n'importe quoi parceque la valeur n'existe plus !! :)
les champs
Long.l ; Float.f ; String.s sont considérés comme un seul Champ !!! d'un point de vue Emplacement Memoire :)
Dernière modification par Backup le ven. 27/juin/2008 16:46, modifié 4 fois.
Avatar de l’utilisateur
Crystal Noir
Messages : 891
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

Et bien ca nous fera deux tutos sur les structures , car moi sur mon tuto liste chainée je fais également les structures :

http://purebasic.hmt-forum.com/viewtopic.php?t=882 :lol:
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Si je puis me permettre un rajout sur les structures en ce qui concerne la syntaxe des pointeurs, voici un exemple

Code : Tout sélectionner

Structure UNPOINTEUR
    *Pointeur
EndStructure

Table.UNPOINTEUR
Table\Pointeur = 1
Debug Table\Pointeur
Voilà, pas d'astérisque (*)! ça peut sembler bête mais ça m'a freiné de l'ignorer...
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: [TUTO] Les Structures

Message par Ollivier »

Backup a écrit :Une structure, c'est ni plus, ni moins qu'une liste de variables qui peuvent être de différents types.
Je reprends cette citation qui permet de cerner rapidement le fonctionnement d'une structure. Par contre, techniquement, il y a une subtilité : une structure est un ensemble ordonné de champs.

Prenons un ensemble ordonné de variables.

Code : Tout sélectionner

Define Marque.S = "Poulain"
Define AnneeCreation.I = 1848
Si on veut lire la marque, on tape

Code : Tout sélectionner

Debug Marque
Si on veut lire la marque en fonction de son adresse mémoire ou pointeur, on tape

Code : Tout sélectionner

Debug PeekS(@Marque)
Si on veut faire la même avec le pointeur explicite, on tape

Code : Tout sélectionner

Define *Ptr = @Marque
Debug PeekS(*Ptr)
Si on veut lire l'année de création, on tape

Code : Tout sélectionner

Debug AnneeCreation
Si on veut lire l'année de création, grâce au pointeur, on tape

Code : Tout sélectionner

Debug PeekI(*Ptr + SizeOf(Integer) )
On va résumer le code :

Code : Tout sélectionner

Define Marque.S = "Poulain"
Define AnneeCreation.I = 1848

Define *Ptr = @Marque

Debug PeekS(*ptr)
Debug PeekI(*ptr + SizeOf(Integer) )
Si on rajoute la nature du produit, on tape

Code : Tout sélectionner

Define Marque.S = "Poulain"
Define AnneeCreation.I = 1848
Define Nature.S = "Chocolat"

Define *Ptr = @Marque

Debug PeekS(*ptr)
Debug PeekI(*ptr + SizeOf(Integer) )
Debug PeekS(*ptr + 2 * SizeOf(Integer) )
Ma première conclusion : c'est moche.

Maintenant, je cherche dans mes fichiers, et je trouve ceci

Code : Tout sélectionner

Define Marque.S = "Grimbergen"
Define AnneeCreation.I = 1128
Define Nature.S = "Bière"
Si je veux interchanger respectivement ces variables avec les trois précédentes, je tape

Code : Tout sélectionner

Define Marque1.S = "Poulain"
Define AnneeCreation1.I = 1848
Define Nature1.S = "Chocolat"

Define Marque2.S = "Grimbergen"
Define AnneeCreation2.I = 1128
Define Nature2.S = "Bière"

Define *Ptr1 = @Marque1
Define *Ptr2 = @Marque2

For I = 1 To 2
   Debug PeekI(*ptr1)
   Debug PeekS(*ptr1 + SizeOf(Integer) )
   Debug PeekS(*ptr1 + 2 * SizeOf(Integer) )
   Swap *ptr1, *ptr2
Next
Et ma seconde conclusion est que c'est très moche.

Si on ajoute les vraies questions de sécurité IMA, les insertions de nouvelles variables, les << ... + SizeOf(xxx) >>, les indices à la pelle, on aboutit à une troisième conclusion qui sous-entend que, même si chacun a ses goûts, tout le monde se devra de tirer la chasse.

Heureusement, il existe "Structure/EndStructure", cette directive du compilateur qui va tout remplacer à notre place :

Code : Tout sélectionner

Structure Prospect
   Marque.S
   AnneeCreation.I
   Produit.S
EndStructure

Define.Prospect Prospect1, Prospect2
With Prospect2
   \Marque = "Grimbergen"
   \AnneeCreation = 1128
   \Produit = "Bière"
EndWith
With Prospect1
   \Marque = "Poulain"
   \AnneeCreation = 1848
   \Produit = "Chocolat"
   For I = 1 To 2
       Debug \Marque
       Debug \AnneeCreation
       Debug \Produit
       Swap Prospect1, Prospect2
   Next
EndWith
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [TUTO] Les Structures

Message par falsam »

Compilateur 5.62 a écrit :[13 :50 :47] [COMPILER] Ligne 21: 'Swap' ne fonctionne qu'avec 2 elements du meme type (non structures).
A part ça je suis 8O de ces codes
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%
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: [TUTO] Les Structures

Message par Marc56 »

Question: Est ce qu'une structure ne doit contenir qu'un seul enregistrement (en cours) pendant le traitement d'une table sqlite ?
Ta question n'est pas claire :?

Une structure est simplement un type de variable, c'est à dire un lot de variables liées sous un seul nom.
Si on faisait le parallèle BDD: une structure = un enregistrement de BDD, donc plusieurs champs.
Pour passer de BDD à structure, il faut le faire enregistrement par enregistrement et champ par champ

SQLite est une base de données autonome, qu'elle soit utilisée sur disque ou en mémoire ne change rien.

La communication entre une structure et une base SQLite se fait par requête SQL

L'intégration de SQLite dans PB ne se fait qu'au niveau intégration des outils de connexion et du transactionnel

Il n'y a pas de partage de mémoire entre base de données et structure, même pour une base SQLite en mode ::memory::
Avatar de l’utilisateur
omega
Messages : 617
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: [TUTO] Les Structures

Message par omega »

Merci Marc56 pour ces précieuses informations. C'est ce genre d'explications que je souhaitais avoir depuis le début.
Bonne continuation
Win7 (x64) 64 bits Pb 5.72
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: [TUTO] Les Structures

Message par boby »

Marc56 a écrit :
Question: Est ce qu'une structure ne doit contenir qu'un seul enregistrement (en cours) pendant le traitement d'une table sqlite ?
Ta question n'est pas claire :? ...
Est-ce que tu répond à ce poste ???

Si oui, je veux bien que ce forum parte totalement en bordel, mais ce serait quand même pas mal de répondre au moins dans les bons postes :-/
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: [TUTO] Les Structures

Message par Ollivier »

Quelle lourdeur cette option pour signaler les abus, surtout quand on balance Falsam : ça bugue totalement.

Bon... Ouais effectivement ça ne swappe pas. Et alors? Le tout c'est aussi de voir l'aspect technique. Un peu comme ouvrir le capot d'une voiture : c'est crade, et ça fait du bruit, mais c'est utile pour certains.
Après, je n'y peux rien si Fred a mis des caches en plastique qui peuvent sentir une petite odeur de brûlé quand on teste l'accélérateur.

Je vais te faire une version qui va avoir moins de répartie quand tu appuies sur F5...
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: [TUTO] Les Structures

Message par Ollivier »

Voilà... C'est moche mais ça marche, et surtout ça explique le fonctionnement des structures. C'est dans Main() que le fonctionnement est grossièrement expliqué. New() et Get() n'expliquent rien, mais servent à ce que [stop le sarcasme à 2 balles merci -- Ar-S]

Code : Tout sélectionner

;***********************************************************************************************
Procedure New(*Ptr.String)
        Define *M.Integer
        If *Ptr >> 12
                Define A.S = PeekS(*Ptr)
                Define Size = StringByteLength(A + "A")
                *M = AllocateMemory(Size)
                CopyMemory(@A, *M, Size)
        Else
                *M = AllocateMemory(SizeOf(Integer) )
                PokeI(*M, *Ptr)
        EndIf
        ProcedureReturn *M
EndProcedure

Procedure.S Get(*Ptr)
        Define Result.S
        *A = PeekI(*Ptr)
        *B = PeekI(*A)
        If *B >> 12
                Result = PeekS(*A)
        Else
                Result = Str(PeekI(*A) )
        EndIf
        ProcedureReturn Result
EndProcedure





;- Exemple

Procedure Main()
        
        Define *Marque1 = New(@"Les suceuses de l'Ouest")
        Define *AnneeCreation1 = New(2006)
        Define *Produit1 = New(@"Prestation de service")
        
        Define *Marque2 = New(@"BN")
        Define *AnneeCreation2 = New(1896)
        Define *Produit2 = New(@"Biscuits")
        
        *Prospect1 = @*Marque1
        *Prospect2 = @*Marque2
        
        For I = 1 To 2
                
                Debug "Marque  : " + Get(*Prospect1)
                Debug "Année   : " + Get(*Prospect1 + SizeOf(Integer) )
                Debug "Produit : " + Get(*Prospect1 + 2 * SizeOf(Integer) )
                Debug " "
                
                Swap *Prospect1, *Prospect2
        Next
        
EndProcedure

Main()
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: [TUTO] Les Structures

Message par Marc56 »

boby a écrit :
Marc56 a écrit :
Question: Est ce qu'une structure ne doit contenir qu'un seul enregistrement (en cours) pendant le traitement d'une table sqlite ?
Ta question n'est pas claire :? ...
Est-ce que tu répond à ce poste ???
Oui, mais j'apporte la précision ici, car Omega parle de structure
boby a écrit : Si oui, je veux bien que ce forum parte totalement en bordel, mais ce serait quand même pas mal de répondre au moins dans les :?: bons postes :-/
:?: postes ? (franglais ?) il faut choisir: topic (sujet) ou post (article) :wink:
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: [TUTO] Les Structures

Message par boby »

Ollivier a écrit :Voilà... C'est moche mais ça marche, et surtout ça explique le fonctionnement des structures. C'est dans Main() que le fonctionnement est grossièrement expliqué. New() et Get() n'expliquent rien, mais servent à ce que sa sublimissime altesse Falsam jouisse d'un code qui, d'un intempestif message d'erreur, point ne l'exorbite.
Bouh bouh ! Vilain Falsam ! Bouh !
Tu devrais pourtant le savoir, le but premier d'un code n'est pas que ça fonctionne, c'est que ce soit beau à lire ! C'est quand même bien connus que l'utilisateur d'un programme se fiche totalement que celui-ci fonctionne du moment qu'au fond de lui, il sait que le code est beau ! Alors j’espère que tu as compris, tu ne fait pas F5 sur les codes qui sont posté, tu les regarde ! c'est tout ! (F1 tout juste toléré !)

Le principe d'un tuto n'est il pas de montrer comment quelque chose fonctionne ? Bah en en code, Si ça compile pas, ça ne fonctionne pas...
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [TUTO] Les Structures

Message par falsam »

Ollivier a écrit :Quelle lourdeur cette option pour signaler les abus, surtout quand on balance Falsam : ça bugue totalement.
je ne vois pas pourquoi signaler un bug dans ton code constitue une offense et justifie un signalement à la modération :twisted:
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
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: [TUTO] Les Structures

Message par Ar-S »

C'est pour cela que je n'ai pas donné suite. Et Ollivier a posté un code fonctionnel.
@boby
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [TUTO] Les Structures

Message par falsam »

Ar-S a écrit :Et Ollivier a posté un code fonctionnel.
heu non je ne crois pas ou alors c'est mon compilateur qui merdouille.

Le code d'ollivier

Code : Tout sélectionner

Structure Prospect
   Marque.S
   AnneeCreation.I
   Produit.S
EndStructure

Define.Prospect Prospect1, Prospect2
With Prospect2
   \Marque = "Grimbergen"
   \AnneeCreation = 1128
   \Produit = "Bière"
EndWith
With Prospect1
   \Marque = "Poulain"
   \AnneeCreation = 1848
   \Produit = "Chocolat"
   For I = 1 To 2
       Debug \Marque
       Debug \AnneeCreation
       Debug \Produit
       Swap Prospect1, Prospect2
   Next
EndWith
Compilateur a écrit :[10 :55 :07] [COMPILER] Ligne 21: 'Swap' ne fonctionne qu'avec 2 elements du meme type (non structures).
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%
Verrouillé