[英]Extracting bit positions in a union of 16 bits in C
I want to declare a union
in C which mainly contains a 16-bit
word, and I should be able to read/write the LSP 7 bits
and 8th bit
separately for each byte in the 16-bit
word, so I declared something like: 我要声明一个
union
用C主要包含16-bit
字,我应该能够读/写的LSP 7 bits
和8th bit
分别在每个字节16-bit
字,所以我声明是这样的:
typedef union {
uint8_t full_8_char_byte[2];
uint8_t ascii_7_bits_word_0 : 7; /* another way of representing LSP 7 ASCII bits */
uint8_t parity_bit_word_0 : 1; /* another way of representing MSP parity bit */
uint8_t ascii_7_bits_word_1 : 7; /* another way of representing LSP 7 ASCII bits */
uint8_t parity_bit_word_1 : 1; /* another way of representing MSP parity bit */
} ip_char_t;
Now, when I write 7-bit
values to these individual bytes in the 16-bit
word: 现在,当我将
7-bit
值写入16-bit
字中的这些单个字节时:
x.full_8_char_byte[0] = 0x7E;
x.full_8_char_byte[1] = 0x7E;
The following simple program: 下面的简单程序:
int main()
{
ip_char_t x;
x.full_8_char_byte[0] = 0x7E;
x.full_8_char_byte[1] = 0x7E;
printf("%c %c\n", x.full_8_char_byte[1], x.full_8_char_byte[0]);
printf("%u %u\n", x.full_8_char_byte[1], x.full_8_char_byte[0]);
printf("%X %X\n\n", x.full_8_char_byte[1], x.full_8_char_byte[0]);
printf("%c %c\n", x.ascii_7_bits_word_1, x.ascii_7_bits_word_0);
printf("%u %u\n", x.ascii_7_bits_word_1, x.ascii_7_bits_word_0);
printf("%X %X\n\n", x.ascii_7_bits_word_1, x.ascii_7_bits_word_0);
printf("%d %d\n", x.parity_bit_word_1, x.parity_bit_word_0);
return 0;
}
gives the correct output as follows: 给出正确的输出,如下所示:
~ ~
126 126
7E 7E
~ ~
126 126
7E 7E
0 0
but when I initialized x.full_8_char_byte[1] to a 8-bit value
: 但是当我将
x.full_8_char_byte[1] to a 8-bit value
初始化x.full_8_char_byte[1] to a 8-bit value
:
x.full_8_char_byte[0] = 0x7E;
x.full_8_char_byte[1] = 0xFF;
the output I get is: 我得到的输出是:
� ~
255 126
FF 7E
~ ~
126 126
7E 7E
0 0
Similar thing happens when I initialize x.full_8_char_byte[0] to 0xFF
, my question is why the value in x.ascii_7_bits_word_1
and x.parity_bit_word_1
did not reflected per change in x.full_8_char_byte[1]
? 当我将
x.full_8_char_byte[0] to 0xFF
初始化x.full_8_char_byte[0] to 0xFF
,会发生类似的事情,我的问题是为什么x.ascii_7_bits_word_1
和x.parity_bit_word_1
的值不反映x.full_8_char_byte[1]
每个更改?
Looking at this: 看这个:
typedef union {
uint8_t full_8_char_byte[2];
uint8_t ascii_7_bits_word_0 : 7; /* another way of representing LSP 7 ASCII bits */
uint8_t parity_bit_word_0 : 1; /* another way of representing MSP parity bit */
uint8_t ascii_7_bits_word_1 : 7; /* another way of representing LSP 7 ASCII bits */
uint8_t parity_bit_word_1 : 1; /* another way of representing MSP parity bit */
} ip_char_t;
The comments suggest you expect the 4 bitfield members to map the bits of the first array member. 这些注释建议您期望4位字段成员映射第一个数组成员的位。 That won't work, because all members of a
union
are alternative possible contents, which also means every member will be placed at the very beginning. 那是行不通的,因为
union
所有成员都是其他可能的内容,这也意味着每个成员都将放在最开始的位置。 What you probably meant to write instead is 您可能要写的是
typedef union {
uint8_t full_8_char_byte[2];
struct {
uint8_t ascii_7_bits_word_0 : 7; /* another way of representing LSP 7 ASCII bits */
uint8_t parity_bit_word_0 : 1; /* another way of representing MSP parity bit */
uint8_t ascii_7_bits_word_1 : 7; /* another way of representing LSP 7 ASCII bits */
uint8_t parity_bit_word_1 : 1; /* another way of representing MSP parity bit */
};
} ip_char_t;
So this union can either contain your array or a struct with bitfields. 所以,这个联盟可以包含你的阵列或与位域的结构体。
Note that this doesn't solve your problem in a portable way: There are no strict guarantees about how your bitfield will be arranged, see Leushenko's comment for details! 请注意,这不能以一种可移植的方式解决您的问题:对于位域的排列方式没有严格的保证,有关详细信息,请参阅Leushenko的评论! For solving this problem portably, you can for example provide macros to access the individual bits, eg
为了可移植地解决此问题,您可以例如提供宏来访问各个位,例如
typedef uint8_t ip_char_t[2];
#define ascii_7_bits_word(x,i) ((x)[i] & 0x7f)
#define parity_bit_word(x,i) ((x)[i] >> 7)
Or, if you also need to write to the bits or want to enforce type safety, write (inline) functions instead. 或者,如果您还需要写入这些位或要强制执行类型安全性,请改用写入(内联)函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.