简体   繁体   English

提取C中16位并集的位位置

[英]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 bits8th 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_1x.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM