2010-03-18 15 views
12

J'ai champ de bits déclaré ainsi:Conversion Bit champ à int

typedef struct morder { 
    unsigned int targetRegister : 3; 
    unsigned int targetMethodOfAddressing : 3; 
    unsigned int originRegister : 3; 
    unsigned int originMethodOfAddressing : 3; 
    unsigned int oCode : 4; 
} bitset; 

J'ai aussi tableau int, et je veux obtenir une valeur int à partir de ce tableau, qui représente la valeur réelle de ce champ de bits (qui est en fait une sorte de mot machine dont j'ai les parties, et je veux la représentation int du mot entier).

Merci beaucoup.

+3

@shaharg: Je pense que vous n'êtes pas très précis avec votre langue. Les champs de bits sont les champs individuels de votre structure, mais vous semblez faire référence à la structure entière en tant que "champ de bits". – JXG

Répondre

13

Vous pouvez utiliser une union:

typedef union bitsetConvertor { 
    bitset bs; 
    uint16_t i; 
} bitsetConvertor; 

bitsetConvertor convertor; 
convertor.i = myInt; 
bitset bs = convertor.bs; 

Vous pouvez aussi utiliser un casting:

bitset bs = *(bitset *)&myInt; 

Ou vous pouvez utiliser un struct anonyme au sein d'un syndicat:

typedef union morder { 
    struct { 
     unsigned int targetRegister : 3; 
     unsigned int targetMethodOfAddressing : 3; 
     unsigned int originRegister : 3; 
     unsigned int originMethodOfAddressing : 3; 
     unsigned int oCode : 4; 
    }; 

    uint16_t intRepresentation; 
} bitset; 

bitset bs; 
bs.intRepresentation = myInt; 
+0

Comment cette union anonyme va-t-elle accomplir quelque chose? – zubergu

+0

@zubergu, commodité. Pas strictement nécessaire, bien sûr. – strager

+0

Downvoted: 'bitset bs = * (bitset *) &myInt;' est un exemple classique de rupture de la règle * strict aliasing *. – user694733

3

Bien sûr - utilisez simplement une union. Vous pouvez ensuite accéder à vos données sous la forme d'un int de 16 bits ou sous forme de champs de bits individuels, par ex.

#include <stdio.h> 
#include <stdint.h> 

typedef struct { 
    unsigned int targetRegister : 3; 
    unsigned int targetMethodOfAddressing : 3; 
    unsigned int originRegister : 3; 
    unsigned int originMethodOfAddressing : 3; 
    unsigned int oCode : 4; 
} bitset; 

typedef union { 
    bitset b; 
    uint16_t i; 
} u_bitset; 

int main(void) 
{ 
    u_bitset u = {{0}}; 

    u.b.originRegister = 1; 
    printf("u.i = %#x\n", u.i); 

    return 0; 
} 
16

S'il vous plaît, s'il vous plaît, faites pas utiliser une union. Ou plutôt, comprenez ce que vous faites en utilisant un syndicat - de préférence avant d'en utiliser un.

Comme vous pouvez le voir dans this answer, ne comptez pas sur les champs de bits pour être portable. Spécifiquement pour votre cas, l'ordre des champs de bits dans une structure dépend de l'implémentation. Maintenant, si votre question était, comment pouvez-vous imprimer le struct bitfield comme un int, pour examen occasionnel privé, bien sûr, les syndicats sont grands. Mais vous semblez vouloir la "valeur réelle" de vos champs de bits. Donc, si vous ne travaillez que sur cette combinaison machine/compilateur, et que vous n'avez pas besoin de compter sur la valeur mathématique de l'int, tant que cela est logique, vous pouvez utiliser des syndicats. Mais si vous pouvez porter votre code, ou si vous avez besoin de la "valeur réelle" de l'int, vous devez écrire du code de manipulation de bits pour obtenir les champs de bits dans les bons bits int.

+6

+1 'l'ordonnancement des champs de bits dans une structure dépend de l'implémentation' – Lazer

+0

L'implémentation dépend-elle du dépendant du compilateur, de la plateforme ou des deux? – gsingh2011

+0

@ gsingh2011, les deux. Un compilateur spécifique pour une architecture spécifique peut faire ce qu'il pense être le meilleur. – JXG