[C] gerer des champs de bits

gerer des champs de bits [C] - C - Programmation

Marsh Posté le 02-01-2005 à 23:35:08    

bonjour,
 
j'aimerai savoir comment gerer des champs de bits,
 
une fonction qui me permettrai de de mettre a 1 ou 0 un bit ds un octet , et reciproquement de savoir si un bit ds un octet est 0 ou 1.
 
j'ai beau chercher , je suis ds le flou
j'ai trouvé sur www.developpez.com :
#define SET(flag, bit) ((flag) |= (1 << (bit)))
#define CLEAR(flag, bit) ((flag) &= ~(1 << (bit)))  
#define GET(flag, bit) ((flag) & (1 << (bit)))
 
mais je suis largué.
 
pouvez-vous m'aider un peu ?
 
merci d'avance.

Reply

Marsh Posté le 02-01-2005 à 23:35:08   

Reply

Marsh Posté le 02-01-2005 à 23:42:02    

avec un | logique


---------------
  ____
Reply

Marsh Posté le 02-01-2005 à 23:48:13    

tu as compris ???
00101010 = 42  
00100000 = 32
 42 | 32 = 42 donc le bit 32 est a 1
 
regarde avec ca...
 
int     main(int ac, char **av)
{
  printf("%d | %d = %d", atoi(av[1]), atoi(av[2]), atoi(av[1]) | atoi(av[2]));
  return (0);
}


---------------
  ____
Reply

Marsh Posté le 03-01-2005 à 00:13:14    

merci , je regarde ca tout de suite.

Reply

Marsh Posté le 03-01-2005 à 00:13:16    

miminou a écrit :

bonjour,
 
j'aimerai savoir comment gerer des champs de bits,
 
une fonction qui me permettrai de de mettre a 1 ou 0 un bit ds un octet , et reciproquement de savoir si un bit ds un octet est 0 ou 1.
 
j'ai beau chercher , je suis ds le flou
j'ai trouvé sur www.developpez.com :
#define SET(flag, bit) ((flag) |= (1 << (bit)))
#define CLEAR(flag, bit) ((flag) &= ~(1 << (bit)))  
#define GET(flag, bit) ((flag) & (1 << (bit)))
 
mais je suis largué.


Tu ne comprends pas ces macros ?
 
Elles utilisent des opérateurs 'bit' (bitwise operators), qui sont:


~  NOT (non)
&  AND (et)
|  OR  (ou inclusif)
^  XOR (ou exclusif)
>> SHR (décalage à droite)
<< SHL (décalage à gauche)


(je te renvoi à ton cours de logique booléenne pour les détails)
 
Analysons cette macro :

#define SET(flag, bit) ((flag) |= (1 << (bit)))


Les paramètres sont 'flag' et 'bit'
flag est en fait la variable dans laquelle on veut bouger le bit.
bit est le numéro di bit à positionner.
La macro positionne ce bit à 1 dans la variable.
 
Exemple d'utilisation :  


   /* tous les bits de x sont a 0 */
   unsigned x = 0;  
 
   /* mettre le bit 2 de x a 1 */
   SET(x, 2);


Cette macro fait les remplacements suivants :  

  ((x) |= (1 << (2)));


soit

  x |= (1 << 2);


1 << 2 consiste à décaler 1 de 2 vers la gauche, soit  
0 : ...001
1 : ...010
2 : ...100 binaire (4 en décimal ou 0x04 en hexadécimal)
 
Ensuite, on fait  

  x |= 0x04;


ce qui est une forme contractée de  

  x = x | 0x04;


On applique donc un OU à x. X valait 0 :  


x    : ... 0000 0000
OU
0x04 : ... 0000 0100
--------------------
x    : ... 0000 0100


etc.
 
Pour le CLEAR, c'est un peu plus compliqué...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-01-2005 à 00:18:32    

oua, c'est ça que tu appelles 'renvoyer à ses cours' :D

Reply

Marsh Posté le 03-01-2005 à 00:55:36    

je te remercie beaucoup Emmanuel Delahaye
 
moi , ds mon petit programme ,a la base j'utilisais une struture
struct octet_bit {
 unsigned int a : 1;
 unsigned int b : 1;
 unsigned int c : 1;
 unsigned int d : 1;
 unsigned int e : 1;
 unsigned int f : 1;
 unsigned int g : 1;
 unsigned int h : 1;
};
 
et lorsque j'utilisais cette structure avec ces macros, ca foirait !
logique je suppose
 
maintenant, pour initialiser ma table bitmap, je la creerai/initialiserais avec des unsigned int =0 ;
 
