c - 通过 C 中具有位字段的结构指针访问无符号整数的各个位

标签 c pointers struct bit-fields

假设我们有一个定义如下的结构:

struct S_BF {
    unsigned first_bit : 1;
    unsigned second_bit : 1;
    unsigned rest : 30;
}

还有一个指向 S_BF 结构的指针:

struct S_BF*  bf;

如果我们有一个变量:

unsigned int p = 0;

我们怎样才能让bf指向p,这样我们就可以通过修改它的位域来修改p的值,例如,如果我们想要将p的值更改为2,我们可以这样做:

bf->second_bit = 1;

最佳答案

想要使用 unsigned p 类型的指针访问 struct S_BF* 的位的问题是它违反了严格别名规则 C11 Standard - §6.5 Expressions (p6,7) 。该规则旨在防止通过使用指向另一种类型的指针来访问一种类型的对象。 (有各种异常(exception)情况,但该规则的目的是防止指针的类型双关)

通过指向 unsigned 的指针访问 struct S_BF 的位的唯一符合标准的方法是通过 unionstruct S_BF 之间的 unsigned 使这些位成为相同的位。您必须可以通过指向 struct S_BF 的指针访问 struct S_BF 的位,并通过并集使 struct S_BFunsigned 相同,而不违反字符串别名规则。一个简短的例子是:

#include <stdio.h>

struct S_BF {               /* bitfield struct */
    unsigned first_bit : 1;
    unsigned second_bit : 1;
    unsigned rest : 30;
};

union s2u {                 /* union bitfield struct/unsigned */
    struct S_BF s;
    unsigned u;
};

int main (void) {

    union s2u s2u = { .u = 0 };             /* union initialized zero */
    struct S_BF *bf = &s2u.s;               /* pointer to bitfield */
    unsigned sz = 32;                       /* no. of bits in unsigned */

    bf->second_bit = 1;         /* set second bit 1 */
    bf->rest = 0x2aaaaaaa;      /* alternating bits 1010101... */

    while (sz--)    /* loop sz times, using unsigned value in union */
        putchar (s2u.u >> sz & 1 ? '1' : '0');  /* output bits */

    putchar ('\n');
}

示例使用/输出

上面的示例将产生以下输出:

$ ./bin/bitfield_union
10101010101010101010101010101010

关于c - 通过 C 中具有位字段的结构指针访问无符号整数的各个位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58350520/

相关文章:

python - 如何在 python 3.2 中解压缩 c 结构?

c - GCC、ARMboot - 创建没有任何库和任何操作系统的独立应用程序

C++ 引用和接口(interface)指针之间的不同行为

c - 如何将结构数组的二进制副本写入文件

c++ - 正确销毁指向对象的指针

你能改变 C 非指针类型的内存地址吗?

c - 指向结构和打印的指针

c - 在C中模拟部分函数的应用

c - Linux 中使用 MMX 进行图像处理

C Typedef 结构问题