2016-04-16 14 views
0

Ich muss Union erstellen, die mir erlauben würde, jedes einzelne Bit von einem bestimmten Byte zu bekommen (und anzuzeigen). Macht das überhaupt Sinn? Ich denke, dass ich weiß, wie man das mit bitweisen Operatoren macht, aber keine Ahnung, wie man Unionen für den gleichen Effekt verwendet.C Union - Anzeige aller 8 Bits eines Bytes

+2

Haben Sie Bit-Feld bedeuten stattdessen? Gewerkschaften sind nicht dafür. – fluter

+3

Was ist falsch an der Verwendung bitweiser Operatoren? –

Antwort

1

Es wird empfohlen, bitweise Operationen zu verwenden. Sie kombinieren Vereinigung und Bit-Felder-Bits zu extrahieren, aber beachten Sie, dies ist endianness abhängig, weshalb dies nicht empfohlen, eine Probe hier für das Lernen aber:

#include <stdio.h> 
#include <string.h> 

union Bits { 
    char b; 
    struct bits { 
#ifdef LITTLE_ENDIAN 
      unsigned int b0: 1; 
      unsigned int b1: 1; 
      unsigned int b2: 1; 
      unsigned int b3: 1; 
      unsigned int b4: 1; 
      unsigned int b5: 1; 
      unsigned int b6: 1; 
      unsigned int b7: 1; 
#else 
      // reverse the order of the bit fields. 
#endif 
    } bits; 
}; 

int main(void) { 
    char a = 'A'; 
    union Bits b; 
    b.b = a; 

    printf("0x%x\n", a); 
    printf("%d%d%d%d%d%d%d%d\n", b.bits.b7, b.bits.b6, b.bits.b5, b.bits.b4, b.bits.b3, b.bits.b2, b.bits.b1, b.bits.b0); 

    return 0; 
} 

Dies sollte Ausgang

0x41 
01000001 
+0

Nein. Sie können nicht angeben, welche Reihenfolge Bit-Felder sein werden. Die Reihenfolge der Bitfelder ist implementierungsdefiniert. Per ** 6.7.2.1 Struktur- und Gewerkschaftsspezifizierer **, Paragraph 11 des [C-Standards] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf): " ... Die Reihenfolge der Zuweisung von Bitfeldern innerhalb einer Einheit (hochrangig zu niedriger Ordnung oder niedriger Ordnung zu hoher Ordnung) ist implementierungsdefiniert. ... " –

+0

Es ist implementationsdefiniert, deshalb Ich sagte, es hängt von Endianness ab und ist nicht portabel, ich habe nie gesagt, dass man die Reihenfolge des Bitfeldes angeben kann. :) – fluter

+0

Es hängt nicht nur von der Endianess ab - verschiedene Compiler können Bitfelder unterschiedlich behandeln. Sie können also nicht wirklich wissen, welches Bit welches ist. Einige von ihnen sogar vermasseln: https://lwn.net/Articles/478657/ –

1

Sie können eine Union von unit8_t und struct verwenden, die 8 Ein-Bit-Bitfelder enthalten. Auch wenn Sie dadurch auf einzelne Bits zugreifen können, werden Sie nicht wissen, welche Bits sie sind! Dies hängt davon ab, wie Ihr Compiler die Bitfelder dem zugrunde liegenden Byte zuordnet, was von der Endianz Ihres Zielrechners abhängen kann.

Siehe this SO Q&A.

+0

** Sie werden nicht wissen, welche Bits sie sind! ** Danke, dass Sie darauf hingewiesen haben. –

1

Seit C99 haben wir anonyme Strukturen und Gewerkschaften, die Dinge einfacher:

#include <stdio.h> 
#include <stdbool.h> 
#include <inttypes.h> 

union disByte 
{ 
    uint8_t byte; 
    // Assuming little endian 
    struct { 
     bool b0: 1; 
     bool b1: 1; 
     bool b2: 1; 
     bool b3: 1; 
     bool b4: 1; 
     bool b5: 1; 
     bool b6: 1; 
     bool b7: 1; 
    }; 
}; 

int main() 
{ 
    union disByte foo; 
    foo.byte = 42; 
    printf("%d %d %d %d %d %d %d %d\n", foo.b0, foo.b1, foo.b2, foo.b3, foo.b4, foo.b5, foo.b6, foo.b7); 
} 

Allerdings ist das Bit Manipulation in der Regel bevorzugt (Ihre Frage „Bit-manipulati getaggt wurde auf").

#define XTH_BIT_OF(NUM, X) (bool)(NUM & (1U << X)) 

Die Vorteile der Bit-Manipulation sind:

  1. Sie nicht über endianness Grund zur Sorge.
  2. Es sieht kürzer und klarer aus.
1

Sie können ein Bit-Feld und eine Vereinigung verwenden, um dies so zu tun:

#include <stdio.h> 


typedef union { 
     struct { 
      unsigned int:0; 
      unsigned int firstBit : 1; 
      unsigned int secondBit : 1; 
      unsigned int thirdBit : 1; 
      unsigned int fourthBit : 1; 
      unsigned int fifthBit : 1; 
      unsigned int sixthBit : 1; 
      unsigned int seventhBit : 1; 
      unsigned int eigthBit : 1; 
     }; 
     int raw; 
} bitsOfByte; 

int main() 
{ 
bitsOfByte dt; 
dt.raw = 254; 
printf("Bits are %d/%d/%d/%d/%d/%d/%d/%d", dt.firstBit, dt.secondBit, dt.thirdBit, dt.fourthBit, dt.fifthBit, dt.sixthBit, dt.seventhBit, dt.eigthBit); 
return 0; 
} 

Beachten Sie, dass bei dieser Implementierung ist das erste Bit ist das untere Bit

+0

Dies ist spezifisch für C99 –