Allocation dynamique : tableau
Publié : sam. 15/janv./2005 18:59
Coucou tout le monde.
Pendant ma journée de repos, entre mes épreuves de partiels, je me suis amusé à faire de l'allocation dynamique (les tableaux).
Donc j'ai créer une structure "Tableau".
Ce tableau peut contenir des Octets, des réels, des objets et aussi ... des strings
On put donc redimensionner sa taille (agrandir ou rétressir).
Voici le détail des fonctions à utiliser :
* SizeOfArray(*tab.Tableau) ; renvoi la taille du tableau
* InitTab(size.b, nbr.w) ; renvoi le pointeur du tableau créé
* Redim(*tab.Tableau, nbr.w) ; redimensionne le tableau
* UnDim(*tab.Tableau) ; supprime le tableau (vide la mémoire utilisée)
Mettre un élément dans le tableau
* SetObject(*tab.Tableau, index.w, *obj) ; ajoute un objet dans le tableau
* SetByte(*tab.Tableau, index.w, b.b)
* SetWord(*tab.Tableau, index.w, w.w)
* SetFloat(*tab.Tableau, index.w, f.f)
* SetLong(*tab.Tableau, index.w, l.l)
* SetString(*tab.Tableau, index.w, s.s)
Récupérer un élément :
* GetObject(*tab.Tableau, index.w) ; récupère l'adresse de l'objet
* GetNewObject(*tab.Tableau, index.w) ; récupère l'adresse de la copie de l'objet prit du tableau
* GetByte(*tab.Tableau, index.w)
* ...
* GetString(*tab.Tableau, index.w)
Voici donc le code :
Pendant ma journée de repos, entre mes épreuves de partiels, je me suis amusé à faire de l'allocation dynamique (les tableaux).
Donc j'ai créer une structure "Tableau".
Ce tableau peut contenir des Octets, des réels, des objets et aussi ... des strings

