operazioni booleane in C utilizzando bitfield

0

Sto cercando di implementare il tipo di dati booleani in C. Fondamentalmente, sto lavorando con i set.

Il seguente codice può essere utilizzato per accedere a ciascun bit, ma non sono sicuro di poter rappresentare set utilizzando questo metodo. Qualcuno può chiarirlo per me?

struct SET {
unsigned int b0     :1;     // bit 0 single bit
unsigned int b1     :1;     // bit 1 single bit
unsigned int b2     :1;
 unsigned int b3    :1;
 };

Posso definire due strutture s1 e s2 .. e sarò in grado di accedere a ciascun bit di queste strutture (trattate come stringhe booleane).

Dovrò eseguire operazioni come UNION, INTERSECTION e MEMBERSHIP. Questo è possibile anche in C?

Nota: non posso usare Java, solo C.

    
posta GermanShepherd 05.08.2014 - 14:18
fonte

2 risposte

1

C non ha operazioni di set predefinite, ma se i tuoi set possono essere rappresentati da un set di bit con meno di 64 bit (32 in implementazioni precedenti), puoi usare le operazioni bit per simulare le operazioni dell'insieme ( utilizzando AND ( & ) per l'intersezione impostata e OR ( | ) per l'unione dei set).

La tua struttura è facile per testare l'appartenenza (basta vedere se il membro corrispondente non è 0 ), ma non è così facile per le operazioni su più bit. È più facile su un numero senza segno. Per ottenere il meglio da entrambi i mondi, usa un sindacato:

union SET {
  struct items {
    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;
  };
  uint8_t bits; // As we only have 8 items for our set
};

Esegui le operazioni di bit sul membro bits e i test / insiemi di appartenenza sui membri items.[abcdefgh] .

    
risposta data 05.08.2014 - 15:32
fonte
0

In memoria a questi si può accedere come flag, in modo da poter utilizzare le operazioni di flag standard,

struct SET {
 unsigned int b0     :1;     // bit 0 single bit
 unsigned int b1     :1;     // bit 1 single bit
 unsigned int b2     :1;
 unsigned int b3     :1;
};

struct SETFlag {
    union {
        SET set;
        unsigned int set_as_flag;
    };
};


 /* example use */
 SETFlag a, b, c;
 /* initialize */
 c.set_as_flag = a.set_as_flag | b.set_as_flag;  /* union */
 /* c.set, now you can use set */

Questo presuppone che tu abbia < = 32 membri per un int di 4 byte, potresti assicurarti che il suo valore sia corretto,

_Static_assert(sizeof(((struct SETFlag *)0)->set) <=
               sizeof(((struct SETFlag *)0)->set_as_flag),
               "SETFlag.set_as_flag is too small!");

Tuttavia, tutto questo solleva la domanda, perché non usare solo le bandiere.

    
risposta data 05.08.2014 - 15:33
fonte

Leggi altre domande sui tag