假设我们有一个定义如下的结构:
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
的位的唯一符合标准的方法是通过 union
和 struct S_BF
之间的 unsigned
使这些位成为相同的位。您必须可以通过指向 struct S_BF
的指针访问 struct S_BF
的位,并通过并集使 struct S_BF
和 unsigned
相同,而不违反字符串别名规则。一个简短的例子是:
#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/