代码之家  ›  专栏  ›  技术社区  ›  Akay

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

  •  1
  • Akay  · 技术社区  · 7 年前

    我想申报 union 在C中,主要包含 16-bit 我应该可以读/写 LSP公司 7 bits 8th bit 中的每个字节 16位 所以我声明如下:

    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位 文字:

    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] ?

    1 回复  |  直到 7 年前
        1
  •  4
  •   user2371524user2371524    7 年前

    看看这个:

    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位字段成员映射第一个数组成员的位。那不行,因为 全部的 a的成员 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)
    

    或者,如果您还需要写入位,或者希望强制类型安全性,请改为写入(内联)函数。