简体   繁体   English

将位域转换为 int

[英]Converting Bit Field to int

I have bit field declared this way:我以这种方式声明了位字段:

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

I also have int array, and I want to get int value from this array, that represents the actual value of this bit field (which is actually some kind of machine word that I have the parts of it, and I want the int representation of the whole word).我也有 int 数组,我想从这个数组中获取 int 值,它代表这个位域的实际值(实际上是某种机器字,我有它的一部分,我想要的 int 表示整个词)。

Please, please, do not use a union.不要使用工会。 Or, rather, understand what you're doing by using a union--preferably before you use one.或者,更确切地说,通过使用联合来了解你在做什么——最好在你使用联合之前。

As you can see in this answer , do not rely on bitfields to be portable.正如您在此答案中所见,不要依赖位域来实现可移植性。 Specifically for your case, the ordering of the bitfields within a struct is implementation-dependent.特别是对于您的情况,结构中位域的顺序取决于实现。

Now, if your question was, how can you print out the bitfield struct as an int, for occasional private review, sure, unions are great.现在,如果您的问题是,您如何将位域结构打印为 int,以便偶尔进行私人审查,当然,联合很棒。 But you seem to want the "actual value" of your bitfields.但是您似乎想要位域的“实际值”。

So: if you only work on this one machine/compiler combination, and you don't need to rely on the mathematical value of the int, so long as it makes sense, you can use unions.所以:如果您只在这台机器/编译器组合上工作,并且您不需要依赖int 的数学值,只要有意义,您就可以使用联合。 But if you might port your code, or if you need the "actual value" of the int, you need to write bit-manipulation code to get the bit fields into the right int bits.但是,如果您可以移植代码,或者如果您需要 int 的“实际值”,则需要编写位操作代码以将位字段放入正确的 int 位。

You can use a union:您可以使用联合:

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

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

Or you can use a cast:或者您可以使用演员表:

bitset bs = *(bitset *)&myInt;

Or you can use an anonymous struct within a union:或者您可以在联合中使用匿名结构:

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;

Just use a union.只需使用联合。 You can then access your data either as a 16 bit int or as individual bit-fields, eg然后,您可以以 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM