[TUTO] Les Pointeurs
Les pointeurs sont justes les éléments les plus importants en prog, on ne peut pas s'en passer, et surtout on n'est souvent obligé de les utiliser pour exploiter les fenêtres Windows et gadgets avec des CallBack. Ils apportent une grande souplesse de programmation car avec un pointeur on peut passer un nombre illimité d'arguments et jouer avec toutes variables en mémoire.
un petit example d'utilisation de pointeurs pour wolfjeremy:
pour example, je choisis de montrer comment une procédure
peut renvoyer plusieurs valeurs d'un coup.
Un seul ProcedureReturn donc, pour plusieurs valeurs retournées.
un pointeur n'a besoin d'avoir une étoile pour se comporter
comme un pointeur. mais son utilisation va en être limitée !
regarde ici comment on aurait fait sans connaitre les structures :
1/
allocation d'un bloc de mémoire de la taille de tous les arguments
taille = 1 octet (.b) + 4 octets (.l) + 4 octets (.s) = 9 octets
args.l est donc le pointeur sur un bloc mémoire
2/
on 'poke' la mémoire avec nos valeurs
3/
et on la 'peek'
4/
on libère la mémoire allouée
bon, çà c'était avant...
en rajoutant maintenant l'étoile devant notre pointeur on peut lui coller une structure derrière (hum).
args devient *args.ARGUMENTS
ainsi PokeL(args+1, 123) devient *args\lValeur = 123
avec les structures c'est plus de code mais c'est surtout plus lisible, plus souple.
pour example, je choisis de montrer comment une procédure
peut renvoyer plusieurs valeurs d'un coup.
Un seul ProcedureReturn donc, pour plusieurs valeurs retournées.
un pointeur n'a besoin d'avoir une étoile pour se comporter
comme un pointeur. mais son utilisation va en être limitée !
regarde ici comment on aurait fait sans connaitre les structures :
1/
allocation d'un bloc de mémoire de la taille de tous les arguments
taille = 1 octet (.b) + 4 octets (.l) + 4 octets (.s) = 9 octets
args.l est donc le pointeur sur un bloc mémoire
2/
on 'poke' la mémoire avec nos valeurs
3/
et on la 'peek'
4/
on libère la mémoire allouée
Code : Tout sélectionner
Procedure.l MaProcedure_Alloc()
Protected args.l = AllocateMemory(1+4+4)
If args
PokeB(args+0, #True)
PokeL(args+1, 123)
PokeS(args+5, "456")
EndIf
ProcedureReturn args
EndProcedure
Procedure.l MaProcedure_Free(args)
If args
FreeMemory(args)
EndIf
EndProcedure
a.l = MaProcedure_Alloc()
If a
Debug PeekB(a+0)
Debug PeekL(a+1)
Debug PeekS(a+5)
MaProcedure_Free(a)
EndIf
en rajoutant maintenant l'étoile devant notre pointeur on peut lui coller une structure derrière (hum).
args devient *args.ARGUMENTS
ainsi PokeL(args+1, 123) devient *args\lValeur = 123
avec les structures c'est plus de code mais c'est surtout plus lisible, plus souple.
Code : Tout sélectionner
Structure ARGUMENTS
bValeur.b
lValeur.l
sValeur.s
EndStructure
Procedure.l MaProcedure_Alloc()
Protected *args.ARGUMENTS = AllocateMemory(SizeOf(ARGUMENTS))
If *args
*args\bValeur = #True
*args\lValeur = 123
*args\sValeur = "456"
EndIf
ProcedureReturn *args
EndProcedure
Procedure.l MaProcedure_Free(*args.ARGUMENTS)
If *args
FreeMemory(*args)
EndIf
EndProcedure
*a.ARGUMENTS = MaProcedure_Alloc()
If *a
Debug *a\bValeur
Debug *a\lValeur
Debug *a\sValeur
MaProcedure_Free(*a)
EndIf
Dernière modification par Flype le mar. 18/juil./2006 13:32, modifié 1 fois.
-
- Messages : 1202
- Inscription : sam. 31/déc./2005 23:52
Petite question qui me traverse l'esprit en voyant ton exemple Flype
ok ça libère les 9 octets alloués avec AllocateMemory, mais un champ était un pointeur vers une chaîne, comment on libère l'espace occupé par une chaîne ?
Faudrait que je fasse des recherches, il me semble avoir déjà vu des débats à ce sujet ici ou sur le forum anglais.
Code : Tout sélectionner
FreeMemory(args)
ok ça libère les 9 octets alloués avec AllocateMemory, mais un champ était un pointeur vers une chaîne, comment on libère l'espace occupé par une chaîne ?
Faudrait que je fasse des recherches, il me semble avoir déjà vu des débats à ce sujet ici ou sur le forum anglais.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
-
- Messages : 1202
- Inscription : sam. 31/déc./2005 23:52
c'est normal qu'ils sont éparpiller un peu partout.
comme le dit si bien nico :
comme le dit si bien nico :
nico a écrit :Les pointeurs sont justes les éléments les plus importants en prog, on ne peut pas s'en passer, et surtout on n'est souvent obligé de les utiliser pour exploiter les fenêtres Windows et gadgets avec des CallBack. Ils apportent une grande souplesse de programmation car avec un pointeur on peut passer un nombre illimité d'arguments et jouer avec toutes variables en mémoire.
-----------comtois a écrit :Petite question qui me traverse l'esprit en voyant ton exemple Flype
Code : Tout sélectionner
FreeMemory(args)
ok ça libère les 9 octets alloués avec AllocateMemory, mais un champ était un pointeur vers une chaîne, comment on libère l'espace occupé par une chaîne ?
Faudrait que je fasse des recherches, il me semble avoir déjà vu des débats à ce sujet ici ou sur le forum anglais.
à mon avis - pas de problème ici.
Si on fait PokeL(args+5, @"456")
"456" est une chaine allouée en dur dans le programme / dans l'exécutable. pas besoin de la libérer.
Imagine, çà reviendrait à chercher à faire FreeMemory(@"456")
ce que je conseille à personne.
-----------
Si on fait :
maChaine.s = "test"
PokeL(args+5, @maChaine)
FreeMemory(args)
La chaine est toujours allouée meme après le FreeMemory puisque la variable maChaine n'est pas détruite (heureusement).
La chaine sera libérée par purebasic en sortant de la procédure (EndProcedure) ou du programme (End).
Dernière modification par Flype le mar. 18/juil./2006 13:49, modifié 1 fois.
Pas bien Flype
Il y a quand même une grossière erreur dans mon premier example.
Voilà la correction, je vous laisse deviner où et pourquoi

Il y a quand même une grossière erreur dans mon premier example.
Voilà la correction, je vous laisse deviner où et pourquoi

Code : Tout sélectionner
Procedure.l MaProcedure_Alloc()
Protected args.l = AllocateMemory(1+4+4)
If args
PokeB(args+0, #True)
PokeL(args+1, 123)
PokeL(args+5, @"456")
EndIf
ProcedureReturn args
EndProcedure
Procedure.l MaProcedure_Free(args)
If args
FreeMemory(args)
EndIf
EndProcedure
a.l = MaProcedure_Alloc()
If a
Debug PeekB(a+0)
Debug PeekL(a+1)
Debug PeekS(PeekL(a+5))
MaProcedure_Free(a)
EndIf
merci Flype, ça me semble logique en effet ; il me passe des trucs bizarres par la tête des fois 

http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.