【问题标题】:C: Typecasting with bitfields reverses values?C:使用位域进行类型转换会反转值?
【发布时间】:2023-02-02 16:53:47
【问题描述】:

我正在尝试将字节流(来自串行端口的原始数据)转换为易于使用的结构。我设法在一个最小的工作示例中复制了这个问题:

#include <stdio.h>

typedef struct {
    unsigned int source: 4;
    unsigned int destination: 4;
    char payload[15];
} packet;

int main(void)
{
    // machine 9 sends a message to machine 10 (A)
    char raw[20] = {0x9A, 'H', 'e', 'l', 'l', 'o', '!', 0};
    packet *message = (packet *)raw;
    printf("machine %d ", message->source);
    printf("says '%s' to ", message->payload);
    printf("machine %d.\n", message->destination);
    return 0;
}

我希望字段 source0x9A 得到 9destination0x9A 得到 A 所以输出说:

machine 9 says 'Hello!' to machine 10.

但我得到:

machine 10 says 'Hello!' to machine 9.

知道为什么会这样吗?

【问题讨论】:

    标签: c struct casting bit-fields


    【解决方案1】:

    问题在于您将原始数据解释为数据包结构的方式。字段源和目标被定义为 4 位字段,这意味着它们只能保存 0 到 15 之间的值。但是,当您将原始数据转换为数据包指针时,您将原始数据的第一个字节解释为 8位整数,而不是两个 4 位整数。

    要获得所需的行为,您需要从原始数据的第一个字节中提取源和目标的值,并将它们存储在单独的变量中,然后再将它们存储在数据包结构中。这是一种方法:

    #include <stdio.h>
    
    typedef struct {
    unsigned int source: 4;
    unsigned int destination: 4;
    char payload[15];
    } packet;
    
    int main(void)
    {
    // machine 9 sends a message to machine 10 (A)
    char raw[20] = {0x9A, 'H', 'e', 'l', 'l', 'o', '!', 0};
    unsigned char source = raw[0] >> 4;
    unsigned char destination = raw[0] & 0x0F;
    
    packet message;
    message.source = source;
    message.destination = destination;
    memcpy(message.payload, &raw[1], sizeof(message.payload));
    
    printf("machine %d ", message.source);
    printf("says '%s' to ", message.payload);
    printf("machine %d.
    ", message.destination);
    return 0;
    }
    

    此代码应产生所需的输出:

    机器 9 说“你好!”加工 10。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 2015-10-17
      • 2021-11-27
      • 1970-01-01
      • 2021-10-18
      相关资源
      最近更新 更多