C语言 将位字段转换为int

k7fdbhmy  于 2023-04-19  发布在  其他
关注(0)|答案(4)|浏览(216)

我用这种方式声明了位字段:

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

qgzx9mmu

qgzx9mmu1#

请,请,不要使用联合。或者,更确切地说,理解你使用联合在做什么--最好在你使用联合之前。
正如你在这个答案中所看到的,不要依赖于位域的可移植性。特别是对于你的情况,结构中位域的顺序是依赖于实现的。
现在,如果你的问题是,如何将位域结构体打印为int,以供偶尔的私人检查,当然,联合是很好的,但你似乎想要位域的“实际值”。
所以:如果你只在这一台机器/编译器组合上工作,并且你不需要 * 依赖 * int的数学值,只要它有意义,你就可以使用联合。但是如果你可能会移植你的代码,或者如果你需要int的“实际值”,你需要编写位操作代码来将位字段转换为正确的int位。

m1m5dgzv

m1m5dgzv2#

你可以使用一个union:

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;
icnyk63a

icnyk63a3#

只要使用一个union就可以了。你可以把你的数据作为一个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;
}
bogh5gae

bogh5gae4#

你可以简单地做

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

short result;
std::memcpy(&result, &bitset, sizeof(short));

通过这种方式,bitset的内存区域将被复制到内存区域内,并被解释为short
resultshort,因为您的位集大小为16位(2字节)。
如果你想要一个更好的方法来设置新缓冲区的内存大小你可以做(用c++11或更高)

std::memcpy(&result, &bitset, sizeof(decltype(result));

另一个解决方案(非常丑陋和危险)是重新解释内存区域:

short result = *reinterpret_cast<short*>(&bitset);

相关问题