On put donc redimensionner sa taille (agrandir ou rétressir).
Voici le détail des fonctions à utiliser :
* SizeOfArray(*tab.Tableau) ; renvoi la taille du tableau
* InitTab(size.b, nbr.w) ; renvoi le pointeur du tableau créé
* Redim(*tab.Tableau, nbr.w) ; redimensionne le tableau
* UnDim(*tab.Tableau) ; supprime le tableau (vide la mémoire utilisée)
Mettre un élément dans le tableau
* SetObject(*tab.Tableau, index.w, *obj) ; ajoute un objet dans le tableau
* SetByte(*tab.Tableau, index.w, b.b)
* SetWord(*tab.Tableau, index.w, w.w)
* SetFloat(*tab.Tableau, index.w, f.f)
* SetLong(*tab.Tableau, index.w, l.l)
* SetString(*tab.Tableau, index.w, s.s)
Récupérer un élément :
* GetObject(*tab.Tableau, index.w) ; récupère l'adresse de l'objet
* GetNewObject(*tab.Tableau, index.w) ; récupère l'adresse de la copie de l'objet prit du tableau
* GetByte(*tab.Tableau, index.w)
* ...
* GetString(*tab.Tableau, index.w)
Voici donc le code :
Code : Tout sélectionner
#aString = 0
#aByte = 1
#aWord = 2
#aLong = 4
#aFloat = 4
Structure Tableau
sizeElt.b
nbrElts.w
adr.l
strg.b
EndStructure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;- Renvoi la taille du tableau
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure.w SizeOfArray(*tab.Tableau)
; le tableau n'a pas été initialisé
If *tab = #Null
ProcedureReturn (#Null)
EndIf
ProcedureReturn (*tab\nbrElts)
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;- Verifie l indice et l'adresse du tableau
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure ControleIndice(*tab.Tableau, index.w)
; le tableau n'a pas été initialisé
If *tab = #Null
ProcedureReturn (-1)
EndIf
; indice en dehors des limites du tableau
If index < 0 Or index >= *tab\nbrElts
ProcedureReturn (-2)
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;- Alloue la memoire au tableau
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure InitTab(size.b, nbr.w)
; pour voir si c'est un tableau de chaine de caractère ou pas
If size = #aString
size = #aLong: strg.b = 1
Else
strg.b = 0
EndIf
*tab.Tableau = AllocateMemory(SizeOf(Tableau))
*b = AllocateMemory(size * nbr)
If *tab
*tab\adr = *b
*tab\sizeElt = size
*tab\nbrElts = nbr
*tab\strg = strg
; si c'est un tableau de string
If strg
For i = 0 To nbr-1
*a = AllocateMemory(1)
If *a
PokeL(*tab\adr + (i * #aLong), *a)
PokeS(*a, "")
EndIf
Next i
EndIf
ProcedureReturn (*tab)
Else
ProcedureReturn (#Null)
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;- Redimension du tableau
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure Redim(*tab.Tableau, nbr.w)
If *tab = #Null
ProcedureReturn (-1)
EndIf
; si c'est un tableau de string, on efface l'espace mémoire réservé aux strings
If *tab\strg
; on enleve les cases en trop
For i = nbr To *tab\nbrElts-1
ad.l = PeekL(*tab\adr + (i * #aLong))
If ad
FreeMemory(ad)
EndIf
Next i
; on rajoute les cases en moins
For i = *tab\nbrElts To nbr-1
*a = AllocateMemory(1)
If *a
PokeL(*tab\adr + (i * #aLong), *a)
PokeS(*a, "")
EndIf
Next i
EndIf
*tab\adr = ReAllocateMemory(*tab\adr, *tab\sizeElt * nbr)
*tab\nbrElts = nbr
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;- Suppression du tableau
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure UnDim(*tab.Tableau)
If *tab = #Null
ProcedureReturn
EndIf
; si c'est un tableau de string, on efface l'espace mémoire réservé aux strings
If *tab\strg
For i = 0 To *tab\nbrElts
ad.l = PeekL(*tab\adr + (i * #aLong))
If ad
FreeMemory(ad)
EndIf
Next i
EndIf
FreeMemory(*tab\adr)
*tab\adr = #Null
*tab\nbrElts = 0
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;- On Ajoute un Object au tableau
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure SetObject(*tab.Tableau, index.w, *obj)
If ControleIndice(*tab.Tableau, index.w) < 0
ProcedureReturn(-1)
EndIf
; obj ne pointe sur rien
If @*obj = #Null
ProcedureReturn (-3)
EndIf
CopyMemory(@*obj, *tab\adr + (*tab\sizeElt * index), *tab\sizeElt)
EndProcedure
Procedure SetByte(*tab.Tableau, index.w, b.b)
If ControleIndice(*tab.Tableau, index.w) < 0
ProcedureReturn(-1)
ElseIf *tab\sizeElt <> #aByte
ProcedureReturn(-1)
Else
PokeB(*tab\adr + (#aByte * index), b)
EndIf
EndProcedure
Procedure SetWord(*tab.Tableau, index.w, w.w)
If ControleIndice(*tab.Tableau, index.w) < 0
ProcedureReturn(-1)
ElseIf *tab\sizeElt <> #aWord
ProcedureReturn(-1)
Else
PokeW(*tab\adr + (#aWord * index), w)
EndIf
EndProcedure
Procedure SetFloat(*tab.Tableau, index.w, f.f)
If ControleIndice(*tab.Tableau, index.w) < 0
ProcedureReturn(-1)
ElseIf *tab\sizeElt <> #aFloat Or *tab\strg
ProcedureReturn(-1)
Else
PokeF(*tab\adr + (#aFloat * index), f)
EndIf
EndProcedure
Procedure SetLong(*tab.Tableau, index.w, l.l)
If ControleIndice(*tab.Tableau, index.w) < 0
ProcedureReturn(-1)
ElseIf *tab\sizeElt <> #aLong Or *tab\strg
ProcedureReturn(-1)
Else
PokeL(*tab\adr + (#aLong * index), l)
EndIf
EndProcedure
Procedure SetString(*tab.Tableau, index.w, s.s)
If ControleIndice(*tab.Tableau, index.w) < 0
ProcedureReturn(-1)
ElseIf *tab\sizeElt <> #aLong
ProcedureReturn(-1)
Else
If PeekL(*tab\adr + (#aLong * index))
; si le block existe déja, on le redmensionne
*a = ReAllocateMemory(PeekL(*tab\adr + (#aLong * index)), Len(s))
Else
; sinon on le crée
*a = AllocateMemory(Len(s))
EndIf
If *a = #Null
ProcedureReturn(-1)
Else
PokeS(*a, s)
PokeL(*tab\adr + (#aLong * index), *a)
EndIf
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;- On recupere l adresse de la case memoire du tableau
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Procedure GetObject(*tab.Tableau, index.w)
If ControleIndice(*tab.Tableau, index.w) < 0
ProcedureReturn(#Null)
EndIf
If index < 0 Or index >= *tab\nbrElts
ProcedureReturn(#Null)
EndIf
ProcedureReturn( *tab\adr + (*tab\sizeElt * index) )
EndProcedure
Procedure GetNewObject(*tab.Tableau, index.w)
*a = GetObject(*tab.Tableau, index)
*b = AllocateMemory(*tab\sizeElt)
If *b
CopyMemory(*a, *b, *tab\sizeElt)
ProcedureReturn( *b )
EndIf
EndProcedure
Procedure GetByte(*tab.Tableau, index.w)
*a = GetObject(*tab.Tableau, index)
If *tab\sizeElt <> #aByte
ProcedureReturn(#Null)
ElseIf *a = #Null
ProcedureReturn(#Null)
Else
ProcedureReturn(PeekB(*a))
EndIf
EndProcedure
Procedure GetWord(*tab.Tableau, index.w)
*a = GetObject(*tab.Tableau, index)
If *tab\sizeElt <> #aWord
ProcedureReturn(#Null)
ElseIf *a = #Null
ProcedureReturn(#Null)
Else
ProcedureReturn(PeekW(*a))
EndIf
EndProcedure
Procedure GetFloat(*tab.Tableau, index.w)
*a = GetObject(*tab.Tableau, index)
If *tab\sizeElt <> #aFloat Or *tab\strg
ProcedureReturn(#Null)
ElseIf *a = #Null
ProcedureReturn(#Null)
Else
ProcedureReturn(PeekF(*a))
EndIf
EndProcedure
Procedure GetLong(*tab.Tableau, index.w)
*a = GetObject(*tab.Tableau, index)
If *tab\sizeElt <> #aLong Or *tab\strg
ProcedureReturn(#Null)
ElseIf *a = #Null
ProcedureReturn(#Null)
Else
ProcedureReturn(PeekL(*a))
EndIf
EndProcedure
Procedure.s GetString(*tab.Tableau, index.w)
*a = GetObject(*tab.Tableau, index)
If *tab\sizeElt <> #aLong Or *tab\strg=0
ProcedureReturn("")
ElseIf *a = #Null
ProcedureReturn("")
Else
ProcedureReturn(PeekS(PeekL(*a)))
EndIf
EndProcedure
;- MAIN
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; - - - - - - - - - JEUX D'ESSAI - - - - - - - - -
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tailleB.b = #aByte ; taille en octets de la structure contenue dans le tableau
elts.w = 100 ; nombrede cases du tableau
; déclaration des deux tableaux dynamiques
*tabByte.Tableau = InitTab(tailleB, elts)
*tabString.Tableau = InitTab(#aString, 10)
; /\/\/\/\/\/\/\/\ Avec des nombres /\/\/\/\/\/\/\/\/\/\
; \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Debug " - - - - TabByte - - - - "
Debug "Taille initiale : " + Str(SizeOfArray(*tabByte))
; on entre les valeurs
For i.w = 0 To 5
SetByte(*tabByte, i, i+5)
SetWord(*tabByte, i, 3)
Next i
; on affiche le tableau (ses 6 1ers elts)
For i = 0 To 5
Debug "Elts(" + Str(i) + ") : " + Str(GetByte(*tabByte, i))
Next i
Debug "Redimension du tableau"
Redim(*tabByte, 6)
Debug "La nouvelle taille est de : " + Str(SizeOfArray(*tabByte))
For i = 0 To SizeOfArray(*tabByte)-1
Debug "Elts(" + Str(i) + ") : " + Str(GetByte(*tabByte, i))
Next i
Debug "Libération de la mémoire"
UnDim(*tabByte)
Debug "Taille : " + Str(SizeOfArray(*tabByte))
; /\/\/\/\/\/\/\/\ Avec des strings /\/\/\/\/\/\/\/\/\/\
; \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Debug " "
Debug " - - - - TabString - - - - "
SetString(*tabString, 0, "Ca")
SetString(*tabString, 1, "va")
SetString(*tabString, 2, "tout")
SetString(*tabString, 3, "le")
SetString(*tabString, 4, "monde")
SetString(*tabString, 5, "???")
a$ = ""
For i = 0 To SizeOfArray(*tabString)-1
a$ + GetString(*tabString, i) + " "
Next i
Debug a$
Debug "Redimension du tableau"
Redim(*tabString, 5)
a$ = ""
For i = 0 To 10
a$ + GetString(*tabString, i) + " "
Next i
Debug a$
Debug "Redimension du tableau"
Redim(*tabString, 6)
SetString(*tabString, 5, "!!!")
a$ = ""
For i = 0 To SizeOfArray(*tabString)-1
a$ + GetString(*tabString, i) + " "
Next i
Debug a$
Debug "Libération de la mémoire"
UnDim(*tabString)