Manipulation bits

Fermé
LInus - 24 juin 2014 à 09:33
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 - 24 juin 2014 à 13:39
Bonjour,

J'ai besoin de manipuler des bits (0 ou 1) dans mon programme C. Cependant, si je stock ce 0 ou ce 1 dans un type char, ben ca vas pas du tout parce que le char occupe 8 bits en mémoire, et moi je veux que mon nombre n'occupe qu'un bit en mémoire (après tout c'est logique, mon bit ne peux prendre que deux valeurs 0 ou 1 : 2¹ = 2). Mais alors comment pourrai-je faire ? Existe-il un type plus petit que le char ?
A voir également:

3 réponses

ElementW Messages postés 4816 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 1 228
24 juin 2014 à 10:58
'lut, non, il n'existe pas de type plus petit que le
char
en C. Même un
bool
en C99, qui est une valeur booléenne qui occupe donc 1 bit, consomme 8 bits de mémoire, et pour preuve, on ne peut pas manipuler la mémoire par unités plus petites que l'octet.

Tant pis, utilise quand même 8 bits, mais utilise uniquement le bit de poids faible (le dernier). Pour éviter tout "dépassement" sur les bits du dessus (si jamais tu utilise des opérateurs arithmétiques dessus), tu peux faire
valeur = [opération] & 1;
, ce
& 1
appliquera un ET binaire, limitant la seule valeur possible à 0 ou 1.
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 2
24 juin 2014 à 13:00
Salut,

Tu peux également, t'aider d'un union de structure:
  union mybits {
      struct {
	  unsigned char b1:1; // LSB
	  unsigned char b2:1;
	  unsigned char b3:1;
	  unsigned char b4:1;
	  unsigned char b5:1;
	  unsigned char b6:1;
	  unsigned char b7:1;
	  unsigned char b8:1; // MSB
      } bits;
      unsigned char value;
  };

0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 094
24 juin 2014 à 13:22
Salut Twinuts,

https://publications.gbdirect.co.uk//c_book/chapter6/bitfields.html

The main use of bitfields is either to allow tight packing of data or to be able to specify the fields within some externally produced data files. C gives no guarantee of the ordering of fields within machine words, so if you do use them for the latter reason, you program will not only be non-portable, it will be compiler-dependent too. The Standard says that fields are packed into `storage units', which are typically machine words. The packing order, and whether or not a bitfield may cross a storage unit boundary, are implementation defined.

La standard ne te permet pas de t'assurer que les champs de bits de ta structure seront dans un ordre donné. Si cela est important pour le programme, c'est une façon de procéder hasardeuse, et qui peut ne pas donner pas la même "value" sur deux architectures, voire deux compilateurs différents.


Dal
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 2
24 juin 2014 à 13:39
Vouis très bonne remarque,

Cela dit niveau arch/compilo tu peux toujours tester l'endianness pour connaitre l'ordre
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 094
Modifié par [Dal] le 24/06/2014 à 14:04
Salut LInus,

Tu peux manipuler les bits individuellement, pour stocker un 0 ou un 1 comme tu le veux dans chaque, et ne pas te limiter au premier bit.

#include <stdio.h>
#include <stdint.h>     // assume C99 pour utiliser le type uint8_t

#define BIT1 (1 << 0)   // 00000001
#define BIT2 (1 << 1)   // 00000010
#define BIT3 (1 << 2)   // 00000100
#define BIT4 (1 << 3)   // 00001000
#define BIT5 (1 << 4)   // 00010000
#define BIT6 (1 << 5)   // 00100000
#define BIT7 (1 << 6)   // 01000000
#define BIT8 (1 << 7)   // 10000000

int main(void)
{
    uint8_t octet = 0;

    // mettre les bits impairs à 1
    octet |= BIT1 | BIT3 | BIT5 | BIT7;

    // mettre les bits pairs à 0
    octet &= ~(BIT2 | BIT4 | BIT6 | BIT6 | BIT8);

    printf("octet = %d\n", octet);

    // vérification (cette notation 0b est une extension gcc seulement)                                                                                                                                                                     
    octet = 0b01010101;
    printf("octet = %d\n", octet);

    return 0;
}


Dal
0