merci bien. :jap:

Reply

Marsh Posté le 03-01-2005 à 04:07:41    

Fait gaffe : quand tu utilises une structure avec des champs de bits comme dans ton exemple ci-dessus, le premier champs est le bit de poid fort. Donc dans ton exemple a est le bit 31, b est le bit 30 et h est le bit 24.

Reply

Marsh Posté le 03-01-2005 à 09:07:42    

matafan a écrit :

Fait gaffe : quand tu utilises une structure avec des champs de bits comme dans ton exemple ci-dessus, le premier champs est le bit de poid fort. Donc dans ton exemple a est le bit 31, b est le bit 30 et h est le bit 24.


 
c'est un peu plateforme dependant, je parie mon chapeau que sur un PPC c'est l'inverse [:aloy]

Reply

Marsh Posté le 03-01-2005 à 09:55:14    

+1. Malheureusement, l'implémentation des champs de bits n'a jamais été normalisé et est laissé au choix des développeurs de compilos. Certaines optimisations conduisent mêmes à insérer des vides entre deux champs pour les aligner.
A n'employer que si la portabilité n'est pas importante...

Citation :

struct octet_bit {
 unsigned int a : 1;
 .../...
 unsigned int h : 1; };
et lorsque j'utilisais cette structure avec ces macros, ca foirait !

Wouarf ! Effectivement, c'est l'un OU l'autre.

Reply

Marsh Posté le 03-01-2005 à 09:55:14   

Reply

Marsh Posté le 03-01-2005 à 11:12:26    

matafan a écrit :

Fait gaffe : quand tu utilises une structure avec des champs de bits comme dans ton exemple ci-dessus, le premier champs est le bit de poid fort.


Ca dépend de l'implémentation, ce qui fait qu'on ne peut pas utiliser les bitfields pour mapper du hard de façon portable. Les bitfields ne sont portables qu'en usage interne.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-01-2005 à 11:15:47    

miminou a écrit :


moi , ds mon petit programme ,a la base j'utilisais une struture
struct octet_bit {
 unsigned int a : 1;
 unsigned int b : 1;
 unsigned int c : 1;
 unsigned int d : 1;
 unsigned int e : 1;
 unsigned int f : 1;
 unsigned int g : 1;
 unsigned int h : 1;
};
 
et lorsque j'utilisais cette structure avec ces macros, ca foirait !
logique je suppose


Oui. Il ne faut pas mélanger les champs de bits (bit fields) et les opération sur les bits (bitwise). Avec un champ de bit, il suffit de positionner le bit avec '= 1' ou '= 0' (si le champ a une largeur de 1)
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-01-2005 à 11:16:47    

Joel F a écrit :

c'est un peu plateforme dependant, je parie mon chapeau que sur un PPC c'est l'inverse [:aloy]


Exact (idem sur 68k)
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-01-2005 à 12:16:04    

j'avoue avoir un peu melangé les 2.
je pensais que ma structure de 8 fois 1 bit etait equivalente a un simple char, OUPS !! erreur...  :pfff:  
 
 
En fait le but de ma fonction est de trouver ,ds un espace de taille  quelconque , le premier bit a 0.
j'ai commencé hier a faire un "truc" avec une double boucle for - une pour les octets et une pour les bits de l'octet- mais les MAcros semblent ne pas apprecier les variables ( genre GET(x,i) avec  i un int =3 par ex )
Je vais donc passer par une methode surement plus "lourde" et longue.
 
merci a tous
(ps: et la, tu te rends compte que reprendre le C, c dur !)

Reply

Marsh Posté le 03-01-2005 à 13:01:08    

miminou a écrit :


En fait le but de ma fonction est de trouver ,ds un espace de taille  quelconque , le premier bit a 0.
j'ai commencé hier a faire un "truc" avec une double boucle for - une pour les octets et une pour les bits de l'octet- mais les MAcros semblent ne pas apprecier les variables ( genre GET(x,i) avec  i un int =3 par ex )


Ca devrait fonctionner. En tout cas, ça fonctionne avec les miennes:
 
http://mapage.noos.fr/emdel/clib.htm
Module BITS


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-01-2005 à 13:39:35    

Desolé , oui , ca marche  
c'etait juste une petite erreur, qui etait deja resolue hier d'aillleurs,  :o  
Je crois que losrque j'ai tapé ce message, j'ai du zappé completement ce que j'ai fait entre 1h30 et 2h.


Message édité par miminou le 03-01-2005 à 13:40:17
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed