[TUTO] Les Pointeurs

Informations pour bien débuter en PureBasic
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

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.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

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

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
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.

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.
Image
wolfjeremy
Messages : 1202
Inscription : sam. 31/déc./2005 23:52

Message par wolfjeremy »

Ouai merci pour l'exemple, il est très clair ! :P

Flype tu m'aura déjà aider beaucoup quand même :D

Encore merci.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

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.
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.
wolfjeremy
Messages : 1202
Inscription : sam. 31/déc./2005 23:52

Message par wolfjeremy »

J'ai aussi une question.

Où trouve où toute les fonctions qui sont en rapport avec les pointeurs dans la doc de PB ? Ces éparpiller un peu partout dans chaque catégorie ? ( 8O )
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

c'est normal qu'ils sont éparpiller un peu partout.

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.
Image
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

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.
Image
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

Pas bien Flype :evil:

Il y a quand même une grossière erreur dans mon premier example.

Voilà la correction, je vous laisse deviner où et pourquoi :wink:

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
Image
wolfjeremy
Messages : 1202
Inscription : sam. 31/déc./2005 23:52

Message par wolfjeremy »

Le PokeS lol
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

oui mais pourquoi ?
c'est intéressant justement pour comprendre.

Quelle différence entre ces 2 là ?
PokeS(args+5, "456")
PokeL(args+5, @"456")

1 piste : l'écrasement mémoire...
Image
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

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.
Répondre