Structures
DescriptionStructure <nom> [Extends <name>] [Align <expression numérique constante>] ... EndStructure
Structure est utile pour définir un type utilisateur et accéder à des zones mémoires du système d'exploitation par exemple. Les structures peuvent être utilisées pour rendre l'accès à des grands fichiers plus facilement. Cela peut être plus efficace dans la mesure où vous pouvez regrouper dans un même objet des informations communes. On accède aux structures avec le caractère \ . Les structures peuvent s'imbriquer. Les tableaux statiques sont acceptés dans une structure.
Les champs de structure doivent avoir un type explicite parmi tous les Types basiques gérés par PureBasic, à savoir Byte (.b), Ascii (.a), Caractère (.c) , Word (.w) , Unicode (.u), Long (.l), Integer (.i), Float (.f ), Quad (.q), Double (.d)), String (.s) et String Fixe (.s{Longueur}).
Les objets dynamiques tel que les tableaux, listes et maps sont aussi supportés dans les structures et sont automatiquement initialisés quand l'objet utilisant la structure est déclaré. Pour définir un tel champ, utiliser les mot-clés suivant: Array, List et Map.
Généralement, les structures sont utilisées en association avec une variable, un tableau, une liste, ou une map. Toutefois, les utilisateurs avancés pourront allouer une structure en mémoire avec AllocateStructure() et la libérer avec FreeStructure(). Il est aussi possible d'initialiser une structure en mémoire avec InitializeStructure(), de la copier avec CopyStructure(), de la vider avec ClearStructure() et de la reinitialiser avec ResetStructure()
Il est possible de copier une structure complète en utilisant l'opérateur égal ("=") entre deux éléments de même type.
Le paramètre optionnel Extends permet d'étendre une structure existante avec de nouveaux champs. Tous les champs se trouvant dans la structure étendue se retrouveront en tête de la nouvelle structure. C'est très utile pour faire un héritage simple de structures.
Pour les utilisateurs avancés seulement. Le paramètre Align permet d'ajuster l'alignement entre chaque champ de la structure. L'alignement par défaut est de 1, ce qui signifie pas d'alignement. Par exemple, si l'alignement est fixé à 4, chaque champs sera aligné sur 4 octets. Cela peut aider à améliorer les performances lors de l'accès aux champs de la structure, mais cela peut utiliser plus de mémoire, car un certain espace entre chaque champs sera perdu. La valeur spéciale #PB_Structure_AlignC peut être utilisée pour aligner la structure telle qu'elle se ferait en langage C, utile lors de l'importation structures C utilisées avec des fonctions API.
- SizeOf permet de connaître la taille en octets d'une structure. - OffsetOf donne la position (offset) en mémoire d'un champ d'une structure.
Note : Un Tableau statique dans une structure ne se comporte pas de la même façon qu'un tableau défini avec la commande Dim. Ceci pour être conforme au format de structures en C/C++ (pour permettre un portage direct des structures de l'API). Ce qui signifie que a[2] assignera un tableau de 0 à 1 (deux éléments) alors que Dim a(2) assignera un tableau de 0 à 2 (trois éléments). Et Les fonctions de la bibliothèque Array ne peuvent pas être utilisées avec ce type de tableaux.
Lorsque vous utilisez des pointeurs dans les structures, L'étoile '*' doit être omise lors de l'utilisation du champ, une fois de plus pour faciliter le portage de code API. Cela peut être considéré comme une bizarrerie (et pour être honnête, ça l'est) mais c'est comme ça depuis le début de PureBasic et beaucoup, beaucoup de sources sont écrites de cette façon et cela restera inchangé.
Quand beaucoup de champs doivent être remplis en une fois, il est conseillé d'utiliser With : EndWith pour réduire la quantité de code à saisir et améliorer sa lisibilité.
Exemple
Structure Personne
Nom.s
Prenom.s
Age.w
EndStructure
Dim MesAmis.Personne(100)
; Ici la position '0' du tableau MesAmis()
; contiendra une personne et ses informations personnelles
MesAmis(0)\Nom = "Durand"
MesAmis(0)\Prenom = "Michel"
MesAmis(0)\Age = 32
Exemple: Structure plus complexe (Tableau statique imbriqué)
Structure Fenetre
*FenetreSuivante.Fenetre ; Pointe vers un autre objet fenêtre
x.w
y.w
Nom.s[10] ; 10 noms possibles
EndStructure
Exemple: Structure étendue
Structure MonPoint
x.l
y.l
EndStructure
Structure MonPointEnCouleur Extends MonPoint
couleur.l
EndStructure
ColoredPoint.MonPointEnCouleur\x = 10
ColoredPoint.MonPointEnCouleur\y = 20
ColoredPoint.MonPointEnCouleur\couleur = RGB(255, 0, 0)
Exemple: Copie de structure
Structure MonPoint
x.l
y.l
EndStructure
PointGauche.MonPoint\x = 10
PointGauche\y = 20
PointDroit.MonPoint = PointGauche
Debug PointDroit\x
Debug PointDroit\y
Exemple: Objet Dynamique
Structure Personne
Nom$
Age.l
List Amis$()
EndStructure
Jean.Personne
Jean\Nom$ = "Jean"
Jean\Age = 23
; Ajoutons des amis à Jean
;
AddElement(Jean\Amis$())
Jean\Amis$() = "Jim"
AddElement(Jean\Amis$())
Jean\Amis$() = "Monica"
ForEach Jean\Amis$()
Debug Jean\Amis$()
Next
Exemple: Tableau statique, dynamique et Structure en argument de procédure
Structure Truc
a.l
b.l[2] ; Tableau statique (Standard C) avec 2 valeurs b[0] et b[1], non redimensionnable
Array c.l(3,3) ; Tableau dynamique avec 16 valeurs de c(0,0) à c(3,3), redimensionnable avec ReDim()
EndStructure
MaVar.Truc
Procedure MaProcedure(*blabla.Truc)
*blabla\a = 5
*blabla\b[0] = 1
*blabla\b[1] = 2
*blabla\c(3,3) = 33
EndProcedure
MaProcedure(@MaVar)
Debug MaVar\a
Debug MaVar\b[0]
Debug MaVar\b[1]
Debug MaVar\c(3,3)
;Debug MaVar\c(0,10) ; Erreur index hors limite
ReDim MaVar\c(3,10) ; Attention, seule la dernière dimension peut être redimensionnée !
Debug MaVar\c(0,10)
Exemple: Structure de structure(s)
Structure pointF
x.f
y.f
EndStructure
Structure Champs
Champs1.q
Champs2.s{6}
Champs3.s
Array Tab.pointF(3)
EndStructure
Define MaVar.Champs
MaVar\Tab(3)\x = 34.67
Exemple: Alignement Mémoire
Structure Type Align 4
Byte.b
Word.w
Long.l
Float.f
EndStructure
Debug OffsetOf(Type\Byte) ; Affiche 0
Debug OffsetOf(Type\Word) ; Affiche 4
Debug OffsetOf(Type\Long) ; Affiche 8
Debug OffsetOf(Type\Float) ; Affiche 12
Exemple: Pointers
Structure Personne *Next.Personne ; Ici, le '*' est obligatoire pour déclarer un pointeur Nom$ Age.b EndStructure Timo.Personne\Nom$ = "Timo" Timo\Age = 25 Fred.Personne\Nom$ = "Fred" Fred\Age = 25 Timo\Next = @Fred ; Lorsque vous utilisez le pointeur, le '*' est omis Debug Timo\Next\Nom$ ; Affichera 'Fred'
DescriptionStructureUnion Champs.Type Champs.Type ... EndStructureUnion
StructureUnion est prévu pour les programmeurs avancés qui souhaitent économiser de la mémoire en partageant certains champs à l'intérieur d'une même structure. Il s'agit d'un équivalent du mot clef 'union' en C/C++.
Note: Chaque champ dans la déclaration StructureUnion peut être d'un type différent.
Note: Chaque champ dans la déclaration StructureUnion est placé à la même adresse mémoire.
Exemple
Structure Type
Nom$
StructureUnion
Long.l ; Chaque champ (Long, Float et Byte) est placé à la même adresse mémoire.
Float.f ;
String.b ;
EndStructureUnion
EndStructure
Exemple: Exemple RVB
Structure StrCouleur
Rouge.a
Vert.a
Bleu.a
Alpha.a
EndStructure
Structure StrCouleurU
StructureUnion
Composant.StrCouleur
Couleur.l
Octet.a[4]
EndStructureUnion
EndStructure
Define Couleur1.StrCouleurU
Couleur1\Couleur = RGBA($10, $20, $30, $FF)
Debug "hex = " + Hex(Couleur1\Couleur, #PB_Long) ;hex = FF302010 (processeurs little-endian)
Debug "r = " + Hex(Couleur1\Composant\Rouge) ;r = 10
Debug "v = " + Hex(Couleur1\Composant\Vert) ;v = 20
Debug "b = " + Hex(Couleur1\Composant\Bleu) ;b = 30
Debug "a = " + Hex(Couleur1\Composant\Alpha) ;a = FF
Debug "Octet0 = " + Hex(Couleur1\Octet[0]) ;Octet0 = 10
Debug "Octet1 = " + Hex(Couleur1\Octet[1]) ;Octet1 = 20
Debug "Octet2 = " + Hex(Couleur1\Octet[2]) ;Octet2 = 30
Debug "Octet3 = " + Hex(Couleur1\Octet[3]) ;Octet3 = FF
Exemple: Exemple gestion de dates
Structure StrDate ;jj.mm.aaa
jour.s{2}
separateur1.s{1}
mois.s{2}
separateur2.s{1}
an.s{4}
EndStructure
Structure StrDateU
StructureUnion
s.s{10}
d.StrDate
EndStructureUnion
EndStructure
;Un tableau
Dim MaDate.StrDateU(365)
MaDate(0)\s = "05.04.2028"
Debug MaDate(0)\d\jour ; 05
Debug MaDate(0)\d\mois ; 04
Debug MaDate(0)\d\an ; 2028
Debug MaDate(0)\s ; 05.04.2028
;Une variable
MaDate2.StrDateU\s = "15.11.2030"
Debug MaDate2\d\jour ; 15
Debug MaDate2\d\mois ; 11
Debug MaDate2\d\an ; 2030
Debug MaDate2\s ; 15.11.2030