c - 在 C 中使用位字段时的字段顺序

标签 c gcc bit-manipulation bit bit-fields

我有以下类型的结构

typedef struct
{
unsigned int a : 8;
unsigned int b : 6;
unsigned int c : 2;
}x, *ptr;

我想做的是更改字段 c 的值。

我做了类似下面的事情

x structure = { 0 };
x->c = 1;

当我查看内存映射时,我希望找到 00 01,但我却找到了 00 40。 看起来在安排第二个字节时,它将 c 字段放在最低位,将 b 字段放在最高位。我在 GCC 和 Windows 编译器上都看到过这种情况。

目前,我所做的是以下工作正常。

unsigned char ptr2 = (unsigned char*) ptr
*(ptr2 + 1)  &= 0xFC
*(ptr2 + 1)  |= 0x01

我是不是看错了内存映射? 感谢您的帮助。

最佳答案

C 标准允许编译器以任何顺序放置位域。没有可靠且便携的方法来确定顺序。

如果您需要知道确切的位位置,最好使用无符号变量和位掩码。

这是使用位域的一种可能的替代方法:

#include <stdio.h>

#define MASK_A    0x00FF
#define MASK_B    0x3F00
#define MASK_C    0xC000
#define SHIFT_A   0
#define SHIFT_B   8
#define SHIFT_C   14

unsigned GetField(unsigned all, unsigned mask, unsigned shift)
{
    return (all & mask) >> shift;
}

unsigned SetField(unsigned all, unsigned mask, unsigned shift, unsigned value)
{
    return (all & ~mask) | ((value << shift) & mask);
}

unsigned GetA(unsigned all)
{
    return GetField(all, MASK_A, SHIFT_A);
}

unsigned SetA(unsigned all, unsigned value)
{
    return SetField(all, MASK_A, SHIFT_A, value);
}

/* Similar functions for B and C here */

int main(void)
{
    unsigned myABC = 0;
    myABC = SetA(myABC, 3);
    printf("%u", GetA(myABC)); // Prints 3
}

关于c - 在 C 中使用位字段时的字段顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19376426/

相关文章:

c - 将双指针传递给函数以在 C 中获取字符串

c - C 中的 TCP/IP 不工作

c - 更好的命令行界面

c++ - 让 gcc 在 if 内对转换发出警告

Delphi:如何从TBytes中读取X位?

c - 如何将 C 中分配的字符串返回给 Ada 并在 Ada 中释放它?

c - S_IFMT 和 S_IFREG 未定义为 -std=c11 或 -std=gnu11

GCC、PIE、PIC、文件和共享对象——什么和什么一起工作?

c++ - 位反转 : Generating Bit Reversal Lookup Table for N-Bits

c# - 从字节数组中读取位范围