将位字段转换为int

时间:2010-03-18 09:37:44

标签: c bit-fields

我有这样声明的位字段:

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

我也有int数组,我想从这个数组得到int值,它表示这个位字段的实际值(实际上是某种机器字,我有它的部分,我想要int表示整个单词)。

非常感谢。

3 个答案:

答案 0 :(得分:20)

请,请使用工会。或者,更确切地说,通过使用联合来理解你正在做什么 - 最好在你使用之前。

正如您在this answer中所看到的,不要依赖位域来移植。特别针对您的情况,结构中位域的排序依赖于实现。

现在,如果您的问题是,如何将bitfield结构打印为int,偶尔进行私人审核,当然,工会很棒。但你似乎想要你的位域的“实际价值”。

所以:如果你只使用这一台机器/编译器组合,并且你不需要依赖对int的数学值,只要它有意义,你就可以使用工会。但是如果您可能移植代码,或者您需要int的“实际值”,则需要编写位操作代码以将位字段转换为正确的int位。

答案 1 :(得分:15)

您可以使用联合:

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

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

或者你可以使用演员:

bitset bs = *(bitset *)&myInt;

或者您可以在联合中使用匿名结构:

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;

答案 2 :(得分:4)

当然 - 只需使用工会。然后,您可以以16位int或单个位字段的形式访问数据,例如

#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;
}