2012-08-07 10 views
7

das Programm ist:Druck-Bit-Typ als Integer? Wie ist die Umwandlung?

typedef struct xp { 
     int a:2; 
     int b:2; 
     int c:1; 
} xp; 

int main(void) 
{ 
     xp x; 
     memset(&x, 0, sizeof(xp)); 

     x.a = 1; 
     x.b = 3; 
     x.c = 1; 

     printf("%d\n",x.a); 
     printf("%d\n",x.b); 
     printf("%d\n",x.c); 

     return 0; 
} 

ich 1 -1 -1, warum? Wie sind a, b und c in x gespeichert? Was ist passiert, wenn printf ("% d \ n", x.a); wird ausgeführt?

+0

Dies ist ein Duplikat; Ich weiß, dass ich genau diese Frage schon einmal beantwortet habe. Ich werde sehen, ob ich es aufspüren kann. –

+0

Bis Carl den Betrogenen findet: weil Ihr Compiler die Bitfelder als Zweierkomplementzahlen interpretiert. –

+2

Es ist in der Implementierung definiert, ob sie signiert oder nicht signiert sind. –

Antwort

5

Sie verwenden einen signierten Typ für Ihre Bitfelder, was bedeutet, dass Sie zwei vorzeichenbehaftete Ganzzahlen mit zwei Bit und eine vorzeichenbehaftete Ganzzahl mit einem Bit erstellt haben.

Die möglichen Werte für eine Zwei-Bit-Ganzzahl mit Vorzeichen (Zweier-Komplement) sind: -2, -1, 0 und 1:

die möglichen Werte für eine Ein-Bit-Ganzzahl mit Vorzeichen (Zweier-Komplement) sind -1 und 0

Durch Werte zu speichern, dass „nicht passen“, wie Sie in diesen Zeilen getan haben:

x.b = 3; 
x.c = 1; 

Sie seltsames Verhalten bekommen, wie die Bitmuster unterschiedlich interpretiert werden Sie speichern, wenn lesen. Sie können so etwas wie eine ähnliche Erfahrung haben, indem Sie:

char x = 58147; 

auf einer Maschine mit einem 8-Bit char Typ, wird dieser Wert nicht passen, so dass Sie etwas anderes zurückgelesen werden, wenn x zugreifen.

+0

@ccsnailpp, es ist -1, weil es Zwei-Komplement ist. Das führende Bit ist eine 1, das heißt, es ist eine negative Zahl. Um zu der entsprechenden positiven Zahl zu übersetzen, mach '~ x + 1'. In diesem Fall ist das "~ 11 + 1 = 00 + 1 = 1".Im Zweierkomplement repräsentiert ein Nur-Einsen-Bitmuster immer -1. –

+0

danke für Ihre Erklärung im Detail. –

2

Ein Bitfeld vom Typ int ist entweder vom Typ signed int oder vom Typ unsigned int. Die Auswahl ist implementierungsdefiniert. Dies ist aus historischen Gründen. Dies ist der einzige Kontext, in dem sich int und signed int unterscheiden können. nach einer Liste der Typdeklarierer

Dies wird in Abschnitt 6.7.2 des C-Standard (C99 draft, C11 draft) angegeben:

Jede der durch Kommata getrennte Multimengen bezeichnet den gleichen Typen, mit der Ausnahme, dass Für Bitfelder ist es implementierungsdefiniert, ob der Spezifizierer int den gleichen Typ wie signed int oder den gleichen Typ als unsigned int bezeichnet.

Die Lösung besteht darin, die Verwendung von einfachen int für Bitfelder zu vermeiden; deklarieren Sie sie immer entweder als signed int oder als unsigned int. (Letzteres macht fast immer mehr Sinn.)

Verwandte Themen