Tutorial : exploitation des flags à l'aide des opérateurs binaire and or xor et imp

Contenu du snippet

Si ce système peux sembler couler de (code-)source pour un developpeur C/C++ ou ASM, il peux paraître plutôt complexe pour quelqu'un n'ayant aucune notion d'informatique de bas niveau.

Qu'est ce qu'une vriable sous forme de flags ???

Pour faire simple, je vais prendre l'exmple du Byte. Que représente-t-il en mémoire? C'est un entier codé sur 1 octet donc représenter par 8 bits(et pas 8 Bytes !!!) qui peuvent être positionner à 1 ou à 0. Donc si on compte en base 2, on peut arriver a 255 :

00000000 : 0
00000001 : 1
00000010 : 2
00000011 : 3
00000100 : 4
...
...
...
11111111 : 255

Mais on peut approcher cette octet sous un autre angle. Chaque octet pouvant être positionner à un 1 ou à 0, chaque octet peut lui même constituer un boolean. Par exemple, si on doit coder un format de police(pour reprendre l'exmple de mon modéliseur de feuille d'impression ;-)), on peut assigner le gras au 1er bit, Italique au 2ème et souligner au 3éme.

Donc,
Un texte en gras aura comme attribut : 00000001 : 1
Un texte en italique aura comme attribut : 00000010 : 2
Un texte en souligner aura comme attribut : 00000100 : 4

pour plus de faciliter, nous allons les déclarer en hexadecimale(Numerotation en base 16 : 0->F) au lieu de la déclarer en décimale (numérotation en base 10 0->9). Les différents attributs auront donc (sur 1 octets)
&h01
&h02
&h04
&h08
&h10
&h20
&h40
&h80

On reprend notre exemple, on déclare les constante suivante :

Const cBOLD = &h1
Const cITALIC = &h2
Const cUNDERLINE = &h4

On crée un nouvel objet avec l'attribut initial 00000000 soit &h0 et on va par exemple le mettre en gras. Pour celà on va utilisaer l'opérateur binaire Or. Un opérateur binaire effectue une opération bit à bit et prend 2 oppérande. Or retourne 1 si une des 2 operande est à 1. Cette opération est défini par une table:

| 0 1
--+------
0 | 0 1
1 | 1 1

Donc il suffit de d'appliquer un or avec le bit de gras à 1 et le reste de la variable à 0 :

Dim Obj as Byte
Obj = 0
Obj = Obj Or cBOLD

on a donc l'operation suivante :

00000000
00000001
Or -----------
00000001

On va également le souligner pour le fun :

Obj = Obj Or cITALIC

Donc Obj vaut maintenant 00000011

Si on veut effacer cet attribut, on utilise And qui retourne 1 uniquement si les 2 bit sont positionné à 1 :

| 0 1
--+------
0 | 0 0
1 | 0 1

Mais pour ça, il faut que l'attribut Gras soit à 0 et le reste à 1. Il faut donc inverser chaque bit de la constante (0->1 et 1-> 0). Il existe pour celà l'opérateur Not qui lui ne prend qu'un seul operande.

0 -> 1
1 -> 0

On obtient donc ceci :

Obj = Obj And Not cBOLD

ce qui fait :

00000001
Not -----------
11111110
00000011
And -----------
00000010

Si on veut inverser le gras sans savoir si il est postionner ou pas, on utilise Xor :

| 0 1
--+------
0 | 0 1
1 | 1 0

Obj = Obj Xor cBOLD

00000001
00000010
Xor -----------
00000011

C'est bien beaux tout ça, mais après comment on fait pour évaluer nos constante ??? Pas de panique, Il suffit d'appliquer nos operateurs : Par exemple on veux savoir si le texte est gras :

If Obj And cBOLD = cBOLD Then MsgBox "Texte en gras"

ou bien :

If Obj And cBOLD Then MsgBox "Texte en gras"

(La condition est convertie en boolean. La conversion retourne False uniquement si la condition = 0)

Obj And cBOLD :
00000011
00000001
And -----------
00000001 = &h1 = cBOLD

VB est même doté d'un opérateur spécial à cette fin : Imp. Mais attention cette opérateur tient compte de l'ordre des operande !!!! Cette opérateur veux dire "est impliquer dans"

1er argument : 0011
2eme argument : 1010
Imp ------
1110

C'est en realiter : arg1 Or (Not arg2)

Si la valeur de la variable (ATTENTION : la valeur entière) retourner est -1 (qui equivaut à une conversion de true de boolean vers un entier) c'est que le test est positif.

Par exemple, on teste Gras et italique en même temps :

If (cBOLD Or cITALIC) Imp Obj = True then MsgBox "Texte gras et italique"

ATTENTION :

Le programme va d'abord conertir True en entier (True = -1). Donc:
If (cBOLD Or cITALIC) Imp Obj then MsgBox "Gras et Italique"
ne fonctionne pas car la condition va retourner un entier qui n'est pas spécialement = 0 si la condition est fausse.
Par exemple : Un cUNDERLINE Imp Obj

00000100
00000011
Imp ------------
11111011

Donc different de 0 même si cUNDERLINE n'est pas impliquer.

Rem : Un "If Obj And (cBOLD Or cITALIC)" aurait tout aussi bien marcher...

Source / Exemple :


Const cBOLD = &h1
Const cITALIC = &h2
Const cUNDERLINE = &h4

Dim Obj as Byte
Obj = 0

Obj = Obj Or cBOLD          ' 00000001 = &h1
Obj = Obj Or cITALIC        ' 00000011 = &h3
Obj = Obj And Not cBOLD  ' 00000010 = &h2 
Obj = Obj Xor cBOLD        ' 00000011 = &h3

If Obj And cBOLD Then MsgBox "Texte en gras"
If (cBOLD Or cITALIC) Imp Obj = True then MsgBox "Texte gras et italique"

Conclusion :


Cette technique est intéressant puisqu'elle ne consomme presqu'aucune place en mémoire (Boolean "pèse" 2 octets alors qu'ici on en a 16 pour le même prix). De plus, dans un fichier, celà permet d'ajouter des fonction à un programme sans changer le format de fichier. Une nouvelle version n'as qu'à rajouter une constante pour le flags donc les version précédente liront toujour le fichier sans toutefois implementer la nouvelle fonctions (ben oui ce serai trop facile sinon ;)). Un autre avantage majeure est le fait de pouvoir évaluer plusieurs condition à la fois et donc une mailleur lisiblité.
Si je devais trouver un defaut, ce serai qu'il faut un peu reflechir :p. Mais bon on ne peux pas tt avoir

J'aimerais avoir vos commentaire...

J'espère que ce tuto pourra en aider quelques-uns. Vous pouvez toujours poser vos question en laissant un commentaire.

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.