14

我有这样声明的位字段:

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 表示整个词)。

4

3 回答 3

25

拜托,拜托,不要使用工会。或者,更确切地说,通过使用联合来了解您在做什么——最好在使用联合之前。

正如您在这个答案中看到的那样,不要依赖位域是可移植的。特别是对于您的情况,结构中位域的顺序取决于实现。

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

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

于 2010-03-18T10:10:13.657 回答
16

您可以使用联合:

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;
于 2010-03-18T09:42:32.557 回答
2

只需使用工会。然后,您可以以 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;
}
于 2010-03-18T09:42:14.943 回答