C语言 将位域转换为 int

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2468708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:53:27  来源:igfitidea点击:

Converting Bit Field to int

cbit-fields

提问by Shahar Gvirtz

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

Thanks a lot.

非常感谢。

回答by JXG

Please, please, do notuse 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. But you seem to want the "actual value" of your bitfields.

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

So: if you only work on this one machine/compiler combination, and you don't need to relyon the mathematical value of the int, so long as it makes sense, you can use unions. 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 的“实际值”,则需要编写位操作代码以将位字段放入正确的 int 位。

回答by strager

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;

回答by Paul R

Sure - just use a union. You can then access your data either as a 16 bit int or as individual bit-fields, e.g.

当然 - 只需使用联合。然后,您可以以 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;
}