我想在C中声明一个union
,主要包含一个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;
现在,当我将7-bit
值写入16-bit
字中的这些单个字节时:
x.full_8_char_byte[0] = 0x7E;
x.full_8_char_byte[1] = 0x7E;
以下简单程序:
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;
}
给出正确的输出,如下所示:
~ ~
126 126
7E 7E
~ ~
126 126
7E 7E
0 0
但是当我初始化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;
我得到的输出是:
� ~
255 126
FF 7E
~ ~
126 126
7E 7E
0 0
类似的事情在我初始化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]
的每次更改?
答案 0 :(得分:4)
看这个:
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;
注释建议您期望4位字段成员映射第一个数组成员的位。这是行不通的,因为union
的所有成员是可能的替代内容,这也意味着每个成员都将放在最开始的位置。您可能打算写的是
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;
因此,此联合可以 包含数组或具有位域的结构。
请注意,这不能以便携式方式解决您的问题:对于位域的排列方式没有严格的保证,有关详细信息,请参阅Leushenko的评论!为了可移植地解决此问题,例如,您可以提供宏来访问各个位,例如
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)
或者,如果您还需要写入这些位或想要加强类型安全性,请改为编写(内联)函数。