通过指向具有 C 中位字段的结构的指针访问无符号整数的各个位
Accessing individual bits of unsigned integer through pointer to struct with bit fields in C
假设我们有一个定义如下的结构:
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
的值p
到 2,我们可以这样做:
bf->second_bit = 1;
想要使用 struct S_BF*
类型的指针访问 unsigned p
的位的问题是它违反了 strict alias 规则 C11 Standard - §6.5 Expressions (p6,7).该规则旨在防止使用指向另一种类型的指针访问一种类型的对象。 (有各种例外,但规则的目的是防止指针的类型双关)
通过指向 struct S_BF
的指针访问 unsigned
的位的唯一符合标准的方法,它通过 struct S_BF
之间的 union
使这些位相同] 和 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');
}
例子Use/Output
以上示例将产生以下输出:
$ ./bin/bitfield_union
10101010101010101010101010101010
假设我们有一个定义如下的结构:
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
的值p
到 2,我们可以这样做:
bf->second_bit = 1;
想要使用 struct S_BF*
类型的指针访问 unsigned p
的位的问题是它违反了 strict alias 规则 C11 Standard - §6.5 Expressions (p6,7).该规则旨在防止使用指向另一种类型的指针访问一种类型的对象。 (有各种例外,但规则的目的是防止指针的类型双关)
通过指向 struct S_BF
的指针访问 unsigned
的位的唯一符合标准的方法,它通过 struct S_BF
之间的 union
使这些位相同] 和 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');
}
例子Use/Output
以上示例将产生以下输出:
$ ./bin/bitfield_union
10101010101010101010101010101010