Procédure avec map en paramètre et sélection d...

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Procédure avec map en paramètre et sélection d...

Message par microdevweb »

Bonjour à tous,

Je ne penses pas que titre soit des plus explicite, mais voici de quoi il s'agis exactement
Passé une map en paramètre de procédure et n'agir que sur certains éléments.

Contrainte (avec un long) 32 éléments dans la map seulement.

Voila si cela peut vous servir.

Première exemple avec des chaînes de caractères.

Code : Tout sélectionner

; exemple avec un map de maximum 32 éléments
; et des flags de sélection
EnumerationBinary 
  #P_1
  #P_2
  #P_3
  #P_4
  #P_5
  ; etc ... 32 possibilités au total
EndEnumeration

Global NewMap myFruts.s() ; map de fruits
; j'ajoute quelques fruits pour l'exercice
AddMapElement(myFruts(),Str(#P_1))
myFruts()= "Pomme"
AddMapElement(myFruts(),Str(#P_2))
myFruts()= "Bannane"
AddMapElement(myFruts(),Str(#P_3))
myFruts()= "Orange"
AddMapElement(myFruts(),Str(#P_4))
myFruts()= "Poire"
AddMapElement(myFruts(),Str(#P_5))
myFruts()= "Fraise"

Procedure test(Map mp.s(),flags)
  Protected i,index= #P_1 ; on commence par le premier élement
  ; parcours des 32 possibités
  For i = 0 To 31
    If flags & index
      If FindMapElement(mp(),Str(index))
        Debug mp()
      EndIf
    EndIf
    index = index<<1 ; décalkages des bit à gauche
  Next
EndProcedure
test(myFruts(),#P_1|#P_3|#P_5)
Autre exemple avec des entiers longs que l'on va modifier

Code : Tout sélectionner

; exemple avec un map de maximum 32 éléments
; et des flags de sélection
EnumerationBinary 
  #P_1
  #P_2
  #P_3
  #P_4
  #P_5
  ; etc ... 32 possibilités au total
EndEnumeration

Global NewMap *myNumber() ; map d'adresse de nombre
Global.l n1=2,n2=4,n3=8,n4=16,n5=32
; j'ajoute quelques nombres pour l'exercice
AddMapElement(*myNumber(),Str(#P_1))
*myNumber()= @n1
AddMapElement(*myNumber(),Str(#P_2))
*myNumber()= @n2
AddMapElement(*myNumber(),Str(#P_3))
*myNumber()= @n3
AddMapElement(*myNumber(),Str(#P_4))
*myNumber()= @n4
AddMapElement(*myNumber(),Str(#P_5))
*myNumber()= @n5

Procedure test(Map *mp(),flags)
  Protected i,index= #P_1 ; on commence par le premier élement
  ; parcours des 32 possibités
  For i = 0 To 31
    If flags & index
      If FindMapElement(*mp(),Str(index))
        ; ici on multiplie par deux (pour l'exemple)
        PokeL(*mp(),PeekL(*mp()) * 2)
      EndIf
    EndIf
    index = index<<1 ; décalkages des bit à gauche
  Next
EndProcedure
test(*myNumber(),#P_1|#P_3|#P_5)

Debug n1
Debug n2
Debug n3
Debug n4
Debug n5
Autre exemple avec des appels de procédures

Code : Tout sélectionner

; exemple avec un map de maximum 32 éléments
; et des flags de sélection
EnumerationBinary 
  #P_1
  #P_2
  #P_3
  #P_4
  #P_5
  ; etc ... 32 possibilités au total
EndEnumeration

Prototype p_proc(*value) ; un prototype pour l'appel de la procédure

Global NewMap *myProc() ; map d'adresses de procédure

Procedure proc_1(*value)
  PokeL(*value,PeekL(*value) * 2)
  Debug "call procedure 1 value * 2  = "+Str(PeekL(*value))
EndProcedure

Procedure proc_2(*value)
  PokeL(*value,PeekL(*value) / 2)
  Debug "call procedure 2 value / 2  = "+Str(PeekL(*value))
EndProcedure

Procedure proc_3(*value)
  PokeL(*value,PeekL(*value) + 10)
  Debug "call procedure 3 value + 10 =  "+Str(PeekL(*value))
EndProcedure

Procedure proc_4(*value)
  PokeL(*value,PeekL(*value) - 3)
  Debug "call procedure 4 value - 3  = "+Str(PeekL(*value))
EndProcedure

Procedure proc_5(*value)
  PokeL(*value,PeekL(*value) + 8)
  Debug "call procedure 5 value + 8  = "+Str(PeekL(*value))
EndProcedure

; j'ajoute quelques procédures pour l'exercice
AddMapElement(*myProc(),Str(#P_1))
*myProc()= @proc_1()
AddMapElement(*myProc(),Str(#P_2))
*myProc()= @proc_2()
AddMapElement(*myProc(),Str(#P_3))
*myProc()= @proc_2()
AddMapElement(*myProc(),Str(#P_4))
*myProc()= @proc_4()
AddMapElement(*myProc(),Str(#P_5))
*myProc()= @proc_5()

Procedure test(Map *mp(),*nombre,flags)
  Protected i,index= #P_1 ; on commence par le premier élement
  Protected myProcedure.p_proc
  ; parcours des 32 possibités
  For i = 0 To 31
    If flags & index
      If FindMapElement(*mp(),Str(index))
        myProcedure = *mp()
        myProcedure(*nombre)
      EndIf
    EndIf
    index = index<<1 ; décalkages des bit à gauche
  Next
EndProcedure
Global value.l = 20
test(*myProc(),@value,#P_1|#P_3|#P_5)

Debug value
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Procédure avec map en paramètre et sélection d...

Message par Micoute »

Grand merci pour le partage.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: Procédure avec map en paramètre et sélection d...

Message par G-Rom »

@Micoute, un exemple plus simple à comprendre : :mrgreen:

Code : Tout sélectionner

EnumerationBinary
  #JE_SUIS_UN_FLAN
  #JE_SUIS_SUSCEPTIBLE
  #JE_SUIS_BON
EndEnumeration


Micoute.l = #JE_SUIS_UN_FLAN | #JE_SUIS_SUSCEPTIBLE

str$ = "Micoute est "

If Micoute & #JE_SUIS_UN_FLAN
  str$ + "un flan "
EndIf 

If Micoute & #JE_SUIS_SUSCEPTIBLE
  str$ + "susceptible "  
EndIf

If Micoute & #JE_SUIS_BON
  str$ + "bon"  
EndIf


Debug str$
Shadow
Messages : 1373
Inscription : mer. 04/nov./2015 17:39

Re: Procédure avec map en paramètre et sélection d...

Message par Shadow »

@G-Rom je suis assez septique, est-ce de l'humour décalé ?
Ou tu n'aime pas Micoute ?, je cherche à comprendre juste.

Surement de l'humour mais je trouve ça un peu décalé comme truc...
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: Procédure avec map en paramètre et sélection d...

Message par G-Rom »

j'ai rien contre le père micoute , c'est de l'humour, z'êtes grave...
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Procédure avec map en paramètre et sélection d...

Message par Micoute »

Bonjour G-Rom, je ne vois aucune offense à ton exemple que j'ai capté 5/5 et pour la réponse que j'avais faite ne visait personne, ni en particulier, ni en général et je demande qu'on veuille bien me pardonner si ça a été mal compris.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Procédure avec map en paramètre et sélection d...

Message par microdevweb »

Petit complément sur les masques logiques :

La plus petite variable manipulable est d'un Byte, sur nos PC un byte équivaut à un octet soit 8 bits.

Les masques logiques permettent de modifier ou de lire un seul ou plusieurs bit à la fois. C'est fortement utilisé pour les microcontrôleurs ou la mémoire est rare, beaucoup moins sur les microprocesseur (pc) ou maintenant la mémoire est en quantité, avec Pb (qui est un des rares à utiliser se système dans ses fonctions) on à l'habitude de séparer nos flag par des | (ou logique)

voici la table de vérité du ou logique

Code : Tout sélectionner

 0 0  ; retourne faux
 0 1  ; retourne vrai
 1 0  ; retourne vrai
 1 1  ; retourne vrai
Le but de l'opération est de ne modifier qu'un seul ou plusieurs bit d'une variable

Exemple pour un seul bit:

Code : Tout sélectionner

V1.b = 1 ; soit en binaire 00000001
Debug RSet(Bin(V1),8,"0")
; maintenant je veux passer le 4 bit à 1 ; ATTENTION : on part du bit de point faible à l'extrême droite
; je crée un masque
V2.b = 8 ; soit en binaire 00001000
Debug RSet(Bin(V2),8,"0")
; en je réalise mon opération binaire
res.b = V1 | V2
; si je fais un debug j'aurais
Debug res ; 9 soit en binaire 00001001
Debug RSet(Bin(res),8,"0")
Maintenant comment lire un seul ou plusieurs bit ? Avec un autre opérateur le & (ET logique)

Voici sa table de vérité

Code : Tout sélectionner

0 0  ; retourne faux
1 0  ; retourne faux
0 1  ; retourne faux
1 1  ; retourne vrai
Je vais reprendre mon exemple au dessus et lire un seul bit

Code : Tout sélectionner

V1.b = 1 ; soit en binaire 00000001
Debug RSet(Bin(V1),8,"0")
; maintenant je veux passer le 4 bit à 1 ; ATTENTION : on part du bit de point faible à l'extrême droite
; je crée un masque
V2.b = 8 ; soit en binaire 00001000
Debug RSet(Bin(V2),8,"0")
; en je réalise mon opération binaire
res.b = V1 | V2
; si je fais un debug j'aurais
Debug res ; 9 soit en binaire 00001001
Debug RSet(Bin(res),8,"0")
; on va lire un seul bit exemple le quatrième bit
Debug "LECTURE D'UN SEUL BIT"
; -> je crée un masque
mask.b = %00001000 ; une autre méthode ou on écrit directemen en binaire
Debug RSet(Bin(V1 & mask),8,"0") ; retourne 00000000
Debug RSet(Bin(V2 & mask),8,"0") ; retourne 00001000
Debug RSet(Bin(res & mask),8,"0") ; retourne 00001000
Il existent bien d'autres opérateurs logiques (Xor,Nand etc...), il faut savoir qu'un microprocesseur ou microcontrôleur n'est composé à la base que de portes logiques qui combinées savamment nous offre toute cette puissance et encore merci à Monsieur Boole.

Exemple pour un simple additionneur
https://fr.wikipedia.org/wiki/Additionneur
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Répondre