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