2017-09-28 1 views
2

Hier setzt die Anweisungen:Ich brauche ein C-Programm zu schreiben, das eine Union Struktur verwendet die Bits einer int

eine Vereinigung Daten struct WORD_T für eine uint16_t ganze Zahl definieren, so dass ein Wert kann auf eine zugeordnet werden WORD_T Ganzzahl auf drei Arten: (1) Um den Wert jedem Bit der ganzen Zahl zuzuweisen, (2) Um den Wert jedem Byte der ganzen Zahl zuzuweisen, (3) Den Wert direkt der ganzen Zahl zuweisen.

Ich weiß, ich brauche etwas anderes mit dieser ersten Struktur zu tun, aber ich bin ziemlich im Allgemeinen verloren. Hier ist, was ich habe:

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/types.h> 

#define BIT(n) (1 << n) 
#define BIT_SET(var, mask) (n |= (mask)) 
#define BIT_CLEAR(var, mask) (n &= ~(mask)) 
#define BIT_FLIP(var, mask) (n ^= (mask)) 

union WORD_T{ 
    struct{ 
     uint16_t integerVar:16 

    }; 
    struct{ 
     unsigned bit1:0; 
     unsigned bit2:0; 
     unsigned bit3:0; 
     unsigned bit4:0; 
     unsigned bit5:0; 
     unsigned bit6:0; 
     unsigned bit7:0; 
     unsigned bit8:0; 
     unsigned bit9:0; 
     unsigned bit10:0; 
     unsigned bit11:0; 
     unsigned bit12:0; 
     unsigned bit13:0; 
     unsigned bit14:0; 
     unsigned bit15:0; 
     unsigned bit16:0; 
    }; 

    void setIndividualBit(unsigned value, int bit) { 
     mask = BIT(value) | BIT(bit); 
     BIT_SET(n, mask); 
    } 
}; 
+0

'unsigned Bit1: 0;' bedeutet es 0 Bit groß ist, das keinen Sinn macht. Meinst du 'unsigned bit1: 1;'? – mch

+0

Ich denke, mch richtig - 'Bit1: 0 'sagt "verwenden Null-Bits des unsigned", wobei' Bit1: 1', sagt – theGleep

+1

"ein Bit verwenden", um einige Fragen der Umsetzung verwenden '#define BIT (n) (1U zu vermeiden << n) '(add 'u') – chux

Antwort

2

Hier ist die Vereinigung Definition:

union WORD_T 
{ 
    uint16_t word; 

    struct 
    { 
     uint8_t byte0; 
     uint8_t byte1; 
    }; 

    struct 
    { 
     uint8_t bit0:1; 
     uint8_t bit1:1; 
     uint8_t bit2:1; 
     uint8_t bit3:1; 
     uint8_t bit4:1; 
     uint8_t bit5:1; 
     uint8_t bit6:1; 
     uint8_t bit7:1; 
     uint8_t bit8:1; 
     uint8_t bit9:1; 
     uint8_t bit10:1; 
     uint8_t bit11:1; 
     uint8_t bit12:1; 
     uint8_t bit13:1; 
     uint8_t bit14:1; 
     uint8_t bit15:1; 
    }; 
}; 

Um zu den einzelnen Komponenten zuweisen, tun Sie etwas ähnlich der folgenden:

union WORD_T data; 

data.word = 0xF0F0; // (3) Assign to entire word 

data.byte0 = 0xAA; // (2) Assign to individual byte 

data.bit0 = 0; // (1) Assign to individual bits 
data.bit1 = 1; 
data.bit2 = 1; 
data.bit2 = 0; 
+0

Wann würde Byte1 verwendet werden? –

+1

@DouglasAdolph Einstellung Byte0 wie in meinem Beispiel überschreibt nur die unteren 8 Bits des 16 Bit Speicherplatzes. Verwenden Sie Byte1, um die oberen 8 Bits desselben 16-Bit-Speicherorts festzulegen. –

3

Das offensichtlichste Problem ist das :0 bedeutet "ein Bit-Feld von Null Bits", die keinen Sinn macht. Sie sollten dies zu 1 ändern und dann können Sie einzelne Bits durch Code wie the_union.the_struct.bit1 = 1; zuweisen.

Dieses Format ist eine Alternative zu dem Bit-Satz/clear Makros, die Sie geschrieben hat.

Ihre Vereinigung sollte wie folgt aussehen:

typedef union 
{ 
    uint16_t word; 
    uint8_t byte[2]; 
    struct{ 
    uint16_t bit1:1; 
    ... 

jedoch. Das ist eine wirklich schlechte Idee und Ihr Lehrer sollte es besser wissen, als solche Aufgaben zu geben. Bit-Felder in C sind eine Tüte Würmer - sie sind vom Standard sehr schlecht spezifiziert. Probleme:

  • Sie nicht wissen können, welche das Bit, dass das MSB ist, ist es nicht definiert.
  • Sie können nicht wissen, ob irgendwo Padding Bits/Bytes sein wird.
  • Sie können nicht einmal uint16_t oder uint8_t verwenden, da Bitfelder nur zum Arbeiten mit int angegeben sind.

Und so weiter. Außerdem muss man mit Endianess und Alignment umgehen. Siehe Why bit endianness is an issue in bitfields?.

Wesentlichen Code-Bit-Felder wie dies stark auf die spezifischen Compiler angewiesen. Es wird komplett nicht portabel sein.

Alle dieser Probleme durch Fallenlassen des Bit-Feld und verwenden Bitoperatoren auf einem uint16_t statt vermieden werden könnten, wie Sie in Ihrem Makros haben. Nur mit bitweisen Operatoren wird Ihr Code deterministisch und 100% portabel. Sie können sie sogar verwenden, um Endlichkeit auszuweichen, indem Sie Bit-Verschiebungen verwenden.

Verwandte Themen