You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中如何将struct结构体变量转换为uint8_t数组

问题原因

这个问题是C语言默认的结构体内存对齐机制导致的。为了提升内存访问效率,编译器会在结构体成员之间插入无意义的填充字节,保证每个成员的地址符合自身对齐要求。
你的结构体实际内存布局如下:

  • time(2字节)→ lat(2字节)→ ns(1字节)→ 1字节填充 → lon(2字节)→ ew(1字节)→ 1字节填充(结构体整体对齐到2字节边界)
    整个结构体的实际长度是10字节而非你预期的8字节,直接用memcpy拷贝会把无意义的填充字节也写入数组,甚至你的ew成员根本没有被拷贝到长度为8的数组里,所以结果不符合预期。

解决方法

方法1:手动序列化(推荐,跨平台通用)

手动逐个将结构体成员的字节写入数组,完全不受编译器对齐规则影响,还可以自主控制字节序,兼容性最高:

// 以下代码按小端序写入,和你原有memcpy的字节序逻辑保持一致
msg_arr[0] = (uint8_t)(msg.time & 0xFF);
msg_arr[1] = (uint8_t)((msg.time >> 8) & 0xFF);
msg_arr[2] = (uint8_t)(msg.lat & 0xFF);
msg_arr[3] = (uint8_t)((msg.lat >> 8) & 0xFF);
msg_arr[4] = msg.ns;
msg_arr[5] = (uint8_t)(msg.lon & 0xFF);
msg_arr[6] = (uint8_t)((msg.lon >> 8) & 0xFF);
msg_arr[7] = msg.ew;

运行后得到的数组就是预期结果:[52, 18, 34, 33, 110, 52, 34, 101]。

方法2:取消结构体对齐

用编译器专属指令声明结构体为紧凑无填充布局,之后直接用memcpy即可:

GCC/Clang 环境:

typedef struct __attribute__((packed)) message_t
{
    uint16_t time;
    uint16_t lat;   
    uint8_t ns;  
    uint16_t lon;  
    uint8_t ew;  
} message;

MSVC 环境:

#pragma pack(1)
typedef struct message_t
{
    uint16_t time;
    uint16_t lat;   
    uint8_t ns;  
    uint16_t lon;  
    uint8_t ew;  
} message;
#pragma pack()

声明完成后直接调用memcpy(msg_arr, &msg, 8);即可得到正确结果。


内容的提问来源于stack exchange,提问作者lei lei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 06:36:05