如何将位字段写入整数值?

时间:2019-11-07 17:18:10

标签: c bit-fields

我正在尝试这样做:

typedef struct {
    uint16_t red : 6;
    uint16_t green : 5;
    uint16_t blue : 5;
} color_t

然后我想得到类似的东西:

color_t clr;
clr.red = 0;
clr.green = 10;
clr.blue = 15;

并将复合变量clr写入一个int:

int value = clr; // this does not work

fprintf(draw, "%4X", value);

我这样做的原因是我想创建橙色,紫色等颜色,并从文件中将其绘制在屏幕上。 在文件内部,我正在以十六进制格式编写颜色。

另一件事是,我想稍后在代码中这样做:

if (clr == value) { ... }

或者换句话说,我想比较struct位域中的值和int保留颜色的真正十六进制值。

2 个答案:

答案 0 :(得分:3)

我认为您最好的选择是编写一个像这样的简单转换器函数:

uint16_t colorToInt(color_t c)
{
    uint16_t ret = 0;
    ret |= c.blue;
    ret |= c.green << 5;
    ret |= c.red << 10;
    return ret;
}

那你就可以做

int value = colorToInt(clr);

这是反函数:

color_t intToColor(uint16_t x)
{
    color_t ret = {
        .blue = 0 | x,
        .green = 0 | x >> 5,
        .red = 0 | x >> 10
    };
    return ret;
}

旁注:避免使用以_t结尾的标识符。它们由POSIX标准保留。我也建议不要使用typedef,除非您要创建一个完全不透明的对象的库。

答案 1 :(得分:0)

这是一个独立的示例,显示了如何使用联合访问具有位字段的结构的值:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    uint16_t red: 6;
    uint16_t green: 5;
    uint16_t blue: 5;
} color_t;

typedef union {
    uint16_t color_value;
    color_t color_bits;
} color_helper_t;

int main(void) {
    color_helper_t clr;

    clr.color_bits.red = 0;
    clr.color_bits.green = 0;
    clr.color_bits.blue = 15;

    uint16_t value = clr.color_value;

    printf("%04X\n", value);

    if (clr.color_value == value) {
        printf("The values are equal\n");
    }

    return 0;
}

输出

7800
The values are equal